BaseRequestXml.php 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. <?php
  2. namespace NavOnlineInvoice;
  3. use Exception;
  4. abstract class BaseRequestXml {
  5. protected $rootName;
  6. protected $config;
  7. /**
  8. * @var \SimpleXMLElement
  9. */
  10. protected $xml;
  11. protected $requestId;
  12. protected $timestamp;
  13. const API_NS = "http://schemas.nav.gov.hu/OSA/3.0/api";
  14. const COMMON_NS = "http://schemas.nav.gov.hu/NTCA/1.0/common";
  15. /**
  16. * Request XML készítése
  17. *
  18. * @param Config $config Konfigurációt tartalmazó objektum
  19. */
  20. function __construct($config) {
  21. $this->config = $config;
  22. $this->createXml();
  23. }
  24. protected function createXml() {
  25. $this->requestId = $this->config->getRequestIdGenerator()->generate();
  26. $this->timestamp = $this->getTimestamp();
  27. $this->createXmlObject();
  28. $this->addHeader();
  29. $this->addUser();
  30. $this->addSoftware();
  31. }
  32. /**
  33. * A kérés kliens oldali időpontja UTC-ben, ezredmásodperccel
  34. *
  35. * @return string
  36. */
  37. protected function getTimestamp() {
  38. $now = microtime(true);
  39. $milliseconds = round(($now - floor($now)) * 1000);
  40. $milliseconds = min($milliseconds, 999);
  41. return gmdate("Y-m-d\TH:i:s", (int) $now) . sprintf(".%03dZ", $milliseconds);
  42. }
  43. protected function createXmlObject() {
  44. $this->xml = new \SimpleXMLElement($this->getInitialXmlString());
  45. }
  46. protected function getInitialXmlString() {
  47. if (empty($this->rootName)) {
  48. throw new Exception("rootName has to be defined!");
  49. }
  50. return '<?xml version="1.0" encoding="UTF-8"?><' . $this->rootName . ' xmlns:common="' . self::COMMON_NS . '" xmlns="' . self::API_NS . '"></' . $this->rootName . '>';
  51. }
  52. protected function addHeader() {
  53. $header = $this->xml->addChild("header", null, self::COMMON_NS);
  54. $header->addChild("requestId", $this->requestId);
  55. $header->addChild("timestamp", $this->timestamp);
  56. $header->addChild("requestVersion", "3.0");
  57. $header->addChild("headerVersion", "1.0");
  58. }
  59. protected function addUser() {
  60. $user = $this->xml->addChild("user", null, self::COMMON_NS);
  61. $passwordHash = isset($this->config->user["passwordHash"]) ? $this->config->user["passwordHash"] : Util::sha512($this->config->user["password"]);
  62. $signature = $this->getRequestSignatureHash();
  63. $user->addChild("login", $this->config->user["login"]);
  64. $user->addChild("passwordHash", $passwordHash)->addAttribute("cryptoType", "SHA-512");
  65. $user->addChild("taxNumber", $this->config->user["taxNumber"]);
  66. $user->addChild("requestSignature", $signature)->addAttribute("cryptoType", "SHA3-512");
  67. }
  68. protected function addSoftware() {
  69. if (!$this->config->software) {
  70. return;
  71. }
  72. $software = $this->xml->addChild("software");
  73. foreach ($this->config->software as $key => $value) {
  74. $software->addChild($key, $value);
  75. }
  76. }
  77. /**
  78. * Aláírás generálása.
  79. *
  80. * manageInvoice esetén (ManageInvoiceRequestXml osztályban) ez a metódus felülírandó,
  81. * mert máshogy kell számolni az értéket (más értékeket is össze kell fűzni).
  82. *
  83. * Kapcsolódó fejezet: 1.5 A requestSignature számítása
  84. */
  85. protected function getRequestSignatureHash() {
  86. $string = $this->getRequestSignatureString();
  87. $hash = Util::sha3_512($string);
  88. return $hash;
  89. }
  90. /**
  91. * Aláírás hash értékének számításához string-ek összefűzése és visszaadása
  92. *
  93. * manageInvoice esetén (ManageInvoiceRequestXml osztályban) ez a metódus felülírandó,
  94. * mert további értékeket is hozzá kell fűzni még.
  95. *
  96. * Kapcsolódó fejezet: 1.5 A requestSignature számítása
  97. */
  98. protected function getRequestSignatureString() {
  99. $string = "";
  100. // requestId értéke
  101. $string .= $this->requestId;
  102. // timestamp tag értéke yyyyMMddHHmmss maszkkal, UTC időben (ezredmásodperc nélkül)
  103. $string .= preg_replace("/\.\d{3}|\D+/", "", $this->timestamp);
  104. // technikai felhasználó aláíró kulcsának literál értéke
  105. $string .= $this->config->user["signKey"];
  106. return $string;
  107. }
  108. /**
  109. * XML objektum lekérése
  110. *
  111. * @return \SimpleXMLElement
  112. */
  113. public function getXML() {
  114. return $this->xml;
  115. }
  116. /**
  117. * XML adat lekérése string-ként
  118. *
  119. * @return string
  120. */
  121. public function asXML() {
  122. return $this->xml->asXML();
  123. }
  124. /**
  125. * A request XML-t validálja a NAV által biztosított 'invoiceApi.xsd'-vel.
  126. * Hiba esetén XsdValidationError exception-t dob.
  127. */
  128. public function validateSchema() {
  129. Xsd::validate($this->asXML(), Config::getApiXsdFilename());
  130. }
  131. public function getRequestId() {
  132. return $this->requestId;
  133. }
  134. }