AuditDataService.php 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. <?php
  2. namespace AuditBundle\Services;
  3. use Doctrine\DBAL\Connection;
  4. use Doctrine\ORM\EntityManagerInterface;
  5. use SimpleThings\EntityAudit\AuditManager;
  6. use SimpleThings\EntityAudit\AuditReader;
  7. use SimpleThings\EntityAudit\Revision;
  8. class AuditDataService
  9. {
  10. /**
  11. * @var Connection
  12. */
  13. private $connection;
  14. /**
  15. * @var AuditReader
  16. */
  17. private $reader;
  18. /**
  19. * @var AuditManager
  20. */
  21. private $auditManager;
  22. /**
  23. * @var EntityManagerInterface
  24. */
  25. private $entityManager;
  26. /**
  27. * @param Connection $connection
  28. * @param AuditReader $reader
  29. * @param AuditManager $auditManager
  30. * @param EntityManagerInterface $entityManager
  31. */
  32. public function __construct(Connection $connection, AuditReader $reader, AuditManager $auditManager, EntityManagerInterface $entityManager)
  33. {
  34. $this->connection = $connection;
  35. $this->reader = $reader;
  36. $this->auditManager = $auditManager;
  37. $this->entityManager = $entityManager;
  38. }
  39. /**
  40. * @return array
  41. */
  42. public function getRevisionUsers()
  43. {
  44. $query = "SELECT DISTINCT(SUBSTRING_INDEX(username, '(', 1)) as username FROM revisions ORDER BY username ASC;";
  45. $usernames = array();
  46. foreach ($this->connection->fetchAll($query) as $username) {
  47. $usernames[$username['username']] = $username['username'];
  48. }
  49. return $usernames;
  50. }
  51. /**
  52. * Applied diff between revisions
  53. *
  54. * @param string $className
  55. * @param int $id
  56. * @param Revision $oldRev
  57. * @param Revision $newRev
  58. *
  59. * @return array
  60. */
  61. public function diff($className, $id, $oldRev, $newRev)
  62. {
  63. return $this->reader->diff($className, $id, $oldRev, $newRev);
  64. }
  65. /**
  66. * Get data of a revision
  67. *
  68. * @param string $className
  69. * @param int $id
  70. * @param Revision $rev
  71. *
  72. * @return array
  73. */
  74. public function viewRevision($className, $id, $rev)
  75. {
  76. $entity = $this->reader->find($className, $id, $rev);
  77. return array(
  78. 'rev_details' => $this->reader->getEntityValues($className, $entity),
  79. 'rev_revisions' => $this->reader->findRevisions($className, $id),
  80. 'revdata' => $this->reader->findRevision($rev),
  81. );
  82. }
  83. /**
  84. * @return array
  85. */
  86. public function getEntities()
  87. {
  88. $mdFactory = $this->auditManager->getMetadataFactory();
  89. $meta = $this->entityManager->getMetadataFactory()->getAllMetadata();
  90. $entities = array();
  91. foreach ($meta as $m) {
  92. $entities[$m->getName()] = $m->table['name'];
  93. }
  94. ksort($entities);
  95. foreach ($entities as $key => $entityName) {
  96. if (!$mdFactory->isAudited($key)) {
  97. unset($entities[$key]);
  98. }
  99. }
  100. return $entities;
  101. }
  102. /**
  103. * @return array
  104. */
  105. public function getColumns()
  106. {
  107. $columns = array();
  108. $meta = $this->entityManager->getMetadataFactory()->getAllMetadata();
  109. foreach ($meta as $m) {
  110. $columns[$m->getName()] = $m->getColumnNames();
  111. }
  112. return $columns;
  113. }
  114. /**
  115. * @param array $data
  116. *
  117. * @return array
  118. */
  119. public function getResults($data)
  120. {
  121. $entities = $this->getEntities();
  122. $pages = 1;
  123. $users = array();
  124. $types = array();
  125. extract($data); // retorna la data del filter form
  126. $entity = array_search($entity, $entities);
  127. $from = $this->buildFrom($entity);
  128. $where = $this->buildWhere($entity, $users, $types, $idx, $dateFrom, $dateTo, $searchValue);
  129. $sql_cnt = $this->buildSelect($entity, true) . $from . $where;
  130. $count = $this->connection->query($sql_cnt)->fetchAll()[0]['total'];
  131. $sql = $this->buildSelect($entity) . $from . $where;
  132. $sql .= "ORDER BY R.timestamp DESC ";
  133. // print_r("<pre>");
  134. // print_r($sql);
  135. // print_r("</pre>");
  136. if(is_null($resxpage)) $resxpage = 10;
  137. if ($resxpage != "inf") {
  138. $pages = ceil(($count / floatval($resxpage)));
  139. $from = ($page - 1) * $resxpage;
  140. //$to = ($page) * $resxpage;
  141. $sql .= "LIMIT {$from},{$resxpage}";
  142. }
  143. return array(
  144. 'result' => $this->connection->query($sql)->fetchAll(),
  145. 'count' => $count,
  146. 'page' => $page,
  147. 'pages' => $pages,
  148. );
  149. }
  150. /**
  151. * @param string $entity
  152. * @param bool $count
  153. *
  154. * @return string
  155. */
  156. private function buildSelect($entity, $count = false)
  157. {
  158. $entities = $this->getEntities();
  159. $primaryKeyQuery = "SHOW KEYS FROM `{$entities[$entity]}` WHERE Key_name = 'PRIMARY';";
  160. $primaryKey = $this->connection->fetchAll($primaryKeyQuery);
  161. $id = 'id';
  162. if (isset($primaryKey[0])) {
  163. $id = $primaryKey[0]['Column_name'];
  164. }
  165. $select = "SELECT C.rev, C.{$id} as id, C.revtype, R.username, R.timestamp ";
  166. if ($count) {
  167. $select = 'SELECT COUNT(*) as total ';
  168. }
  169. $columns = $this->getColumns();
  170. foreach ($columns[$entity] as $column) {
  171. $select .= ", C." . $column . " ";
  172. }
  173. return $select;
  174. }
  175. /**
  176. * @param string $entity
  177. *
  178. * @return string
  179. */
  180. private function buildFrom($entity)
  181. {
  182. $entities = $this->getEntities();
  183. return "FROM `{$entities[$entity]}_audit` AS C INNER JOIN `revisions` AS R ON C.rev = R.id ";
  184. }
  185. /**
  186. * @param string $entity
  187. * @param array $users
  188. * @param array $types
  189. * @param int $idx
  190. * @param string $dateFrom
  191. * @param string $dateTo
  192. * @param string $searchValue
  193. *
  194. * @return string
  195. */
  196. private function buildWhere($entity, $users = null, $types = null, $idx = null, $dateFrom = null, $dateTo = null, $searchValue = null)
  197. {
  198. $where = '';
  199. $columns = $this->getColumns();
  200. if ($users || $types || $idx || $dateFrom || $dateTo || $searchValue) {
  201. $where .= 'WHERE C.id > 0 ';
  202. if ($users) {
  203. foreach ($users as $key => $user) {
  204. if ($key == 0) {
  205. $where .= "AND (R.username = '{$user}' ";
  206. } else {
  207. $where .= "OR R.username = '{$user}' ";
  208. }
  209. }
  210. $where .= ') ';
  211. }
  212. if ($types) {
  213. foreach ($types as $key => $type) {
  214. if ($key == 0) {
  215. $where .= "AND (C.revtype = '{$type}' ";
  216. } else {
  217. $where .= "OR C.revtype = '{$type}' ";
  218. }
  219. }
  220. $where .= ') ';
  221. }
  222. if ($idx) {
  223. $where .= "AND (C.id = '{$idx}') ";
  224. }
  225. if ($dateFrom && $dateTo) {
  226. $where .= " AND R.timestamp BETWEEN '{$dateFrom->format('Y-m-d')} 00:00:00' AND '{$dateTo->format('Y-m-d')} 23:59:59' ";
  227. }elseif($dateFrom) {
  228. $where .= " AND R.timestamp > '{$dateFrom->format('Y-m-d')} 00:00:00' ";
  229. }elseif($dateTo) {
  230. $where .= " AND R.timestamp < '{$dateTo->format('Y-m-d')} 23:59:59' ";
  231. }
  232. if ($searchValue) {
  233. foreach ($columns[$entity] as $key => $col) {
  234. if ($key == 0) {
  235. $where .= " AND (C.{$col} LIKE '{$searchValue}' ";
  236. } else {
  237. $where .= " OR C.{$col} LIKE '{$searchValue}' ";
  238. }
  239. }
  240. $where .= ') ';
  241. }
  242. }
  243. return $where;
  244. }
  245. }