vendor/pierre-granger/apidae-core/src/ApidaeCore.php line 51

  1. <?php
  2. namespace PierreGranger;
  3. use PierreGranger\ApidaeTimer;
  4. use PierreGranger\ApidaeException;
  5. /**
  6.  *
  7.  * @author  Pierre Granger <pierre.granger@apidae-tourisme.com>
  8.  *
  9.  */
  10. class ApidaeCore
  11. {
  12.     private static $url_api = [
  13.         'prod' => 'https://api.apidae-tourisme.com/',
  14.         'dev' => 'https://api.apidae-tourisme.dev/',
  15.         'cooking' => 'https://api.apidae-tourisme.cooking/'
  16.     ];
  17.     private static $url_base = [
  18.         'prod' => 'https://base.apidae-tourisme.com/',
  19.         'dev' => 'https://base.apidae-tourisme.dev/',
  20.         'cooking' => 'https://base.apidae-tourisme.cooking/'
  21.     ];
  22.     /**
  23.      *
  24.      * @var string prod|dev|cooking
  25.      */
  26.     private $env 'prod';
  27.     protected $timeout 15// secondes
  28.     protected $debug;
  29.     protected $timer;
  30.     public static $idApidae = [11157]; // Identifiants des membres Auvergne - Rhône-Alpes Tourisme et Apidae Tourisme
  31.     protected $_config;
  32.     private $token_cache;
  33.     protected $lastPostfields;
  34.     protected $lastResult;
  35.     protected $custom_url_api null;
  36.     protected $custom_url_base null;
  37.     public function __construct(array $params null)
  38.     {
  39.         if (isset($params['debug'])) {
  40.             $this->debug $params['debug'] ? true false;
  41.         }
  42.         if (isset($params['type_prod']) && !isset($params['env'])) {
  43.             $params['env'] = $params['type_prod'];
  44.         }
  45.         if (isset($params['env'])) {
  46.             if (in_array($params['env'], array_keys(self::$url_api))) {
  47.                 $this->env $params['env'];
  48.             } else {
  49.                 throw new ApidaeException(''ApidaeException::NO_PROD);
  50.             }
  51.         }
  52.         if (isset($params['url_api'])) {
  53.             $this->custom_url_api $params['url_api'];
  54.         }
  55.         if (isset($params['url_base'])) {
  56.             $this->custom_url_base $params['url_base'];
  57.         }
  58.         if (in_array($this->env, ['preprod''dev'])) {
  59.             $this->timeout 30;
  60.         }
  61.         $this->_config $params;
  62.         if (isset($params['timer'])) {
  63.             $this->timer $params['timer'] ? true false;
  64.         }
  65.         if ($this->timer) {
  66.             $this->timer = new ApidaeTimer(true);
  67.         }
  68.         $this->token_store = [];
  69.     }
  70.     public function url_base()
  71.     {
  72.         if ($this->custom_url_base != null) {
  73.             return $this->custom_url_base;
  74.         }
  75.         return self::$url_base[$this->env];
  76.     }
  77.     public function url_api()
  78.     {
  79.         if ($this->custom_url_api != null) {
  80.             return $this->custom_url_api;
  81.         }
  82.         return self::$url_api[$this->env];
  83.     }
  84.     public function setTimeout(int $timeout)
  85.     {
  86.         if ((int)$timeout && (int)$timeout 300) {
  87.             $this->timeout = (int)$timeout;
  88.         }
  89.     }
  90.     public function gimme_token($clientId null$secret null$debugToken false)
  91.     {
  92.         $this->start(__METHOD__);
  93.         $clientId = ($clientId != null) ? $clientId : (isset($this->projet_ecriture_clientId) ? $this->projet_ecriture_clientId null);
  94.         $secret = ($secret != null) ? $secret : (isset($this->projet_ecriture_secret) ? $this->projet_ecriture_secret null);
  95.         if ($clientId == null || $secret == null) {
  96.             $this->stop(__METHOD__);
  97.             throw new ApidaeException('no clientId'ApidaeException::MISSING_PARAMETER);
  98.         }
  99.         if (isset($this->token_cache[$clientId])) {
  100.             $this->stop(__METHOD__'token on token_cache');
  101.             return $this->token_cache[$clientId];
  102.         }
  103.         $result $this->request('/oauth/token', [
  104.             'USERPWD' => $clientId ":" $secret,
  105.             'POSTFIELDS' => "grant_type=client_credentials",
  106.             'format' => 'json'
  107.         ]);
  108.         if ($result['code'] != 200) {
  109.             $this->stop(__METHOD__);
  110.             throw new ApidaeException('invalid token'ApidaeException::INVALID_TOKEN, [
  111.                 'debug' => $this->debug,
  112.                 'result' => $result
  113.             ]);
  114.         }
  115.         $this->stop(__METHOD__);
  116.         $this->token_cache[$clientId] = $result['access_token'];
  117.         return $result['access_token'];
  118.     }
  119.     public function debug($var$titre null)
  120.     {
  121.         if (!$this->debug) {
  122.             return;
  123.         }
  124.         if (php_sapi_name() !== 'cli') {
  125.             echo '<p style="font-size:16px;font-weight:bold ;">[debug] ' . (($titre !== null) ? $titre '') . ' / ' gettype($var) . '</p>' PHP_EOL;
  126.             echo '<pre style="color:white;background:black;font-family:monospace;font-size:8px;width:100%;max-height:500px;overflow:auto;">' PHP_EOL;
  127.             if (is_object($var) || gettype($var) == 'boolean') {
  128.                 print_r($var);
  129.             } elseif (is_array($var) || $this->isJson($var)) {
  130.                 echo json_encode($varJSON_PRETTY_PRINT);
  131.             } else {
  132.                 echo $var;
  133.             }
  134.             echo PHP_EOL '</pre>' PHP_EOL;
  135.         } else {
  136.             if ($titre) {
  137.                 echo $titre PHP_EOL;
  138.             }
  139.             if (is_object($var) || gettype($var) == 'boolean') {
  140.                 print_r($var);
  141.             } elseif (is_array($var) || $this->isJson($var)) {
  142.                 echo json_encode($varJSON_PRETTY_PRINT);
  143.             } else {
  144.                 echo $var;
  145.             }
  146.             echo PHP_EOL;
  147.         }
  148.     }
  149.     // https://stackoverflow.com/questions/6041741/fastest-way-to-check-if-a-string-is-json-in-php
  150.     protected function isJson($string)
  151.     {
  152.         json_decode($string);
  153.         return (json_last_error() == JSON_ERROR_NONE);
  154.     }
  155.     public function alerte($sujet$msg$mailto null$options null)
  156.     {
  157.         if (is_array($this->_config['mail_admin'])) {
  158.             foreach ($this->_config['mail_admin'] as $mail_admin) {
  159.                 if (!filter_var($mail_adminFILTER_VALIDATE_EMAIL)) {
  160.                     throw new \Exception(__LINE__ ' mail admin incorrect : ' $mail_admin);
  161.                 }
  162.                 if (!isset($first_mail_admin)) {
  163.                     $first_mail_admin $mail_admin;
  164.                 }
  165.             }
  166.             $mails_admin $this->_config['mail_admin'];
  167.         } else {
  168.             if (!filter_var($this->_config['mail_admin'], FILTER_VALIDATE_EMAIL)) {
  169.                 throw new \Exception(__LINE__ ' mail admin incorrect : ' $this->_config['mail_admin']);
  170.             }
  171.             $first_mail_admin $this->_config['mail_admin'];
  172.             $mails_admin = [$this->_config['mail_admin']];
  173.         }
  174.         $from = (isset($this->_config['mail_expediteur']) && filter_var($this->_config['mail_expediteur'], FILTER_VALIDATE_EMAIL)) ? $this->_config['mail_expediteur'] : $first_mail_admin;
  175.         if (is_array($mailto)) {
  176.             foreach ($mailto as $mt) {
  177.                 if (!filter_var($mtFILTER_VALIDATE_EMAIL)) {
  178.                     throw new \Exception(__LINE__ ' mail to incorrect' print_r($mttrue));
  179.                 }
  180.             }
  181.         } elseif ($mailto !== null) {
  182.             if (!filter_var($mailtoFILTER_VALIDATE_EMAIL)) {
  183.                 throw new \Exception(__LINE__ ' mail to incorrect' print_r($mailtotrue));
  184.             }
  185.             $mailto = [$mailto];
  186.         } else {
  187.             $mailto $mails_admin;
  188.         }
  189.         $endline "\n";
  190.         $h1 strip_tags($sujet);
  191.         $sujet $h1;
  192.         if (is_array($msg)) {
  193.             $new_msg null;
  194.             if (isset($msg['message'])) {
  195.                 $new_msg .= $msg['message'];
  196.                 unset($msg['message']);
  197.             }
  198.             unset($msg['x']);
  199.             unset($msg['y']);
  200.             $tble '<table style="clear:both; background:#FFF ; font-size:11px ; margin-bottom:20px ;" border="1" cellspacing="0" cellpadding="6">';
  201.             foreach ($msg as $key => $value) {
  202.                 $tble .= '<tr>';
  203.                 $tble .= '<th><strong>' ucfirst($key) . '</strong></th>';
  204.                 $tble .= '<td>';
  205.                 if (!is_array($value)) {
  206.                     $tble .= stripslashes(nl2br($value));
  207.                 } else {
  208.                     $tble .= '<pre>' json_encode($valueJSON_PRETTY_PRINT) . '</pre>';
  209.                 }
  210.                 $tble .= '</td>';
  211.                 $tble .= '</tr>';
  212.             }
  213.             $tble .= '</table>';
  214.             $new_msg .= $tble;
  215.             $msg $new_msg;
  216.         }
  217.         $message_html '<html style="text-align : center; margin : 0; padding:0 ; font-family:Verdana ;font-size:10px ;">' $endline;
  218.         $message_html .= '<div style="text-align:left ;">' $endline;
  219.         $message_html .= '<div>' $msg '</div>' $endline;
  220.         $message_html .= '</div>' $endline;
  221.         $message_html .= '</html>' $endline;
  222.         $message_texte strip_tags(nl2br($message_html));
  223.         $mail = new \PHPMailer\PHPMailer\PHPMailer();
  224.         $mail->setFrom($from);
  225.         foreach ($mailto as $t) {
  226.             $mail->addAddress($t);
  227.         }
  228.         foreach ($mails_admin as $mail_admin) {
  229.             $mail->AddBCC($mail_admin);
  230.         }
  231.         $mail->CharSet 'UTF-8';
  232.         $mail->isHTML(true);
  233.         $mail->Subject $sujet;
  234.         $mail->Body $message_html;
  235.         $mail->AltBody $message_texte;
  236.         return $mail->send();
  237.     }
  238.     public function start($titre$details null)
  239.     {
  240.         if ($this->timer) {
  241.             $this->timer->start($titre$details);
  242.         }
  243.     }
  244.     public function stop($titre$details null)
  245.     {
  246.         if ($this->timer) {
  247.             $this->timer->stop($titre$details);
  248.         }
  249.     }
  250.     public function timer()
  251.     {
  252.         if ($this->timer) {
  253.             $this->timer->timer();
  254.         }
  255.     }
  256.     public function showException($e)
  257.     {
  258.         ApidaeException::showException($e);
  259.     }
  260.     /**
  261.      * Cette fonction a pour but de gérer tous les appels aux API Apidae.
  262.      * Elle ne gère pas les erreurs elle-même, parce que selon les cas les erreurs n'ont pas la même signifiation :
  263.      * un retour 404 sur un objet est acceptable, mais il ne l'est pas sur un "getUserProfile" par exemple (qui suppose que l'utilisateur soit identifié, et donc qu'il existe)
  264.      *
  265.      * @param    string    $path    chemin relatif vers l'API (/api/v002/...)
  266.      * @param    array|null    $params    paramètres
  267.      * @param    string    $params['format']    Si json : déclenchera une exception en cas de retour non json
  268.      * @param    string    $params['POST']
  269.      * @param    string    $params['CUSTOMREQUEST']    PUT
  270.      * @param    string    $params['POSTFIELDS']
  271.      * @param    string    $params['USERPWD']    couple clientId:secret
  272.      * @param    array    $params['header']
  273.      * @param    string    $params['token']    token, récupéré le plus souvent avec gimme_token
  274.      * @param    string    $params['url_type']    api|base (default : api)
  275.      * @see        ApidaeSso::getSsoToken
  276.      * @see        ApidaeSso::refreshSsoToken
  277.      * @see        ApidaeSso::getUserProfile
  278.      * @see        ApidaeSso::getUserPermissionOnObject
  279.      *
  280.      */
  281.     protected function request(string $path$params null)
  282.     {
  283.         $this->lastResult null;
  284.         $expr '#^(/api/v002)?/[a-zA-Z0-9-_/]+#ui';
  285.         if (!preg_match($expr$path)) {
  286.             throw new ApidaeException('request : wrong path'ApidaeException::INVALID_PARAMETER, [
  287.                 'debug' => $this->debug,
  288.                 'method' => __METHOD__,
  289.                 'preg_fail' => $expr ' failed on ' $path
  290.             ]);
  291.         }
  292.         $header = [];
  293.         if (isset($params['header'])) {
  294.             $header $params['header'];
  295.         }
  296.         $header[] = 'Accept: application/json';
  297.         if (isset($params['token'])) {
  298.             $header[] = "Authorization: Bearer " $params['token'];
  299.         }
  300.         if (isset($params['url_type']) && $params['url_type'] == 'base') {
  301.             $url $this->url_base() . $path;
  302.         } else {
  303.             $url $this->url_api() . $path;
  304.         }
  305.         // Remplacement des // par /
  306.         $url preg_replace('#([^:])//#''$1/'$url);
  307.         $ch curl_init();
  308.         $curl_opts = [];
  309.         $curl_opts[CURLOPT_URL] = $url;
  310.         if (sizeof($header) > 0) {
  311.             $curl_opts[CURLOPT_HTTPHEADER] = $header;
  312.         }
  313.         if (isset($params['USERPWD'])) {
  314.             $curl_opts[CURLOPT_USERPWD] = $params['USERPWD'];
  315.         }
  316.         if (isset($params['POSTFIELDS'])) {
  317.             $curl_opts[CURLOPT_POSTFIELDS] = $params['POSTFIELDS'];
  318.             $this->lastPostfields $params['POSTFIELDS'];
  319.         }
  320.         if (isset($params['CUSTOMREQUEST'])) {
  321.             $curl_opts[CURLOPT_CUSTOMREQUEST] = $params['CUSTOMREQUEST'];
  322.         }
  323.         if (isset($params['POST'])) {
  324.             $curl_opts[CURLOPT_POST] = $params['POST'];
  325.         }
  326.         $curl_opts[CURLOPT_HEADER] = true;
  327.         $curl_opts[CURLOPT_SSL_VERIFYPEER] = false;
  328.         /** Le verbose affiche surtout des infos d'identification, en général peu utiles */
  329.         //$curl_opts[CURLOPT_VERBOSE] = $this->debug;
  330.         $curl_opts[CURLOPT_ENCODING] = 'UTF-8';
  331.         $curl_opts[CURLOPT_RETURNTRANSFER] = true;
  332.         $curl_opts[CURLOPT_FOLLOWLOCATION] = true;
  333.         $curl_opts[CURLOPT_CONNECTTIMEOUT] = $this->timeout;
  334.         $curl_opts[CURLOPT_TIMEOUT] = $this->timeout;
  335.         curl_setopt_array($ch$curl_opts);
  336.         $response curl_exec($ch);
  337.         if ($response === false) {
  338.             $details = [
  339.                 'curl_error' => curl_error($ch),
  340.                 'curl_opts' => $curl_opts
  341.             ];
  342.             throw new ApidaeException('curl_response false'ApidaeException::NO_RESPONSE$details);
  343.         }
  344.         $header_size curl_getinfo($chCURLINFO_HEADER_SIZE);
  345.         $return = [
  346.             'code' => curl_getinfo($chCURLINFO_HTTP_CODE),
  347.             'header' => substr($response0$header_size),
  348.             'body' => substr($response$header_size)
  349.         ];
  350.         $body_array json_decode($return['body'], true);
  351.         if (json_last_error() == JSON_ERROR_NONE) {
  352.             if (is_array($body_array)) {
  353.                 $return array_merge($return$body_array);
  354.             }
  355.         } elseif (isset($params['format']) && $params['format'] == 'json') {
  356.             $details = [
  357.                 'debug' => $this->debug,
  358.                 'curl_opts' => $curl_opts,
  359.                 'return' => @$return
  360.             ];
  361.             throw new ApidaeException('response body is not json'ApidaeException::NO_JSON$details);
  362.         }
  363.         $this->lastResult $return;
  364.         return $return;
  365.     }
  366.     /**
  367.      * Renvoie le détail de $result de ApidaeCore::request
  368.      * En cas de retour correct, renvoie un tableau :
  369.      * [
  370.      *     'code' => 200,
  371.      *     'header' => 'HTTP/1.1 100 Continue...',
  372.      *     'body' => '{"status":"MODIFICATION_VALIDATION_ASKED"}',
  373.      *     'object' => {
  374.      *         'status' => 'MODIFICATION_VALIDATION_ASKED'
  375.      *     }
  376.      *     'array' => [
  377.      *         'status' => 'MODIFICATION_VALIDATION_ASKED'
  378.      *     ]
  379.      * ]
  380.      *
  381.      * Exemple erreur
  382.      * [
  383.      *     'body' => '{"message":"Cet objet est déjà en cours de modification","errorType":"ECRITURE_FORBIDDEN}',
  384.      *     'object' => {
  385.      *         'message' => 'Cet objet...',
  386.      *         'errorType' => 'ECRITURE_FORBIDDEN,
  387.      *     },
  388.      *     'array' => [
  389.      *         'message' => 'Cet objet...',
  390.      *         'errorType' => 'ECRITURE_FORBIDDEN,
  391.      *     ]
  392.      * ]
  393.      */
  394.     public function lastResult()
  395.     {
  396.         return $this->lastResult;
  397.     }
  398.     public function lastPostfields()
  399.     {
  400.         return $this->lastPostfields;
  401.     }
  402.     public function lastRequest()
  403.     {
  404.         return $this->lastPostfields();
  405.     }
  406.     public function getEnv()
  407.     {
  408.         return $this->env ;
  409.     }
  410. }