src/Helpers/System/LoggerHelper.php line 21

Open in your IDE?
  1. <?php
  2. namespace App\Helpers\System;
  3. use Symfony\Component\DependencyInjection\ContainerInterface as Container;
  4. use Symfony\Component\Yaml\Parser;
  5. use Doctrine\ORM\EntityManagerInterface;
  6. use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
  7. use Symfony\Component\HttpFoundation\RequestStack;
  8. use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
  9. class LoggerHelper
  10. {
  11. protected $em;
  12. public function __construct(UrlGeneratorInterface $router, TokenStorageInterface $tokenStorage, EntityManagerInterface $entityManager, RequestStack $requestStack)
  13. {
  14. $this->router = $router;
  15. $this->token_storage = $tokenStorage;
  16. $this->em = $entityManager;
  17. $this->request = $requestStack;
  18. // Known identifiers
  19. $this->knownIdentifiers = [
  20. "BOOKING" => [
  21. "CREATE" => "created booking {{ BOOKING }}",
  22. "EDIT" => "edited booking {{ BOOKING }}",
  23. "DELETE" => "deleted {{ BOOKING }}",
  24. "CANCELLED" => "cancelled booking {{ BOOKING }}",
  25. "UNCANCELLED" => "uncancelled booking {{ BOOKING }}",
  26. "EDIT_ADD_ANIMAL" => "added {{ ANIMAL }} to booking {{ BOOKING }}",
  27. "EDIT_REMOVE_ANIMAL" => "removed {{ ANIMAL }} from booking {{ BOOKING }}",
  28. "EDIT_EDIT_ANIMAL" => "edited {{ ANIMAL }} on booking {{ BOOKING }}",
  29. "EDIT_ANIMAL_ADD_SERVICE" => "added the service '{{ SERVICE }}' to {{ ANIMAL }} on booking {{ BOOKING }}",
  30. "EDIT_ANIMAL_EDIT_SERVICE" => "edited the service '{{ SERVICE }}' for {{ ANIMAL }} on booking {{ BOOKING }}",
  31. "EDIT_ANIMAL_REMOVE_SERVICE" => "removed the service '{{ SERVICE }}' from {{ ANIMAL }} on booking {{ BOOKING }}",
  32. "EDIT_ADD_PAYMENT" => "added a payment on booking {{ BOOKING }}",
  33. "EDIT_REFUND_PAYMENT" => "refunded a payment from booking {{ BOOKING }}",
  34. "EDIT_REMOVE_PAYMENT" => "removed a payment from booking {{ BOOKING }}",
  35. "EDIT_EDIT_GUARDIAN" => "edited the guardian on booking {{ BOOKING }}",
  36. "EDIT_REVERSE_CHECKIN" => "reversed the check in for animal: {{ ANIMAL }} on booking {{ BOOKING }}",
  37. "EDIT_REVERSE_CHECKOUT" => "reversed the check out for animal: {{ ANIMAL }} on booking {{ BOOKING }}",
  38. "EDIT_DISCOUNT" => "updated the discount on booking {{ BOOKING }}"
  39. ],
  40. "ANIMAL" => [
  41. "CREATE" => "created {{ ANIMAL }}",
  42. "EDIT" => "edited {{ ANIMAL }}",
  43. "DELETE" => "deleted {{ ANIMAL }}",
  44. "EDIT_VET" => "edited the vet for animal: {{ ANIMAL }}",
  45. "REMOVE_VET" => "removed the vet from animal: {{ ANIMAL }}",
  46. "MARKED_DECEASED" => "marked the animal {{ ANIMAL }} as deceased",
  47. "UNMARKED_DECEASED" => "unmarked the animal {{ ANIMAL }} as deceased",
  48. "DOCUMENT_UPLOAD" => "uploaded a document to {{ ANIMAL }}",
  49. "DOCUMENT_DELETE" => "deleted a document from {{ ANIMAL }}"
  50. ],
  51. "CUSTOMER" => [
  52. "CREATE" => "created {{ CUSTOMER }}",
  53. "EDIT" => "edited {{ CUSTOMER }}",
  54. "EDIT_BLACKLIST" => "blacklisted customer {{ CUSTOMER }}",
  55. "EDIT_REMOVEBLACKLIST" => "un-blacklisted customer {{ CUSTOMER }}",
  56. "EDIT_ARCHIVE" => "archived customer {{ CUSTOMER }}",
  57. "EDIT_RESTORE" => "restored customer {{ CUSTOMER }}",
  58. "DELETE" => "deleted {{ CUSTOMER }}"
  59. ],
  60. "VET" => [
  61. "CREATE" => "created {{ VET }}",
  62. "EDIT" => "edited {{ VET }}",
  63. "DELETE" => "deleted {{ VET }}"
  64. ],
  65. "AGREEMENT" => [
  66. "CREATE" => "created {{ AGREEMENT }} for {{ CUSTOMER }}",
  67. "EDIT" => "edited {{ AGREEMENT }} for {{ CUSTOMER }}"
  68. ],
  69. "CUSTOMERAGREEMENT" => [
  70. "EMAIL" => "sent agreement {{ CUSTOMERAGREEMENT }} via email to {{ CUSTOMER }}",
  71. "DELETE" => "deleted {{ AGREEMENT }} for {{ CUSTOMER }}",
  72. "INVALIDATE" => "invalidated agreement {{ CUSTOMERAGREEMENT }} for {{ CUSTOMER }}"
  73. ],
  74. "PERMISSION" => [
  75. "EDIT" => "edited the permissions",
  76. ],
  77. "USER" => [
  78. "CREATE" => "created {{ USER }}",
  79. "EDIT" => "edited {{ USER }}",
  80. "DELETE" => "deleted {{ USER }}",
  81. "SUSPEND" => "suspended {{ USER }}"
  82. ],
  83. "SETTING" => [
  84. "CAPACITY_EDIT" => "edited capacity in settings",
  85. "VACCINATION_CREATE" => "created vaccination type: {{ VACCINATION }}",
  86. "VACCINATION_EDIT" => "edited vaccination type: {{ VACCINATION }}",
  87. "VACCINATION_DELETE" => "deleted vaccination type: {{ VACCINATION }}",
  88. "SERVICE_CREATE" => "created service: {{ SERVICE }}",
  89. "SERVICE_EDIT" => "edited service: {{ SERVICE }}",
  90. "SERVICE_DELETE" => "deleted service: {{ SERVICE }}",
  91. "MIXERCATEGORY_CREATE" => "created mixer category: {{ MIXERCATEGORY }}",
  92. "MIXERCATEGORY_EDIT" => "edited mixer category: {{ MIXERCATEGORY }}",
  93. "MIXERCATEGORY_DELETE" => "deleted mixer category: {{ MIXERCATEGORY }}",
  94. "ANIMALSIZE_CREATE" => "created animal size: {{ ANIMALSIZE }}",
  95. "ANIMALSIZE_EDIT" => "edited animal size: {{ ANIMALSIZE }}",
  96. "ANIMALSIZE_DELETE" => "deleted animal size: {{ ANIMALSIZE }}",
  97. "ANIMALTYPE_CREATE" => "created animal type: {{ ANIMALTYPE }}",
  98. "ANIMALTYPE_EDIT" => "edited animal type: {{ ANIMALTYPE }}",
  99. "ANIMALTYPE_DELETE" => "deleted animal type: {{ ANIMALTYPE }}",
  100. "PRICING_EDIT" => "edited pricing",
  101. "ADDITIONALCHARGE_CREATE" => "created the additional charge: {{ ADDITIONALCHARGE }}",
  102. "ADDITIONALCHARGE_EDIT" => "edited the additional charge: {{ ADDITIONALCHARGE }}",
  103. "ADDITIONALCHARGE_DELETE" => "deleted the additional charge: {{ ADDITIONALCHARGE }}",
  104. "DEPOSIT_CREATE" => "created the deposit type: {{ DEPOSIT }}",
  105. "DEPOSIT_EDIT" => "edited the deposit type: {{ DEPOSIT }}",
  106. "DEPOSIT_DELETE" => "deleted the deposit type: {{ DEPOSIT }}",
  107. "MEAL_CREATE" => "created the meal: {{ MEAL }}",
  108. "MEAL_EDIT" => "edited the meal: {{ MEAL }}",
  109. "MEAL_DELETE" => "deleted the meal: {{ MEAL }}",
  110. "MEALSIZE_CREATE" => "created the meal size: {{ MEALSIZE }}",
  111. "MEALSIZE_EDIT" => "edited the meal size: {{ MEALSIZE }}",
  112. "MEALSIZE_DELETE" => "deleted the meal size: {{ MEALSIZE }}",
  113. "AGREEMENT_CREATE" => "created the agreement: {{ AGREEMENT }}",
  114. "AGREEMENT_EDIT" => "edited the agreement: {{ AGREEMENT }}",
  115. "AGREEMENT_INVALIDATE" => "invalidated the agreement: {{ AGREEMENT }}",
  116. "AGREEMENT_DELETE" => "delete the agreement: {{ AGREEMENT }}",
  117. "OPENINGTIME_CREATE" => "created the opening time: {{ OPENINGTIME }}",
  118. "OPENINGTIME_EDIT" => "edited the opening time: {{ OPENINGTIME }}",
  119. "OPENINGTIME_DELETE" => "deleted the opening time: {{ OPENINGTIME }}",
  120. "BLOCKOUTDATE_CREATE" => "created the blockout date: {{ BLOCKOUTDATE }}",
  121. "BLOCKOUTDATE_EDIT" => "edited the blockout date: {{ BLOCKOUTDATE }}",
  122. "BLOCKOUTDATE_DELETE" => "deleted the blockout date: {{ BLOCKOUTDATE }}",
  123. "USERGROUP_CREATE" => "created the user group: {{ USERGROUP }}",
  124. "USERGROUP_EDIT" => "edited the user group: {{ USERGROUP }}",
  125. "USERGROUP_DELETE" => "deleted the user group: {{ USERGROUP }}",
  126. "MISC_EDIT" => "edited the misc settings",
  127. ],
  128. "HANDSONCHECKLIST" => [
  129. "CREATE" => "created {{ HANDSONCHECKLIST }}",
  130. "DELETE" => "deleted {{ HANDSONCHECKLIST }}"
  131. ],
  132. "LONGSTAYCHECKLIST" => [
  133. "CREATE" => "created {{ LONGSTAYCHECKLIST }}",
  134. "DELETE" => "deleted {{ LONGSTAYCHECKLIST }}"
  135. ]
  136. ];
  137. }
  138. public function record($identifier = null, $data = array())
  139. {
  140. $identifier = strtoupper($identifier);
  141. // Split the itentifier up
  142. $identifierBits = explode("_", $identifier);
  143. // The area which the identifier belongs to
  144. $identifierSection = $identifierBits[0];
  145. // The rest of the identifier
  146. unset($identifierBits[0]);
  147. $identifierAction = implode("_", $identifierBits);
  148. // Check if identifier section exists
  149. if(!array_key_exists($identifierSection, $this->knownIdentifiers))
  150. throw new \Exception("Section identifier '" . $identifierSection . "' does not exist.");
  151. // Check if identifier is valid
  152. if(!array_key_exists($identifierAction, $this->knownIdentifiers[$identifierSection]))
  153. throw new \Exception("Identifier '" . $identifier . "' is not a known identifier.");
  154. // Fetch the action into a variable
  155. $action = $this->knownIdentifiers[$identifierSection][$identifierAction];
  156. // Build data array
  157. $formattedData = array();
  158. // Loop the data
  159. foreach($data AS $key => $someData)
  160. {
  161. $formattedData[$key] = array(
  162. 'id' => $someData->getId(),
  163. 'label' => $someData->__toString(),
  164. 'class' => get_class($someData)
  165. );
  166. }
  167. // Count the number of tags in string
  168. preg_match_all('/(?<={)[^}]*(?=})/', $action, $tagMatches);
  169. // Inconsistent tag matches?
  170. if(count($tagMatches[0]) != count($formattedData))
  171. throw new \Exception("Inconsistent tag matches. You have provided " . count($formattedData) . ' data parameters. ' . count($tagMatches) . ' required!');
  172. // Create new instance of audit log
  173. $auditLog = new \App\Entity\System\AuditLog([
  174. "ipAddress" => $_SERVER['REMOTE_ADDR'],
  175. "url" => $this->request->getCurrentRequest()->getRequestUri(),
  176. "identifier" => $identifier,
  177. "data" => $formattedData,
  178. "user" => $this->token_storage->getToken()->getUser()
  179. ]);
  180. // Persist and flush
  181. $this->em->persist($auditLog);
  182. $this->em->flush($auditLog);
  183. return;
  184. }
  185. public function render(?\App\Entity\System\AuditLog $auditLog = null)
  186. {
  187. if(!$auditLog)
  188. throw new \Exception("Audit log must be provided!");
  189. // Get identifier
  190. $identifier = $auditLog->getIdentifier();
  191. // Split the itentifier up
  192. $identifierBits = explode("_", $identifier);
  193. // The area which the identifier belongs to
  194. $identifierSection = $identifierBits[0];
  195. // The rest of the identifier
  196. unset($identifierBits[0]);
  197. $identifierAction = implode("_", $identifierBits);
  198. // Fetch the action into a variable
  199. $action = $this->knownIdentifiers[$identifierSection][$identifierAction];
  200. // No action?
  201. if(!$action)
  202. return 'Unsupported action';
  203. // Loop data to inject data
  204. foreach($auditLog->getData() AS $key => $someData)
  205. {
  206. // Uppercase key
  207. $tag = strtoupper($key);
  208. // Search for the object
  209. $entity = $this->em->getRepository($someData['class'])->findOneFiltered(array(
  210. 'id' => $someData['id'],
  211. ));
  212. // Found an entity
  213. if($entity)
  214. {
  215. // Get associated url
  216. $url = $this->getEntityUrl($entity);
  217. // Inject the tags with links
  218. if($url)
  219. $action = str_replace("{{ " . $tag . " }}", '<a href="' . $url . '">' . $someData['label'] . '</a>', $action);
  220. else
  221. $action = str_replace("{{ " . $tag . " }}", $someData['label'], $action);
  222. }
  223. else
  224. $action = str_replace("{{ " . $tag . " }}", $someData['label'], $action);
  225. }
  226. // Got a user?
  227. if($auditLog->getUser())
  228. $action = $auditLog->getUser()->getName() . " " . $action;
  229. // Return the action
  230. return $action;
  231. }
  232. public function getEntityUrl($entity = null)
  233. {
  234. if(!$entity)
  235. throw new \Exception("Provide an entity when looking up a url");
  236. if($entity instanceof \App\Entity\Animals\Animal)
  237. {
  238. return $this->router->generate("animals_view", array(
  239. 'animal_uuid' => $entity->getUuid()
  240. ));
  241. }
  242. elseif($entity instanceof \App\Entity\Bookings\Booking)
  243. {
  244. return $this->router->generate("bookings_edit", array(
  245. 'booking_uuid' => $entity->getUuid()
  246. ));
  247. }
  248. elseif($entity instanceof \App\Entity\Bookings\Item)
  249. {
  250. return $this->router->generate("bookings_edit", array(
  251. 'booking_uuid' => $entity->getBooking()->getUuid()
  252. ));
  253. }
  254. elseif($entity instanceof \App\Entity\Customers\Customer)
  255. {
  256. return $this->router->generate("customers_edit", array(
  257. 'customer_uuid' => $entity->getUuid()
  258. ));
  259. }
  260. elseif($entity instanceof \App\Entity\Users\User)
  261. {
  262. return $this->router->generate("users_edit", array(
  263. 'user_uuid' => $entity->getUuid()
  264. ));
  265. }
  266. elseif($entity instanceof \App\Entity\Vets\Vet)
  267. {
  268. return $this->router->generate("vets_view", array(
  269. 'vet_uuid' => $entity->getUuid()
  270. ));
  271. }
  272. elseif($entity instanceof \App\Entity\Agreements\Agreement)
  273. {
  274. return $this->router->generate("settings_agreements_edit", array(
  275. 'agreement_uuid' => $entity->getUuid()
  276. ));
  277. }
  278. elseif($entity instanceof \App\Entity\Customers\Agreement)
  279. {
  280. return $this->router->generate("customers_view_agreements_download", array(
  281. 'agreement_uuid' => $entity->getUuid(),
  282. 'customer_uuid' => $entity->getCustomer()->getUuid()
  283. ));
  284. }
  285. elseif($entity instanceof \App\Entity\Services\AdditionalCharge)
  286. {
  287. return $this->router->generate("settings_additionalcharges_edit", array(
  288. 'additionalcharge_uuid' => $entity->getUuid()
  289. ));
  290. }
  291. elseif($entity instanceof \App\Entity\Services\Deposit)
  292. {
  293. return $this->router->generate("settings_deposits_edit", array(
  294. 'deposit_uuid' => $entity->getUuid()
  295. ));
  296. }
  297. elseif($entity instanceof \App\Entity\Users\Group)
  298. {
  299. return $this->router->generate("settings_usergroups_edit", array(
  300. 'group_uuid' => $entity->getUuid()
  301. ));
  302. }
  303. elseif($entity instanceof \App\Entity\System\BlockoutDate)
  304. {
  305. return $this->router->generate("settings_blockoutdates_edit", array(
  306. 'date_uuid' => $entity->getUuid()
  307. ));
  308. }
  309. elseif($entity instanceof \App\Entity\Meals\Size)
  310. {
  311. return $this->router->generate("settings_meal_sizes_edit", array(
  312. 'size_uuid' => $entity->getUuid()
  313. ));
  314. }
  315. elseif($entity instanceof \App\Entity\Meals\Meal)
  316. {
  317. return $this->router->generate("settings_meals_edit", array(
  318. 'meal_uuid' => $entity->getUuid()
  319. ));
  320. }
  321. elseif($entity instanceof \App\Entity\Vaccinations\Type)
  322. {
  323. return $this->router->generate("settings_vaccinations_edit", array(
  324. 'vaccinationtype_uuid' => $entity->getUuid()
  325. ));
  326. }
  327. elseif($entity instanceof \App\Entity\Services\Service)
  328. {
  329. return $this->router->generate("settings_services_edit", array(
  330. 'service_uuid' => $entity->getUuid()
  331. ));
  332. }
  333. elseif($entity instanceof \App\Entity\System\OpeningTime)
  334. {
  335. return $this->router->generate("settings_openingtimes_edit", array(
  336. 'period_uuid' => $entity->getUuid()
  337. ));
  338. }
  339. elseif($entity instanceof \App\Entity\Animals\Type)
  340. {
  341. return $this->router->generate("settings_animaltypes_edit", array(
  342. 'type_uuid' => $entity->getUuid()
  343. ));
  344. }
  345. elseif($entity instanceof \App\Entity\Animals\Size)
  346. {
  347. return $this->router->generate("settings_animalsizes_edit", array(
  348. 'size_uuid' => $entity->getUuid()
  349. ));
  350. }
  351. elseif($entity instanceof \App\Entity\Animals\MixerCategory)
  352. {
  353. return $this->router->generate("settings_mixercategories_edit", array(
  354. 'mixer_uuid' => $entity->getUuid()
  355. ));
  356. }
  357. return null;
  358. }
  359. public function getCategory(?\App\Entity\System\AuditLog $auditLog = null)
  360. {
  361. if(!$auditLog)
  362. throw new \Exception("Audit log must be provided!");
  363. $identifierBits = explode("_", $auditLog->getIdentifier());
  364. // Return category only
  365. return ucfirst(strtolower($identifierBits[0]));
  366. }
  367. }