src/Entity/CategoriaForo.php line 15

Open in your IDE?
  1. <?php
  2. namespace App\Entity;
  3. use Doctrine\Common\Collections\ArrayCollection;
  4. use Doctrine\Common\Collections\Collection;
  5. use Doctrine\DBAL\Types\Types;
  6. use Doctrine\ORM\Mapping as ORM;
  7. use Gedmo\Mapping\Annotation as Gedmo;
  8. /**
  9. * @ORM\Entity
  10. * @ORM\Table(name="categoria_foro")
  11. */
  12. class CategoriaForo
  13. {
  14. /**
  15. * @ORM\Id
  16. * @ORM\Column(type="integer")
  17. * @ORM\GeneratedValue(strategy="AUTO")
  18. */
  19. private $id;
  20. /**
  21. * @ORM\Column(type="string", nullable=false)
  22. */
  23. private $nombre;
  24. /**
  25. * @ORM\Column(type="text", nullable=true)
  26. * @ORM\GeneratedValue(strategy="AUTO")
  27. */
  28. private $descripcion;
  29. /**
  30. * @ORM\Column(type="string", unique=true, nullable=true)
  31. * @Gedmo\Slug(fields={"nombre"})
  32. */
  33. private $slug;
  34. /**
  35. * @ORM\Column(type="integer", nullable=true, options={"default":0})
  36. */
  37. private $ordenacion;
  38. /**
  39. * @ORM\Column(type="boolean", nullable=true, options={"default":true})
  40. */
  41. private $activa;
  42. /**
  43. * @ORM\Column(type="datetime", nullable=true, name="deleted_at")
  44. */
  45. private $deletedAt;
  46. /**
  47. * @ORM\Column(type="datetime", nullable=false, name="updated_at", options={"default":"2024-01-01 00:00:00"})
  48. * @Gedmo\Timestampable(on="update")
  49. */
  50. private $updatedAt;
  51. /**
  52. * @ORM\Column(type="datetime", nullable=false, name="created_at", options={"default":"2024-01-01 00:00:00"})
  53. * @Gedmo\Timestampable(on="create")
  54. */
  55. private $createdAt;
  56. /**
  57. * Roles permitidos para ver esta categoría
  58. * @ORM\Column(type="json", nullable=true, name="roles_permitidos")
  59. */
  60. private ?array $rolesPermitidos = [];
  61. /**
  62. * Relación jerárquica - Categoría padre
  63. * @ORM\ManyToOne(targetEntity=\App\Entity\CategoriaForo::class, inversedBy="subcategorias")
  64. * @ORM\JoinColumn(name="categoria_padre_id", referencedColumnName="id")
  65. */
  66. private $categoriaPadre;
  67. /**
  68. * Relación jerárquica - Subcategorías
  69. * @ORM\OneToMany(targetEntity=\App\Entity\CategoriaForo::class, mappedBy="categoriaPadre", cascade={"persist"})
  70. * @ORM\OrderBy({"ordenacion":"ASC","nombre":"ASC"})
  71. */
  72. private $subcategorias;
  73. /**
  74. * @ORM\OneToMany(targetEntity=\App\Entity\Tema::class, mappedBy="categoriaForo")
  75. * @ORM\OrderBy({"updatedAt":"DESC"})
  76. */
  77. private $temas;
  78. public function __construct()
  79. {
  80. $this->subcategorias = new ArrayCollection();
  81. $this->temas = new ArrayCollection();
  82. $this->activa = true;
  83. $this->ordenacion = 0;
  84. }
  85. public function __toString(): string
  86. {
  87. return $this->getNombre() ?? '--';
  88. }
  89. public function getId(): ?int
  90. {
  91. return $this->id;
  92. }
  93. public function setId($id)
  94. {
  95. $this->id = $id;
  96. return $this;
  97. }
  98. public function getNombre(): ?string
  99. {
  100. return $this->nombre;
  101. }
  102. public function setNombre(string $nombre): static
  103. {
  104. $this->nombre = $nombre;
  105. return $this;
  106. }
  107. public function getDescripcion(): ?string
  108. {
  109. return $this->descripcion;
  110. }
  111. public function setDescripcion(?string $descripcion): static
  112. {
  113. $this->descripcion = $descripcion;
  114. return $this;
  115. }
  116. public function getSlug(): ?string
  117. {
  118. return $this->slug;
  119. }
  120. public function setSlug(?string $slug): static
  121. {
  122. $this->slug = $slug;
  123. return $this;
  124. }
  125. public function getOrdenacion(): ?int
  126. {
  127. return $this->ordenacion;
  128. }
  129. public function setOrdenacion(?int $ordenacion): static
  130. {
  131. $this->ordenacion = $ordenacion;
  132. return $this;
  133. }
  134. public function isActiva(): bool
  135. {
  136. return $this->activa ?? true;
  137. }
  138. public function setActiva(?bool $activa): static
  139. {
  140. $this->activa = $activa;
  141. return $this;
  142. }
  143. public function getDeletedAt(): ?\DateTimeInterface
  144. {
  145. return $this->deletedAt;
  146. }
  147. public function setDeletedAt(?\DateTimeInterface $deletedAt): static
  148. {
  149. $this->deletedAt = $deletedAt;
  150. return $this;
  151. }
  152. public function getUpdatedAt(): ?\DateTimeInterface
  153. {
  154. return $this->updatedAt;
  155. }
  156. public function setUpdatedAt(\DateTimeInterface $updatedAt): static
  157. {
  158. $this->updatedAt = $updatedAt;
  159. return $this;
  160. }
  161. public function getCreatedAt(): ?\DateTimeInterface
  162. {
  163. return $this->createdAt;
  164. }
  165. public function setCreatedAt(\DateTimeInterface $createdAt): static
  166. {
  167. $this->createdAt = $createdAt;
  168. return $this;
  169. }
  170. public function getCategoriaPadre(): ?self
  171. {
  172. return $this->categoriaPadre;
  173. }
  174. public function setCategoriaPadre(?self $categoriaPadre): static
  175. {
  176. $this->categoriaPadre = $categoriaPadre;
  177. return $this;
  178. }
  179. /**
  180. * @return Collection<int, CategoriaForo>
  181. */
  182. public function getSubcategorias(): Collection
  183. {
  184. return $this->subcategorias;
  185. }
  186. public function addSubcategoria(CategoriaForo $subcategoria): static
  187. {
  188. if (!$this->subcategorias->contains($subcategoria)) {
  189. $this->subcategorias->add($subcategoria);
  190. $subcategoria->setCategoriaPadre($this);
  191. }
  192. return $this;
  193. }
  194. public function removeSubcategoria(CategoriaForo $subcategoria): static
  195. {
  196. if ($this->subcategorias->removeElement($subcategoria)) {
  197. if ($subcategoria->getCategoriaPadre() === $this) {
  198. $subcategoria->setCategoriaPadre(null);
  199. }
  200. }
  201. return $this;
  202. }
  203. /**
  204. * @return Collection<int, Tema>
  205. */
  206. public function getTemas(): Collection
  207. {
  208. return $this->temas;
  209. }
  210. public function addTema(Tema $tema): static
  211. {
  212. if (!$this->temas->contains($tema)) {
  213. $this->temas->add($tema);
  214. $tema->setCategoriaForo($this);
  215. }
  216. return $this;
  217. }
  218. public function removeTema(Tema $tema): static
  219. {
  220. if ($this->temas->removeElement($tema)) {
  221. if ($tema->getCategoriaForo() === $this) {
  222. $tema->setCategoriaForo(null);
  223. }
  224. }
  225. return $this;
  226. }
  227. /**
  228. * Métodos helper para la jerarquía
  229. */
  230. public function esCategoriaPadre(): bool
  231. {
  232. return $this->categoriaPadre === null;
  233. }
  234. public function esSubcategoria(): bool
  235. {
  236. return $this->categoriaPadre !== null;
  237. }
  238. public function tieneSubcategorias(): bool
  239. {
  240. return $this->subcategorias->count() > 0;
  241. }
  242. public function getNivel(): int
  243. {
  244. $nivel = 0;
  245. $categoria = $this;
  246. while ($categoria->getCategoriaPadre() !== null) {
  247. $nivel++;
  248. $categoria = $categoria->getCategoriaPadre();
  249. }
  250. return $nivel;
  251. }
  252. public function getNumeroTemas(): int
  253. {
  254. return $this->temas->count();
  255. }
  256. public function getNumeroTemasTotal(): int
  257. {
  258. $total = $this->getNumeroTemas();
  259. foreach ($this->subcategorias as $subcategoria) {
  260. $total += $subcategoria->getNumeroTemasTotal();
  261. }
  262. return $total;
  263. }
  264. /**
  265. * Get roles permitidos para esta categoría
  266. */
  267. public function getRolesPermitidos(): ?array
  268. {
  269. return $this->rolesPermitidos;
  270. }
  271. /**
  272. * Set roles permitidos para esta categoría
  273. */
  274. public function setRolesPermitidos(?array $rolesPermitidos): static
  275. {
  276. $this->rolesPermitidos = $rolesPermitidos;
  277. return $this;
  278. }
  279. /**
  280. * Verifica si un array de roles tiene acceso a esta categoría
  281. */
  282. public function tieneAcceso(array $userRoles): bool
  283. {
  284. // Si no hay roles específicos configurados, la categoría es pública
  285. if (empty($this->rolesPermitidos)) {
  286. return true;
  287. }
  288. // Verificar si hay al menos un rol en común
  289. return !empty(array_intersect($userRoles, $this->rolesPermitidos));
  290. }
  291. /**
  292. * Verifica si la categoría es pública (sin restricciones de roles)
  293. */
  294. public function esPublica(): bool
  295. {
  296. return empty($this->rolesPermitidos);
  297. }
  298. /**
  299. * Obtiene los labels de los roles permitidos para mostrar en interfaz
  300. */
  301. public function getRolesPermitidosLabels(): array
  302. {
  303. if (empty($this->rolesPermitidos)) {
  304. return ['Pública (todos los roles)'];
  305. }
  306. $labels = [];
  307. foreach ($this->rolesPermitidos as $rol) {
  308. $labels[] = \App\Enum\RolEnum::getLabel($rol);
  309. }
  310. return $labels;
  311. }
  312. /**
  313. * Obtiene los roles permitidos como string para mostrar
  314. */
  315. public function getRolesPermitidosString(): string
  316. {
  317. $labels = $this->getRolesPermitidosLabels();
  318. return implode(', ', $labels);
  319. }
  320. }