================================================================================ INTOUCH FRAMEWORK - DOCUMENTACIÓN COMPLETA PARA REGISTRO EN DEPARTAMENTO DE DERECHOS INTELECTUALES ================================================================================ Autor: Claudio Alfonso González Almeyda Año de Creación: 2018 Año Actual: 2025 Framework: InTouch Framework Esta documentación contiene el código fuente completo del InTouch Framework para su registro en el Departamento de Derechos Intelectuales de Chile. Fecha de Generación: 2025-11-03 20:16:06 ================================================================================ ESTRUCTURA DEL PROYECTO ================================================================================ Total de archivos: 464 Tamaño total: 1.52 MB LISTA DE ARCHIVOS: -------------------------------------------------------------------------------- 1. generate_documentation.php 4.78 KB 2. src/Annotation/AnnotationHelper.php 12.32 KB 3. src/Annotation/AttributeContainer.php 1.87 KB 4. src/Annotation/Attributes/CacheMulti.php 380 bytes 5. src/Annotation/Attributes/CacheSingle.php 381 bytes 6. src/Annotation/Attributes/CheckSession.php 356 bytes 7. src/Annotation/Attributes/ConfigDetails.php 411 bytes 8. src/Annotation/Attributes/Entity.php 563 bytes 9. src/Annotation/Attributes/EntityField.php 865 bytes 10. src/Annotation/Attributes/Key.php 347 bytes 11. src/Annotation/Attributes/PreventCache.php 382 bytes 12. src/Annotation/Attributes/ReturnActionResult.php 389 bytes 13. src/Annotation/Attributes/ReturnActionViewResult.php 393 bytes 14. src/Annotation/Attributes/ReturnExcelResult.php 388 bytes 15. src/Annotation/Attributes/ReturnJsonPlainResult.php 392 bytes 16. src/Annotation/Attributes/ReturnJsonResult.php 387 bytes 17. src/Annotation/Attributes/ReturnJsonResultMovil.php 392 bytes 18. src/Annotation/Attributes/ReturnPdfInlineResult.php 392 bytes 19. src/Annotation/Attributes/ReturnRedirectResult.php 391 bytes 20. src/Annotation/Attributes/ReturnViewResult.php 387 bytes 21. src/Annotation/Attributes/Route.php 780 bytes 22. src/Annotation/Attributes/Template.php 469 bytes 23. src/Annotation/Attributes/ViewDisplay.php 580 bytes 24. src/Annotation/Attributes/ViewDisplayKey.php 360 bytes 25. src/Annotation/Attributes/Widget.php 521 bytes 26. src/Annotation/ClassAttribute.php 377 bytes 27. src/Annotation/ContainerTypeEnum.php 397 bytes 28. src/Annotation/MethodAttribute.php 437 bytes 29. src/Annotation/MethodParameter.php 527 bytes 30. src/Annotation/PropertyAttribute.php 383 bytes 31. src/Assets/Entities/ImageResource.php 1.12 KB 32. src/Assets/Entities/PdfResource.php 361 bytes 33. src/Assets/IAssetManager.php 447 bytes 34. src/Assets/IAssetManagerFactory.php 534 bytes 35. src/Assets/Managers/CloudFrontAssetManager.php 2.32 KB 36. src/Assets/Managers/LocalAssetManager.php 1.29 KB 37. src/Assets/Managers/S3AssetManager.php 1.54 KB 38. src/Assets/Requests/CloudFrontImageRequest.php 987 bytes 39. src/Assets/Resource.php 1.18 KB 40. src/BLL/DataTransferObjects/RangoDto.php 368 bytes 41. src/BLL/Filters/CustomExcelSettingsFilterDto.php 553 bytes 42. src/BLL/Filters/DataTableSettingsFilterDto.php 1.54 KB 43. src/BLL/Service/GenericSvc.php 7.03 KB 44. src/BLL/WebService/HttpHelper.php 5.23 KB 45. src/BLL/WebService/HttpMethodEnum.php 400 bytes 46. src/Bin/environment.php 270 bytes 47. src/Bin/generator.php 1.27 KB 48. src/Bin/mantenedor.php 1.27 KB 49. src/Cache/Page.php 25.80 KB 50. src/Cache/PageDefinition.php 1.49 KB 51. src/Cache/PageResults.php 475 bytes 52. src/Cache/RedisSvc.php 1.37 KB 53. src/Collection/AttachDefinition.php 537 bytes 54. src/Collection/CollectionDefinition.php 543 bytes 55. src/Collection/Collections.php 15.39 KB 56. src/Collection/Condition.php 698 bytes 57. src/Collection/ConditionBuilder.php 4.72 KB 58. src/Collection/GenericCollection.php 41.63 KB 59. src/Collection/GenericDefinition.php 2.43 KB 60. src/Collection/GenericValidator.php 3.51 KB 61. src/Collection/MergeDefinition.php 514 bytes 62. src/Configuration/BaseConfig.php 1.97 KB 63. src/Configuration/BundleConfig.php 1.65 KB 64. src/Configuration/ConnectionConfig.php 1.04 KB 65. src/Configuration/MensajeConfig.php 937 bytes 66. src/Configuration/MenuConfig.php 10.08 KB 67. src/Configuration/RedisConfig.php 908 bytes 68. src/Configuration/RestrictionConfig.php 2.13 KB 69. src/Configuration/SystemConfig.php 2.40 KB 70. src/Controllers/ActionResult.php 865 bytes 71. src/Controllers/ActionViewResult.php 868 bytes 72. src/Controllers/BaseController.php 30.21 KB 73. src/Controllers/Chart/LineChartSerie.php 495 bytes 74. src/Controllers/Chart/PieChartSerie.php 454 bytes 75. src/Controllers/Chart/SeriesColorEnum.php 688 bytes 76. src/Controllers/ChartHelper.php 5.54 KB 77. src/Controllers/ControllerDefinition.php 691 bytes 78. src/Controllers/Display.php 7.78 KB 79. src/Controllers/ErrorJsonMovilResult.php 507 bytes 80. src/Controllers/ErrorJsonResult.php 688 bytes 81. src/Controllers/ErrorResult.php 944 bytes 82. src/Controllers/ErrorViewResult.php 1006 bytes 83. src/Controllers/ExcelResult.php 857 bytes 84. src/Controllers/InternalControllers/DefaultAssetManager.php 1023 bytes 85. src/Controllers/InternalControllers/DefaultAssetManagerFactory.php 927 bytes 86. src/Controllers/InternalControllers/PageController.php 1.19 KB 87. src/Controllers/JsonPlainResult.php 386 bytes 88. src/Controllers/JsonResult.php 677 bytes 89. src/Controllers/JsonResultMovil.php 479 bytes 90. src/Controllers/PdfInlineResult.php 860 bytes 91. src/Controllers/RedirectResult.php 864 bytes 92. src/Controllers/Result.php 575 bytes 93. src/Controllers/ResultPrevio.php 475 bytes 94. src/Controllers/ViewResult.php 856 bytes 95. src/Core/Audit.php 3.35 KB 96. src/Core/Cacheable.php 1.33 KB 97. src/Core/CacheableSingleton.php 2.25 KB 98. src/Core/Dynamic.php 344 bytes 99. src/Core/ErrorTypeEnum.php 382 bytes 100. src/Core/FileHelper.php 1.04 KB 101. src/Core/Log.php 6.83 KB 102. src/Core/MemoryInfo.php 1.50 KB 103. src/Core/Rut.php 1.14 KB 104. src/Core/SingleSignOn/OpenId.php 4.15 KB 105. src/Core/System.php 2.99 KB 106. src/Dao/AuditField.php 859 bytes 107. src/Dao/AuditInfo.php 3.90 KB 108. src/Dao/BasicDao.php 31.77 KB 109. src/Dao/BindVariable.php 2.32 KB 110. src/Dao/ConnectionTypeEnum.php 411 bytes 111. src/Dao/DataConfig.php 2.17 KB 112. src/Dao/DefinitionTypeEnum.php 453 bytes 113. src/Dao/Entity/Annotation.php 343 bytes 114. src/Dao/Entity/DocComment.php 2.42 KB 115. src/Dao/Entity/EntityDefinition.php 9.28 KB 116. src/Dao/Entity/IAuditable.php 389 bytes 117. src/Dao/Entity/PropertyDefinition.php 3.33 KB 118. src/Dao/ExecuteDao.php 6.53 KB 119. src/Dao/Format.php 480 bytes 120. src/Dao/FormatTypeEnum.php 451 bytes 121. src/Dao/GenericDao.php 18.28 KB 122. src/Dao/OperatorEnum.php 551 bytes 123. src/Dao/Queryable.php 23.83 KB 124. src/Dates/Date.php 20.25 KB 125. src/Dates/Interval.php 2.48 KB 126. src/Document/GenericDocument.php 6.98 KB 127. src/Document/GenericDocumentDefinition.php 548 bytes 128. src/Document/GenericFileExtensionEnum.php 425 bytes 129. src/Environment/Globals.php 1.14 KB 130. src/Environment/Headers.php 1.33 KB 131. src/Environment/Ini.php 1.28 KB 132. src/Environment/IniEnum.php 553 bytes 133. src/Environment/Request.php 1.67 KB 134. src/Environment/Server.php 1.07 KB 135. src/Environment/Session.php 1.14 KB 136. src/Exceptions/BaseException.php 594 bytes 137. src/Exceptions/BusinessException.php 2.38 KB 138. src/Exceptions/ExceptionCodesEnum.php 866 bytes 139. src/Exceptions/ExceptionResult.php 623 bytes 140. src/Exceptions/ExceptionTypeEnum.php 485 bytes 141. src/Generator/Config.php 1.46 KB 142. src/Generator/Engine.php 80.64 KB 143. src/Generator/Templates/Dao.php 552 bytes 144. src/Generator/Templates/DaoT.php 235 bytes 145. src/Generator/Templates/Dto.php 441 bytes 146. src/Generator/Templates/DtoT.php 461 bytes 147. src/Generator/Templates/Ent.php 837 bytes 148. src/Generator/Templates/EntT.php 288 bytes 149. src/Generator/Templates/Mantenedores/ApiController.php 6.59 KB 150. src/Generator/Templates/Mantenedores/ApiControllerT.php 261 bytes 151. src/Generator/Templates/Mantenedores/BusinessObject.php 10.19 KB 152. src/Generator/Templates/Mantenedores/BusinessObjectT.php 1.82 KB 153. src/Generator/Templates/Mantenedores/ViewController.php 1.35 KB 154. src/Generator/Templates/Mantenedores/ViewControllerT.php 257 bytes 155. src/Generator/Templates/Mantenedores/popupView.php 9.67 KB 156. src/Generator/Templates/Mantenedores/verGridAsPopUpView.php 5.78 KB 157. src/Generator/Templates/Mantenedores/verGridT.php 7.90 KB 158. src/Generator/Templates/Mantenedores/verGridView.php 4.93 KB 159. src/Generator/Templates/Mantenedores/verView.php 7.77 KB 160. src/Generator/Templates/Svc.php 842 bytes 161. src/Generator/Templates/SvcT.php 266 bytes 162. src/Generator/TemplatesOld/Dao.php 481 bytes 163. src/Generator/TemplatesOld/DaoT.php 208 bytes 164. src/Generator/TemplatesOld/Dto.php 300 bytes 165. src/Generator/TemplatesOld/DtoT.php 438 bytes 166. src/Generator/TemplatesOld/Ent.php 425 bytes 167. src/Generator/TemplatesOld/EntT.php 261 bytes 168. src/Generator/TemplatesOld/Mantenedores/ApiController.php 3.40 KB 169. src/Generator/TemplatesOld/Mantenedores/ApiControllerT.php 234 bytes 170. src/Generator/TemplatesOld/Mantenedores/BusinessObject.php 4.49 KB 171. src/Generator/TemplatesOld/Mantenedores/BusinessObjectT.php 230 bytes 172. src/Generator/TemplatesOld/Mantenedores/Prueba.php 595 bytes 173. src/Generator/TemplatesOld/Mantenedores/ViewController.php 1.22 KB 174. src/Generator/TemplatesOld/Mantenedores/ViewControllerT.php 230 bytes 175. src/Generator/TemplatesOld/Mantenedores/popupView.php 3.21 KB 176. src/Generator/TemplatesOld/Mantenedores/verGridAsPopUpView.php 2.74 KB 177. src/Generator/TemplatesOld/Mantenedores/verGridT.php 6.04 KB 178. src/Generator/TemplatesOld/Mantenedores/verGridView.php 1.81 KB 179. src/Generator/TemplatesOld/Mantenedores/verView.php 3.73 KB 180. src/Generator/TemplatesOld/Svc.php 707 bytes 181. src/Generator/TemplatesOld/SvcT.php 239 bytes 182. src/IdeHelpers/_ide_helper_redis.php 5.10 KB 183. src/Init/func.php 16.07 KB 184. src/Loaders.php 5.39 KB 185. src/MailHelper/Attachment.php 479 bytes 186. src/MailHelper/ComposeReplacement.php 586 bytes 187. src/MailHelper/DispositionEnum.php 383 bytes 188. src/MailHelper/Mail.php 6.51 KB 189. src/MailHelper/MailConfig.php 475 bytes 190. src/MailHelper/MailUtil.php 805 bytes 191. src/MailHelper/Message.php 496 bytes 192. src/MailHelper/Recipient.php 463 bytes 193. src/MailHelper/RecipientTypeEnum.php 511 bytes 194. src/MailHelper/ResultMultipleSend.php 560 bytes 195. src/Mapper/Map.php 5.34 KB 196. src/Mapper/Mapper.php 21.20 KB 197. src/Mapping/BaseMapper.php 697 bytes 198. src/Mapping/Reflect.php 654 bytes 199. src/Math/Modulo.php 1012 bytes 200. src/Mensajes/Mensaje.php 7.58 KB 201. src/Mensajes/MensajeDto.php 356 bytes 202. src/OfficeHelper/.claude/settings.local.json 99 bytes 203. src/OfficeHelper/BigCsvSql.php 11.23 KB 204. src/OfficeHelper/BigExcel copy.php 35.26 KB 205. src/OfficeHelper/BigExcel.php 65.56 KB 206. src/OfficeHelper/BigExcelDefinition.php 549 bytes 207. src/OfficeHelper/BigExcelSheet.php 721 bytes 208. src/OfficeHelper/BigExcelSql.php 39.05 KB 209. src/OfficeHelper/CeldaExcel.php 720 bytes 210. src/OfficeHelper/Excel.php 22.93 KB 211. src/OfficeHelper/ExcelTemplate/[Content_Types].xml 1.01 KB 212. src/OfficeHelper/ExcelTemplate/docProps/app.xml 988 bytes 213. src/OfficeHelper/ExcelTemplate/docProps/core.xml 651 bytes 214. src/OfficeHelper/ExcelTemplate/xl/styles.xml 1.89 KB 215. src/OfficeHelper/ExcelTemplate/xl/theme/theme1.xml 11.59 KB 216. src/OfficeHelper/ExcelTemplate/xl/workbook.xml 942 bytes 217. src/OfficeHelper/ExcelTemplate/xl/worksheets/sheet_template.xml 580 bytes 218. src/OfficeHelper/ExcelUnzipInfo.php 585 bytes 219. src/OfficeHelper/RowReadFilter.php 795 bytes 220. src/OfficeHelper/SheetDimensions.php 304 bytes 221. src/ProjectionEngine/DefaultProjectionBuilder.php 15.26 KB 222. src/ProjectionEngine/IProjectionBuilder.php 603 bytes 223. src/ProjectionEngine/IProjectionCalculator.php 449 bytes 224. src/ProjectionEngine/IProjectionResultWriter.php 464 bytes 225. src/ProjectionEngine/Intervalo.php 398 bytes 226. src/ProjectionEngine/IntervaloCollection.php 481 bytes 227. src/ProjectionEngine/Projection.php 6.01 KB 228. src/ProjectionEngine/ProjectionValidator.php 1.54 KB 229. src/ProjectionEngine/Projector.php 18.51 KB 230. src/ProjectionEngine/WorkShift.php 10.18 KB 231. src/ProjectionEngine/WorkShiftCompleted.php 1.24 KB 232. src/ProjectionEngine/WorkShiftDatePartEnum.php 401 bytes 233. src/ProjectionEngine/WorkShiftSchedule.php 4.08 KB 234. src/ReportEngine/Report.php 4.71 KB 235. src/ReportEngine/ReportDataset.php 716 bytes 236. src/ReportEngine/ReportDefinition.php 1.98 KB 237. src/ReportEngine/ReportFilter.php 739 bytes 238. src/ReportEngine/ReportOutputDefinition.php 766 bytes 239. src/ReportEngine/ReportOutputEnum.php 403 bytes 240. src/Route/BaseDispatcher.php 25.01 KB 241. src/Route/ControllerContainer.php 1.78 KB 242. src/Route/IDispatchResponse.php 1.67 KB 243. src/Route/RouteHelper.php 13.71 KB 244. src/Route/Uri.php 10.52 KB 245. src/Security/Encoder.php 3.98 KB 246. src/String/Concat.php 1.31 KB 247. src/Stubs/Intouch/Dao/BasicDao.zep.php 502 bytes 248. src/Stubs/Intouch/Dao/ExecuteDao.zep.php 389 bytes 249. src/Stubs/Intouch/Dao/GenericDao.zep.php 456 bytes 250. src/Styles/StyleObject.php 2.74 KB 251. src/Styles/ThemeConfig.php 4.58 KB 252. src/Styles/TipoLoginEnum.php 416 bytes 253. src/SystemViews/localizationView.php 16.95 KB 254. src/Utils.php 4.10 KB 255. src/View/Display.php 150.54 KB 256. src/View/DisplayDefinitions/Button.php 1.68 KB 257. src/View/DisplayDefinitions/ButtonBadge.php 675 bytes 258. src/View/DisplayDefinitions/DisplayFunctionModeEnum.php 396 bytes 259. src/View/DisplayDefinitions/FormButton.php 1.25 KB 260. src/View/DisplayDefinitions/FormRowField.php 1.36 KB 261. src/View/DisplayDefinitions/FormRowFieldCheck.php 1.80 KB 262. src/View/DisplayDefinitions/FormRowFieldContent.php 743 bytes 263. src/View/DisplayDefinitions/FormRowFieldDate.php 1.46 KB 264. src/View/DisplayDefinitions/FormRowFieldEmpty.php 493 bytes 265. src/View/DisplayDefinitions/FormRowFieldFile.php 1.23 KB 266. src/View/DisplayDefinitions/FormRowFieldHidden.php 706 bytes 267. src/View/DisplayDefinitions/FormRowFieldLabel.php 780 bytes 268. src/View/DisplayDefinitions/FormRowFieldSelect.php 1.12 KB 269. src/View/DisplayDefinitions/FormRowFieldSelectDefinition.php 1.14 KB 270. src/View/DisplayDefinitions/FormRowFieldSubTitle.php 598 bytes 271. src/View/DisplayDefinitions/FormRowFieldText.php 1.93 KB 272. src/View/DisplayDefinitions/FormRowFieldTypeEnum.php 1.04 KB 273. src/View/DisplayDefinitions/FormRowGroup.php 988 bytes 274. src/View/DisplayDefinitions/FormRowSection.php 400 bytes 275. src/View/DisplayDefinitions/HrefSpec.php 425 bytes 276. src/View/DisplayDefinitions/JSTable/JSTableBodyTemplate.php 414 bytes 277. src/View/DisplayDefinitions/JSTable/JSTableCell.php 1.42 KB 278. src/View/DisplayDefinitions/JSTable/JSTableCellDefinitions.php 784 bytes 279. src/View/DisplayDefinitions/JSTableButton.php 2.09 KB 280. src/View/DisplayDefinitions/LabelSpec.php 432 bytes 281. src/View/DisplayDefinitions/Tab.php 1.13 KB 282. src/View/DisplayDefinitions/TableButton.php 2.15 KB 283. src/View/DisplayDefinitions/TableCell.php 865 bytes 284. src/View/DisplayDefinitions/TableDropDownButton.php 1.64 KB 285. src/View/DisplayDefinitions/TableJSCell.php 3.12 KB 286. src/View/DisplayDefinitions/TableJSCellFunctions.php 8.81 KB 287. src/View/DisplayDefinitions/TogglePlacementEnum.php 454 bytes 288. src/View/DisplayDefinitions/ValidadoresEnum.php 440 bytes 289. src/View/DisplayDefinitions/ValidationRuleEnum.php 471 bytes 290. src/View/DisplayEnumerations/DateRangeIntervalsEnum.php 691 bytes 291. src/View/DisplayEventActions/Action.php 1.06 KB 292. src/View/DisplayEventActions/CallFunctionAction.php 1.14 KB 293. src/View/DisplayEventActions/ChangeVisibilityAction.php 2.34 KB 294. src/View/DisplayEventActions/RefreshListAction.php 3.22 KB 295. src/View/DisplayEventActions/VisibilityActionEnum.php 470 bytes 296. src/View/DisplayEvents/ButtonOnClickEvent.php 751 bytes 297. src/View/DisplayEvents/Event.php 1.56 KB 298. src/View/DisplayEvents/FormButtonOnClickEvent.php 686 bytes 299. src/View/DisplayEvents/FormEvent.php 3.31 KB 300. src/View/DisplayEvents/FormOnBlurEvent.php 670 bytes 301. src/View/DisplayEvents/FormOnChangeEvent.php 837 bytes 302. src/View/DisplayEvents/FormOnClickEvent.php 750 bytes 303. src/View/DisplayEvents/FormOnKeyPressEvent.php 1.73 KB 304. src/View/DisplayEvents/FormOnKeyUpEvent.php 1.17 KB 305. src/View/DisplayEvents/JsEventEnum.php 570 bytes 306. src/View/DisplayEvents/JsRegExpEnum.php 435 bytes 307. src/View/DisplayEvents/SexyPageButtonOnClickEvent.php 1.21 KB 308. src/View/DisplayEvents/SexyPageButtonOnRefreshEvent.php 2.85 KB 309. src/View/DisplayEvents/TableButtonOnClickEvent.php 993 bytes 310. src/View/DisplayEvents/TableEvent.php 2.72 KB 311. src/View/DisplayValidations/Validation.php 398 bytes 312. src/Widget/Action.php 1.48 KB 313. src/Widget/ActionButton.php 4.00 KB 314. src/Widget/ActionButtonDropDown.php 3.81 KB 315. src/Widget/ActionButtonDropDownChild.php 3.41 KB 316. src/Widget/ActionMenu.php 2.36 KB 317. src/Widget/ActionMenuItem.php 1.48 KB 318. src/Widget/ActionMenuMiniSeparator.php 894 bytes 319. src/Widget/ActionMenuSeparator.php 886 bytes 320. src/Widget/ActionMenuTitle.php 963 bytes 321. src/Widget/ActionMenuTitleSubtitle.php 2.55 KB 322. src/Widget/ActionMenuTree.php 1.76 KB 323. src/Widget/Am5Chart.php 1.69 KB 324. src/Widget/AmChartGeneric.php 3.38 KB 325. src/Widget/AmChartGraph.php 31.28 KB 326. src/Widget/AmchartPie.php 5.39 KB 327. src/Widget/Card.php 3.58 KB 328. src/Widget/CardAction.php 2.52 KB 329. src/Widget/CardActionIconText.php 3.20 KB 330. src/Widget/CardActionImageText.php 3.59 KB 331. src/Widget/CardIconText.php 2.56 KB 332. src/Widget/Chart.php 1.36 KB 333. src/Widget/Container.php 3.59 KB 334. src/Widget/DateAndTime.php 2.79 KB 335. src/Widget/Definitions/Action/ActionTargetEnum.php 479 bytes 336. src/Widget/Definitions/ActionButton/ButtonStyleEnum.php 623 bytes 337. src/Widget/Definitions/ActionMenu/AnimationTypeEnum.php 2.15 KB 338. src/Widget/Definitions/AmChart/AmChartAddData.php 693 bytes 339. src/Widget/Definitions/AmChart/AmChartBarData.php 3.45 KB 340. src/Widget/Definitions/AmChart/AmChartColorEnum.php 508 bytes 341. src/Widget/Definitions/AmChart/AmChartControls.php 2.10 KB 342. src/Widget/Definitions/AmChart/AmChartGeneric.php 1.11 KB 343. src/Widget/Definitions/AmChart/AmChartGenericToAmData.php 4.14 KB 344. src/Widget/Definitions/AmChart/AmChartLegend.php 3.69 KB 345. src/Widget/Definitions/AmChart/AmChartPieData.php 2.60 KB 346. src/Widget/Definitions/AmChart/AmChartSeries.php 1.16 KB 347. src/Widget/Definitions/AmChart/AmChartTypeEnum.php 1007 bytes 348. src/Widget/Definitions/AmChart5/Axis/Axis.php 629 bytes 349. src/Widget/Definitions/AmChart5/Axis/CategoryAxis.php 1.19 KB 350. src/Widget/Definitions/AmChart5/Axis/RoundedRectangleTitle.php 2.20 KB 351. src/Widget/Definitions/AmChart5/Axis/Title.php 3.29 KB 352. src/Widget/Definitions/AmChart5/Axis/ValueAxis.php 1.83 KB 353. src/Widget/Definitions/AmChart5/Axis/XAxis.php 557 bytes 354. src/Widget/Definitions/AmChart5/Basic.php 2.05 KB 355. src/Widget/Definitions/AmChart5/Chart/Chart.php 1.24 KB 356. src/Widget/Definitions/AmChart5/Chart/ChartOrientationEnum.php 393 bytes 357. src/Widget/Definitions/AmChart5/Chart/ChartXY.php 3.86 KB 358. src/Widget/Definitions/AmChart5/Chart/ChartXY2.php 3.93 KB 359. src/Widget/Definitions/AmChart5/Data/DataCollection.php 1.09 KB 360. src/Widget/Definitions/AmChart5/Data/DataItem.php 1.27 KB 361. src/Widget/Definitions/AmChart5/Data/DataItemDefinition.php 844 bytes 362. src/Widget/Definitions/AmChart5/Enum/AlignEnum.php 428 bytes 363. src/Widget/Definitions/AmChart5/Enum/ColorEnum.php 1.09 KB 364. src/Widget/Definitions/AmChart5/Enum/VerticalAlignEnum.php 431 bytes 365. src/Widget/Definitions/AmChart5/RootElement.php 2.17 KB 366. src/Widget/Definitions/AmChart5/Series/AxisDefinition.php 445 bytes 367. src/Widget/Definitions/AmChart5/Series/Bullet.php 446 bytes 368. src/Widget/Definitions/AmChart5/Series/ColumnSeriesDefinition.php 1.61 KB 369. src/Widget/Definitions/AmChart5/Series/LabelSprite.php 666 bytes 370. src/Widget/Definitions/AmChart5/Series/LineSeriesDefinition.php 1.26 KB 371. src/Widget/Definitions/AmChart5/Series/Series.php 9.27 KB 372. src/Widget/Definitions/AmChart5/Series/SeriesDefinition.php 888 bytes 373. src/Widget/Definitions/AmChart5/Series/SeriesTypeEnum.php 422 bytes 374. src/Widget/Definitions/AmChart5/Series/Sprite.php 462 bytes 375. src/Widget/Definitions/Chart/ChartDefinition.php 426 bytes 376. src/Widget/Definitions/Chart/ChartTypeEnum.php 678 bytes 377. src/Widget/Definitions/Chart/Root.php 450 bytes 378. src/Widget/Definitions/Chart/XYChart/ValueAxis.php 819 bytes 379. src/Widget/Definitions/Chart/XYChart/XYChartDefinition.php 902 bytes 380. src/Widget/Definitions/Container/Edge.php 610 bytes 381. src/Widget/Definitions/Container/Position.php 658 bytes 382. src/Widget/Definitions/Container/PositionEnum.php 401 bytes 383. src/Widget/Definitions/General/Badge.php 547 bytes 384. src/Widget/Definitions/General/UnitEnum.php 515 bytes 385. src/Widget/Definitions/Label/LabelSizeEnum.php 544 bytes 386. src/Widget/Definitions/Label/LabelStyleEnum.php 894 bytes 387. src/Widget/Definitions/Photo/PhotoDefinition.php 725 bytes 388. src/Widget/Definitions/PopUpModal/ColorLineStyleEnum.php 579 bytes 389. src/Widget/Definitions/Table/ButtonColumnDefinition.php 832 bytes 390. src/Widget/Definitions/Table/ColumnDefinition.php 626 bytes 391. src/Widget/Definitions/Table/ColumnTypeEnum.php 583 bytes 392. src/Widget/Definitions/Table/HeaderColumnDefinition.php 653 bytes 393. src/Widget/Definitions/Table/TableDefinition.php 780 bytes 394. src/Widget/Definitions/TimeLine/TimeLineStyleEnum.php 595 bytes 395. src/Widget/Definitions/ZingChart/ZChart.php 1.88 KB 396. src/Widget/Definitions/ZingChart/ZLabel.php 443 bytes 397. src/Widget/Definitions/ZingChart/ZSerie.php 759 bytes 398. src/Widget/Definitions/ZingChart/ZSeries.php 1.88 KB 399. src/Widget/ExcelInput.php 1.49 KB 400. src/Widget/FaIcon.php 1.25 KB 401. src/Widget/FaIconText.php 1.92 KB 402. src/Widget/FileInput.php 1.48 KB 403. src/Widget/FlexGroup.php 1.92 KB 404. src/Widget/FlexItem.php 1.60 KB 405. src/Widget/Form.php 1.89 KB 406. src/Widget/FormGroup.php 1.82 KB 407. src/Widget/FormGroupColumn.php 2.34 KB 408. src/Widget/FormGroupColumnContent.php 1.88 KB 409. src/Widget/FormGroupColumnEmpty.php 1.60 KB 410. src/Widget/FormGroupColumnLabel.php 4.21 KB 411. src/Widget/FormGroupRow.php 2.04 KB 412. src/Widget/FormGroupSeparator.php 1.23 KB 413. src/Widget/GenericWidget.php 9.34 KB 414. src/Widget/Html.php 560 bytes 415. src/Widget/IDrawable.php 366 bytes 416. src/Widget/Image.php 2.54 KB 417. src/Widget/Input.php 373 bytes 418. src/Widget/InputAddon.php 1.37 KB 419. src/Widget/InputCheck.php 3.20 KB 420. src/Widget/InputColor.php 1.76 KB 421. src/Widget/InputDate.php 2.88 KB 422. src/Widget/InputDateRange.php 2.59 KB 423. src/Widget/InputSelect.php 4.72 KB 424. src/Widget/InputSelectMultiple.php 3.13 KB 425. src/Widget/InputSelectOption.php 938 bytes 426. src/Widget/InputText.php 1.81 KB 427. src/Widget/InputTextArea.php 1.97 KB 428. src/Widget/JSTableContent.php 726 bytes 429. src/Widget/JSTableRow.php 617 bytes 430. src/Widget/JSTableScriptFilter.php 799 bytes 431. src/Widget/Label.php 1.58 KB 432. src/Widget/LeftItem.php 2.96 KB 433. src/Widget/Menu.php 1.59 KB 434. src/Widget/MenuItem.php 1.61 KB 435. src/Widget/Nav.php 1.81 KB 436. src/Widget/PageHeader.php 2.89 KB 437. src/Widget/PageHeaderActionCard.php 5.05 KB 438. src/Widget/Panel.php 3.94 KB 439. src/Widget/Photo.php 2.06 KB 440. src/Widget/PhotoGallery.php 2.17 KB 441. src/Widget/PopUpContent.php 2.86 KB 442. src/Widget/Progress.php 1.84 KB 443. src/Widget/Script.php 844 bytes 444. src/Widget/ScriptDirect.php 945 bytes 445. src/Widget/ScriptDirectSimple.php 1.62 KB 446. src/Widget/SexyTab.php 4.25 KB 447. src/Widget/SexyTabGroup.php 3.63 KB 448. src/Widget/SexyTabPage.php 3.27 KB 449. src/Widget/SimpleList.php 2.15 KB 450. src/Widget/SimpleListItem.php 1.24 KB 451. src/Widget/SimpleScript.php 856 bytes 452. src/Widget/Table.php 2.79 KB 453. src/Widget/TableBody.php 1.06 KB 454. src/Widget/TableColumn.php 1.67 KB 455. src/Widget/TableHeader.php 1010 bytes 456. src/Widget/TableHeaderColumn.php 1.65 KB 457. src/Widget/TableHeaderRow.php 2.35 KB 458. src/Widget/TableRow.php 4.04 KB 459. src/Widget/Text.php 1.34 KB 460. src/Widget/TimeLineContainer.php 3.77 KB 461. src/Widget/TimeLineItem.php 6.29 KB 462. src/Widget/TitleDescription.php 3.62 KB 463. src/Widget/Waiting.php 1.40 KB 464. src/Widget/ZingChart.php 1.57 KB ================================================================================ CONTENIDO DE LOS ARCHIVOS ================================================================================ ================================================================================ ARCHIVO #1: generate_documentation.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/generate_documentation.php Tamaño: 4.78 KB -------------------------------------------------------------------------------- 1 | isFile()) { 38 | $extension = $file->getExtension(); 39 | if (in_array($extension, ['php', 'md', 'txt', 'json', 'xml', 'yml', 'yaml'])) { 40 | $relativePath = str_replace($baseDir . '/', '', $file->getPathname()); 41 | $files[] = [ 42 | 'path' => $file->getPathname(), 43 | 'relative' => $relativePath, 44 | 'size' => $file->getSize() 45 | ]; 46 | } 47 | } 48 | } 49 | 50 | usort($files, function($a, $b) { 51 | return strcmp($a['relative'], $b['relative']); 52 | }); 53 | 54 | return $files; 55 | } 56 | 57 | function formatBytes($bytes) { 58 | if ($bytes >= 1048576) { 59 | return number_format($bytes / 1048576, 2) . ' MB'; 60 | } elseif ($bytes >= 1024) { 61 | return number_format($bytes / 1024, 2) . ' KB'; 62 | } else { 63 | return $bytes . ' bytes'; 64 | } 65 | } 66 | 67 | echo "Generando documentación para DDI...\n"; 68 | echo "Directorio base: $baseDir\n"; 69 | echo "Archivo de salida: $outputFile\n\n"; 70 | 71 | $files = getAllFiles($baseDir, $baseDir); 72 | $totalFiles = count($files); 73 | $totalSize = array_sum(array_column($files, 'size')); 74 | 75 | echo "Archivos encontrados: $totalFiles\n"; 76 | echo "Tamaño total: " . formatBytes($totalSize) . "\n\n"; 77 | 78 | $output = sprintf($header, date('Y-m-d H:i:s')); 79 | 80 | $output .= "Total de archivos: $totalFiles\n"; 81 | $output .= "Tamaño total: " . formatBytes($totalSize) . "\n\n"; 82 | 83 | $output .= "LISTA DE ARCHIVOS:\n"; 84 | $output .= str_repeat("-", 80) . "\n"; 85 | 86 | foreach ($files as $index => $file) { 87 | $num = $index + 1; 88 | $output .= sprintf("%4d. %-60s %10s\n", $num, $file['relative'], formatBytes($file['size'])); 89 | } 90 | 91 | $output .= "\n" . str_repeat("=", 80) . "\n"; 92 | $output .= " CONTENIDO DE LOS ARCHIVOS\n"; 93 | $output .= str_repeat("=", 80) . "\n\n"; 94 | 95 | foreach ($files as $index => $file) { 96 | $num = $index + 1; 97 | echo "Procesando ($num/$totalFiles): {$file['relative']}\n"; 98 | 99 | $output .= "\n" . str_repeat("=", 80) . "\n"; 100 | $output .= "ARCHIVO #$num: {$file['relative']}\n"; 101 | $output .= str_repeat("=", 80) . "\n"; 102 | $output .= "Ruta: {$file['path']}\n"; 103 | $output .= "Tamaño: " . formatBytes($file['size']) . "\n"; 104 | $output .= str_repeat("-", 80) . "\n\n"; 105 | 106 | $content = file_get_contents($file['path']); 107 | $lines = explode("\n", $content); 108 | $lineCount = count($lines); 109 | 110 | foreach ($lines as $lineNum => $line) { 111 | $output .= sprintf("%5d | %s\n", $lineNum + 1, $line); 112 | } 113 | 114 | $output .= "\n" . str_repeat("-", 80) . "\n"; 115 | $output .= "Total de líneas: $lineCount\n"; 116 | $output .= str_repeat("=", 80) . "\n\n"; 117 | } 118 | 119 | $output .= "\n" . str_repeat("=", 80) . "\n"; 120 | $output .= " FIN DE LA DOCUMENTACIÓN\n"; 121 | $output .= str_repeat("=", 80) . "\n\n"; 122 | 123 | $output .= "Generado el: " . date('Y-m-d H:i:s') . "\n"; 124 | $output .= "Total de archivos documentados: $totalFiles\n"; 125 | $output .= "Tamaño total del código fuente: " . formatBytes($totalSize) . "\n\n"; 126 | 127 | $output .= "Esta documentación ha sido generada para el registro del InTouch Framework\n"; 128 | $output .= "en el Departamento de Derechos Intelectuales de Chile.\n\n"; 129 | 130 | $output .= "Autor: Claudio Alfonso González Almeyda\n"; 131 | $output .= "Copyright 2018 - 2025. Todos los derechos reservados.\n"; 132 | 133 | file_put_contents($outputFile, $output); 134 | 135 | echo "\n"; 136 | echo str_repeat("=", 80) . "\n"; 137 | echo "Documentación generada exitosamente!\n"; 138 | echo str_repeat("=", 80) . "\n"; 139 | echo "Archivo: $outputFile\n"; 140 | echo "Tamaño del archivo de documentación: " . formatBytes(filesize($outputFile)) . "\n"; 141 | echo "Total de archivos documentados: $totalFiles\n"; 142 | echo "Total de líneas de código: " . substr_count($output, "\n") . "\n"; 143 | echo str_repeat("=", 80) . "\n"; 144 | -------------------------------------------------------------------------------- Total de líneas: 144 ================================================================================ ================================================================================ ARCHIVO #2: src/Annotation/AnnotationHelper.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Annotation/AnnotationHelper.php Tamaño: 12.32 KB -------------------------------------------------------------------------------- 1 | __ClassAttributes; 28 | case "MethodAttributes": return $this->__MethodAttributes; 29 | case "PropertyAttributes": return $this->__PropertyAttributes; 30 | case "Reflected": return $this->__Reflected; 31 | default: 32 | user_error("Invalid property: " . __CLASS__ . "->$name"); 33 | return null; 34 | } 35 | 36 | } 37 | 38 | private function __construct(public string $fullClassname) { 39 | 40 | $this->__ClassAttributes = null; 41 | $this->__MethodAttributes = []; 42 | $this->__PropertyAttributes = []; 43 | 44 | $this->__Reflected = new \ReflectionClass($fullClassname); 45 | 46 | $this->LoadAttributes(); 47 | } 48 | 49 | public static function FromClass($fullClassname) { 50 | return new AnnotationHelper(fullClassname: $fullClassname); 51 | } 52 | 53 | public static function FromObject($object) { 54 | $classname = $object::class; 55 | 56 | return new AnnotationHelper(fullClassname: $classname); 57 | } 58 | 59 | private function LoadAttributes() { 60 | 61 | $this->__ClassAttributes = null; 62 | $this->__MethodAttributes = []; 63 | $this->__PropertyAttributes = []; 64 | 65 | $reflector = $this->__Reflected; // new \ReflectionClass($this->fullClassname); 66 | 67 | // Atributos de clase 68 | // 69 | $classContainer = new AttributeContainer(type: ContainerTypeEnum::TYPE_CLASS, name: $reflector->getShortName()); 70 | $classAttributes = $reflector->getAttributes(); 71 | 72 | if (isset($classAttributes) && $classAttributes !== false && is_array($classAttributes) && count($classAttributes) > 0) { 73 | 74 | // Instanciar cada atributo de clase encontrado para agregarlo a la coleccion 75 | // 76 | foreach($classAttributes as $classAttribute) { 77 | $instancia = $classAttribute->newInstance(); 78 | if (isset($instancia)) { 79 | $classContainer->AddAttribute(name: $classAttribute->getName(), attribute: $instancia); 80 | } 81 | } 82 | } 83 | 84 | // Actualizar los atributos de clase actuales 85 | if (isset($classContainer)) 86 | $this->__ClassAttributes = $classContainer; 87 | 88 | 89 | // Atributos de metodo 90 | // 91 | foreach ($reflector->getMethods() as $method) { 92 | 93 | if (isset($method) && isset($method->class) && $method->class == 'Intouch\Framework\Widget\Definitions\AmChart5\Data\DataCollection' ) { 94 | $stop = 1; 95 | } 96 | 97 | $methodType = $method->getReturnType(); 98 | 99 | $methodContainer = new AttributeContainer( 100 | type: ContainerTypeEnum::TYPE_METHOD, name: $method->getName(), 101 | returnType: isset($methodType) ? $methodType->getName() : '' 102 | ); 103 | $methodAttributes = $method->getAttributes(); 104 | 105 | if (isset($methodAttributes) && $methodAttributes !== false && is_array($methodAttributes) && count($methodAttributes) > 0) { 106 | 107 | // Instanciar cada atributo de clase encontrado para agregarlo a la coleccion 108 | // 109 | foreach($methodAttributes as $methodAttribute) { 110 | $instancia = $methodAttribute->newInstance(); 111 | if (isset($instancia)) { 112 | $methodContainer->AddAttribute(name: $methodAttribute->getName(), attribute: $instancia); 113 | } 114 | } 115 | } 116 | 117 | // Agregar los parametros del metodo al contenedor 118 | // 119 | $methodParameters = $method->getParameters(); 120 | 121 | foreach($methodParameters as $methodParameter) { 122 | $methodContainer->AddParameter( 123 | $methodParameter->getName(), 124 | new MethodParameter( 125 | name: $methodParameter->getName(), 126 | type: ($methodParameter->hasType()) ? $methodParameter->getType()->getName() : "", 127 | allowsNull: $methodParameter->allowsNull(), 128 | defaultValue: ($methodParameter->isDefaultValueAvailable()) ? $methodParameter->getDefaultValue() : null, 129 | position: $methodParameter->getPosition(), 130 | isOptional: $methodParameter->isOptional() 131 | ) 132 | ); 133 | } 134 | 135 | // agregar el contenedor al listado, con el nombre del metodo 136 | if (isset($methodContainer)) 137 | $this->__MethodAttributes[$method->getName()] = $methodContainer; 138 | } 139 | 140 | // Atributos de propiedades 141 | // 142 | foreach ($reflector->getProperties() as $property) { 143 | 144 | $propertyType = $property->getType(); 145 | 146 | $propertyContainer = new AttributeContainer( 147 | type: ContainerTypeEnum::TYPE_PROPERTY, name: $property->getName(), 148 | dataType: isset($propertyType) ? $propertyType->getName() : '' 149 | ); 150 | $propertyAttributes = $property->getAttributes(); 151 | 152 | if (isset($propertyAttributes) && $propertyAttributes !== false && is_array($propertyAttributes) && count($propertyAttributes) > 0) { 153 | 154 | // Instanciar cada atributo de clase encontrado para agregarlo a la coleccion 155 | // 156 | foreach($propertyAttributes as $propertyAttribute) { 157 | $instancia = $propertyAttribute->newInstance(); 158 | if (isset($instancia)) { 159 | $propertyContainer->AddAttribute(name: $propertyAttribute->getName(), attribute: $instancia); 160 | } 161 | } 162 | } 163 | 164 | // agregar el contenedor al listado, con el nombre del metodo 165 | if (isset($propertyContainer)) 166 | $this->__PropertyAttributes[$property->getName()] = $propertyContainer; 167 | } 168 | } 169 | 170 | /** 171 | * Obtiene una colección con todas las propiedades que tienen el atributo especificado 172 | * 173 | * @param string $fullAtrributeClassname El nombre de clase del atributo buscado 174 | * 175 | * @return GenericCollection 176 | */ 177 | public function GetAttributeProperties(string $fullAtrributeClassname) { 178 | 179 | $results = array(); 180 | 181 | // Verificar si existen propiedades 182 | // 183 | if (isset($this->__PropertyAttributes) || count($this->__PropertyAttributes) > 0) { 184 | 185 | // Recorrer las propiedades y recopilar aquellas que tengan el atributo buscado 186 | // 187 | foreach($this->__PropertyAttributes as $propertyName => $attributeContainer) { 188 | foreach($attributeContainer->Attributes as $attributeName => $attribute) { 189 | if ($attributeName == $fullAtrributeClassname) { 190 | array_push($results, new PropertyAttribute(propertyName: $propertyName, attribute: $attribute)); 191 | break; 192 | } 193 | } 194 | } 195 | 196 | } 197 | 198 | if (count($results) > 0) 199 | return new GenericCollection( 200 | DtoName: PropertyAttribute::class, 201 | Key: 'propertyName', 202 | Values: $results 203 | ); 204 | else 205 | return null; 206 | } 207 | 208 | /** 209 | * Obtiene la propiedad que contenga el atributo especificado. Si hay más de una, devuelve la primera encontrada 210 | * 211 | * @param string $fullAtrributeClassname El nombre de clase del atributo buscado 212 | * 213 | * @return Collection 214 | */ 215 | public function FindAttributeProperty(string $fullAttributeClassname) { 216 | 217 | $attributes = $this->GetAttributeProperties($fullAttributeClassname); 218 | 219 | if (isset($attributes) && $attributes->Count() > 0) { 220 | return $attributes->First(); 221 | } 222 | 223 | return null; 224 | } 225 | 226 | /** 227 | * Obtiene una colección con todos los metodos que tienen el atributo especificado 228 | * 229 | * @param string $fullAtrributeClassname El nombre de clase del atributo buscado 230 | * 231 | * @return Collection 232 | */ 233 | public function GetAttributeMethods(string $fullAttributeClassname) { 234 | 235 | $results = array(); 236 | 237 | // Verificar si existen metodos 238 | // 239 | if (isset($this->__MethodAttributes) || count($this->__MethodAttributes) > 0) { 240 | 241 | // Recorrer los metodos y recopilar aquellos que tengan el atributo buscado 242 | // 243 | foreach($this->__MethodAttributes as $methodName => $attributeContainer) { 244 | foreach($attributeContainer->Attributes as $attributeName => $attribute) { 245 | if ($attributeName == $fullAttributeClassname) { 246 | array_push($results, new MethodAttribute(methodName: $methodName, methodParameters: $attributeContainer->Parameters, attribute: $attribute)); 247 | break; 248 | } 249 | } 250 | } 251 | 252 | } 253 | 254 | if (count($results) > 0) 255 | return new GenericCollection( 256 | Key: 'methodName', 257 | DtoName: MethodAttribute::class, 258 | Values: $results 259 | ); 260 | else 261 | return null; 262 | } 263 | 264 | 265 | public function GetMethodAttributes(MethodAttribute $method) : AttributeContainer { 266 | 267 | if (isset($this->__MethodAttributes[$method->methodName])) { 268 | return $this->__MethodAttributes[$method->methodName]; 269 | } 270 | else { 271 | return null; 272 | } 273 | } 274 | 275 | /** 276 | * Obtiene el metodo que contenga el atributo especificado. Si hay más de uno, devuelve el primero encontrado 277 | * 278 | * @param string $fullAtrributeClassname El nombre de clase del atributo buscado 279 | * 280 | * @return Collection 281 | */ 282 | public function FindAttributeMethod(string $fullAttributeClassname) { 283 | 284 | $attributes = $this->GetAttributeMethods($fullAttributeClassname); 285 | 286 | if (isset($attributes) && $attributes->Count() > 0) { 287 | return $attributes->First(); 288 | } 289 | 290 | return null; 291 | } 292 | 293 | public function MethodHasAttribute(string $method, string $fullAttributeClassname): bool { 294 | 295 | $results = array(); 296 | 297 | // Verificar si existen metodos 298 | // 299 | if (isset($this->__MethodAttributes) || count($this->__MethodAttributes) > 0) { 300 | 301 | // Recorrer los metodos y encontrar el metodo buscado, y verificar si tiene el atributo 302 | // 303 | foreach($this->__MethodAttributes as $methodName => $attributeContainer) { 304 | 305 | if (strtolower($methodName) == strtolower($method)) { 306 | foreach($attributeContainer->Attributes as $attributeName => $attribute) { 307 | if ($attributeName == $fullAttributeClassname) { 308 | return true; 309 | } 310 | } 311 | } 312 | } 313 | 314 | } 315 | 316 | return false; 317 | 318 | } 319 | 320 | public function FindAttributeClass($fullAttributeClassname) { 321 | 322 | $results = array(); 323 | 324 | // Verificar si existen attributos de clase 325 | // 326 | if (isset($this->__ClassAttributes->Attributes) || count($this->__ClassAttributes->Attributes) > 0) { 327 | 328 | // Recorrer los atributos de la clase y verificar si existe el atributo buscado 329 | // 330 | foreach($this->__ClassAttributes->Attributes as $attributeName => $attribute) { 331 | if ($attributeName == $fullAttributeClassname) { 332 | array_push($results, new ClassAttribute(className: $this->fullClassname, attribute: $attribute)); 333 | break; 334 | } 335 | } 336 | 337 | } 338 | 339 | if (count($results) > 0) 340 | return $results[0]; 341 | else 342 | return null; 343 | } 344 | 345 | public function Exists(string $property, string $attribute) { 346 | 347 | if (isset($this->__PropertyAttributes[$property]) && $this->__PropertyAttributes[$property]->HasAttribute($attribute)) { 348 | return true; 349 | } 350 | else { 351 | return false; 352 | } 353 | } 354 | 355 | } -------------------------------------------------------------------------------- Total de líneas: 355 ================================================================================ ================================================================================ ARCHIVO #3: src/Annotation/AttributeContainer.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Annotation/AttributeContainer.php Tamaño: 1.87 KB -------------------------------------------------------------------------------- 1 | __Type; 28 | case "Name": return $this->__Name; 29 | case "ReturnType": return $this->__ReturnType; 30 | case "DataType": return $this->__DataType; 31 | case "Attributes": return $this->__Attributes; 32 | case "Parameters": return $this->__Parameters; 33 | default: 34 | user_error("Invalid property: " . __CLASS__ . "->$name"); 35 | return null; 36 | } 37 | 38 | } 39 | 40 | public function AddAttribute($name, $attribute) { 41 | $this->__Attributes[$name] = $attribute; 42 | } 43 | 44 | public function AddParameter(string $name, MethodParameter $parameter) { 45 | $this->__Parameters[$name] = $parameter; 46 | } 47 | 48 | public function __construct( 49 | int $type, string $name, string $returnType = '', string $dataType = '' 50 | ) { 51 | $this->__Type = $type; 52 | $this->__Name = $name; 53 | $this->__ReturnType = $returnType; 54 | $this->__DataType = $dataType; 55 | } 56 | 57 | public function HasAttribute(string $fullAtrributeClassname) { 58 | 59 | foreach($this->__Attributes as $attribueName => $attribute) { 60 | if ($attribueName == $fullAtrributeClassname) 61 | return true; 62 | } 63 | 64 | return false; 65 | } 66 | } -------------------------------------------------------------------------------- Total de líneas: 66 ================================================================================ ================================================================================ ARCHIVO #4: src/Annotation/Attributes/CacheMulti.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Annotation/Attributes/CacheMulti.php Tamaño: 380 bytes -------------------------------------------------------------------------------- 1 | uri = $this->GetImageUri($asset); 60 | } 61 | else if ($asset instanceof PdfResource) { 62 | $asset->uri = $this->GetPdfUri($asset); 63 | } 64 | 65 | return $asset; 66 | } 67 | 68 | function GetImageUri(ImageResource $asset): null|string { 69 | 70 | $resource = new \stdClass(); 71 | $resource->bucket = "website-assets-shutdown-cl"; 72 | $resource->key = $this->mainFolder . ( ($asset->location != '') ? '/' . $asset->location : ''); 73 | 74 | if ($asset->width > 0) { 75 | $resource->edits = new \stdClass(); 76 | $resource->edits->resize = new \stdClass(); 77 | $resource->edits->resize->width = 100; 78 | $resource->edits->resize->fit = "inside"; 79 | } 80 | 81 | $json = str_replace("\\", "", json_encode($resource)); 82 | $encoded = base64_encode($json); 83 | 84 | return $this->apiEndpoint . '/' . $encoded; 85 | } 86 | 87 | function GetPdfUri(PdfResource $asset): null|string { 88 | 89 | $endpoint = $this->apiEndpoint . '/' . $asset->location; 90 | 91 | // Construct the CloudFront request 92 | return null; 93 | } 94 | 95 | private function SolicitarRecurso($ruta) { 96 | 97 | } 98 | } -------------------------------------------------------------------------------- Total de líneas: 98 ================================================================================ ================================================================================ ARCHIVO #36: src/Assets/Managers/LocalAssetManager.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Assets/Managers/LocalAssetManager.php Tamaño: 1.29 KB -------------------------------------------------------------------------------- 1 | rootPath . '/' . $asset->location . '/' . $asset->name; 42 | 43 | if (file_exists($path)) { 44 | $content = file_get_contents($path); 45 | $asset->content = $content; 46 | } 47 | else { 48 | $asset->content = null; 49 | } 50 | 51 | return $asset; 52 | } 53 | 54 | /** 55 | * 56 | * @param Resource $asset 57 | * 58 | * @return Resource 59 | */ 60 | function GetAssetUri(Resource $asset): Resource { 61 | $asset->uri = $this->rootUri . '/' . $asset->location . '/' . $asset->name; 62 | 63 | return $asset; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- Total de líneas: 66 ================================================================================ ================================================================================ ARCHIVO #37: src/Assets/Managers/S3AssetManager.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Assets/Managers/S3AssetManager.php Tamaño: 1.54 KB -------------------------------------------------------------------------------- 1 | __content; 22 | case "uri": return $this->__uri; 23 | default: 24 | user_error("Invalid property: " . __CLASS__ . "->$name"); 25 | return null; 26 | } 27 | 28 | } 29 | 30 | function __set($name, $value) { 31 | 32 | switch($name) { 33 | case "content": 34 | $this->__content = $value; 35 | break; 36 | case "uri": 37 | $this->__uri = $value; 38 | break; 39 | default: 40 | user_error("Invalid property: " . __CLASS__ . "->$name"); 41 | return null; 42 | } 43 | 44 | } 45 | public function __construct( 46 | public string $id, 47 | public string $name, 48 | public string $localpath = '', 49 | public string $location = '' 50 | ) {} 51 | 52 | } -------------------------------------------------------------------------------- Total de líneas: 52 ================================================================================ ================================================================================ ARCHIVO #40: src/BLL/DataTransferObjects/RangoDto.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/BLL/DataTransferObjects/RangoDto.php Tamaño: 368 bytes -------------------------------------------------------------------------------- 1 | Dao = $dao; 32 | $this->DtoName = $dtoName; 33 | $this->EntityName = $entityName; 34 | } 35 | 36 | public function GetDomain() 37 | { 38 | return $this->Dao->Domain; 39 | } 40 | 41 | public function GetDtoName() 42 | { 43 | return $this->DtoName; 44 | } 45 | 46 | 47 | public static function BeginMultipleOperations($domain, $transactionLevel = null) 48 | { 49 | // Obtener una transaccion 50 | self::$Transaction = ExecuteDao::OpenTransaction($domain, $transactionLevel); 51 | 52 | if (isset(self::$Transaction)) { 53 | return true; 54 | } else { 55 | return false; 56 | } 57 | } 58 | 59 | public static function SaveMultipleOperations() 60 | { 61 | ExecuteDao::CommitTransaction(self::$Transaction); 62 | self::$Transaction = null; 63 | } 64 | 65 | public static function UndoMultipleOperations() 66 | { 67 | ExecuteDao::RollbackTransaction(self::$Transaction); 68 | self::$Transaction = null; 69 | } 70 | 71 | public function Find($keyValue, $incluirNoVigentes = true, $incluirEliminados = true, $nosanear = false) 72 | { 73 | $dto = Mapper::ToDto($this->Dao->Find($keyValue, $incluirNoVigentes, $incluirEliminados, GenericSvc::$Transaction), $this->DtoName, [], $nosanear); 74 | return $dto; 75 | } 76 | 77 | public function FindBy($bindings, $orderFields = '', $nosanear = false) 78 | { 79 | return Mapper::ToDto($this->Dao->FindBy($bindings, $orderFields, GenericSvc::$Transaction), $this->DtoName, [], $nosanear); 80 | } 81 | 82 | public function FindByForeign($foreignKey, $foreignKeyValue, $nosanear = false) 83 | { 84 | return Mapper::ToDto($this->Dao->FindByForeign($foreignKey, $foreignKeyValue, GenericSvc::$Transaction), $this->DtoName, [], $nosanear); 85 | } 86 | 87 | public function GetAll($order = "", $avoidNull = false, $nosanear = false) 88 | { 89 | return Mapper::ToDtos(entityArray: $this->Dao->GetAll($order, GenericSvc::$Transaction), dtoName: $this->DtoName, avoidNull: $avoidNull, nosanear: $nosanear); 90 | } 91 | 92 | public function GetBy($bindings, $orderFields = '', $avoidNull = false, $top = 0, $nosanear = false, $aplicarTope = true, $ramSinTope = IniEnum::MEM_2G) 93 | { 94 | return Mapper::ToDtos(entityArray: $this->Dao->GetBy($bindings, $orderFields, $top, GenericSvc::$Transaction), dtoName: $this->DtoName, avoidNull: $avoidNull, nosanear: $nosanear, aplicarTope: $aplicarTope, ramSinTope: $ramSinTope); 95 | } 96 | 97 | public function GetByToFile($bindings, $orderFields = '', $top = 0, $localDataFolder = "") { 98 | 99 | return $this->Dao->GetByToFile($bindings, $orderFields, $top, GenericSvc::$Transaction, $localDataFolder); 100 | 101 | } 102 | 103 | 104 | public function GetByForeign($foreignKey, $foreignKeyValue, $orderFields = '', $avoidNull = false, $nosanear = false) 105 | { 106 | return Mapper::ToDtos(entityArray: $this->Dao->GetByForeign($foreignKey, $foreignKeyValue, $orderFields, GenericSvc::$Transaction), dtoName: $this->DtoName, avoidNull: $avoidNull, nosanear: $nosanear); 107 | } 108 | 109 | public function GetByCodigoRegistro($codigoRegistro, $avoidNull = false) 110 | { 111 | return Mapper::ToDtos(entityArray: $this->Dao->GetByCodigoRegistro($codigoRegistro, GenericSvc::$Transaction), dtoName: $this->DtoName, avoidNull: $avoidNull); 112 | } 113 | 114 | public function Insert($dto, $nosanear = false, ?IAuditable $auditable = null) 115 | { 116 | if ($this->DtoName !== get_class($dto)) { 117 | throw new \Exception('El DTO a insertar debe ser una instancia de la clase: ' . $this->DtoName); 118 | return null; 119 | } 120 | 121 | return Mapper::ToDto($this->Dao->Insert(Mapper::ToEntity($dto, $this->EntityName, false, $nosanear), GenericSvc::$Transaction, $auditable), $this->DtoName); 122 | } 123 | 124 | public function Update($dto, $nosanear = false, ?IAuditable $auditable = null) 125 | { 126 | if ($this->DtoName !== get_class($dto)) { 127 | throw new \Exception('El DTO a insertar debe ser una instancia de la clase: ' . $this->DtoName); 128 | return null; 129 | } 130 | 131 | $this->Dao->Update(Mapper::ToEntity($dto, $this->EntityName, false, $nosanear), GenericSvc::$Transaction, $auditable); 132 | } 133 | 134 | public function Delete($keyValue) 135 | { 136 | $this->Dao->Delete($keyValue, GenericSvc::$Transaction); 137 | } 138 | 139 | public function LogicDelete($keyValue) 140 | { 141 | $this->Dao->LogicDelete($keyValue, GenericSvc::$Transaction); 142 | } 143 | 144 | public function DeleteBy($bindings) 145 | { 146 | $this->Dao->DeleteBy($bindings, GenericSvc::$Transaction); 147 | } 148 | 149 | public function LogicDeleteBy($bindings) 150 | { 151 | $this->Dao->LogicDeleteBy($bindings, GenericSvc::$Transaction); 152 | } 153 | 154 | public function Count() 155 | { 156 | return $this->Dao->Count(GenericSvc::$Transaction); 157 | } 158 | 159 | public function CountBy($bindings) 160 | { 161 | return $this->Dao->CountBy($bindings, GenericSvc::$Transaction); 162 | } 163 | 164 | function SumFieldByForeign($fieldName, $foreignKeyName, $foreignKeyValue) 165 | { 166 | return $this->Dao->SumFieldByForeign($fieldName, $foreignKeyName, $foreignKeyValue, GenericSvc::$Transaction); 167 | } 168 | 169 | function CountByForeign($foreignKeyName, $foreignKeyValue) 170 | { 171 | return $this->Dao->CountByForeign($foreignKeyName, $foreignKeyValue, GenericSvc::$Transaction); 172 | } 173 | 174 | function Query(Queryable $query, bool $returnFirstRecord = false, $avoidNull = false) 175 | { 176 | return Mapper::GetInstance()->map($this->Dao->Query($query, $returnFirstRecord, GenericSvc::$Transaction), null, true, '', true, $avoidNull); 177 | } 178 | 179 | function GetIN($foreignKey, $foreignKeyValue, $orderFields = '') 180 | { 181 | //return $this->Dao->GetIN($foreignKey, $foreignKeyValue, $orderFields); 182 | return Mapper::ToDtos($this->Dao->GetIN($foreignKey, $foreignKeyValue, $orderFields, GenericSvc::$Transaction), $this->DtoName); 183 | } 184 | 185 | public function Max($field, $ignoreBlanks = false) 186 | { 187 | return $this->Dao->Max($field, ignoreBlanks: $ignoreBlanks, transaction: GenericSvc::$Transaction); 188 | } 189 | 190 | public function Min($field, $ignoreBlanks = false) 191 | { 192 | return $this->Dao->Min(field: $field, ignoreBlanks: $ignoreBlanks, transaction: GenericSvc::$Transaction); 193 | } 194 | 195 | public function Rango($field, $ignoreBlanks = false) 196 | { 197 | 198 | $menor = $this->Dao->Min($field, $ignoreBlanks); 199 | $mayor = $this->Dao->Max($field, $ignoreBlanks); 200 | 201 | if (!isset($menor)) $menor = 0; 202 | if (!isset($mayor)) $mayor = 0; 203 | 204 | return new RangoDto( 205 | Menor: $menor, 206 | Mayor: $mayor 207 | ); 208 | } 209 | } 210 | -------------------------------------------------------------------------------- Total de líneas: 210 ================================================================================ ================================================================================ ARCHIVO #44: src/BLL/WebService/HttpHelper.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/BLL/WebService/HttpHelper.php Tamaño: 5.23 KB -------------------------------------------------------------------------------- 1 | > <> 21 | 22 | // Obtener los parametros 23 | if (isset($argc) && $argc >= 4) { 24 | $engine = new Engine( 25 | entityDomain: $argv[1], 26 | entityNamespace: $argv[2], 27 | entityTable: $argv[3] 28 | ); 29 | 30 | $overwrite = false; 31 | if ($argc >= 5) { 32 | if (trim($argv[4]) == 'overwrite') { 33 | $overwrite = true; 34 | } 35 | } 36 | 37 | $engine->Generate($overwrite); 38 | } 39 | else { 40 | echo "\nError: parámetros no válidos\n\n"; 41 | echo "Usage: ./gen.sh <> <> <
> [[overwrite]]\n"; 42 | echo "\nEjs:\n./gen.sh default Administracion TipoCliente,TipoProducto\n./gen.sh default Administracion TipoCliente,Cuenta,Usuario overwrite\n\n"; 43 | die(); 44 | } -------------------------------------------------------------------------------- Total de líneas: 44 ================================================================================ ================================================================================ ARCHIVO #48: src/Bin/mantenedor.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Bin/mantenedor.php Tamaño: 1.27 KB -------------------------------------------------------------------------------- 1 | > <
> 21 | 22 | // Obtener los parametros 23 | if (isset($argc) && $argc >= 4) { 24 | $engine = new Engine( 25 | entityDomain: $argv[1], 26 | entityNamespace: $argv[2], 27 | entityTable: $argv[3] 28 | ); 29 | 30 | $overwrite = false; 31 | if ($argc >= 5) { 32 | if (trim($argv[4]) == 'overwrite') { 33 | $overwrite = true; 34 | } 35 | } 36 | 37 | $engine->Mantenedor($overwrite); 38 | } 39 | else { 40 | echo "\nError: parámetros no válidos\n\n"; 41 | echo "Usage: ./gen.sh <> <> <
> [[overwrite]]\n"; 42 | echo "\nEjs:\n./gen.sh default Administracion TipoCliente,TipoProducto\n./gen.sh default Administracion TipoCliente,Cuenta,Usuario overwrite\n\n"; 43 | die(); 44 | } -------------------------------------------------------------------------------- Total de líneas: 44 ================================================================================ ================================================================================ ARCHIVO #49: src/Cache/Page.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Cache/Page.php Tamaño: 25.80 KB -------------------------------------------------------------------------------- 1 | (int)$draw, // Castear a int por seguridad 105 | "recordsTotal" => $pageResults->RecordCount, // $recordsTotal, 106 | "recordsFiltered" => $pageResults->RecordCount, // $recordsFiltered, 107 | "data" => $pageResults->Data, // $data, 108 | // El campo "error" no se incluirá si no hay mensajes de error explícitos. 109 | ]; 110 | 111 | // Retornar la respuesta como un string JSON. 112 | return json_encode($response); 113 | } 114 | 115 | /** 116 | * Recupera un segmento paginado de resultados desde Redis. 117 | * Refresca el TTL de todas las llaves (índice y chunks) asociadas al conjunto de resultados 118 | * si el índice principal indica que se debe hacer. 119 | * 120 | * @param string $resultsId El GUID del conjunto de resultados principal. 121 | * @param int $pageNumber El número de página a recuperar (base 1). 122 | * @param int $recordsPerPage La cantidad de registros por página. 123 | * @return PageResults Un arreglo con los registros de la página solicitada. 124 | * @throws Exception Si ocurre un error crítico que impide la recuperación de los datos. 125 | */ 126 | public static function GetResults(string $resultsId, int $pageNumber, ?int $recordsPerPage=0): PageResults 127 | { 128 | $result = new PageResults( 129 | ResultsId: $resultsId 130 | ); 131 | 132 | // 1. Obtener la instancia de Redis 133 | try { 134 | $redis = RedisSvc::Init(); 135 | } catch (Throwable $e) { // Captura cualquier excepción de conexión de RedisSvc::Init() 136 | throw new Exception("Error al conectar a Redis para GetResults: " . $e->getMessage(), 0, $e); 137 | } 138 | 139 | // 2. Construir la llave del índice principal 140 | $indexKey = "{$resultsId}_resultindex"; 141 | 142 | // 3. Recuperar y deserializar el índice principal 143 | $indexData =self::GetIndex($resultsId); 144 | 145 | // $serializedIndex = $redis->get($indexKey); 146 | 147 | // if ($serializedIndex === false) { 148 | // // El índice no existe o ya expiró. Esto es una condición esperada, no un error de sistema. 149 | // return $result; 150 | // } 151 | 152 | // $indexData = json_decode($serializedIndex, true); 153 | 154 | // if (json_last_error() !== JSON_ERROR_NONE) { 155 | // throw new Exception("Error al deserializar el índice de resultados '$indexKey': " . json_last_error_msg()); 156 | // } 157 | 158 | // // Validar que los datos esenciales estén presentes en el índice 159 | // if (!isset($indexData['RecordCount'], $indexData['ChunkSize'], $indexData['Llaves'], $indexData['ChunkTtl'], $indexData['ChunkTtlRefresh'])) { 160 | // throw new Exception("Índice de resultados '$indexKey' incompleto o malformado."); 161 | // } 162 | 163 | // $recordCount = (int) $indexData['RecordCount']; 164 | // $chunkSize = (int) $indexData['ChunkSize']; 165 | // $allChunkKeys = (array) $indexData['Llaves']; 166 | // $chunkTtl = (int) $indexData['ChunkTtl']; 167 | // $chunkTtlRefresh = (int) $indexData['ChunkTtlRefresh']; // 0 o 1 168 | $recordCount = $indexData->RecordCount; 169 | $chunkSize = $indexData->ChunkSize; 170 | $allChunkKeys = $indexData->Llaves; 171 | $chunkTtl = $indexData->ChunkTtl; 172 | $chunkTtlRefresh = $indexData->ChunkTtlRefresh; // 0 o 1 173 | 174 | // 4. Refrescar el TTL de la llave del índice (siempre) 175 | if (!$redis->expire($indexKey, $chunkTtl)) { 176 | // No lanzamos excepción aquí, ya que el fallo en el refresh del TTL no impide obtener los datos 177 | // pero es un problema digno de loggear para monitoreo. 178 | error_log("ADVERTENCIA: No se pudo refrescar el TTL de la llave del índice: '$indexKey'"); 179 | } 180 | 181 | // 5. Calcular el rango de registros necesario para la página 182 | if ($pageNumber >= 0) { 183 | $startIndex = ($pageNumber - 1) * $recordsPerPage; 184 | 185 | // Asegurarse de que el número de página sea válido y que los registros no excedan el total 186 | if ($pageNumber < 1 || $startIndex >= $recordCount) { 187 | return $result; // Página fuera de rango o sin registros - esto es un caso de negocio, no un error. 188 | } 189 | 190 | $endIndex = min($startIndex + $recordsPerPage - 1, $recordCount - 1); // El último índice de registro de la página 191 | $recordsToFetchCount = $endIndex - $startIndex + 1; // Cantidad exacta de registros a recuperar para esta página 192 | 193 | // 6. Identificar los chunks que necesitamos (y todos los demás para el refresh) 194 | // 6. Calcular qué chunks específicos necesitamos cargar 195 | $firstChunkIndex = floor($startIndex / $chunkSize); 196 | $lastChunkIndex = floor($endIndex / $chunkSize); 197 | } 198 | else { 199 | $startIndex = 0; 200 | $endIndex = $recordCount-1; 201 | } 202 | 203 | $relevantChunkKeys = []; 204 | for ($i = $firstChunkIndex; $i <= $lastChunkIndex; $i++) { 205 | // Aquí es crucial que tengas un patrón para tus claves de chunk 206 | // Por ejemplo, si tus claves son 'resultados:chunk:0', 'resultados:chunk:1', etc. 207 | // Necesitas reconstruirlas o tener un array mapeado por índice. 208 | // Para este ejemplo, asumiremos que $allChunkKeys está indexado o podemos generar la clave. 209 | // Si tus claves no son secuenciales o predecibles, necesitarás una lógica diferente para obtenerlas. 210 | 211 | // Suponiendo que $allChunkKeys contiene las claves ordenadas por índice. 212 | // Si no es el caso, deberías tener una forma de generar la clave dado el índice del chunk, 213 | // por ejemplo, $chunkKey = "prefijo:chunk:" . $i; 214 | 215 | if (isset($allChunkKeys[$i])) { 216 | $relevantChunkKeys[] = $allChunkKeys[$i]; 217 | } else { 218 | // Esto indica un problema grave: el chunk esperado no existe en la lista de claves. 219 | // Podría ser un desincronización o un error en la generación de claves. 220 | throw new Exception("Chunk clave para el índice {$i} no encontrado. El conjunto de resultados podría estar incompleto."); 221 | } 222 | } 223 | 224 | $allRecords = []; // Aquí se acumularán todos los registros de los chunks recuperados 225 | 226 | foreach ($relevantChunkKeys as $chunkKey) { 227 | $serializedChunk = $redis->get($chunkKey); 228 | 229 | if ($serializedChunk === false) { 230 | // Si un chunk no se encuentra, es un problema. 231 | // Podría ser por expiración prematura, o una inconsistencia. 232 | throw new Exception("Chunk de resultados '$chunkKey' no encontrado o expirado. El conjunto de resultados podría estar incompleto."); 233 | } 234 | 235 | $chunkData = json_decode($serializedChunk, true); 236 | 237 | if (json_last_error() !== JSON_ERROR_NONE) { 238 | throw new Exception("Error al deserializar chunk de resultados '$chunkKey': " . json_last_error_msg()); 239 | } 240 | 241 | // Refrescar el TTL del chunk si ChunkTtlRefresh está activado 242 | if ($chunkTtlRefresh === 1) { 243 | if (!$redis->expire($chunkKey, $chunkTtl)) { 244 | // Similar al índice, loggeamos la advertencia si el refresh falla. 245 | error_log("ADVERTENCIA: No se pudo refrescar el TTL del chunk: '$chunkKey'"); 246 | } 247 | } 248 | 249 | // Acumular los registros de este chunk 250 | if (is_array($chunkData)) { 251 | $allRecords = array_merge($allRecords, $chunkData); 252 | } else { 253 | // Si el chunk no contiene un arreglo, es un dato corrupto 254 | throw new Exception("El chunk '$chunkKey' no contenía un arreglo de registros como se esperaba."); 255 | } 256 | } 257 | 258 | // 7. Extraer solo los registros de la página solicitada del arreglo combinado 259 | $offsetInLoadedRecords = $startIndex - ($firstChunkIndex * $chunkSize); 260 | $paginatedResults = array_slice($allRecords, $offsetInLoadedRecords, $recordsToFetchCount); 261 | 262 | 263 | $result->RecordCount = $recordCount; 264 | $result->RecordsFiltered = count($paginatedResults); 265 | $result->Data = $paginatedResults; 266 | 267 | return $result; 268 | } 269 | 270 | public static function GetIndex(string $resultsId) { 271 | 272 | if (isset(self::$index)) { 273 | return self::$index; 274 | } 275 | 276 | // 1. Obtener la instancia de Redis 277 | try { 278 | $redis = RedisSvc::Init(); 279 | } catch (Throwable $e) { // Captura cualquier excepción de conexión de RedisSvc::Init() 280 | throw new Exception("Error al conectar a Redis para GetResults: " . $e->getMessage(), 0, $e); 281 | } 282 | 283 | // 2. Construir la llave del índice principal 284 | $indexKey = "{$resultsId}_resultindex"; 285 | 286 | // 3. Recuperar y deserializar el índice principal 287 | $serializedIndex = $redis->get($indexKey); 288 | 289 | if ($serializedIndex === false) { 290 | // El índice no existe o ya expiró. Esto es una condición esperada, no un error de sistema. 291 | return null; 292 | } 293 | 294 | $indexData = json_decode($serializedIndex, true); 295 | 296 | if (json_last_error() !== JSON_ERROR_NONE) { 297 | throw new Exception("Error al deserializar el índice de resultados '$indexKey': " . json_last_error_msg()); 298 | } 299 | 300 | // Mapear 301 | // autoMapper($sourceObject, $targetObject, $nosanear = false, $honorPrefix = '', $useTargetProperties = false, array $innerMappings = []) 302 | $pageDef = PageDefinition::NewFromIndex((object)$indexData); 303 | 304 | if ($pageDef instanceof PageDefinition) { 305 | if (!isset($pageDef->RecordCount, $pageDef->ChunkSize, $pageDef->Llaves, $pageDef->ChunkTtl, $pageDef->ChunkTtlRefresh)) { 306 | throw new Exception("Índice de resultados '$indexKey' incompleto o malformado."); 307 | } 308 | } 309 | else { 310 | throw new Exception("Índice de resultados '$indexKey' no es del tipo esperado."); 311 | } 312 | 313 | return $pageDef; 314 | } 315 | 316 | /** 317 | * Almacena un arreglo completo de resultados en Redis, dividiéndolo en "chunks" 318 | * para optimizar la recuperación paginada. 319 | * 320 | * Este método genera un GUID único para el conjunto de resultados, serializa los datos, 321 | * y los guarda en Redis usando pipelining para mayor eficiencia. Crea un índice principal 322 | * con metadata y llaves de los chunks, aplicando el TTL definido. 323 | * 324 | * @param array $results El arreglo completo de registros a almacenar. Cada elemento debe ser serializable a JSON. 325 | * @return PageDefinition Un objeto PageDefinition con los detalles de la paginación y el estado de la inserción. 326 | * @throws Exception Si falla la conexión a Redis, la serialización de datos, o la inserción en Redis. 327 | * @throws InvalidArgumentException Si los datos de entrada no son válidos (ej. $results no es un arreglo). 328 | */ 329 | public static function PutResults(array|GenericCollection $results, ?string $dtoName = '', $key = '', $orderColumn = '', $orderDir = 'asc'): PageDefinition 330 | { 331 | if (empty($results) || (is_array($results) && count($results) == 0)) { 332 | // Se podría lanzar una excepción si no se permite insertar arreglos vacíos. 333 | // Para este caso, podemos simplemente crear un índice vacío. 334 | // throw new InvalidArgumentException("El arreglo de resultados no puede estar vacío."); 335 | } 336 | 337 | 338 | if (is_array($results)) { 339 | if ($dtoName == '') { 340 | throw new Exception("Debe especificar el nombre del DTO (dtoName) cuando no usa GenericCollection"); 341 | } 342 | } 343 | else if ($results instanceof GenericCollection) { 344 | $dtoName = $results->GetDtoName(); 345 | $results = $results->Values; 346 | } 347 | else { 348 | if ($dtoName == '') { 349 | throw new Exception("Debe especificar el nombre del DTO (dtoName) cuando no usa GenericCollection"); 350 | } 351 | } 352 | 353 | // 1. Obtener la instancia de Redis y preparar IDs y metadata 354 | try { 355 | $redis = RedisSvc::Init(); 356 | } catch (Throwable $e) { 357 | throw new Exception("Error al conectar a Redis para PutResults: " . $e->getMessage(), 0, $e); 358 | } 359 | 360 | // Importante: Asegúrate de que _guid() sea robusta (ej. usando random_bytes o Ramsey\Uuid) 361 | $resultsId = _guid(); // Genera un GUID único para el conjunto de resultados 362 | $idResultIndex = $resultsId . "_resultindex"; // Llave para el índice principal 363 | $idResultPrefix = $resultsId . "_results_"; // Prefijo para las llaves de los chunks 364 | 365 | $recordCount = count($results); 366 | $chunks = array_chunk($results, self::$CHUNK_SIZE); 367 | $chunkLength = count($chunks); 368 | $llaves = []; // Array para almacenar las llaves de los chunks creados 369 | 370 | // 2. Preparar el índice principal (metadata) 371 | $resultIndex = new PageDefinition( 372 | ResultsId : $resultsId, 373 | DtoName : $dtoName, 374 | Key : $key, 375 | OrderColumn : $orderColumn, 376 | OrderDir : $orderDir, 377 | InsertStatus : false, 378 | RecordCount : $recordCount, 379 | ChunkSize : self::$CHUNK_SIZE, 380 | ChunkLength : $chunkLength, 381 | ChunkTtl : self::$CHUNK_TTL, 382 | ChunkTtlRefresh : self::$CHUNK_TTL_REFRESH, 383 | Llaves : [], 384 | ); 385 | 386 | // $resultIndex = [ 387 | // "ResultsId" => $resultsId, 388 | // "DtoName" => $dtoName, 389 | // "InsertStatus" => false, // Se actualiza al final si todo es exitoso 390 | // "RecordCount" => $recordCount, 391 | // "ChunkSize" => self::$CHUNK_SIZE, 392 | // "ChunkLength" => $chunkLength, 393 | // "ChunkTtl" => self::$CHUNK_TTL, 394 | // "ChunkTtlRefresh" => self::$CHUNK_TTL_REFRESH, 395 | // "Llaves" => [], // Se llenará en el pipeline 396 | // ]; 397 | 398 | // 3. Usar Pipelining para insertar todos los chunks y el índice atómicamente/eficientemente 399 | try { 400 | // Iniciar el pipeline 401 | $redis->multi(Redis::PIPELINE); 402 | 403 | // Generar y serializar los chunks, y añadir comandos SET al pipeline 404 | foreach ($chunks as $idx => $chunk) { 405 | $chunkKey = $idResultPrefix . $idx; 406 | $llaves[] = $chunkKey; // Acumular llaves para el índice 407 | 408 | $serializedChunk = json_encode($chunk); 409 | if ($serializedChunk === false) { 410 | // Descartar el pipeline si la serialización de un chunk falla 411 | $redis->discard(); 412 | throw new Exception("Error al serializar el chunk {$idx} para Redis: " . json_last_error_msg()); 413 | } 414 | // Añadir comando SET con TTL al pipeline 415 | $redis->set($chunkKey, $serializedChunk, ['EX' => self::$CHUNK_TTL]); 416 | } 417 | 418 | // Actualizar el índice con las llaves de los chunks 419 | // $resultIndex['Llaves'] = $llaves; 420 | // $resultIndex['InsertStatus'] = true; // Si llegamos aquí, la inserción se considera exitosa 421 | $resultIndex->Llaves = $llaves; 422 | $resultIndex->InsertStatus = true; // Si llegamos aquí, la inserción se considera exitosa 423 | 424 | $serializedIndex = json_encode($resultIndex); 425 | if ($serializedIndex === false) { 426 | $redis->discard(); 427 | throw new Exception("Error al serializar el índice de resultados para Redis: " . json_last_error_msg()); 428 | } 429 | // Añadir comando SET para el índice al pipeline 430 | $redis->set($idResultIndex, $serializedIndex, ['EX' => self::$CHUNK_TTL]); 431 | 432 | // Ejecutar todos los comandos en el pipeline 433 | // Las respuestas individuales de SET (true/false) no se chequean aquí 434 | // para mantener el pipeline simple. Si se necesita validación de cada SET, 435 | // se pueden revisar las respuestas del exec. 436 | $redis->exec(); 437 | 438 | // Opcional: Si self::$lastResultId todavía se usa y es seguro en este contexto 439 | // self::$lastResultId = $resultsId; 440 | 441 | } catch (Exception $e) { 442 | // El pipeline se descarta automáticamente en caso de excepción en multi/exec. 443 | // Si quieres asegurarte de que ningún dato parcial quede, podrías intentar borrar llaves aquí, 444 | // pero si usas MULTI/EXEC, es "todo o nada". 445 | // Para errores de serialización, el discard ya fue llamado. 446 | throw new Exception("Fallo en la operación de inyección de resultados a Redis: " . $e->getMessage(), 0, $e); 447 | } 448 | 449 | // 4. Construir y devolver el objeto PageDefinition 450 | // El InsertStatus reflejará el éxito o fracaso capturado por la excepción 451 | // (si la excepción se lanza, esta parte del código no se ejecuta). 452 | // Si no hay excepción, InsertStatus será true. 453 | // $pageDef = new PageDefinition( 454 | // ResultsId: $resultIndex["ResultsId"], // Usar la clave correcta del array asociativo 455 | // InsertStatus: true, // Si llegamos aquí, la operación fue exitosa 456 | // RecordCount: $resultIndex["RecordCount"], 457 | // ChunkSize: $resultIndex["ChunkSize"], 458 | // ChunkLength: $resultIndex["ChunkLength"], 459 | // ChunkTtl: $resultIndex["ChunkTtl"], 460 | // ChunkTtlRefresh: $resultIndex["ChunkTtlRefresh"], 461 | // Llaves: $resultIndex["Llaves"], 462 | // ); 463 | 464 | // return $pageDef; 465 | return $resultIndex; 466 | } 467 | 468 | public static function GetChunk($chunkKey) { 469 | 470 | // 1. Obtener la instancia de Redis 471 | try { 472 | $redis = RedisSvc::Init(); 473 | } catch (Throwable $e) { // Captura cualquier excepción de conexión de RedisSvc::Init() 474 | throw new Exception("Error al conectar a Redis para GetResults: " . $e->getMessage(), 0, $e); 475 | } 476 | 477 | // 2. Obtener el chunk 478 | $serializedChunk = $redis->get($chunkKey); 479 | 480 | if ($serializedChunk === false) { 481 | // Si un chunk no se encuentra, es un problema. 482 | // Podría ser por expiración prematura, o una inconsistencia. 483 | throw new Exception("Chunk de resultados '$chunkKey' no encontrado o expirado. El conjunto de resultados podría estar incompleto."); 484 | } 485 | 486 | $chunkData = json_decode($serializedChunk, true); 487 | 488 | if (json_last_error() !== JSON_ERROR_NONE) { 489 | throw new Exception("Error al deserializar chunk de resultados '$chunkKey': " . json_last_error_msg()); 490 | } 491 | 492 | return $chunkData; 493 | } 494 | 495 | public static function OrderBy(string $resultsId, string $orderField, $columns) { 496 | 497 | $topeRAM = 2048; 498 | 499 | if (!isset($orderField) || !isset($orderField['column'])) { 500 | return; 501 | } 502 | else { 503 | } 504 | 505 | try { 506 | // Primero obtener el indice 507 | // 508 | $index = self::GetIndex($resultsId); 509 | 510 | // Obtener una llave para calcular el tamaño de cada registro 511 | // 512 | $llaves = $index->Llaves; 513 | $llave = $llaves[0]; 514 | 515 | if (!$index instanceof PageDefinition) { 516 | return; 517 | } 518 | 519 | // Obtener el chunk 520 | // 521 | $chunk = self::GetChunk($llave); 522 | 523 | if (is_array($chunk) && isset($chunk[0])) { 524 | $item = $chunk[0]; 525 | } 526 | else { 527 | return; 528 | } 529 | 530 | // Calcular la cantidad de RAM utilizada por el objeto 531 | // (aproximado) 532 | $serializedItem = serialize($item); 533 | $sizeOfSerializedItem = strlen($serializedItem); 534 | 535 | // Dar un poco de holgura porque el método no es exacto 536 | // y no contempla el overhead de PHP con los objetos 537 | $sizeOfSerializedItemBytes = $sizeOfSerializedItem * 1.1; 538 | 539 | // Calcular para el total de registros 540 | $dataSizeMb = ($sizeOfSerializedItemBytes * $index->RecordCount) / (1024 * 1024); 541 | 542 | // Reservar memoria suficiente para los datos 543 | // 544 | $memFree = MemoryInfo::Instance()->AvailableMBCalculated; 545 | 546 | // Debemos reservar al menos 512MB para el sistema operativo 547 | // 548 | $dif = $memFree - $dataSizeMb; 549 | 550 | if ($dif < 512 || $dataSizeMb > $topeRAM) { 551 | throw new Exception('El ordenamiento no es posible debido a restricciones de tamaño del set de datos'); 552 | } 553 | 554 | // Reservar la RAM 555 | // 556 | if ($dataSizeMb > 100) { 557 | $newSize = $dataSizeMb + 30; 558 | Ini::Instance()->Change(IniEnum::MEMORY_LIMIT, $newSize); 559 | } 560 | 561 | // Primero obtener TODOS los elementos 562 | // 563 | $resultado = self::GetResults($resultsId, -1); 564 | 565 | // Reordenar 566 | // 567 | $elementos = new GenericCollection( 568 | DtoName: $index->DtoName, 569 | Values: $resultado 570 | ); 571 | 572 | //$elementos->OrderBy($column, $orderField[1]); 573 | } 574 | catch (Throwable $ex) { 575 | return; 576 | } 577 | 578 | } 579 | 580 | 581 | /** 582 | * Inserta un arreglo (chunk) en Redis con un TTL. 583 | * 584 | * @param string $chunkId La llave única para este chunk. 585 | * @param array $chunk El arreglo de datos a almacenar. 586 | * @return bool True si la operación fue exitosa, false en caso contrario. 587 | */ 588 | private static function SaveChunk(string $chunkId, array $chunk) 589 | { 590 | // Serializa el arreglo a una cadena JSON antes de guardarlo en Redis 591 | $serializedChunk = json_encode($chunk); 592 | 593 | if ($serializedChunk === false) { 594 | throw new Exception("La información no se ha podido serializar"); 595 | } 596 | 597 | $redis = RedisSvc::Init(); 598 | 599 | // Si tenemos redis, actualizamos el valor de la coleccion 600 | if (isset($redis)) { 601 | 602 | // Inserta la llave con el valor serializado y el TTL 603 | // El método set de phpredis permite pasar un array de opciones 604 | // 'EX' para especificar el TTL en segundos 605 | $success = $redis->set($chunkId, $serializedChunk, ['EX' => self::$CHUNK_TTL]); 606 | 607 | if (!$success) { 608 | throw new Exception("No se ha podido ingresar la información a REDIS"); 609 | } 610 | } 611 | else { 612 | throw new Exception("No se ha podido instanciar REDIS"); 613 | } 614 | } 615 | } -------------------------------------------------------------------------------- Total de líneas: 615 ================================================================================ ================================================================================ ARCHIVO #50: src/Cache/PageDefinition.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Cache/PageDefinition.php Tamaño: 1.49 KB -------------------------------------------------------------------------------- 1 | ResultsId, 36 | DtoName : $index->DtoName, 37 | Key : $index->Key, 38 | OrderColumn : $index->OrderColumn, 39 | OrderDir : $index->OrderDir, 40 | InsertStatus : $index->InsertStatus, 41 | RecordCount : $index->RecordCount, 42 | ChunkSize : $index->ChunkSize, 43 | ChunkLength : $index->ChunkLength, 44 | ChunkTtl : $index->ChunkTtl, 45 | ChunkTtlRefresh : $index->ChunkTtlRefresh, 46 | Llaves : $index->Llaves, 47 | ); 48 | 49 | } 50 | 51 | } -------------------------------------------------------------------------------- Total de líneas: 51 ================================================================================ ================================================================================ ARCHIVO #51: src/Cache/PageResults.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Cache/PageResults.php Tamaño: 475 bytes -------------------------------------------------------------------------------- 1 | connect($redisConfig->Endpoint, $redisConfig->Port); 28 | $redis->setOption(\Redis::OPT_SERIALIZER, \Redis::SERIALIZER_PHP); 29 | 30 | // Probar la conexion 31 | if (self::Test($redis)) 32 | return $redis; 33 | else 34 | return null; 35 | } 36 | 37 | static public function Test($redis) { 38 | return ($redis->ping() == "+PONG"); 39 | } 40 | 41 | public static function FlushAll($includeSessions = false) { 42 | 43 | $redis = RedisSvc::Init(); 44 | 45 | if (isset($redis)) { 46 | 47 | $allKeys = $redis->keys('*'); 48 | 49 | foreach($allKeys as $key) { 50 | $encontrada = strpos($key, 'PHPREDIS_SESSION'); 51 | if ($encontrada === false) { 52 | $redis->unlink($key); 53 | } 54 | } 55 | } 56 | 57 | } 58 | 59 | } -------------------------------------------------------------------------------- Total de líneas: 59 ================================================================================ ================================================================================ ARCHIVO #53: src/Collection/AttachDefinition.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Collection/AttachDefinition.php Tamaño: 537 bytes -------------------------------------------------------------------------------- 1 | $fieldX ?? ''; 37 | $valueY = $item->$fieldY ?? ''; 38 | 39 | $valuesX[$valueX] = true; 40 | $valuesY[$valueY] = true; 41 | 42 | // Mantener la clave con pipe ya que es segura 43 | $key = $valueX . '|' . $valueY; 44 | if (!isset($groupedData[$key])) { 45 | $groupedData[$key] = []; 46 | } 47 | $groupedData[$key][] = $item; 48 | } 49 | 50 | // Paso 2: Pre-procesar nombres de campos Y 51 | $cleanedValuesY = []; 52 | foreach (array_keys($valuesY) as $valueY) { 53 | $cleanedValuesY[$valueY] = self::CleanPropertyName($valueY); 54 | } 55 | 56 | // Paso 3: Construir matriz 57 | $matrix = []; 58 | 59 | foreach (array_keys($valuesX) as $valueX) { 60 | $row = new stdClass(); 61 | $row->$fieldX = $valueX; 62 | $total = 0; 63 | 64 | foreach (array_keys($valuesY) as $valueY) { 65 | $cleanedFieldY = $cleanedValuesY[$valueY]; 66 | $key = $valueX . '|' . $valueY; 67 | 68 | if (isset($groupedData[$key])) { 69 | // Optimización: array_sum con array_map 70 | $result = array_sum(array_map($function, $groupedData[$key])); 71 | $row->$cleanedFieldY = $result; 72 | $total += $result; 73 | } else { 74 | $row->$cleanedFieldY = null; 75 | } 76 | } 77 | 78 | $row->Total_Item = $total; 79 | $matrix[] = $row; 80 | } 81 | 82 | return $matrix; 83 | } 84 | 85 | 86 | public static function GetMatrixOld($data, string $fieldX, string $fieldY, callable $function): array 87 | { 88 | // Paso 1: Obtener todos los valores únicos para X e Y 89 | $valuesX = []; 90 | $valuesY = []; 91 | $groupedData = []; 92 | 93 | // Recorrer la colección para extraer valores únicos y agrupar datos 94 | foreach ($data as $item) { 95 | $valueX = $item->$fieldX ?? ''; 96 | $valueY = $item->$fieldY ?? ''; 97 | 98 | // Almacenar valores únicos para X e Y 99 | if (!in_array($valueX, $valuesX)) { 100 | $valuesX[] = $valueX; 101 | } 102 | if (!in_array($valueY, $valuesY)) { 103 | $valuesY[] = $valueY; 104 | } 105 | 106 | // Agrupar datos por combinación X,Y 107 | $key = $valueX . '|' . $valueY; 108 | if (!isset($groupedData[$key])) { 109 | $groupedData[$key] = []; 110 | } 111 | $groupedData[$key][] = $item; 112 | } 113 | 114 | // Paso 2: Limpiar nombres de campos Y para usarlos como propiedades 115 | $cleanedValuesY = []; 116 | foreach ($valuesY as $valueY) { 117 | $cleanedValuesY[$valueY] = self::CleanPropertyName($valueY); 118 | } 119 | 120 | // Paso 3: Crear la matriz resultado 121 | $matrix = []; 122 | 123 | foreach ($valuesX as $valueX) { 124 | // Crear objeto dinámico para esta fila 125 | $row = new stdClass(); 126 | $row->$fieldX = $valueX; 127 | 128 | $row->Total_Item = 0; 129 | 130 | // Agregar columnas para cada valor Y 131 | $total = 0; 132 | foreach ($valuesY as $valueY) { 133 | $cleanedFieldY = $cleanedValuesY[$valueY]; 134 | $key = $valueX . '|' . $valueY; 135 | 136 | if (isset($groupedData[$key])) { 137 | // Aplicar la función a todos los elementos de esta combinación 138 | $result = 0; 139 | foreach ($groupedData[$key] as $element) { 140 | $result += $function($element); 141 | } 142 | $row->$cleanedFieldY = $result; 143 | $total += $result; 144 | } else { 145 | // No hay datos para esta combinación 146 | $row->$cleanedFieldY = null; 147 | } 148 | } 149 | 150 | $row->Total_Item = $total; 151 | $matrix[] = $row; 152 | } 153 | 154 | return $matrix; 155 | } 156 | 157 | /** 158 | * Limpia el nombre de una propiedad para que sea válido en PHP 159 | * Reemplaza caracteres especiales y espacios 160 | * 161 | * @param string $name Nombre original 162 | * @return string Nombre limpio 163 | */ 164 | private static function CleanPropertyName(string $name): string 165 | { 166 | // Reemplazar caracteres problemáticos 167 | $cleaned = str_replace(['/', '-', ' ', '.', ':', ';', ','], '_', $name); 168 | 169 | // Remover caracteres especiales adicionales 170 | $cleaned = preg_replace('/[^a-zA-Z0-9_]/', '_', $cleaned); 171 | 172 | // Remover múltiples guiones bajos consecutivos 173 | $cleaned = preg_replace('/_+/', '_', $cleaned); 174 | 175 | // Remover guiones bajos al inicio y final 176 | $cleaned = trim($cleaned, '_'); 177 | 178 | // Si queda vacío o empieza con número, agregar prefijo 179 | if (empty($cleaned) || is_numeric($cleaned[0])) { 180 | $cleaned = 'field_' . $cleaned; 181 | } 182 | 183 | return $cleaned; 184 | } 185 | 186 | /** 187 | * Crea una tabla jerárquica donde las filas se agrupan por jerarquía y las columnas por un campo específico 188 | * 189 | * @param GenericCollection $data Colección de objetos que implementa Iterable 190 | * @param string $fieldX Campo para las columnas 191 | * @param callable $function Función que se aplicará a cada elemento para obtener el valor de la celda 192 | * @param string ...$fieldY Campos para la jerarquía de filas (del principal al detalle) 193 | * @return array Tabla jerárquica con totales por columnas 194 | */ 195 | public static function GetTreeTable($data, string $fieldX, callable $function, string ...$fieldY): array 196 | { 197 | if (empty($fieldY)) { 198 | throw new InvalidArgumentException('Se requiere al menos un campo Y para construir la tabla'); 199 | } 200 | 201 | // Obtener todos los valores únicos para las columnas (fieldX) 202 | $columnValues = []; 203 | foreach ($data as $item) { 204 | $colValue = $item->$fieldX ?? ''; 205 | if (!in_array($colValue, $columnValues)) { 206 | $columnValues[] = $colValue; 207 | } 208 | } 209 | 210 | // Limpiar nombres de columnas 211 | $cleanedColumns = []; 212 | foreach ($columnValues as $colValue) { 213 | $cleanedColumns[$colValue] = self::CleanPropertyName($colValue); 214 | } 215 | 216 | // Construir la tabla jerárquica 217 | return self::BuildTreeTableLevel($data, $fieldY, 0, $fieldX, $cleanedColumns, $function, $campoTotal); 218 | } 219 | 220 | /** 221 | * Construye recursivamente un nivel de la tabla jerárquica 222 | */ 223 | private static function BuildTreeTableLevel($data, array $hierarchyFields, int $level, string $columnField, array $cleanedColumns, callable $function): array 224 | { 225 | $currentField = $hierarchyFields[$level]; 226 | 227 | // Agrupar datos por el campo actual 228 | $grouped = []; 229 | foreach ($data as $item) { 230 | $key = $item->$currentField ?? ''; 231 | if (!isset($grouped[$key])) { 232 | $grouped[$key] = []; 233 | } 234 | $grouped[$key][] = $item; 235 | } 236 | 237 | $result = []; 238 | 239 | foreach ($grouped as $key => $items) { 240 | // Crear fila principal para este grupo 241 | $row = self::CreateTreeTableRow($key, $items, $columnField, $cleanedColumns, $level, $function); 242 | $result[] = (object)$row; 243 | 244 | // Si hay más niveles de jerarquía, crear sub-filas 245 | if ($level + 1 < count($hierarchyFields)) { 246 | $subRows = self::BuildTreeTableLevel($items, $hierarchyFields, $level + 1, $columnField, $cleanedColumns, $function); 247 | $result = array_merge($result, $subRows); 248 | } 249 | } 250 | 251 | return $result; 252 | } 253 | 254 | /** 255 | * Crea una fila de la tabla jerárquica con los totales por columna 256 | */ 257 | private static function CreateTreeTableRow(string $item, array $items, string $columnField, array $cleanedColumns, int $level, callable $function): array 258 | { 259 | $row = [ 260 | 'Item' => $item, 261 | 'Total_Item' => 0, 262 | 'Level' => $level 263 | ]; 264 | 265 | // Agrupar items por valor de columna y aplicar la función 266 | $columnGroups = []; 267 | 268 | foreach ($items as $dataItem) { 269 | $colValue = $dataItem->$columnField ?? ''; 270 | if (!isset($columnGroups[$colValue])) { 271 | $columnGroups[$colValue] = 0; 272 | } 273 | // Aplicar la función a cada elemento 274 | $columnGroups[$colValue] += $function($dataItem); 275 | } 276 | 277 | // Crear propiedades para cada columna 278 | $total = 0; 279 | foreach ($cleanedColumns as $originalValue => $cleanedName) { 280 | if (isset($columnGroups[$originalValue])) { 281 | $row[$cleanedName] = $columnGroups[$originalValue]; 282 | } else { 283 | $row[$cleanedName] = 0; 284 | } 285 | 286 | $total += $row[$cleanedName]; 287 | } 288 | 289 | $row['Total_Item'] = $total; 290 | 291 | return $row; 292 | } 293 | 294 | 295 | /** 296 | * Agrupa elementos iguales y cuenta las repeticiones 297 | * 298 | * @param GenericCollection $data Colección de objetos que implementa Iterable 299 | * @param string $countField Nombre del campo donde se almacenará el conteo 300 | * @param array $ignoredFields Campos que se ignoran para la comparación de igualdad 301 | * @return array Arreglo de objetos sin duplicados con el conteo en $countField 302 | */ 303 | public static function GroupAndCount($data, string $countField, array $ignoredFields = []): array 304 | { 305 | $groups = []; 306 | 307 | foreach ($data as $item) { 308 | // Crear una clave única basada en los campos relevantes 309 | $key = self::CreateGroupKey($item, $ignoredFields); 310 | 311 | if (!isset($groups[$key])) { 312 | // Primer elemento de este grupo - clonar el objeto 313 | $groups[$key] = [ 314 | 'item' => clone $item, 315 | 'count' => 1 316 | ]; 317 | } else { 318 | // Incrementar el contador para este grupo 319 | $groups[$key]['count']++; 320 | } 321 | } 322 | 323 | // Preparar el resultado final 324 | $result = []; 325 | foreach ($groups as $group) { 326 | $resultItem = $group['item']; 327 | // Agregar la propiedad de conteo 328 | $resultItem->$countField = $group['count']; 329 | $result[] = $resultItem; 330 | } 331 | 332 | return $result; 333 | } 334 | 335 | /** 336 | * Crea una clave única para agrupar elementos basada en sus propiedades 337 | * excluyendo los campos ignorados 338 | * 339 | * @param object $item Elemento a procesar 340 | * @param array $ignoredFields Campos a ignorar en la comparación 341 | * @return string Clave única para el grupo 342 | */ 343 | private static function CreateGroupKey($item, array $ignoredFields): string 344 | { 345 | $keyParts = []; 346 | 347 | // Obtener todas las propiedades públicas del objeto 348 | $properties = get_object_vars($item); 349 | 350 | // Ordenar las propiedades para consistencia 351 | ksort($properties); 352 | 353 | foreach ($properties as $property => $value) { 354 | // Saltar campos ignorados 355 | if (in_array($property, $ignoredFields)) { 356 | continue; 357 | } 358 | 359 | // Convertir el valor a string para la clave 360 | $stringValue = ''; 361 | if ($value === null) { 362 | $stringValue = 'NULL'; 363 | } elseif (is_bool($value)) { 364 | $stringValue = $value ? 'TRUE' : 'FALSE'; 365 | } elseif (is_object($value)) { 366 | $stringValue = 'OBJECT_' . get_class($value); 367 | } elseif (is_array($value)) { 368 | $stringValue = 'ARRAY_' . json_encode($value); 369 | } else { 370 | $stringValue = (string) $value; 371 | } 372 | 373 | $keyParts[] = $property . ':' . $stringValue; 374 | } 375 | 376 | return md5(implode('|', $keyParts)); 377 | } 378 | } 379 | 380 | // Ejemplo de uso: 381 | /* 382 | $result = Collections::GetMatrix( 383 | $data, 384 | 'Proveedor', 385 | 'FechaPicking', 386 | function($element) { 387 | if ($element->IdEstado == 1) return 1; 388 | else return 0; 389 | } 390 | ); 391 | 392 | // El resultado sería un arreglo de objetos como: 393 | // [ 394 | // { 395 | // "Proveedor": "Claudio", 396 | // "_10_09_2025": 1, 397 | // "_11_09_2025": 1, 398 | // "_13_09_2025": null 399 | // }, 400 | // { 401 | // "Proveedor": "Juan", 402 | // "_10_09_2025": null, 403 | // "_11_09_2025": null, 404 | // "_13_09_2025": 1 405 | // } 406 | // ] 407 | 408 | // Para acceder a los datos: 409 | foreach ($result as $row) { 410 | echo "Proveedor: " . $row->Proveedor . "\n"; 411 | foreach (get_object_vars($row) as $prop => $value) { 412 | if ($prop !== 'Proveedor' && $value !== null) { 413 | echo " $prop: $value\n"; 414 | } 415 | } 416 | } 417 | */ 418 | 419 | // Ejemplo de uso de GetTreeTable: 420 | /* 421 | $treeTableResult = Collections::GetTreeTable( 422 | $data, 423 | 'FechaPicking', // Campo X (columnas) 424 | function($element) { 425 | if ($element->IdEstado == 1) return 1; 426 | else return 0; 427 | }, // Función para evaluar cada elemento 428 | 'Proveedor', // Campo Y_1 (filas principales) 429 | 'Categoria' // Campo Y_2 (sub-filas) 430 | ); 431 | 432 | // El resultado sería un arreglo como: 433 | // [ 434 | // [ 435 | // "Item" => "Claudio", 436 | // "Level" => 0, 437 | // "field_2025_09_10" => 3, 438 | // "field_2025_09_11" => 2, 439 | // "field_2025_09_13" => 0 440 | // ], 441 | // [ 442 | // "Item" => "Categoria1", 443 | // "Level" => 1, 444 | // "field_2025_09_10" => 2, 445 | // "field_2025_09_11" => 2, 446 | // "field_2025_09_13" => 0 447 | // ], 448 | // [ 449 | // "Item" => "Categoria2", 450 | // "Level" => 1, 451 | // "field_2025_09_10" => 1, 452 | // "field_2025_09_11" => 0, 453 | // "field_2025_09_13" => 0 454 | // ], 455 | // [ 456 | // "Item" => "Juan", 457 | // "Level" => 0, 458 | // "field_2025_09_10" => 4, 459 | // "field_2025_09_11" => 0, 460 | // "field_2025_09_13" => 1 461 | // ], 462 | // [ 463 | // "Item" => "Categoria1", 464 | // "Level" => 1, 465 | // "field_2025_09_10" => 0, 466 | // "field_2025_09_11" => 0, 467 | // "field_2025_09_13" => 1 468 | // ], 469 | // [ 470 | // "Item" => "Categoria2", 471 | // "Level" => 1, 472 | // "field_2025_09_10" => 4, 473 | // "field_2025_09_11" => 0, 474 | // "field_2025_09_13" => 0 475 | // ] 476 | // ] 477 | */ -------------------------------------------------------------------------------- Total de líneas: 477 ================================================================================ ================================================================================ ARCHIVO #56: src/Collection/Condition.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Collection/Condition.php Tamaño: 698 bytes -------------------------------------------------------------------------------- 1 | Entity; 40 | if (!isset($dtoName) || $dtoName == "") { 41 | throw new \Exception("La definición de entidad debe especificar el tipo de objeto contenido en -Entity-"); 42 | } 43 | 44 | // Verificar que la definicion de entidad tenga definida la llave "Key" 45 | $key = $entityDefinition->KeyName; 46 | if (!isset($key) || $key == "") { 47 | throw new \Exception("La definicion de entidad debe especificar la llave principal en -KeyName-"); 48 | } 49 | 50 | $this->ConditionsSentence = $conditions; 51 | $this->EntityDefinition = $entityDefinition; 52 | 53 | $this->Conditions = $this->PrepareConditions($conditions, $entityDefinition); 54 | } 55 | 56 | private function PrepareConditions($conditionsSentence, $entityDefinition) { 57 | 58 | // Analizar las condiciones y establecer parametros para la búsqueda en los índices 59 | 60 | // Separadores admitidos son: 61 | // && 62 | // || 63 | // 64 | // El separador && genera 2 condiciones 65 | // El separador || genera 2 subcondiciones dentro de 1 condicion 66 | 67 | // Separar las condiciones 68 | // ************************************************ 69 | 70 | // Separador inicial && 71 | $condicionesInicio = explode('&&', $conditionsSentence); 72 | 73 | $condicionesAnd = array(); 74 | // Separador secundario || 75 | foreach($condicionesInicio as $condicionInicio) { 76 | $condicionesOr = explode("||", $condicionInicio); 77 | 78 | foreach($condicionesOr as $or) { 79 | $cond = $this->BuildCondition($or, $entityDefinition); 80 | if (isset($cond)) { 81 | array_push($condicionesAnd, $cond); 82 | } 83 | } 84 | } 85 | 86 | return $condicionesAnd; 87 | } 88 | 89 | private function BuildCondition($condition, $entityDefinition) { 90 | 91 | // Construye una condición unitaria 92 | // ************************************** 93 | 94 | // Obtener el operador 95 | // *********************** 96 | // Operadores admitidos son: 97 | // == 98 | // > 99 | // >= 100 | // < 101 | // <= 102 | // != 103 | $operadoresPosibles = ["==", ">", ">=", "<", "<=", "!="]; 104 | $operador = ""; 105 | 106 | foreach($operadoresPosibles as $op) { 107 | if (strpos($condition, $op)) { 108 | $operador = $op; 109 | break; 110 | } 111 | } 112 | 113 | // si no se encontró el operador, generar excepcion 114 | if ($operador == "") 115 | throw new \Exception("No se encontró del operador"); 116 | 117 | // Procesar los operandos 118 | $parts = explode($operador, $condition); 119 | 120 | if (!isset($parts) || count($parts) != 2) { 121 | throw new \Exception("Condicion con error de sintaxis"); 122 | } 123 | 124 | // Revisar el tipo de dato 125 | $fieldName = trim($parts[0]); 126 | $value = trim($parts[1]); 127 | 128 | if ($fieldName == "" || $value == "") { 129 | throw new \Exception("Condicion con error de sintaxis"); 130 | } 131 | 132 | if (isset($entityDefinition)) { 133 | // Buscar el tipo de dato de la propiedad actual 134 | if (isset($entityDefinition->Properties[$fieldName])) { 135 | $plop = $entityDefinition->Properties[$fieldName]; 136 | } 137 | } 138 | 139 | // Construir la condicion 140 | $condicion = new Condition([ 141 | "FieldName" => $fieldName, 142 | "Operator" => $operador, 143 | "Value" => $value, 144 | "FieldType" => "unknown" 145 | ]); 146 | 147 | return $condicion; 148 | } 149 | } -------------------------------------------------------------------------------- Total de líneas: 149 ================================================================================ ================================================================================ ARCHIVO #58: src/Collection/GenericCollection.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Collection/GenericCollection.php Tamaño: 41.63 KB -------------------------------------------------------------------------------- 1 | 86 | */ 87 | 88 | #[AllowDynamicProperties] 89 | class GenericCollection implements IteratorAggregate, JsonSerializable { 90 | 91 | public $Type = "Collection"; 92 | public $DtoDefinition = null; 93 | public $Cache; 94 | protected $EntityDefinition; 95 | 96 | /** 97 | * @param array $definition 98 | * 99 | * Arreglo asociativo con los elementos necesarios para crear la coleccion 100 | * 101 | * Ej: 102 | * 103 | * ["Key" => "Id", "DtoName" => "myClass", "Values" => $miArreglo ] 104 | * 105 | */ 106 | function __construct( 107 | protected $DtoName = '', 108 | protected $Key = '', 109 | public $Values = [], 110 | protected $Indexes = [], 111 | protected $ClassName = '', 112 | public $ReflectDto = false 113 | ) 114 | { 115 | $this->Cache = new Cache(); 116 | 117 | if (!isset($this->Values)) { 118 | $this->Values = []; 119 | } 120 | 121 | if ($this->DtoName == '' && $this->Key != '') { 122 | throw new \Exception("Debe especificar el DTO para usar una GenericCollection con designacion de KEY"); 123 | } 124 | 125 | if (isset($this->Indexes) && count($this->Indexes) > 0 && $this->Key == '') { 126 | throw new \Exception("Debe especificar una llave -Key- cuando desea especificar índices secundarios"); 127 | } 128 | 129 | if ($this->DtoName != '' && $this->ClassName == '') { 130 | $this->ClassName = $this->GetClassName($this->DtoName); 131 | } 132 | 133 | $dtStartIndexMonitor = microtime(true); 134 | if ($this->Key != '' && isset($this->Values)) { 135 | $this->CreatePrimaryIndex($this->Key); 136 | } 137 | 138 | if (isset($this->Indexes) && count($this->Indexes) > 0) { 139 | $this->CreateSecondaryIndexes($this->Indexes); 140 | } 141 | $dtEndIndexMonitor = microtime(true); 142 | 143 | // Obtener las propiedades reflectadas de la coleccion 144 | if ($this->DtoName != '' && $this->ReflectDto) { 145 | $this->EntityDefinition = EntityDefinition::Instance($this->DtoName); 146 | } 147 | 148 | Monitor::$KeyIndexExecutions++; 149 | Monitor::$KeyIndexExecutionTime += ($dtEndIndexMonitor - $dtStartIndexMonitor); 150 | } 151 | 152 | public function __clone() { 153 | // Obtenemos una copia de los valores 154 | $clonedValues = array(); 155 | 156 | foreach($this->Values as $val) { 157 | 158 | $clonedItem = new $this->DtoName(); 159 | // recorrer los valores 160 | foreach($val as $propname => $propvalue) { 161 | $clonedItem->$propname = $propvalue; 162 | } 163 | array_push($clonedValues, $clonedItem); 164 | } 165 | 166 | $this->Key = $this->Key; 167 | $this->DtoName = $this->DtoName; 168 | $this->Values = $clonedValues; 169 | } 170 | 171 | public function jsonSerialize(): mixed { 172 | 173 | return $this->Values; 174 | 175 | } 176 | 177 | public function getIterator() : Traversable { 178 | return new ArrayIterator($this->Values); 179 | } 180 | 181 | public function CreateIndex(array $values, $key, $secondaryKey = "") { 182 | 183 | $outputArray = array(); 184 | 185 | foreach($values as $idx => $value) { 186 | 187 | // Convertir el valor de la llave en un número para acelerar las búsquedas, de ser posible 188 | if (is_numeric($value->$key)) { 189 | $valKey = $value->$key * 1; 190 | } 191 | else { 192 | $valKey = $value->$key; 193 | } 194 | 195 | if ($secondaryKey == "") { 196 | // Si es sólo la llave principal, indexamos en el indice principal 197 | // el indice del arreglo asociado a dicha llave 198 | $outputArray[$valKey] = $idx; 199 | } 200 | else { 201 | // Si es un índice secundario, sólo indexamos el valor 202 | // de la llave principal como un subarreglo dentro 203 | // del índice asociado a la llave secundaria 204 | // 205 | // arr['idsecundario'] = [ 'key1', 'key2', 'key3', ... , 'keyN'] 206 | // 207 | // Convertir el valor de la llave secundaria en un número para acelerar las búsquedas 208 | 209 | // obtener el valor multinivel en caso de existir 210 | $valueMultilevel = Mapper::EvaluateKeyMultilevel($value, $secondaryKey); // $this->GetMultiLevelKeyValue($value, $secondaryKey); 211 | 212 | if (is_numeric($valueMultilevel)) { 213 | $secKey = $valueMultilevel * 1; 214 | } 215 | else { 216 | $secKey = $valueMultilevel; 217 | } 218 | 219 | if ( !isset( $outputArray[$secKey] ) ) { 220 | $outputArray[$secKey] = array(); 221 | } 222 | 223 | // Agregar la llave principal como subitem (sólo si no existe) 224 | if (!isset( $outputArray[ $secKey ] [ $valKey ] )) { 225 | // asociamos el IDX del arreglo original en el indice secundario 226 | $outputArray[$secKey][$valKey] = $idx; 227 | } 228 | } 229 | } 230 | 231 | // Para acelerar las búsquedas, debemos ordenar el arreglo por su llave 232 | ksort($outputArray); 233 | 234 | return $outputArray; 235 | } 236 | 237 | private function CreatePrimaryIndex(string $key) { 238 | $this->GetLocalCache()->PrimaryIndex = $this->CreateIndex($this->Values, $key); 239 | } 240 | 241 | private function CreateSecondaryIndexes(array $indices) { 242 | 243 | foreach($indices as $indice) { 244 | // Generar un índice secundario 245 | if (!isset($this->GetLocalCache()->SecondaryIndexes[$indice])) { 246 | $this->GetLocalCache()->SecondaryIndexes[$indice] = $this->CreateIndex($this->Values, $this->Key, $indice); 247 | } 248 | } 249 | 250 | } 251 | 252 | public function Reindex() { 253 | // Regenerar el indice principal 254 | if ($this->Key != "") 255 | $this->GetLocalCache()->PrimaryIndex = $this->CreateIndex($this->Values, $this->Key); 256 | 257 | // Regenerar los indices secundarios 258 | foreach($this->GetLocalCache()->SecondaryIndexes as $key => $indice) { 259 | $this->GetLocalCache()->SecondaryIndexes[$key] = $this->CreateIndex($this->Values, $this->Key, $key); 260 | } 261 | } 262 | 263 | /** 264 | * Ordena la colección según las propiedades del objeto 265 | * 266 | * @param string $fields 267 | * Especifica las propiedades y el orden en el que se realizará el ordenamiento. 268 | * Admite el uso de ASC y DESC. 269 | * 270 | * Si no es especifica, el valor por defecto del orden de cada campo será ASC. 271 | * 272 | * Ej: 273 | * 274 | * $mycollection->OrderBy("FechaRegistro DESC, IdComuna"); 275 | * 276 | * @author Claudio Gonzalez 277 | * @return void 278 | */ 279 | public function OrderBy($fields) { 280 | 281 | $orders = explode(",", trim($fields)); 282 | 283 | $arrOrders = array(); 284 | foreach($orders as $order) { 285 | $parts = explode(' ', trim($order)); 286 | $order = new \StdClass(); 287 | $order->Fieldname = $parts[0]; 288 | 289 | if (count($parts) == 1 || ( count($parts) == 2 && strtolower(trim($parts[1])) != "desc" )) { 290 | $order->Direction = "ASC"; 291 | } 292 | else if ( count($parts) == 2 && strtolower(trim($parts[1])) == "desc" ) { 293 | $order->Direction = "DESC"; 294 | } 295 | 296 | $arrOrders[$parts[0]] = $order; 297 | } 298 | 299 | // Ordenar el arreglo 300 | usort($this->Values, function($a, $b) use($arrOrders) { 301 | 302 | // Comparar los valores en el orden para ir viendo el orden 303 | foreach($arrOrders as $order) { 304 | $fieldName = $order->Fieldname; 305 | $campoSource = $a->$fieldName; 306 | $campoCompare = $b->$fieldName; 307 | $direction = $order->Direction; 308 | 309 | if ($direction == "ASC") { 310 | // Si a es mayor, va primero 311 | if ($campoSource != $campoCompare) { 312 | return ($campoSource > $campoCompare) ? 1 : -1; 313 | } 314 | } 315 | else { 316 | // Si a es menor, va primero 317 | return ($campoSource < $campoCompare) ? 1 : -1; 318 | } 319 | } 320 | 321 | // No se encontraron diferencias 322 | return 0; 323 | }); 324 | 325 | // Reindexar 326 | $this->Reindex(); 327 | } 328 | 329 | public function Top(int $rows) : GenericCollection { 330 | 331 | if ($rows > 350) { 332 | $rows = 350; 333 | } 334 | 335 | $result = array_slice($this->Values, 0, $rows); 336 | 337 | return new GenericCollection( 338 | DtoName: $this->DtoName, 339 | Key: $this->Key, 340 | Values: $result 341 | ); 342 | } 343 | 344 | public function Tail(int $rows) : GenericCollection { 345 | 346 | if ($rows > 350) { 347 | $rows = 350; 348 | } 349 | 350 | $count = count($this->Values); 351 | $offset = max(0, $count - $rows); 352 | 353 | $result = array_slice($this->Values, $offset, $rows); 354 | 355 | return new GenericCollection( 356 | DtoName: $this->DtoName, 357 | Key: $this->Key, 358 | Values: $result 359 | ); 360 | } 361 | 362 | /** 363 | * Crea una copia de la colección, ordenada según las propiedades del objeto 364 | * 365 | * @param string $fields 366 | * Especifica las propiedades y el orden en el que se realizará el ordenamiento. 367 | * Admite el uso de ASC y DESC. 368 | * 369 | * Si no es especifica, el valor por defecto del orden de cada campo será ASC. 370 | * 371 | * Ej: 372 | * 373 | * $newCollection = $mycollection->OrderedBy("FechaRegistro DESC, IdComuna"); 374 | * 375 | * 376 | * @author Claudio Gonzalez 377 | * @return GenericCollection 378 | */ 379 | public function OrderedBy($fields) { 380 | 381 | // Revisar caché 382 | if ($fields != $this->GetLocalCache()->LastOrderedByCondition) { 383 | 384 | // Actualizar caché 385 | $this->GetLocalCache()->LastOrderedByCondition = $fields; 386 | 387 | $clone = null; 388 | 389 | $orders = explode(",", trim($fields)); 390 | 391 | $arrOrders = array(); 392 | foreach($orders as $order) { 393 | $parts = explode(' ', trim($order)); 394 | $order = new \StdClass(); 395 | $order->Fieldname = $parts[0]; 396 | 397 | if (count($parts) == 1 || ( count($parts) == 2 && strtolower(trim($parts[1])) != "desc" )) { 398 | $order->Direction = "ASC"; 399 | } 400 | else if ( count($parts) == 2 && strtolower(trim($parts[1])) == "desc" ) { 401 | $order->Direction = "DESC"; 402 | } 403 | 404 | $arrOrders[$parts[0]] = $order; 405 | } 406 | 407 | // Clonamos los valores de la colección para no afectar los valores originales, los cuales 408 | // mantienen su orden inicial. 409 | $clone = clone $this; 410 | 411 | // Ordenar el arreglo 412 | usort($clone->Values, function($a, $b) use($arrOrders) { 413 | 414 | // Comparar los valores en el orden para ir viendo el orden 415 | foreach($arrOrders as $order) { 416 | $fieldName = $order->Fieldname; 417 | $campoSource = $a->$fieldName; 418 | $campoCompare = $b->$fieldName; 419 | $direction = $order->Direction; 420 | 421 | if ($direction == "ASC") { 422 | // Si a es mayor, va primero 423 | if ($campoSource != $campoCompare) { 424 | return ($campoSource > $campoCompare) ? 1 : -1; 425 | } 426 | } 427 | else { 428 | // Si a es menor, va primero 429 | return ($campoSource < $campoCompare) ? 1 : -1; 430 | } 431 | } 432 | 433 | // No se encontraron diferencias 434 | return 0; 435 | }); 436 | 437 | // Actualizar caché 438 | $this->GetLocalCache()->LastOrderedBy = $clone; 439 | } 440 | 441 | return $this->GetLocalCache()->LastOrderedBy; 442 | } 443 | 444 | /** 445 | * Encuentra el primer elemento de la colección según el orden actual 446 | * 447 | * 448 | * @author Claudio Gonzalez 449 | * @return object 450 | */ 451 | public function First() { 452 | 453 | if (count($this->Values) <= 0) { 454 | return null; 455 | } 456 | else { 457 | return reset($this->Values); 458 | } 459 | 460 | } 461 | 462 | public function Last() { 463 | 464 | if (count($this->Values) <= 0) { 465 | return null; 466 | } 467 | else { 468 | return end($this->Values); 469 | } 470 | 471 | } 472 | 473 | public function Count() { 474 | 475 | if ($this->GetLocalCache()->LastCount < 0) { 476 | // Actualizar caché 477 | $this->GetLocalCache()->LastCount = count($this->Values); 478 | } 479 | 480 | return $this->GetLocalCache()->LastCount; 481 | } 482 | 483 | private function RemoveItem($item) { 484 | $pos = -1; 485 | 486 | for ($i = 0; $i < count($this->Values); $i++) { 487 | if ($this->Values[$i] == $item) { 488 | $pos = $i; 489 | break; 490 | } 491 | } 492 | 493 | if ($pos >= 0) { 494 | \array_splice($this->Values, $pos, 1); 495 | } 496 | } 497 | 498 | public function Remove($item, $reIndex = true) { 499 | 500 | $this->RemoveItem($item); 501 | 502 | // Invalidar la caché 503 | $this->InvalidarCache(); 504 | 505 | // Reindexar 506 | if ($reIndex) 507 | $this->Reindex(); 508 | } 509 | 510 | public function RemoveWhere($condicion, $reIndex = true) { 511 | 512 | $condicion = $this->SingleEqualSignReplace($condicion); 513 | 514 | // Buscar variables dentro de la condicion 515 | $pivote = get_class_vars($this->DtoName); // new $this->DtoName(); 516 | 517 | foreach($pivote as $propname => $propvalue) { 518 | $condicion = $this->TokenReplace($propname, "\$value->" . $propname, $condicion); 519 | } 520 | 521 | // Clonamos el arreglo 522 | $clone = clone $this; 523 | $deletedValues = array(); 524 | 525 | $idx= 0; 526 | foreach($clone->Values as $value) { 527 | $resultado = eval('return (' . $condicion . ');'); 528 | 529 | if ($resultado) { 530 | $deletedValues[$idx] = $value; 531 | $idx++; 532 | } 533 | } 534 | 535 | // Borrar los elementos encontrados 536 | foreach($deletedValues as $delete) { 537 | $this->RemoveItem($delete); 538 | } 539 | 540 | $this->InvalidarCache(); 541 | // Reindexar 542 | if ($reIndex) 543 | $this->Reindex(); 544 | } 545 | 546 | private function AddItem($item, $first = false) { 547 | 548 | if ($first) { 549 | array_unshift($this->Values, $item); 550 | } 551 | else { 552 | array_push($this->Values, $item); 553 | } 554 | } 555 | 556 | public function Add($item, $reIndex = true, $first = false) { 557 | 558 | $this->AddItem($item, $first); 559 | $this->InvalidarCache(); 560 | 561 | // Reindexar 562 | if ($reIndex) 563 | $this->Reindex(); 564 | 565 | return $this; 566 | } 567 | 568 | public function AddRange($items, $reIndex = true) { 569 | 570 | foreach($items as $item) { 571 | $this->AddItem($item); 572 | } 573 | 574 | $this->InvalidarCache(); 575 | // Reindexar 576 | if ($reIndex) 577 | $this->Reindex(); 578 | 579 | return $this; 580 | } 581 | 582 | private function InvalidarCache() { 583 | $this->GetLocalCache()->LastOrderedBy = array(); 584 | $this->GetLocalCache()->LastOrderedByCondition = ""; 585 | $this->GetLocalCache()->LastWhere = array(); 586 | $this->GetLocalCache()->LastWhereCondition = ""; 587 | $this->GetLocalCache()->LastFirstWhere = null; 588 | $this->GetLocalCache()->LastFirstWhereCondition = ""; 589 | $this->GetLocalCache()->LastAvg = 0; 590 | $this->GetLocalCache()->LastAvgField = ""; 591 | $this->GetLocalCache()->LastSum = 0; 592 | $this->GetLocalCache()->LastSumField = ""; 593 | $this->GetLocalCache()->LastMax = 0; 594 | $this->GetLocalCache()->LastMaxField = ""; 595 | $this->GetLocalCache()->LastMin = 0; 596 | $this->GetLocalCache()->LastMinField = ""; 597 | $this->GetLocalCache()->LastItemMax = null; 598 | $this->GetLocalCache()->LastItemMaxField = ""; 599 | $this->GetLocalCache()->LastMinItem = null; 600 | $this->GetLocalCache()->LastMinItemField = ""; 601 | $this->GetLocalCache()->LastCount = -1; 602 | $this->GetLocalCache()->LastDistinctField = ""; 603 | $this->GetLocalCache()->LastDistinct = null; 604 | $this->GetLocalCache()->LastDistinctItemField = ""; 605 | $this->GetLocalCache()->LastDistinctItem = null; 606 | } 607 | 608 | public function Clear() { 609 | $this->Values = array(); 610 | 611 | // Eliminar caché 612 | $this->InvalidarCache(); 613 | 614 | // Reindexar 615 | $this->Reindex(); 616 | } 617 | 618 | public function Where($condicion) { 619 | 620 | $condicion = $this->SingleEqualSignReplace($condicion); 621 | 622 | if ($this->GetLocalCache()->LastWhereCondition != $condicion) { 623 | 624 | $condicion = $this->SingleEqualSignReplace($condicion); 625 | 626 | // Actualizar caché 627 | $this->GetLocalCache()->LastWhereCondition = $condicion; 628 | 629 | // Buscar variables dentro de la condicion 630 | $pivote = get_class_vars($this->DtoName); // new $this->DtoName(); 631 | 632 | foreach($pivote as $propname => $propvalue) { 633 | $condicion = $this->TokenReplace($propname, "\$value->" . $propname, $condicion); 634 | } 635 | 636 | $newValues = array(); 637 | 638 | $idx= 0; 639 | // Los valores no se clonan, para que hereden cualquier modificacion 640 | // que se realice posterior a la llamada 641 | foreach($this->Values as $value) { 642 | $resultado = eval('return (' . $condicion . ');'); 643 | 644 | if ($resultado) { 645 | $newValues[$idx] = $value; 646 | $idx++; 647 | } 648 | } 649 | 650 | // Actualizar caché 651 | $this->GetLocalCache()->LastWhere = new GenericCollection( 652 | Key: $this->Key, 653 | DtoName: $this->DtoName, 654 | Values: $newValues 655 | ); 656 | } 657 | 658 | return $this->GetLocalCache()->LastWhere; 659 | } 660 | 661 | private function GetLocalCache() { 662 | 663 | if (!isset($this->Cache)) { 664 | $this->Cache = new Cache(); 665 | } 666 | 667 | return $this->Cache; 668 | } 669 | 670 | public function FirstWhere($condicion) { 671 | 672 | $condicion = $this->SingleEqualSignReplace($condicion); 673 | 674 | $dtStartMonitor = microtime(true); 675 | 676 | if ($this->GetLocalCache()->LastFirstWhereCondition != $condicion) { 677 | 678 | $found = null; 679 | 680 | // Actualizar caché 681 | $this->GetLocalCache()->LastFirstWhereCondition = $condicion; 682 | 683 | // Buscar variables dentro de la condicion 684 | $pivote = get_class_vars($this->DtoName); // new $this->DtoName(); 685 | 686 | foreach($pivote as $propname => $propvalue) { 687 | $condicion = $this->TokenReplace($propname, "\$value->" . $propname, $condicion); 688 | } 689 | 690 | // Evitar la asignacion 691 | $condicion = str_replace(" = ", " == ", $condicion); 692 | 693 | $idx = 0; 694 | // precalcular para que no se calcule con cada ciclo for(;;) 695 | $cant = count($this->Values); 696 | 697 | // Recorremos en el orden del arreglo actual (no utilizaremos foreach) 698 | for($i = 0; $i < $cant; $i++) { 699 | $value = $this->Values[$i]; 700 | $resultado = eval('return (' . $condicion . ');'); 701 | 702 | if ($resultado) { 703 | // retornamos el primer resultado que encontremos 704 | $found = $value; 705 | break; 706 | } 707 | } 708 | 709 | // Actualizar caché (podría ser null inclusive) 710 | $this->GetLocalCache()->LastFirstWhere = $found; 711 | } 712 | 713 | $dtEndMonitor = microtime(true); 714 | 715 | Monitor::$FromTimeExecutions++; 716 | Monitor::$FromTimeExecutionTime += ($dtEndMonitor - $dtStartMonitor); 717 | 718 | return $this->GetLocalCache()->LastFirstWhere; 719 | } 720 | 721 | public function Find($primaryIndexKey) { 722 | 723 | // Para acelerar el proceso, debemos indexar por la llave primaria!!, si es que existe 724 | if (!isset($this->GetLocalCache()->PrimaryIndex) && $this->Key != "") { 725 | $this->CreatePrimaryIndex($this->Key); 726 | } 727 | 728 | if (isset($this->GetLocalCache()->PrimaryIndex[$primaryIndexKey])) { 729 | $indexKey = $this->GetLocalCache()->PrimaryIndex[$primaryIndexKey]; 730 | return (isset($this->Values[$indexKey])) ? $this->Values[$indexKey] : null; 731 | } 732 | else { 733 | return null; 734 | } 735 | 736 | } 737 | 738 | public function Exists($primaryIndexKey) { 739 | // Para acelerar el proceso, debemos indexar por la llave primaria!!, si es que existe 740 | if (!isset($this->GetLocalCache()->PrimaryIndex) && $this->Key != "") { 741 | $this->CreatePrimaryIndex($this->Key); 742 | } 743 | 744 | return (isset($this->GetLocalCache()->PrimaryIndex[$primaryIndexKey])); 745 | } 746 | 747 | public function Attach(AttachDefinition $attachDefinition) { 748 | 749 | // Los valores deben ser una Coleccion basada en GenericCollection 750 | // el valor de $attachDefinition->Values, debe ser un objeto GenericCollection o una clase derivada 751 | if (!isset($attachDefinition->Values) || !($attachDefinition->Values instanceof GenericCollection)) 752 | throw new \Exception("Debe especificar una coleccion basada en GenericCollection para atachar"); 753 | 754 | if ($attachDefinition->AttachPrimaryKey != "") { 755 | $attachPrimaryKey = $attachDefinition->AttachPrimaryKey; 756 | } 757 | else if ($attachDefinition->Values->Key != "") { 758 | $attachPrimaryKey = $attachDefinition->Values->Key; 759 | } 760 | else if ( isset($attachDefinition->Values) && isset($attachDefinition->Values->EntityDefinition) && $attachDefinition->Values->EntityDefinition->KeyName != "") { 761 | $attachPrimaryKey = $attachDefinition->Values->EntityDefinition->KeyName; 762 | } 763 | 764 | // Foreign Key representa el campo del registro actual (al cual le atacharemos su PARENT row) que hace referencia a la primary key del PARENT 765 | $foreignKey = $attachDefinition->ForeignKey == "" ? $attachPrimaryKey : $attachDefinition->ForeignKey; 766 | 767 | $attachPropertyName = $attachDefinition->AttachPropertyName == "" ? $attachDefinition->Values->ClassName : $attachDefinition->AttachPropertyName; 768 | $values = $attachDefinition->Values; 769 | 770 | if ( $values->Count() <= 0) 771 | return; 772 | 773 | // Para acelerar las asignaciones, debemos crear un índice con la definición 774 | // de la entidad ATTACH 775 | if (!isset($this->GetLocalCache()->SecondaryIndexes[$foreignKey]) && $this->Key != "") { 776 | $this->CreateSecondaryIndexes([ 777 | $foreignKey 778 | ]); 779 | } 780 | 781 | // Comenzar el bucle de busqueda por cada referencia 782 | foreach($values as $attach) { 783 | 784 | // Tenemos que incorporar los $values como una nueva propiedad en cada elemento cuyas llaves coincidan 785 | 786 | // Revisar si existe un índice secundario con este campo 787 | if (isset($this->GetLocalCache()->PrimaryIndex) && isset($this->GetLocalCache()->SecondaryIndexes) && count($this->GetLocalCache()->SecondaryIndexes) > 0 && isset($this->GetLocalCache()->SecondaryIndexes[$foreignKey])) { 788 | // Buscamos el elemento directo en el índice 789 | $idxSecondary = null; 790 | 791 | if (isset($this->GetLocalCache()->SecondaryIndexes[$foreignKey]) && isset($this->GetLocalCache()->SecondaryIndexes[$foreignKey] [$attach->$attachPrimaryKey])) 792 | $idxSecondary = $this->GetLocalCache()->SecondaryIndexes[$foreignKey] [$attach->$attachPrimaryKey]; 793 | 794 | if (isset($idxSecondary)) { 795 | foreach($idxSecondary as $secondary) { 796 | $found = $this->Values[$secondary]; 797 | $found->$attachPropertyName = $attach; 798 | } 799 | } 800 | } 801 | else { 802 | $condicion = $foreignKey . " == " . $attach->$attachPrimaryKey; 803 | 804 | if (isset($condicion)) { 805 | // Buscar el elemento que aplique a esta condicion de referencia 806 | $found = $this->Where($condicion); 807 | 808 | if (isset($found)) { 809 | foreach($found as $item) { 810 | $item->$attachPropertyName = $attach; 811 | } 812 | } 813 | } 814 | } 815 | } 816 | } 817 | 818 | public function MergeChildren(MergeDefinition $mergeDefinition) { 819 | 820 | $dtStartMonitor = microtime(true); 821 | 822 | // Para acelerar el proceso, debemos indexar por la llave primaria!!, si es que existe 823 | if (!isset($this->GetLocalCache()->PrimaryIndex) && $this->Key != "") { 824 | $this->CreatePrimaryIndex($this->Key); 825 | } 826 | 827 | // Los valores deben ser una Coleccion basada en GenericCollection 828 | if (!isset($mergeDefinition->Values) || !($mergeDefinition->Values instanceof GenericCollection)) 829 | throw new \Exception("Debe especificar una coleccion basada en GenericCollection para realizar merge"); 830 | 831 | $parentKey = $mergeDefinition->ParentKey == "" ? $this->Key : $mergeDefinition->ParentKey; 832 | $childReferenceKey = $mergeDefinition->ChildReferenceKey == "" ? $parentKey : $mergeDefinition->ChildReferenceKey; 833 | $parentCollectionName = $mergeDefinition->ParentCollectionName == "" ? $this->Pluralize($mergeDefinition->Values->ClassName) : $mergeDefinition->ParentCollectionName; 834 | $values = $mergeDefinition->Values; 835 | 836 | if (is_array($values) && count($values) <= 0) 837 | return; 838 | else if ( $values->Count() <= 0) 839 | return; 840 | 841 | // Almacenar resultados en un arreglo caché para acelerar 842 | // las búsquedas en grandes cantidades de elementos, cuando 843 | // el índice no existe 844 | $searchCache = array(); 845 | $parentFound = null; 846 | 847 | // Comenzar el bucle de busqueda por cada child 848 | foreach($values as $child) { 849 | // Buscar el parent 850 | unset($parentFound); 851 | 852 | // SI EL ARREGLO ESTA INDEXADO usamos el indice 853 | if (isset($this->GetLocalCache()->PrimaryIndex) && count($this->GetLocalCache()->PrimaryIndex) > 0) { 854 | if (isset($this->GetLocalCache()->PrimaryIndex[$child->$childReferenceKey])) { 855 | $llaveBuscada = $this->GetLocalCache()->PrimaryIndex[$child->$childReferenceKey]; 856 | if (isset($this->Values[$llaveBuscada])) 857 | $parentFound = $this->Values[$llaveBuscada]; 858 | } 859 | } 860 | 861 | if (!isset($parentFound)) { 862 | // SI NO EXISTE INDICE, buscamos por condicion, utilizamos caché para almacenar búsquedas previas 863 | //else { 864 | $condicion = null; 865 | 866 | if (isset($child->$childReferenceKey)) { 867 | if (is_string($child->$childReferenceKey)) 868 | $condicion = $parentKey . " == '" . $child->$childReferenceKey . "'"; 869 | else 870 | $condicion = $parentKey . " == " . $child->$childReferenceKey; 871 | } 872 | 873 | if (isset($condicion)) { 874 | // Buscar el elemento padre que aplique a esta condicion de referencia 875 | // Buscar primero en caché 876 | if (isset($searchCache[$child->$childReferenceKey])) { 877 | $parentFound = $searchCache[$child->$childReferenceKey]; 878 | } 879 | else { 880 | $parentFound = $this->FirstWhere($condicion); 881 | // Agregar al cache 882 | $searchCache[$child->$childReferenceKey] = $parentFound; 883 | } 884 | } 885 | } 886 | 887 | if (isset($parentFound)) { 888 | if (!isset($parentFound->$parentCollectionName)) 889 | $parentFound->$parentCollectionName = []; 890 | 891 | array_push($parentFound->$parentCollectionName, $child); 892 | } 893 | } 894 | 895 | $dtEndMonitor = microtime(true); 896 | 897 | Monitor::$MergeChildrenExecutions++; 898 | Monitor::$MergeChildrenExecutionTime += ($dtEndMonitor - $dtStartMonitor); 899 | } 900 | 901 | private function GetClassName(string $dtoName) { 902 | 903 | $pos = strrpos($dtoName, '\\'); 904 | 905 | if ($pos) { 906 | return str_replace('\\', '', substr($dtoName, $pos)); 907 | } 908 | } 909 | 910 | private function Pluralize(string $definition) { 911 | 912 | $plural = "es"; 913 | 914 | // Primero revisar el ultimo elemento 915 | $lastChar = strtolower(substr($definition, -1, 1)); 916 | 917 | if ($lastChar == 'a' || $lastChar == 'e' || $lastChar == 'o') { 918 | $plural = "s"; 919 | } 920 | 921 | return $definition . $plural; 922 | } 923 | 924 | public function Avg($field) { 925 | 926 | if ($this->GetLocalCache()->LastAvgField != $field) { 927 | 928 | // Actualizar caché 929 | $this->GetLocalCache()->LastAvgField = $field; 930 | 931 | if ($this->Count() <= 0) 932 | return 0; 933 | 934 | $sum = $this->Sum($field); 935 | 936 | // Actualizar caché 937 | $this->GetLocalCache()->LastAvg = ($sum / $this->Count()); 938 | } 939 | 940 | return $this->GetLocalCache()->LastAvg; 941 | } 942 | 943 | public function Sum($field) { 944 | 945 | if ($this->GetLocalCache()->LastSumField != $field) { 946 | // Actualizar caché 947 | $this->GetLocalCache()->LastSumField = $field; 948 | 949 | $sum = 0; 950 | 951 | foreach($this->Values as $value) { 952 | $sum += $value->$field * 1; 953 | } 954 | 955 | // Actualizar caché 956 | $this->GetLocalCache()->LastSum = $sum; 957 | } 958 | 959 | return $this->GetLocalCache()->LastSum; 960 | } 961 | 962 | public function SumWhere($sumField, $condicion) { 963 | 964 | $sumResult = 0; 965 | 966 | $condicion = $this->SingleEqualSignReplace($condicion); 967 | 968 | // Buscar variables dentro de la condicion 969 | $pivote = get_class_vars($this->DtoName); // new $this->DtoName(); 970 | 971 | foreach($pivote as $propname => $propvalue) { 972 | $condicion = $this->TokenReplace($propname, "\$value->" . $propname, $condicion); 973 | } 974 | 975 | // Evitar la asignacion 976 | $condicion = str_replace(" = ", " == ", $condicion); 977 | 978 | foreach($this->Values as $value) { 979 | 980 | $resultado = eval('return (' . $condicion . ');'); 981 | 982 | if ($resultado) { 983 | $fieldValue = $value->$sumField; 984 | 985 | if (isset($fieldValue) && is_numeric($fieldValue)) { 986 | $sumResult += $fieldValue * 1; 987 | } 988 | } 989 | } 990 | 991 | return $sumResult; 992 | } 993 | 994 | public function Max($field) { 995 | 996 | if ($this->GetLocalCache()->LastMaxField != $field) { 997 | 998 | // Revisar en el indice principal si el campo es la llave 999 | if ($this->Key != "" && $field == $this->Key) { 1000 | 1001 | if (!isset($this->GetLocalCache()->PrimaryIndex)) { 1002 | // Crear el indice 1003 | $this->CreatePrimaryIndex($this->Key); 1004 | } 1005 | 1006 | if (count($this->GetLocalCache()->PrimaryIndex) > 0) { 1007 | // Buscar en el indice principal el primer elemento 1008 | $idx = array_key_last($this->GetLocalCache()->PrimaryIndex); 1009 | 1010 | if (isset($idx)) { 1011 | $this->GetLocalCache()->LastMax = $idx; 1012 | } 1013 | } 1014 | else { 1015 | $this->GetLocalCache()->LastMax = null; 1016 | } 1017 | } 1018 | // Probar utilizando el índice secundario del campo si no es la llave 1019 | else { 1020 | if (!isset($this->GetLocalCache()->SecondaryIndexes[$field])) { 1021 | // Crear el indice 1022 | $this->CreateSecondaryIndexes([$field]); 1023 | } 1024 | 1025 | $idx = array_key_last($this->GetLocalCache()->SecondaryIndexes[$field]); 1026 | 1027 | if (isset($idx)) { 1028 | $this->GetLocalCache()->LastMax = $idx; 1029 | } 1030 | else { 1031 | $this->GetLocalCache()->LastMax = null; 1032 | } 1033 | } 1034 | 1035 | // Actualizar caché 1036 | $this->GetLocalCache()->LastMaxField = $field; 1037 | } 1038 | 1039 | return $this->GetLocalCache()->LastMax; 1040 | } 1041 | 1042 | public function Min($field) { 1043 | 1044 | $dtStartMonitor = microtime(true); 1045 | 1046 | if ($this->GetLocalCache()->LastMinField != $field) { 1047 | 1048 | // Revisar en el indice principal si el campo es la llave 1049 | if ($this->Key != "" && $field == $this->Key) { 1050 | 1051 | if (!isset($this->GetLocalCache()->PrimaryIndex)) { 1052 | // Crear el indice 1053 | $this->CreatePrimaryIndex($this->Key); 1054 | } 1055 | 1056 | if (count($this->GetLocalCache()->PrimaryIndex) > 0) { 1057 | // Buscar en el indice principal el primer elemento 1058 | $idx = array_key_first($this->GetLocalCache()->PrimaryIndex); 1059 | 1060 | if (isset($idx)) { 1061 | $this->GetLocalCache()->LastMin = $idx; 1062 | } 1063 | } 1064 | else { 1065 | $this->GetLocalCache()->LastMin = null; 1066 | } 1067 | } 1068 | // Probar utilizando el índice secundario del campo si no es la llave 1069 | else { 1070 | if (!isset($this->GetLocalCache()->SecondaryIndexes[$field])) { 1071 | // Crear el indice 1072 | $this->CreateSecondaryIndexes([$field]); 1073 | } 1074 | 1075 | $idx = array_key_first($this->GetLocalCache()->SecondaryIndexes[$field]); 1076 | 1077 | if (isset($idx)) { 1078 | $this->GetLocalCache()->LastMin = $idx; 1079 | } 1080 | else { 1081 | $this->GetLocalCache()->LastMin = null; 1082 | } 1083 | } 1084 | 1085 | // Actualizar caché 1086 | $this->GetLocalCache()->LastMinField = $field; 1087 | } 1088 | 1089 | $dtEndMonitor = microtime(true); 1090 | 1091 | Monitor::$MinExecutions++; 1092 | Monitor::$MinExecutionTime += ($dtEndMonitor - $dtStartMonitor); 1093 | 1094 | return $this->GetLocalCache()->LastMin; 1095 | } 1096 | 1097 | public function IndexedMin($field) { 1098 | 1099 | $dtStartMonitor = microtime(true); 1100 | 1101 | if ($this->GetLocalCache()->LastMinField != $field) { 1102 | 1103 | // Primero probar utilizando el índice del campo si este existe 1104 | // (no se creará un índice automático puesto que el campo puede no ser de tipo INT y el índice no funcionaría) 1105 | if (isset($this->GetLocalCache()->SecondaryIndexes[$field])) { 1106 | } 1107 | 1108 | // Actualizar caché 1109 | $this->GetLocalCache()->LastMinField = $field; 1110 | 1111 | $parts = explode(" ", $field); 1112 | $fieldName = $parts[0]; 1113 | 1114 | $order = $this->OrderedBy($fieldName); 1115 | 1116 | // Actualizar caché 1117 | $this->GetLocalCache()->LastMin = $order->First()->$fieldName; 1118 | } 1119 | 1120 | $dtEndMonitor = microtime(true); 1121 | 1122 | Monitor::$IndexedMinExecutions++; 1123 | Monitor::$IndexedMinExecutionTime += ($dtEndMonitor - $dtStartMonitor); 1124 | 1125 | return $this->GetLocalCache()->LastMin; 1126 | } 1127 | 1128 | public function ItemMax($field) { 1129 | 1130 | if ($this->GetLocalCache()->LastItemMaxField != $field) { 1131 | 1132 | // Actualizar caché 1133 | $this->GetLocalCache()->LastItemMaxField = $field; 1134 | 1135 | $parts = explode(" ", $field); 1136 | $fieldName = $parts[0]; 1137 | 1138 | $order = $this->OrderedBy($fieldName); 1139 | 1140 | // Actualizar caché 1141 | $this->GetLocalCache()->LastItemMax = $order->Last(); 1142 | } 1143 | 1144 | return $this->GetLocalCache()->LastItemMax; 1145 | } 1146 | 1147 | public function ItemMin($field) { 1148 | 1149 | if ($this->GetLocalCache()->LastMinItemField != $field) { 1150 | 1151 | // Actualizar caché 1152 | $this->GetLocalCache()->LastMinItemField = $field; 1153 | 1154 | $parts = explode(" ", $field); 1155 | $fieldName = $parts[0]; 1156 | 1157 | $order = $this->OrderedBy($fieldName); 1158 | 1159 | // Actualizar caché 1160 | $this->GetLocalCache()->LastMinItem = $order->First(); 1161 | } 1162 | 1163 | return $this->GetLocalCache()->LastMinItem; 1164 | } 1165 | 1166 | public function Distinct($field) { 1167 | 1168 | if ($this->GetLocalCache()->LastDistinctField != $field) { 1169 | 1170 | // Actualizar caché 1171 | $this->GetLocalCache()->LastDistinctField = $field; 1172 | 1173 | // Enumerar la colección sin repetir el campo 1174 | $result = array(); 1175 | 1176 | foreach($this->Values as $value) { 1177 | $itemFieldValue = $value->$field; 1178 | 1179 | if (!isset($result[$itemFieldValue])) { 1180 | $result[$itemFieldValue] = $value->$field; 1181 | } 1182 | } 1183 | 1184 | // Actualizar caché 1185 | $this->GetLocalCache()->LastDistinct = $result; 1186 | } 1187 | 1188 | return $this->GetLocalCache()->LastDistinct; 1189 | } 1190 | 1191 | public function DistinctItem($field = "") { 1192 | 1193 | if ($this->GetLocalCache()->LastDistinctItemField != $field) { 1194 | 1195 | // Actualizar caché 1196 | $this->GetLocalCache()->LastDistinctItemField = $field; 1197 | 1198 | // Enumerar la colección sin repetir el campo 1199 | $result = array(); 1200 | 1201 | foreach($this->Values as $value) { 1202 | $itemFieldValue = $value->$field; 1203 | 1204 | if (!isset($result[$itemFieldValue])) { 1205 | $result[$itemFieldValue] = $value; 1206 | } 1207 | } 1208 | 1209 | // Actualizar caché 1210 | $this->GetLocalCache()->LastDistinctItem = new GenericCollection( 1211 | Key: $this->Key, 1212 | DtoName: $this->DtoName, 1213 | Values: $result 1214 | ); 1215 | } 1216 | 1217 | return $this->GetLocalCache()->LastDistinctItem; 1218 | } 1219 | 1220 | public function SingleEqualSignReplace($condicion) { 1221 | $fase1 = str_replace("==", "<>", $condicion); 1222 | $fase2 = str_replace("=", "==", $fase1); 1223 | 1224 | return str_replace("<>", "==", $fase2); 1225 | } 1226 | 1227 | 1228 | // Monitoring functions 1229 | public static function ResetMonitor() { 1230 | Monitor::$FromTimeExecutions = 0; 1231 | Monitor::$FromTimeExecutionTime = 0; 1232 | Monitor::$MergeChildrenExecutions = 0; 1233 | Monitor::$MergeChildrenExecutionTime = 0; 1234 | Monitor::$KeyIndexExecutions = 0; 1235 | Monitor::$KeyIndexExecutionTime = 0; 1236 | Monitor::$MinExecutions = 0; 1237 | Monitor::$MinExecutionTime = 0; 1238 | Monitor::$IndexedMinExecutions = 0; 1239 | Monitor::$IndexedMinExecutionTime = 0; 1240 | } 1241 | 1242 | public static function GetMonitorVars() { 1243 | return (object)[ 1244 | "FromTimeExecutions" => Monitor::$FromTimeExecutions, 1245 | "FromTimeExecutionTime" => Monitor::$FromTimeExecutionTime, 1246 | "FromTimeAverageTime" => (Monitor::$FromTimeExecutions == 0) ? 0 : (Monitor::$FromTimeExecutionTime / Monitor::$FromTimeExecutions), 1247 | "MergeChildrenExecutions" => Monitor::$MergeChildrenExecutions, 1248 | "MergeChildrenExecutionTime" => Monitor::$MergeChildrenExecutionTime, 1249 | "MergeChildrenAverageTime" => (Monitor::$MergeChildrenExecutions == 0) ? 0 : (Monitor::$MergeChildrenExecutionTime / Monitor::$MergeChildrenExecutions), 1250 | "KeyIndexExecutions" => Monitor::$KeyIndexExecutions, 1251 | "KeyIndexExecutionTime" => Monitor::$KeyIndexExecutionTime, 1252 | "MinExecutions" => Monitor::$MinExecutions, 1253 | "MinExecutionTime" => Monitor::$MinExecutionTime, 1254 | "MinExecutionAverageTime" => (Monitor::$MinExecutions == 0) ? 0 : (Monitor::$MinExecutionTime / Monitor::$MinExecutions), 1255 | "IndexedMinExecutions" => Monitor::$IndexedMinExecutions, 1256 | "IndexedMinExecutionTime" => Monitor::$IndexedMinExecutionTime, 1257 | "IndexedMinExecutionAverageTime" => (Monitor::$IndexedMinExecutions == 0) ? 0 : (Monitor::$IndexedMinExecutionTime / Monitor::$IndexedMinExecutions) 1258 | ]; 1259 | } 1260 | 1261 | // Getters 1262 | // ******************************************* 1263 | public function GetValue($property) { 1264 | return $this->$property; 1265 | } 1266 | 1267 | /** 1268 | * Reemplaza el token, teniendo la precaucion de realizar una comparación de palabra completa 1269 | */ 1270 | public static function TokenReplace($search, $replace, $subject) { 1271 | return preg_replace("/\b" . $search . "\b/i", $replace, $subject); 1272 | } 1273 | 1274 | public function GetKey() { 1275 | return $this->Key; 1276 | } 1277 | 1278 | public function GetDtoName() { 1279 | return $this->DtoName; 1280 | } 1281 | 1282 | } -------------------------------------------------------------------------------- Total de líneas: 1282 ================================================================================ ================================================================================ ARCHIVO #59: src/Collection/GenericDefinition.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Collection/GenericDefinition.php Tamaño: 2.43 KB -------------------------------------------------------------------------------- 1 | ValidateRequiredFields($definition); 23 | 24 | if (isset($errors)) { 25 | $mensaje = ""; 26 | 27 | foreach($errors as $error) { 28 | if ($mensaje != "") $mensaje .= "\n"; 29 | $mensaje.= $error; 30 | } 31 | 32 | throw new \Exception("No se han especificado los siguientes parametros obligatorios en la definicion:\n" . $mensaje); 33 | } 34 | } 35 | */ 36 | 37 | // Escribir las propiedades en el objeto final 38 | foreach($properties as $propname => $propvalue) { 39 | // Seteamos la propiedad 40 | if (isset($definition[$propname])) { 41 | $this->$propname = $definition[$propname]; 42 | } 43 | } 44 | 45 | // Validacion 46 | if (isset($validatorClass) && $validatorClass != "") { 47 | 48 | // Instanciar el validador 49 | $this->Validator = new $validatorClass($this); 50 | 51 | // Ejecutar la validacion 52 | try { 53 | $this->Validator->RunValidations($definition); 54 | } 55 | catch (\Exception $e) { 56 | throw ($e); 57 | } 58 | 59 | } 60 | } 61 | 62 | // Getters 63 | // ******************************************* 64 | public function GetValue($property) { 65 | return $this->$property; 66 | } 67 | 68 | // protected function ValidateRequiredFields($definition) { 69 | // // Verificar que todos los campos de la definicion han sido especificados 70 | // $errors = array(); 71 | 72 | // $vars = get_object_vars($this); 73 | 74 | // foreach($vars as $prop => $value) { 75 | // if (!isset($definition[$prop])) { 76 | // array_push($errors, "El campo $prop no ha sido especificado en la definicion"); 77 | // } 78 | // } 79 | 80 | // if (count($errors) > 0) { 81 | // return $errors; 82 | // } 83 | // else { 84 | // return null; 85 | // } 86 | // } 87 | 88 | } -------------------------------------------------------------------------------- Total de líneas: 88 ================================================================================ ================================================================================ ARCHIVO #60: src/Collection/GenericValidator.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Collection/GenericValidator.php Tamaño: 3.51 KB -------------------------------------------------------------------------------- 1 | Element = $element; 24 | $this->LoadValidations(); 25 | } 26 | 27 | // Obtener las propiedades y los validadores del objeto actual 28 | private function LoadValidations() { 29 | 30 | if (!isset($this->Element)) 31 | return; 32 | 33 | $entity = new \ReflectionClass(get_class($this->Element)); 34 | $propiedades = get_class_vars($entity->getName()); 35 | 36 | foreach($propiedades as $propiedad=>$valor) { 37 | $prop = new \ReflectionProperty($entity->getName(), $propiedad); 38 | $annotations = DocComment::GetPropertyAnnotations($prop, "\n"); 39 | 40 | foreach($annotations as $annotation) { 41 | switch(strtolower($annotation->Name)) { 42 | case "validation" : 43 | array_push($this->Validations, (object) ["Property" => $prop, "Validation" => $annotation->Value]); 44 | break; 45 | case "required" : 46 | array_push($this->RequiredFields, $propiedad); 47 | break; 48 | } 49 | } 50 | 51 | } 52 | } 53 | 54 | public function RunValidations(array $definition = array()) { 55 | 56 | $mensajes = ""; 57 | 58 | // Evaluar los campos que no se cargaron en la definicion y que son requeridos 59 | foreach($this->RequiredFields as $propiedad) { 60 | if (!isset($definition[$propiedad])) { 61 | if ($mensajes!="") $mensajes .= "\n"; 62 | $mensajes .= "Propiedad: \"" . $propiedad . "\", No se ha definido esta propiedad obligatoria"; 63 | } 64 | } 65 | 66 | foreach($this->Validations as $validation) { 67 | 68 | $sentence = $validation->Validation; 69 | $property = $validation->Property->name; 70 | 71 | // Reemplazar las ocurrencias de la propiedad 72 | $sentence = str_replace('@prop', '$this->Element->'.$property, $sentence); 73 | 74 | // Reemplazar llamadas a metodos 75 | $sentence = str_replace('@', '$this->', $sentence); 76 | 77 | // Ejecutar la validacion 78 | $result = eval("return (" . $sentence . ");"); 79 | 80 | if (!$result) { 81 | if ($mensajes!="") $mensajes .= "\n"; 82 | $mensajes .= "Propiedad: \"" . $property . "\", Validacion: [ " . $sentence . " ]"; 83 | } 84 | } 85 | 86 | if ($mensajes != "") { 87 | throw new Exception($mensajes); 88 | } 89 | 90 | return true; 91 | } 92 | 93 | // General purpose validators 94 | // *************************************************************** 95 | public function is_date($date, $format) { 96 | 97 | $d = \DateTime::createFromFormat($format, $date); 98 | 99 | return $d && $d->format($format) === $date; 100 | } 101 | 102 | public function is_valid_array($array) { 103 | return (isset($array) && is_array($array) && count($array) > 0); 104 | } 105 | 106 | public function is_collection($collection) { 107 | return ($collection instanceof GenericCollection); 108 | } 109 | 110 | public function instance_of($property, $className) { 111 | 112 | $plop = ($property instanceof $className); 113 | 114 | return ($property instanceof $className); 115 | } 116 | } -------------------------------------------------------------------------------- Total de líneas: 116 ================================================================================ ================================================================================ ARCHIVO #61: src/Collection/MergeDefinition.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Collection/MergeDefinition.php Tamaño: 514 bytes -------------------------------------------------------------------------------- 1 | decodeMultiple($jsonData, static::class); 64 | } 65 | else { 66 | $configResult = $jsonDecoder->decode($jsonData, static::class); 67 | } 68 | 69 | return $configResult; 70 | } 71 | 72 | 73 | } -------------------------------------------------------------------------------- Total de líneas: 73 ================================================================================ ================================================================================ ARCHIVO #63: src/Configuration/BundleConfig.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Configuration/BundleConfig.php Tamaño: 1.65 KB -------------------------------------------------------------------------------- 1 | __ControllerContainer->methods; 58 | 59 | $userMenu = array(); 60 | if (isset($methods) && isset($menus)) { 61 | 62 | foreach ($menus as $idMenu => $menu) { 63 | 64 | // Revisar si el menú está autorizado 65 | $authorizedMenu = self::GetMenuIfAuthorized($menu, $dispatcher, $idioma, $locale); 66 | 67 | // es menu suelto o tiene submenu? 68 | if (count($menu->Items) == 0) { // <- menú suelto sin hijos 69 | if (isset($authorizedMenu)) { 70 | $userMenu[$idMenu] = $authorizedMenu; 71 | } 72 | } 73 | else { // <- menú principal con hijos 74 | 75 | // Se deben chequear primero los hijos, si al menos tiene 1, entonces agregamos el menú padre 76 | $childMenus = array(); 77 | 78 | foreach($menu->Items as $childMenu) { 79 | $child = (new BaseMapper((object)$childMenu))->MapTo(MenuConfig::class); 80 | $authorizedChildMenu = self::GetMenuIfAuthorized($child, $dispatcher, $idioma, $locale); 81 | 82 | if (isset($authorizedChildMenu)) { 83 | array_push($childMenus, $authorizedChildMenu); 84 | } 85 | } 86 | 87 | // Revisar si exiten menus hijos 88 | // 89 | if (count($childMenus) > 0) { 90 | // Si tiene hijos autorizados, autorizamos el menu padre también 91 | $menu->Items = $childMenus; 92 | $userMenu[$idMenu] = $menu; 93 | } 94 | } 95 | } 96 | } 97 | 98 | return $userMenu; 99 | } 100 | 101 | private static function GetMenuIfAuthorized(MenuConfig $menu, BaseDispatcher $dispatcher, $idioma, $locale) { 102 | 103 | // Buscar primero la ruta URI del menu en los métodos 104 | // 105 | $methods = $dispatcher->__ControllerContainer->methods; 106 | $foundRoutes = $methods->Where('FullPath == "' . $menu->Uri . '"'); 107 | 108 | // Si no encontramos el URI en los métodos, buscar si existe a nivel de controlador 109 | // 110 | if (!isset($foundRoutes) || !$foundRoutes || $foundRoutes->Count() == 0) { 111 | $found = array(); 112 | foreach($dispatcher->__ControllerContainer->controllers as $controller) { 113 | if ($controller->ControllerRoute->FullPath == $menu->Uri) 114 | array_push($found, $controller->ControllerRoute); 115 | } 116 | 117 | if (count($found) > 0) { 118 | $foundRoutes = new GenericCollection( 119 | Key : 'FullPath', 120 | DtoName : Route::class, 121 | Values : $found 122 | ); 123 | } 124 | } 125 | 126 | if (isset($foundRoutes) && $foundRoutes && $foundRoutes->Count() > 0) { 127 | $route = $foundRoutes->First(); 128 | 129 | // agregar si está autorizado o el menu es público 130 | // 131 | if ($route->Authorization == 'ALLOW_ALL' || $dispatcher->HasAnyRol($route->Roles)) { 132 | $result = new MenuConfig(); 133 | 134 | if (strpos($menu->Description, '@@')) { 135 | $descripcion = BaseController::RenderMensaje($menu->Description, '@@', $idioma, $locale); 136 | 137 | foreach($descripcion as $key => $value) { 138 | $result->Description = $value; 139 | break; 140 | } 141 | } 142 | else { 143 | $result->Description = $menu->Description; 144 | } 145 | 146 | $result->Icon = $menu->Icon; 147 | $result->Uri = $menu->Uri; 148 | $result->Decorators = $menu->Decorators; 149 | $result->Items = array(); 150 | 151 | foreach($result->Decorators as $decorator) { 152 | if ($decorator['Type'] == 'TITULO' && strpos($decorator['Definition'], '@@')) { 153 | $descripcion = BaseController::RenderMensaje($decorator['Definition'], '@@', $idioma, $locale); 154 | 155 | foreach($descripcion as $key => $value) { 156 | $decorator['Definition'] = $value; 157 | break; 158 | } 159 | } 160 | } 161 | 162 | return $result; 163 | } 164 | } 165 | 166 | return null; 167 | } 168 | 169 | public static function GetUserMenuWidget($funcs) { 170 | 171 | $itemsMenuSistema = []; 172 | 173 | if (isset($funcs)) { 174 | foreach($funcs as $idFunc=>$func) { 175 | 176 | // Ver si es un menu suelto o un menu con items 177 | if (count($func->Items) == 0) { 178 | $activa = ($_SERVER['REQUEST_URI'] == $func->Uri) ? " active " : ""; 179 | 180 | if ($func->Description == '') { 181 | $iconclass = 'menu-icono'; 182 | } 183 | else { 184 | $iconclass = 'menu-icono-withtext'; 185 | } 186 | 187 | $nuevoMenu = new MenuItem( 188 | Title: $func->Description, 189 | Action: $func->Uri, 190 | Classes: ['menu-icon-text'], 191 | Icon: ($func->Icon != '') ? new FaIcon(Name: $func->Icon, Classes: [$iconclass]) : null, 192 | Active: ($_SERVER['REQUEST_URI'] == $func->Uri) 193 | ); 194 | } 195 | else { 196 | $activaMnu = false; 197 | foreach ($func->Items as $idItem=>$item) 198 | { 199 | if ($_SERVER['REQUEST_URI'] == $item->Uri) { 200 | $activaMnu = true; 201 | break; 202 | } 203 | } 204 | 205 | $menuItems = []; 206 | 207 | foreach ($func->Items as $idItem=>$item) 208 | { 209 | $activa = ($_SERVER['REQUEST_URI'] == $item->Uri); 210 | 211 | // Agregar decoradores 212 | if (count($item->Decorators) > 0) { 213 | foreach($item->Decorators as $decorator) { 214 | if ($decorator['Type'] == 'TITULO') { 215 | array_push($menuItems, new ActionMenuTitle( 216 | Content: $decorator['Definition'], 217 | Classes: ['menu-titulo'] 218 | )); 219 | } 220 | else if ($decorator['Type'] == 'SEPARATOR') { 221 | array_push($menuItems, new ActionMenuSeparator( 222 | Classes: ['menu-separador'] 223 | )); 224 | } 225 | else if ($decorator['Type'] == 'MINISEPARATOR') { 226 | array_push($menuItems, new ActionMenuMiniSeparator( 227 | Classes: ['menu-mini-separador'] 228 | )); 229 | } 230 | } 231 | } 232 | 233 | $icon = null; 234 | if (isset($item->Icon) && $item->Icon != '') { 235 | $icon = new FaIcon( 236 | Name: $item->Icon, 237 | Classes: ['menu-item-icono'] 238 | ); 239 | } 240 | 241 | // Agregar el item de menu 242 | array_push($menuItems, new ActionMenuItem( 243 | Classes: ['dropdown'], 244 | Action: $item->Uri, 245 | Content: $item->Description, 246 | Icon: $icon, 247 | Active: $activa 248 | )); 249 | } 250 | 251 | $nuevoMenu = new ActionMenu( 252 | Title: $func->Description, 253 | Items: $menuItems, 254 | Classes: [$activaMnu], 255 | Active: $activaMnu 256 | ); 257 | } 258 | 259 | array_push($itemsMenuSistema, $nuevoMenu); 260 | } 261 | } 262 | 263 | $menuSistema = new Menu( 264 | Items: $itemsMenuSistema, 265 | ContainerClasses: ['navbar-left'], 266 | MenuClasses: ['nav navbar-nav no-borders'] 267 | ); 268 | 269 | return $menuSistema; 270 | } 271 | } -------------------------------------------------------------------------------- Total de líneas: 271 ================================================================================ ================================================================================ ARCHIVO #67: src/Configuration/RedisConfig.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Configuration/RedisConfig.php Tamaño: 908 bytes -------------------------------------------------------------------------------- 1 | Exists($idRestriction)) { 53 | $restriction = $restrictions->Find($idRestriction); 54 | 55 | $roles = $restriction->Roles; 56 | $positiveAction = $restriction->PositiveAction; 57 | $negativeAction = $restriction->NegativeAction; 58 | 59 | if (isset($roles) && isset($positiveAction) && isset($negativeAction)) { 60 | // Verificar si el perfil consultado tiene alguno de estos roles 61 | if (PerfilSvc::HasAnyRol($perfil, $roles)) { 62 | return $positiveAction; 63 | } 64 | else { 65 | return $negativeAction; 66 | } 67 | } 68 | } 69 | 70 | return "Hide"; 71 | } 72 | } -------------------------------------------------------------------------------- Total de líneas: 72 ================================================================================ ================================================================================ ARCHIVO #69: src/Configuration/SystemConfig.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Configuration/SystemConfig.php Tamaño: 2.40 KB -------------------------------------------------------------------------------- 1 | strtolower($_SERVER['HTTP_HOST']) 82 | ]; 83 | } 84 | else { 85 | return []; 86 | } 87 | 88 | } 89 | } -------------------------------------------------------------------------------- Total de líneas: 89 ================================================================================ ================================================================================ ARCHIVO #70: src/Controllers/ActionResult.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Controllers/ActionResult.php Tamaño: 865 bytes -------------------------------------------------------------------------------- 1 | imageReader = $assetManagerFactory->GetImageReaderAM(); 36 | $this->assetReader = $assetManagerFactory->GetImageReaderAM(); 37 | $this->controller = $forcedController; 38 | } 39 | 40 | public function Redirect(string $uri) { 41 | header("Location: $uri"); 42 | die(); 43 | } 44 | 45 | public static function GetPathExtension($uri) { 46 | 47 | $path_parts = pathinfo($uri); 48 | 49 | return isset($path_parts['extension']) ? $path_parts['extension'] : ''; 50 | } 51 | 52 | private function GetViewFileLocation($viewname) { 53 | 54 | if ($this->controller != '') { 55 | $controllerName = $this->controller; 56 | } 57 | else { 58 | $classFullName = str_replace('Application\\Controllers\\', '', (new \ReflectionClass(get_called_class()))->getName()); 59 | $controllerName = str_replace('\\', '/', str_replace('Controller', '', $classFullName)); 60 | } 61 | 62 | $masterPath = VIEW_ROOT . '/' . $controllerName; 63 | 64 | return $masterPath . '/' . $viewname . 'View.php'; 65 | } 66 | 67 | public function RenderView($view, $data = null) { 68 | 69 | Log::ErrorLog('FWK-Inicio Renderizado'); 70 | 71 | $viewFilePath = $this->GetViewFileLocation($view); 72 | 73 | Log::ErrorLog('FWK-Inicio Renderizado'); 74 | 75 | return $this->RenderFile($viewFilePath, $data); 76 | } 77 | 78 | private function RenderFile($file, $data = null) { 79 | 80 | Log::ErrorLog('FWK-Inicio RenderFile - File: ' . $file); 81 | 82 | //$dtInicio = microtime(true); 83 | 84 | if (file_exists($file)) { 85 | Log::ErrorLog('FWK-RenderFile fin file_exists($file)'); 86 | ob_start(); 87 | Log::ErrorLog('FWK-RenderFile fin ob_start()'); 88 | include( $file ); 89 | Log::ErrorLog('FWK-RenderFile fin include( $file )'); 90 | $content = ob_get_contents(); 91 | Log::ErrorLog('FWK-RenderFile fin ob_get_contents()'); 92 | ob_end_clean(); 93 | Log::ErrorLog('FWK-RenderFile fin ob_end_clean'); 94 | } 95 | else { 96 | return "
No existe la vista especificada (".$file.")
"; 97 | } 98 | 99 | //$dtFin = microtime(true); 100 | 101 | // Log::ErrorLog('FWK-RenderFile fin ob_clean - Time: ' . round(($dtFin - $dtInicio), 4) . ' segs.'); 102 | 103 | // Obtener el layout si es que existe 104 | 105 | // La funcion "ObtenerRenderSections" devuelve un arreglo de pares "Id => StringTotal" 106 | // Ej: "guest" => "@@Layout(guest)" 107 | $layouts = $this->ObtenerRenderSections($content, '@@Layout'); 108 | 109 | Log::ErrorLog('FWK-Fin Obtener RenderSections'); 110 | 111 | if (count($layouts) > 0) { 112 | // Solo se considerará el primer layout 113 | if (count($layouts) > 1) { 114 | return "
Error de definición se ha definido más de 1 layout para esta vista (".$view.")
"; 115 | } 116 | else { 117 | // Obtener el layout 118 | foreach($layouts as $layout=>$searchString) { 119 | 120 | Log::ErrorLog('FWK-Inicio Busqueda Layout'); 121 | 122 | $layoutFilePath = LAYOUT_ROOT . '/' . $layout . 'Layout.php'; 123 | $layoutContent = ""; 124 | 125 | if (isset($layout) && $layout != "") { 126 | 127 | // Ver si existe el archivo 128 | if (file_exists($layoutFilePath)) { 129 | ob_start(); 130 | include( $layoutFilePath ); 131 | $layoutContent = ob_get_contents(); 132 | ob_end_clean(); 133 | } 134 | else { 135 | return "
No existe el layout (".$layoutFilePath.") especificado en esta vista (".$file.")
"; 136 | } 137 | } 138 | 139 | Log::ErrorLog('FWK-Fin ob_end layout'); 140 | 141 | $content = $this->RenderContent($content, $layoutContent, $searchString); 142 | 143 | // Solo se debe ejecutar 1 vez. 144 | break; 145 | } 146 | 147 | } 148 | 149 | Log::ErrorLog('FWK-Fin Renderfile'); 150 | } 151 | 152 | // Renderizar las secciones 153 | $content = $this->RenderSections($content, $data); 154 | 155 | // Renderizar las cadenas de texto 156 | // Ejemplo: @@{MsgWrongPassword} se convierte en "Wrong username or password" (sin las comillas) 157 | 158 | //$prueba = $this->RenderStrings($content); 159 | 160 | Log::ErrorLog('FWK-Inicio RenderStrings'); 161 | $content = $this->RenderStrings($content); 162 | Log::ErrorLog('FWK-Fin RenderStrings'); 163 | 164 | 165 | Log::ErrorLog('FWK-Fin RenderFile'); 166 | 167 | return $content; 168 | } 169 | 170 | 171 | public function RenderContent($content, $layoutContent = '', $searchString = '') { 172 | 173 | Log::ErrorLog('FWK-Inicio RenderContent'); 174 | 175 | // Encontrar los bundles de la vista e inyectarlos en el layout 176 | // La funcion "ObtenerCadenasReemplazoBundles" devuelve un arreglo de pares "CadenaTotal" => "reemplazo" 177 | // Ej: '@@IncludeStyleBundle(estilosCss)' => '' 178 | $renderStyleResults = $this->ObtenerCadenasReemplazoBundles($content, '@@IncludeStyleBundle'); 179 | 180 | Log::ErrorLog('FWK-Fin ObtenerCadenasReemplazoBundles'); 181 | 182 | if (count($renderStyleResults) > 0) { 183 | 184 | $insertarStyle = ""; 185 | foreach($renderStyleResults as $searchBundle=>$replaceBundle) { 186 | // Acumulamos el código para insertar en el layout 187 | $insertarStyle .= $replaceBundle; 188 | // Borramos la definición desde la vista (aquí no será útil) 189 | $content = \str_replace($searchBundle, '', $content); 190 | } 191 | 192 | // Buscamos en el layout dónde insertar el código 193 | // Debemos reemplazar la llave "@@RenderViewStyles()" 194 | // Reemplazamos en el layout el código acumulado 195 | if (isset($layoutContent)) 196 | $layoutContent = \str_replace('@@RenderViewStyle()', $insertarStyle, $layoutContent); 197 | 198 | } else { 199 | // Si la vista no ha definido bundle de estilo, en el layout 200 | // debemos quitar la referencia que pueda existir 201 | if (isset($layoutContent)) 202 | $layoutContent = \str_replace('@@RenderViewStyle()', '', $layoutContent); 203 | } 204 | 205 | Log::ErrorLog('FWK-Fin RenderStyles'); 206 | 207 | // Ej: '@@IncludeScriptBundle(vistaJS)' => '' . "\n"; 703 | case "javascript": 704 | return '' . "\n"; 705 | case "css": 706 | return '' . "\n"; 707 | case "font": 708 | return '' . "\n"; 709 | default: 710 | return $filePath; 711 | } 712 | } 713 | 714 | // public function RenderWsResult($idError = 0, $msgError = '', $msgFriendly = '', $data = null) { 715 | // $wsResult = new StandardJsonResultWS(); 716 | 717 | // $wsResult->IdError = $idError; 718 | // $wsResult->MsgError = $msgError; 719 | // $wsResult->MsgFriendly = $msgFriendly; 720 | // $wsResult->Data = $data; 721 | 722 | // return $wsResult; 723 | // } 724 | 725 | 726 | public function EncodeWsResult($wsResult) { 727 | return json_encode($wsResult, JSON_UNESCAPED_UNICODE); 728 | } 729 | 730 | public function RenderJsonResult($idError = 0, $msgError = '', $msgFriendly = '', $data = null) { 731 | $json = new StandardJsonResultWS(); 732 | 733 | $json->IdError = $idError; 734 | $json->MsgError = $msgError; 735 | $json->MsgFriendly = $msgFriendly; 736 | $json->Data = $data; 737 | 738 | $encoded = json_encode($json, JSON_UNESCAPED_UNICODE); 739 | 740 | return $encoded; 741 | } 742 | 743 | public function DecodeJsonParameter($jsonParameter, $class) { 744 | $jsonDecoder = new JsonDecoder(); 745 | 746 | return $jsonDecoder->decode($jsonParameter, $class); 747 | } 748 | 749 | 750 | public function GetRequest($name = '') { 751 | if (isset($_REQUEST[$name])) { 752 | return $_REQUEST[$name]; 753 | } 754 | else if (isset($_POST[$name])) { 755 | return $_POST[$name]; 756 | } 757 | else if (isset($_GET[$name])) { 758 | return $_GET[$name]; 759 | } 760 | else { 761 | return file_get_contents('php://input'); 762 | } 763 | } 764 | 765 | public function GetObjectParams() { 766 | 767 | $objparams = $_GET; 768 | 769 | if (isset($objparams)) { 770 | return (object) $objparams; 771 | } 772 | else { 773 | return null; 774 | } 775 | } 776 | 777 | public function DecodeJsonRequest($requestId, $class) { 778 | $jsonParameter = $this->GetRequest($requestId); // $_REQUEST[$requestId]; 779 | 780 | if (isset($jsonParameter)) { 781 | $jsonDecoder = new JsonDecoder(); 782 | return $jsonDecoder->decode($jsonParameter, $class); 783 | } 784 | else { 785 | return null; 786 | } 787 | } 788 | 789 | public function DecodeJsonParameterArray($jsonParameter, $class) { 790 | $jsonDecoder = new JsonDecoder(); 791 | 792 | return $jsonDecoder->decodeMultiple($jsonParameter, $class); 793 | } 794 | 795 | protected function DisplayImage($image) { 796 | 797 | header('Cache-Control: no-cache, no-store, max-age=0, must-revalidate'); 798 | header('Expires: January 01, 2013'); 799 | header('Pragma: no-cache'); 800 | header("Content-Type: image/jpg"); 801 | 802 | echo $image; 803 | } 804 | 805 | protected function DownloadXml($file, $filename) { 806 | 807 | header('Cache-Control: no-cache, no-store, max-age=0, must-revalidate'); 808 | header('Expires: January 01, 2013'); 809 | header('Pragma: no-cache'); 810 | header('Content-Disposition: attachment; filename=' . $filename); 811 | header("Content-Type: application/xml"); 812 | 813 | echo $file; 814 | } 815 | 816 | protected function DownloadPdf($file, $filename) { 817 | 818 | //header('Cache-Control: no-cache, no-store, max-age=0, must-revalidate'); 819 | // header('Pragma: no-cache'); 820 | //header('Content-Disposition: attachment; filename=' . $filename); 821 | header("Content-Description: File Transfer"); 822 | header("Content-Type: application/octet-stream"); 823 | header('Content-Type: application/pdf'); 824 | 825 | 826 | echo $file; 827 | 828 | } 829 | 830 | } -------------------------------------------------------------------------------- Total de líneas: 830 ================================================================================ ================================================================================ ARCHIVO #73: src/Controllers/Chart/LineChartSerie.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Controllers/Chart/LineChartSerie.php Tamaño: 495 bytes -------------------------------------------------------------------------------- 1 | Texto - $serie->Valor'"; 30 | } 31 | else { 32 | $legendText = ""; 33 | } 34 | 35 | $series .= 36 | " 37 | { 38 | values: [$serie->Valor], 39 | text: '$serie->Texto', 40 | backgroundColor: '$serie->Color', 41 | $legendText 42 | } 43 | "; 44 | } 45 | 46 | return "\n 47 | {\n 48 | type: 'pie',\n 49 | title: {\n 50 | text: '$titulo'\n 51 | },\n 52 | scale: {\n 53 | 'size-factor':$scale\n 54 | },\n 55 | subtitle: {\n 56 | text: '$subtitulo'\n 57 | },\n 58 | legend: {\n 59 | layout: '$layout', 60 | y: '20px',\n 61 | margin: '$layouttopmargin 5px 5px 5px',\n 62 | adjustLayout: true,\n 63 | },\n 64 | plot: {\n 65 | valueBox: {\n 66 | placement: 'out'\n 67 | }\n 68 | },\n 69 | series: [\n 70 | $series \n 71 | ]\n 72 | }\n 73 | "; 74 | } 75 | 76 | public static function CreateLine(array $lineChartSeries, array $etiquetas, $format) { 77 | 78 | $scaleX = ''; 79 | $series = ''; 80 | 81 | $scaleX = join(",\n", $etiquetas); 82 | 83 | foreach($lineChartSeries as $line) { 84 | 85 | $label = $line->Label; 86 | $values = join(',', $line->Values); 87 | $highs = join(',', $line->DataHighs); 88 | $color = $line->Color; 89 | 90 | $series .= "\n 91 | {\n 92 | text: '$label',\n 93 | values: [\n 94 | $values\n 95 | ],\n 96 | dataHighs: [\n 97 | $highs\n 98 | ],\n 99 | lineColor: '$color',\n 100 | marker:{\n 101 | backgroundColor:'$color'\n 102 | }\n 103 | },\n 104 | "; 105 | } 106 | 107 | return "\n 108 | {\n 109 | type: 'line',\n 110 | backgroundColor:'#ffffff',\n 111 | legend:{\n 112 | align: 'center',\n 113 | verticalAlign: 'top',\n 114 | backgroundColor:'none',\n 115 | borderWidth: 0,\n 116 | item:{\n 117 | fontColor:'#6a6c6f',\n 118 | cursor: 'hand'\n 119 | },\n 120 | marker:{\n 121 | type:'circle',\n 122 | borderWidth: 0,\n 123 | cursor: 'hand'\n 124 | }\n 125 | },\n 126 | plotarea:{\n 127 | margin:'dynamic 70'\n 128 | },\n 129 | plot:{\n 130 | aspect: 'spline',\n 131 | lineWidth: 2,\n 132 | marker:{\n 133 | borderWidth: 0,\n 134 | size: 5\n 135 | }\n 136 | }, \n 137 | scaleX:{\n 138 | lineColor: '#6a6c6f',\n 139 | zooming: false,\n 140 | minValue: 0,\n 141 | step: 'day',\n 142 | item:{\n 143 | fontColor:'#6a6c6f'\n 144 | },\n 145 | transform:{\n 146 | type: 'date',\n 147 | all: '$format'\n 148 | }, \n 149 | values: [\n 150 | $scaleX\n 151 | ],\n 152 | }, \n 153 | scaleY:{\n 154 | minorTicks: 1,\n 155 | lineColor: '#6a6c6f',\n 156 | tick:{\n 157 | lineColor: '#6a6c6f'\n 158 | },\n 159 | minorTick:{\n 160 | lineColor: '#6a6c6f'\n 161 | },\n 162 | minorGuide:{\n 163 | visible: true,\n 164 | lineWidth: 1,\n 165 | lineColor: '#6a6c6f',\n 166 | alpha: 0.9,\n 167 | lineStyle: 'dashed'\n 168 | },\n 169 | guide:{\n 170 | lineStyle: 'dashed'\n 171 | },\n 172 | item:{\n 173 | fontColor:'#6a6c6f'\n 174 | }\n 175 | },\n 176 | tooltip:{\n 177 | borderWidth: 0,\n 178 | borderRadius: 3\n 179 | },\n 180 | crosshairX:{\n 181 | plotLabel:{\n 182 | multiple: true,\n 183 | borderRadius: 3,\n 184 | text: '%data-highs'\n 185 | },\n 186 | scaleLabel:{\n 187 | backgroundColor:'#53535e',\n 188 | borderRadius: 3\n 189 | },\n 190 | marker:{\n 191 | size: 7,\n 192 | alpha: 0.5\n 193 | }\n 194 | },\n 195 | crosshairY:{\n 196 | lineColor:'#6a6c6f',\n 197 | type:'multiple',\n 198 | scaleLabel:{\n 199 | decimals: 2,\n 200 | borderRadius: 3,\n 201 | offsetX: -5,\n 202 | fontColor: '#2C2C39',\n 203 | bold: true\n 204 | }\n 205 | },\n 206 | tooltip: {\n 207 | text: '%data-highs'\n 208 | },\n 209 | series: [\n 210 | $series \n 211 | ]\n 212 | }\n 213 | "; 214 | } 215 | } -------------------------------------------------------------------------------- Total de líneas: 215 ================================================================================ ================================================================================ ARCHIVO #77: src/Controllers/ControllerDefinition.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Controllers/ControllerDefinition.php Tamaño: 691 bytes -------------------------------------------------------------------------------- 1 | RenderMensaje($message); 22 | } 23 | 24 | // Imprime una fecha con formato dinámico para cambio de idioma en línea 25 | public static function DrawDateTime(\DateTime $fecha, $format, $classes = '') { 26 | 27 | $fmt = Mensaje::_($format); 28 | $fechaDisplay = $fecha->format($fmt); 29 | $Y = $fecha->format('Y'); 30 | $m = $fecha->format('m'); 31 | $d = $fecha->format('d'); 32 | $H = $fecha->format('H'); 33 | $i = $fecha->format('i'); 34 | $s = $fecha->format('s'); 35 | 36 | $html = "$fechaDisplay"; 37 | 38 | echo $html; 39 | } 40 | 41 | public static function GetRenderer($controller = "", $forceNew = false) { 42 | 43 | if ($forceNew || self::$Renderer == null || $controller != self::$Controller) { 44 | self::$Renderer = new BaseController($controller); 45 | self::$Controller = $controller; 46 | } 47 | 48 | return self::$Renderer; 49 | } 50 | 51 | public static function DrawSection($title, $info, $classes = "") { 52 | echo " 53 |
54 |
55 |
56 |
57 | "; 58 | } 59 | 60 | public static function DrawInputSection($title, $id, $placeholder, $inputType, $inputAtributes = "", $classes = "") { 61 | echo " 62 |
63 |
64 |
65 | 66 |
67 |
68 | "; 69 | } 70 | 71 | public static function DrawInputTextAreaSection($title, $id, $placeholder, $inputType, $inputAtributes = "", $classes = "") { 72 | echo " 73 |
74 |
75 |
76 | 77 |
78 |
79 | "; 80 | } 81 | 82 | public static function DrawLabelSection($title, $info, $labelType, $classes = "") { 83 | 84 | echo " 85 |
86 |
" . $info . "
87 |
88 |
89 | "; 90 | } 91 | 92 | public static function DrawProgressSection($title, $percentage, $labelType, $classes = "") { 93 | 94 | $progressType = ""; 95 | 96 | if ($labelType == "") { 97 | $labelType = "default"; 98 | $progressType = "info"; 99 | } 100 | else { 101 | $progressType = $labelType; 102 | } 103 | 104 | echo " 105 |
106 |
107 |
108 | $title " . number_format($percentage, 0, '.', ',') . " % 109 |
110 |
111 |
112 |
113 |
117 |
118 |
119 |
120 |
121 | "; 122 | } 123 | 124 | public static function DrawProgressBar( 125 | $progressId, 126 | $containerStyle = "background-color: #f5f5f5; margin-top: 5px;", 127 | $progressStyle = "background-color: transparent;" 128 | ) { 129 | 130 | echo " 131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 | "; 141 | } 142 | 143 | public static function DrawPanelLabel($title, $size = 0) { 144 | 145 | if (isset($size) && $size > 0) { 146 | $font = "font-size: " . $size . "px;"; 147 | } 148 | else { 149 | $font = ""; 150 | } 151 | 152 | echo " 153 |
154 | "; 155 | } 156 | 157 | public static function DrawInfoLabel($title) { 158 | 159 | echo " 160 |
161 | "; 162 | } 163 | 164 | public static function DrawPageTile($title, $subtitle) { 165 | echo " 166 |
167 |

168 | " . $title ." 169 |

170 |
171 | " . $subtitle . " 172 | "; 173 | } 174 | 175 | public static function DrawInfoBox($content, $closable = false, $show = true) { 176 | 177 | echo " 178 |
179 | $content 180 |
181 | "; 182 | } 183 | 184 | public static function DrawInfoIcon($text, $placement = "top", $isHtml = false, $icon="fa-info-circle") { 185 | echo ""; 186 | } 187 | 188 | public static function DrawValueLabel($value, $style = 'default', $disableOnZero = true) { 189 | 190 | if ($disableOnZero && ($value == 0 || $value == '')) { 191 | echo "0"; 192 | } 193 | else { 194 | echo "$value"; 195 | } 196 | } 197 | 198 | public static function DrawTabTitle($title = "", $icon = "", $iconsize = 20) { 199 | 200 | if ($title=="") { 201 | echo " 202 |
203 | 204 |
205 | "; 206 | } 207 | else if ($icon=="") { 208 | echo " 209 |
210 | $title 211 |
212 | "; 213 | } 214 | else { 215 | echo " 216 |
217 | 218 | $title 219 |
220 | "; 221 | } 222 | } 223 | 224 | } -------------------------------------------------------------------------------- Total de líneas: 224 ================================================================================ ================================================================================ ARCHIVO #79: src/Controllers/ErrorJsonMovilResult.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Controllers/ErrorJsonMovilResult.php Tamaño: 507 bytes -------------------------------------------------------------------------------- 1 | Usuario = $usuario; 25 | } 26 | 27 | public function Define($nombre, mixed $traza) 28 | { 29 | 30 | $this->CheckTrazas(); 31 | 32 | $this->Trazas[$nombre] = $traza; 33 | } 34 | 35 | public function GetValorTraza($nombre) 36 | { 37 | $this->CheckTrazas(); 38 | 39 | return $this->Trazas[$nombre]; 40 | } 41 | 42 | public function GetAuditJson() 43 | { 44 | 45 | $this->CheckTrazas(); 46 | $out = (object)$this->Trazas; 47 | 48 | return json_encode($out, JSON_INVALID_UTF8_SUBSTITUTE | JSON_PRETTY_PRINT); 49 | } 50 | 51 | public function GetAudit() 52 | { 53 | $this->CheckTrazas(); 54 | return (object)$this->Trazas; 55 | } 56 | 57 | private function CheckTrazas() 58 | { 59 | 60 | if (!isset($this->Trazas)) { 61 | $this->Trazas = []; 62 | 63 | if (!isset($this->Usuario)) { 64 | 65 | $usuario = $_SESSION['usuario']; 66 | 67 | $usuario = (isset($usuario)) 68 | ? (object) [ 69 | "IdUsuario" => $usuario->IdUsuario, 70 | "IdCliente" => $usuario->IdCliente, 71 | "IdEmpresa" => $usuario->IdEmpresa, 72 | "LoginName" => $usuario->LoginName, 73 | "Nombre" => $usuario->Nombre, 74 | "IdContacto" => $usuario->IdContacto, 75 | "IdTipoClave" => $usuario->IdTipoClave, 76 | "IndSoloUsoLoginSistema" => $usuario->IndSoloUsoLoginSistema, 77 | "Cargo" => $usuario->Cargo, 78 | "NombrePerfil" => $usuario->NombrePerfil, 79 | "IdPerfil" => (isset($usuario->Perfil)) ? $usuario->Perfil->IdPerfil : -1, 80 | "Cliente" => (isset($usuario->Cliente)) ? $usuario->Cliente->RazonSocial : "", 81 | ] 82 | : null; 83 | } 84 | 85 | $result = BaseDispatcher::GetLastResultForAudit(); 86 | $resultType = (isset($result)) ? get_class($result) : ''; 87 | 88 | $uriLastInstance = Uri::$LastInstance; 89 | $actionForJson = (isset($uriLastInstance->Action)) ? $uriLastInstance->Action : null; 90 | 91 | $this->Trazas['Fecha'] = ""; 92 | $this->Trazas['Usuario'] = $usuario; 93 | $this->Trazas['Cookie'] = $_COOKIE; 94 | $this->Trazas['Server'] = $_SERVER; 95 | $this->Trazas['Request'] = $_REQUEST; 96 | $this->Trazas['Result'] = $result; 97 | $this->Trazas['ResultType'] = $resultType; 98 | $this->Trazas['ResultError'] = str_contains($resultType, "Error"); 99 | $this->Trazas['Action'] = $actionForJson; 100 | $this->Trazas['HostName'] = gethostname(); 101 | $this->Trazas['ServerIP'] = gethostbyname(gethostname()); 102 | } 103 | } 104 | } 105 | -------------------------------------------------------------------------------- Total de líneas: 105 ================================================================================ ================================================================================ ARCHIVO #96: src/Core/Cacheable.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Core/Cacheable.php Tamaño: 1.33 KB -------------------------------------------------------------------------------- 1 | > [[ERRORTYPE]]: [[MESSAGE]]", 29 | public $DateFormat = 'Y-m-d', 30 | public $TimeFormat = 'H:i', 31 | $Flags = 0 32 | ) { 33 | $this->Flags = $Flags; 34 | } 35 | public static function CreateTraceLog($ex, $type) 36 | { 37 | $exception = new ExceptionResult(); 38 | 39 | $exception->TypeException = $type; 40 | if ($type == ExceptionTypeEnum::FATAL) { 41 | $exception->Message = $ex["message"]; 42 | $exception->Line = $ex["line"]; 43 | $exception->FatalType = $ex["type"]; 44 | $trace = 'Achivo donde se cae en : ' . $ex["file"]; 45 | $exception->Trace = $trace; 46 | } else { 47 | $exception->Message = $ex->getMessage(); 48 | $exception->Line = $ex->getLine(); 49 | $exception->Code = $ex->getCode(); 50 | $exception->Trace = $ex->getTraceAsString(); 51 | 52 | if ($type == ExceptionTypeEnum::BUSINESS) 53 | $exception->DebugMessage = $ex->getDebugMessage(); 54 | } 55 | 56 | $exception->ServerIP = $_SERVER["SERVER_ADDR"]; 57 | $exception->RequestUri = $_SERVER["REQUEST_URI"]; 58 | $exception->UserAgent = $_SERVER["HTTP_USER_AGENT"]; 59 | 60 | if (isset($_SESSION['usuario'])) { 61 | $usuario = $_SESSION['usuario']; 62 | 63 | $exception->Usuario = (object) [ 64 | "IdUsuario" => $usuario->IdUsuario, 65 | "LoginName" => $usuario->LoginName, 66 | ]; 67 | } 68 | 69 | $log = self::NewTraceLog(); 70 | $log->Log($exception, ErrorType: ErrorTypeEnum::ERROR); 71 | } 72 | 73 | public static function NewTraceLog() 74 | { 75 | $today = (new Date()); 76 | $year = $today->format('Y'); 77 | $month = $today->format('m'); 78 | 79 | $directorio = SITE_ROOT . '/FileData/trace/' . $year . '/' . $month; 80 | 81 | if (!is_dir($directorio)) { 82 | mkdir($directorio, 0775, true); 83 | } 84 | 85 | $filename = 'trace_' . $today->format('Y-m-d') . '.json'; 86 | 87 | $fullPath = $directorio . '/' . $filename; 88 | 89 | return new Log( 90 | LogFile: $fullPath, 91 | Format: "\n[[MESSAGE]]", 92 | DateFormat: 'Y-m-d', 93 | TimeFormat: 'H:i:s', 94 | Flags: FILE_APPEND | LOCK_EX 95 | ); 96 | } 97 | 98 | public static function NewAuditLog() 99 | { 100 | $today = (new Date()); 101 | $year = $today->format('Y'); 102 | $month = $today->format('m'); 103 | 104 | $directorio = SITE_ROOT . "/FileData/audit/" . $year . '/' . $month; 105 | 106 | if (!is_dir($directorio)) { 107 | mkdir($directorio, 0775, true); 108 | } 109 | 110 | $filename = 'audit_' . $today->format('Y-m-d') . '.json'; 111 | 112 | $fullPath = $directorio . '/' . $filename; 113 | 114 | return new Log( 115 | LogFile: $fullPath, 116 | Format: "\n[[MESSAGE]]", 117 | DateFormat: 'Y-m-d', 118 | TimeFormat: 'H:i:s', 119 | Flags: FILE_APPEND | LOCK_EX 120 | ); 121 | } 122 | 123 | public function Log($Message, $ErrorType = ErrorTypeEnum::INFO, $Echo = FALSE, $ContinuarAnterior = false) 124 | { 125 | 126 | $dt = new Date(); 127 | $date = $dt->format($this->DateFormat); 128 | $time = $dt->format($this->TimeFormat); 129 | $tipoLog = "INFO"; 130 | 131 | switch ($ErrorType) { 132 | case "e": 133 | $tipoLog = "ERROR"; 134 | break; 135 | case "w": 136 | $tipoLog = "WARNING"; 137 | break; 138 | } 139 | 140 | $pathActual = self::GestionarPesoArchivo($this->LogFile, $tipoLog); 141 | 142 | if (gettype($Message) == "object") { 143 | $Message->Fecha = $date . " " . $time; 144 | $Message = json_encode($Message, JSON_INVALID_UTF8_SUBSTITUTE | JSON_PRETTY_PRINT); 145 | } else if (gettype($Message) == "array") { 146 | $Message = (object)(["Fecha" => $date . " " . $time] + $Message); 147 | $Message = json_encode($Message, JSON_INVALID_UTF8_SUBSTITUTE | JSON_PRETTY_PRINT); 148 | } 149 | 150 | 151 | if ($ContinuarAnterior) { 152 | $msg = $Message; 153 | } else { 154 | $msg = str_replace("[[DATE]]", $date, $this->Format); 155 | $msg = str_replace("[[TIME]]", $time, $msg); 156 | $msg = str_replace("[[MESSAGE]]", $Message, $msg); 157 | $msg = str_replace("[[ERRORTYPE]]", $tipoLog, $msg); 158 | 159 | if (!$this->new) { 160 | $msg = "\n" . $msg; 161 | } 162 | $this->new = false; 163 | } 164 | 165 | file_put_contents($pathActual, $msg, $this->Flags); 166 | //fwrite($this->File, $msg); 167 | 168 | if ($Echo) { 169 | echo $msg; 170 | } 171 | } 172 | 173 | public static function ErrorLog($message, $message_type = 0, ?string $destination = '', ?string $additional_headers = '') 174 | { 175 | 176 | if (self::$PhpErrorLogActive) { 177 | error_log($message, $message_type, $destination, $additional_headers); 178 | } 179 | 180 | return true; 181 | } 182 | 183 | public static function GestionarPesoArchivo($fullPath, $tipo) 184 | { 185 | $folder = pathinfo($fullPath, PATHINFO_DIRNAME); 186 | $baseName = $tipo . "_" . pathinfo($fullPath, PATHINFO_FILENAME); 187 | $extension = pathinfo($fullPath, PATHINFO_EXTENSION); 188 | $patchConTipo = "$folder/$baseName.$extension"; 189 | 190 | // si no existe el archivo se termina la gestion 191 | if (!file_exists($patchConTipo)) return $patchConTipo; 192 | 193 | // Obtener lista de archivos en la carpeta con el formato específico 194 | $files = glob("$folder/{$baseName}*.$extension"); 195 | 196 | // Extraer números de los archivos que coinciden con el formato 197 | $numbers = []; 198 | 199 | foreach ($files as $file) { 200 | $filename = pathinfo($file, PATHINFO_FILENAME); 201 | 202 | // Buscar el número en el nombre del archivo 203 | if (preg_match('/^' . preg_quote($baseName, '/') . '_(\d+)$/', $filename, $matches)) { 204 | $numbers[] = (int)$matches[1]; 205 | } 206 | } 207 | 208 | // Ordenar de mayor a menor 209 | rsort($numbers); 210 | 211 | // Obtener el mayor número 212 | $maxNumber = $numbers[0] ?? 0; 213 | 214 | $peso = filesize($patchConTipo); 215 | if (round($peso / (1024 * 1024), 2) > self::$PesoMaximo) { 216 | $newPath = "$folder/$baseName" . "_" . ($maxNumber + 1) . ".$extension"; 217 | // se agrega el nuevo archivo 218 | rename($patchConTipo, $newPath); 219 | // se vacia el actual 220 | file_put_contents($patchConTipo, ""); 221 | } 222 | return $patchConTipo; 223 | } 224 | } 225 | -------------------------------------------------------------------------------- Total de líneas: 225 ================================================================================ ================================================================================ ARCHIVO #102: src/Core/MemoryInfo.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Core/MemoryInfo.php Tamaño: 1.50 KB -------------------------------------------------------------------------------- 1 | total_kb ?? 0, 43 | $mem->free_kb ?? 0, 44 | $mem->buffers_kb ?? 0, 45 | $mem->cached_kb ?? 0, 46 | $mem->available_kb_kernel ?? 0, 47 | $mem->available_kb_calculated ?? 0, 48 | $mem->total_mb ?? 0, 49 | $mem->available_mb_kernel ?? 0, 50 | $mem->available_mb_calculated ?? 0, 51 | ); 52 | 53 | return $result; 54 | } 55 | 56 | 57 | } -------------------------------------------------------------------------------- Total de líneas: 57 ================================================================================ ================================================================================ ARCHIVO #103: src/Core/Rut.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Core/Rut.php Tamaño: 1.14 KB -------------------------------------------------------------------------------- 1 | MapTo($userClass); 34 | } 35 | 36 | if (!isset($decoded) || $decoded->nonce != $tokenValidador) { 37 | $userObj->tokenInvalido = 1; 38 | } 39 | 40 | return $decoded; 41 | } 42 | 43 | public static function ValidarTokenJWK($token, $jwk, $tokenValidador, $userClass = null, $algoritmo = "RS256") 44 | { 45 | 46 | $decoded = JWT::decode($token, JWK::parseKeySet($jwk, $algoritmo)); 47 | if ($userClass == null) { 48 | $userObj = $decoded; 49 | } else { 50 | $userObj = (new BaseMapper($decoded))->MapTo($userClass); 51 | } 52 | 53 | if (!isset($decoded) || $decoded->nonce != $tokenValidador) { 54 | $userObj->tokenInvalido = 1; 55 | } 56 | 57 | return $decoded; 58 | } 59 | 60 | public static function ValidarTokenUri($token, $ConfigUri, $tokenValidador, $EsIdToken = true, $userClass = null) 61 | { 62 | $result = HttpHelper::Call( 63 | Method: HttpMethodEnum::GET, 64 | Url: $ConfigUri 65 | ); 66 | $configuracion = (object)json_decode($result, true); 67 | 68 | try { 69 | if($EsIdToken){ 70 | $jwkUri = HttpHelper::Call( 71 | Method: HttpMethodEnum::GET, 72 | Url: $configuracion->jwks_uri 73 | ); 74 | $data = json_decode($jwkUri, true); 75 | $decoded = JWT::decode($token, JWK::parseKeySet($data, $configuracion->id_token_signing_alg_values_supported[0])); 76 | }else{ 77 | $decoded =HttpHelper::Call( 78 | Method: HttpMethodEnum::GET, 79 | Url: $configuracion->userinfo_endpoint, 80 | Headers: array('Authorization: Bearer '.$token) 81 | ); 82 | $decoded = json_decode($decoded, true); 83 | } 84 | 85 | } catch (\Exception $ex) { 86 | $userObj = new stdClass(); 87 | $userObj->tokenInvalido = 1; 88 | $userObj->ex = $ex; 89 | 90 | return $userObj; 91 | } 92 | 93 | if ($userClass == null) 94 | $userObj = $decoded; 95 | else 96 | $userObj = (new BaseMapper((object)$decoded))->MapTo($userClass); 97 | 98 | // Se valida que el token enviado por el servicio de SSO es de la misma consulta que nuestro servicio envio. 99 | if (!isset($decoded) || ($EsIdToken && $decoded->nonce != $tokenValidador)) { 100 | $userObj->tokenInvalido = 1; 101 | } 102 | 103 | return $userObj; 104 | } 105 | 106 | public static function GenerarUuidV4() 107 | { 108 | return sprintf( 109 | '%04x%04x-%04x-%04x-%04x-%04x%04x%04x', 110 | // 32 bits for "time_low" 111 | mt_rand(0, 0xffff), 112 | mt_rand(0, 0xffff), 113 | 114 | // 16 bits for "time_mid" 115 | mt_rand(0, 0xffff), 116 | 117 | // 16 bits for "time_hi_and_version", 118 | // four most significant bits holds version number 4 119 | mt_rand(0, 0x0fff) | 0x4000, 120 | 121 | // 16 bits, 8 bits for "clk_seq_hi_res", 122 | // 8 bits for "clk_seq_low", 123 | // two most significant bits holds zero and one for variant DCE1.1 124 | mt_rand(0, 0x3fff) | 0x8000, 125 | 126 | // 48 bits for "node" 127 | mt_rand(0, 0xffff), 128 | mt_rand(0, 0xffff), 129 | mt_rand(0, 0xffff) 130 | ); 131 | } 132 | } 133 | -------------------------------------------------------------------------------- Total de líneas: 133 ================================================================================ ================================================================================ ARCHIVO #105: src/Core/System.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Core/System.php Tamaño: 2.99 KB -------------------------------------------------------------------------------- 1 | TableName = $Definition->Table; 32 | $this->Schema = $Definition->Schema; 33 | 34 | foreach ($Definition->Properties as $item) { 35 | 36 | if ($item instanceof PropertyDefinition) { 37 | $name = $item->Name; 38 | $oldValue = (isset($this->CurrentEntity)) ? $this->CurrentEntity->$name : null; 39 | $newValue = (isset($this->NewEntity)) ? $this->NewEntity->$name : null; 40 | 41 | if ($item->IsAuditable) { 42 | $displayFormat = ""; 43 | $currentValueFormated = ""; 44 | $newValueFormated = ""; 45 | 46 | if (isset($item->DisplayFormat) && $item->DisplayFormat instanceof Format) { 47 | $displayFormat = $item->DisplayFormat->Type; 48 | $currentValueFormated = $this->FormatValue($item->DisplayFormat, $oldValue); 49 | $newValueFormated = $this->FormatValue($item->DisplayFormat, $newValue); 50 | } 51 | 52 | $this->AuditableFields[] = new AuditField( 53 | FieldName: $item->Name, 54 | IsKey: $item->IsKey, 55 | ColumnName: $item->ColumnName, 56 | ColumnType: $item->ColumnType, 57 | IsNullable: $item->IsNullable, 58 | Display: $item->Display, 59 | DisplayFormat: $displayFormat, 60 | CurrentValue: $oldValue, 61 | CurrentValueFormated: $currentValueFormated, 62 | NewValue: $newValue, 63 | NewValueFormated: $newValueFormated, 64 | ); 65 | } 66 | } 67 | } 68 | } 69 | 70 | public function Run() 71 | { 72 | 73 | // Inicializamos 74 | // 75 | $this->Auditable->GuardarAuditoria($this); 76 | 77 | // Ok, obtener el objeto si es un update, para cargar 78 | // los valores previos 79 | } 80 | 81 | private function FormatValue(Format $formato, $value) 82 | { 83 | $result = ""; 84 | switch ($formato->Type) { 85 | case FormatTypeEnum::MONEY: 86 | $result = _mon($value, $formato->Decimals); 87 | break; 88 | case FormatTypeEnum::INTEGER: 89 | $result = _num($value); 90 | break; 91 | case FormatTypeEnum::DECIMAL: 92 | $result = _dec($value, $formato->Decimals); 93 | break; 94 | case FormatTypeEnum::DATE: 95 | $formatDate = "d-m-Y"; 96 | if (isset($formato->FromatString) && $formato->FromatString != "") 97 | $formatDate = $formato->FromatString; 98 | if (isset($value) && $value != "") 99 | $result = (new Date($value))->format($formatDate); 100 | break; 101 | case FormatTypeEnum::DATETIME: 102 | $formatDate = "d-m-Y H:i:s"; 103 | if (isset($formato->FromatString) && $formato->FromatString != "") 104 | $formatDate = $formato->FromatString; 105 | if (isset($value) && $value != "") 106 | $result = (new Date($value))->format($formatDate); 107 | break; 108 | default: 109 | break; 110 | } 111 | return $result; 112 | } 113 | } 114 | -------------------------------------------------------------------------------- Total de líneas: 114 ================================================================================ ================================================================================ ARCHIVO #108: src/Dao/BasicDao.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Dao/BasicDao.php Tamaño: 31.77 KB -------------------------------------------------------------------------------- 1 | 0) { 33 | self::$GlobalTop = $top; 34 | } 35 | } 36 | 37 | public function GetEntityName() 38 | { 39 | return $this->EntityDefinition->Entity; 40 | } 41 | 42 | function __construct($entity, $domain) 43 | { 44 | 45 | // Obtener la información de la entidad 46 | //$this->EntityDefinition = EntityDefinition::GetInstance(new \ReflectionClass($entity)); 47 | $this->EntityDefinition = EntityDefinition::Instance($entity); // << version con control de caché y almacenamiento en redis 48 | 49 | // Asignar el dominio para el acceso a datos 50 | // Buscar el dominio 51 | $dominios = ConnectionConfig::Instance(); 52 | 53 | $this->Domain = $dominios[$domain]; 54 | //$this->Domain = $domain; 55 | 56 | // Obtener una instancia de conexión PDO para utilizar 57 | // con este DAO 58 | if ($this->Connection === null) { 59 | $this->Connection = DataConfig::GetPDOConnection($domain); 60 | } 61 | } 62 | 63 | public function Query(Queryable $query, bool $returnFirstRecord = false, $transaction = null, $nosanear = false) 64 | { 65 | 66 | $qry = $query->Build(); 67 | if (!isset($transaction)) { 68 | $transaction = $this->Connection; 69 | } 70 | 71 | $stmt = $transaction->prepare($qry->Statement); 72 | 73 | foreach ($qry->Bindings as $binding) { 74 | 75 | $param = FALSE; 76 | 77 | if (is_int($binding->BindingValue)) 78 | $param = PDO::PARAM_INT; 79 | else if (is_bool($binding->BindingValue)) 80 | $param = PDO::PARAM_BOOL; 81 | else if (is_null($binding->BindingValue)) 82 | $param = PDO::PARAM_NULL; 83 | else if (is_string($binding->BindingValue)) 84 | $param = PDO::PARAM_STR; 85 | else 86 | $param = PDO::PARAM_STR; 87 | 88 | if ($param) 89 | $stmt->bindValue($binding->BindingVariable, $binding->BindingValue, $param); 90 | } 91 | 92 | $results = new GenericCollection( 93 | Key: $qry->FromDefinition->Key, 94 | Values: $this->ExecuteStatementForQueryable($stmt), 95 | DtoName: $qry->FromDefinition->Entity 96 | ); 97 | 98 | // FROM results 99 | $fromKey = $qry->FromDefinition->Key; 100 | 101 | // Obtener el DISTINCT de la tabla padre 102 | $parentDistinct = $results->DistinctItem($fromKey)->Values; 103 | $parentEntities = Mapper::ToEntities($parentDistinct, $qry->FromDefinition->Entity, '', true, $nosanear); 104 | 105 | $fromResults = new GenericCollection( 106 | Key: $qry->FromDefinition->Key, 107 | Values: $parentEntities, 108 | DtoName: $qry->FromDefinition->Entity 109 | ); 110 | 111 | // JOIN results 112 | foreach ($qry->JoinDefinitions as $joinDefinition) { 113 | $joinKey = $joinDefinition->TablePrefix . '.' . $joinDefinition->Key; 114 | 115 | $distincts = $results->DistinctItem($joinKey); 116 | 117 | $joinResults = new GenericCollection( 118 | Key: $joinDefinition->Key, 119 | Values: Mapper::ToEntities( 120 | $distincts, 121 | $joinDefinition->Entity, 122 | $joinDefinition->TablePrefix, 123 | true, 124 | $nosanear 125 | ), 126 | DtoName: $joinDefinition->Entity 127 | ); 128 | 129 | // Incorporarlo al resultado principal como JOIN 130 | $fromResults->MergeChildren( 131 | new MergeDefinition( 132 | Values: $joinResults, 133 | ParentKey: (isset($joinDefinition->CustomParentKey) && $joinDefinition->CustomParentKey != '') ? $joinDefinition->CustomParentKey : $qry->FromDefinition->Key, 134 | ChildReferenceKey: (isset($joinDefinition->CustomForeignKey) && $joinDefinition->CustomForeignKey != '') ? $joinDefinition->CustomForeignKey : $qry->FromDefinition->Key 135 | ) 136 | ); 137 | } 138 | 139 | // LEFT JOIN results 140 | foreach ($qry->LeftJoinDefinitions as $joinDefinition) { 141 | $joinKey = $joinDefinition->TablePrefix . '.' . $joinDefinition->Key; 142 | $joinResults = new GenericCollection( 143 | Key: $joinDefinition->Key, 144 | Values: Mapper::ToEntities( 145 | $results->DistinctItem($joinKey), 146 | $joinDefinition->Entity, 147 | $joinDefinition->TablePrefix, 148 | true, 149 | $nosanear 150 | ), 151 | DtoName: $joinDefinition->Entity 152 | ); 153 | 154 | // Incorporarlo al resultado principal como JOIN 155 | $fromResults->MergeChildren( 156 | new MergeDefinition( 157 | Values: $joinResults, 158 | ParentKey: (isset($joinDefinition->CustomParentKey) && $joinDefinition->CustomParentKey != '') ? $joinDefinition->CustomParentKey : $qry->FromDefinition->Key, 159 | ChildReferenceKey: (isset($joinDefinition->CustomForeignKey) && $joinDefinition->CustomForeignKey != '') ? $joinDefinition->CustomForeignKey : $qry->FromDefinition->Key 160 | ) 161 | ); 162 | } 163 | 164 | // WITH results 165 | foreach ($qry->WithDefinitions as $withDefinition) { 166 | $withKey = $withDefinition->TablePrefix . '.' . $withDefinition->Key; 167 | $withResults = new GenericCollection( 168 | Values: Mapper::ToEntities( 169 | $results->DistinctItem($withKey), 170 | $withDefinition->Entity, 171 | $withDefinition->TablePrefix, 172 | true, 173 | $nosanear 174 | ), 175 | DtoName: $withDefinition->Entity 176 | ); 177 | 178 | $fromResults->Attach( 179 | new AttachDefinition( 180 | Values: $withResults, 181 | AttachPrimaryKey: (isset($withDefinition->CustomParentKey) && $withDefinition->CustomParentKey != '') ? $withDefinition->CustomParentKey : $withDefinition->Key, 182 | ForeignKey: (isset($withDefinition->CustomForeignKey) && $withDefinition->CustomForeignKey != '') ? $withDefinition->CustomForeignKey : $withDefinition->Key 183 | ) 184 | ); 185 | } 186 | 187 | if ($returnFirstRecord) { 188 | if (isset($fromResults) && $fromResults->Count() > 0) { 189 | return $fromResults->First(); 190 | } else { 191 | return null; 192 | } 193 | } else { 194 | return $fromResults->Values; 195 | } 196 | } 197 | 198 | public function Find($keyValue, $incluirNoVigentes = true, $incluirEliminados = true, $transaction = null) 199 | { 200 | if ($incluirNoVigentes && $incluirEliminados) { 201 | $where = ""; 202 | } else { 203 | if (!$incluirNoVigentes) { 204 | $where = " 205 | AND IndVigente = 1"; 206 | } 207 | if (!$incluirEliminados) { 208 | $where = " 209 | AND IndEliminado = 0"; 210 | } 211 | } 212 | 213 | if (!isset($transaction)) { 214 | $transaction = $this->Connection; 215 | } 216 | 217 | $stmt = $transaction->prepare(' 218 | SELECT ' . $this->EntityDefinition->NotIgnoredFields . ' 219 | FROM ' . $this->EntityDefinition->Table . ' 220 | WHERE ' . $this->EntityDefinition->Key . ' = :keyValue' . ' 221 | ' . $where); 222 | 223 | $stmt->bindParam(':keyValue', $keyValue); 224 | 225 | return $this->ExecuteStatementForObject($stmt); 226 | } 227 | 228 | public function FindByForeign($foreignKey, $foreignKeyValue, $transaction = null) 229 | { 230 | 231 | $foreignKeyBind = ':' . $foreignKey; 232 | 233 | $qry = ' 234 | SELECT ' . $this->EntityDefinition->NotIgnoredFields . ' 235 | FROM ' . $this->EntityDefinition->Table . ' 236 | WHERE ' . $foreignKey . ' = ' . $foreignKeyBind; 237 | 238 | if (!isset($transaction)) { 239 | $transaction = $this->Connection; 240 | } 241 | 242 | $stmt = $transaction->prepare($qry); 243 | 244 | $stmt->bindValue("$foreignKeyBind", $foreignKeyValue); 245 | 246 | return $this->ExecuteStatementForObject($stmt); 247 | } 248 | 249 | function GetByCodigoRegistro($codigoRegistro, $transaction = null) 250 | { 251 | if (!isset($transaction)) { 252 | $transaction = $this->Connection; 253 | } 254 | 255 | $stmt = $transaction->prepare(" 256 | SELECT 257 | " . $this->EntityDefinition->NotIgnoredFields . " 258 | FROM " . $this->EntityDefinition->Table . " 259 | WHERE CodigoRegistro = :keyValue 260 | "); 261 | 262 | $stmt->bindParam(':keyValue', $codigoRegistro); 263 | 264 | return $this->ExecuteStatementForObjects($stmt); 265 | } 266 | 267 | public function GetByForeign($foreignKey, $foreignKeyValue, $orderFields = '', $transaction = null) 268 | { 269 | 270 | $foreignKeyBind = ':' . $foreignKey; 271 | 272 | $qry = ' 273 | SELECT ' . $this->EntityDefinition->NotIgnoredFields . ' 274 | FROM ' . $this->EntityDefinition->Table . ' 275 | WHERE ' . $foreignKey . ' = ' . $foreignKeyBind; 276 | 277 | if ($orderFields != '') { 278 | $qry .= ' ORDER BY ' . $orderFields; 279 | } 280 | 281 | if (!isset($transaction)) { 282 | $transaction = $this->Connection; 283 | } 284 | 285 | $stmt = $transaction->prepare($qry); 286 | 287 | $stmt->bindValue("$foreignKeyBind", $foreignKeyValue); 288 | 289 | return $this->ExecuteStatementForObjects($stmt); 290 | } 291 | 292 | 293 | public function GetByToFile($bindings, $orderFields = '', $top = 0, $transaction = null, $localDataFolder = "") { 294 | if ($top == 0) { 295 | if (isset(self::$GlobalTop) && self::$GlobalTop > 0) { 296 | $top = self::$GlobalTop; 297 | } 298 | } 299 | 300 | $select = "SELECT "; 301 | 302 | if ($this->Domain->Type == 'sqlserver' && is_numeric($top) && $top > 0) { 303 | $select .= 'TOP ' . $top . ' '; 304 | } 305 | 306 | $qry = $select . $this->EntityDefinition->NotIgnoredFields . ' FROM ' . $this->EntityDefinition->Table; 307 | 308 | /* @var $var BindVariable */ 309 | $count = 0; 310 | $where = ''; 311 | $bind = array(); 312 | 313 | if ($bindings instanceof BindVariable) { 314 | $bindings = [$bindings]; 315 | } 316 | 317 | foreach ($bindings as $key => $var) { 318 | 319 | if ($count > 0) { 320 | $where .= ' 321 | AND 322 | '; 323 | } 324 | 325 | if (strtoupper($var->Operator) == 'LIKE') { 326 | 327 | // Ver si es campo fecha 328 | if ($this->Domain->Type == "sqlserver") { 329 | $where .= $var->Field . " LIKE :var" . $count . " "; 330 | } else if ($this->Domain->Type == "mysql") { 331 | $where .= $var->Field . " LIKE :var" . $count . " "; 332 | } else { 333 | $where .= $var->Field . " LIKE :var" . $count . " "; 334 | } 335 | 336 | $bind['var' . $count] = $var->Operand1; 337 | $count++; 338 | } else if (strtoupper($var->Operator) == 'BETWEEN') { 339 | 340 | // Ver si es campo fecha 341 | if ( 342 | $this->Domain->Type == "sqlserver" 343 | && isset($this->EntityDefinition->Properties[$var->Field]) 344 | && $this->EntityDefinition->Properties[$var->Field]->ColumnType == 'datetime' 345 | ) { 346 | $where .= $var->Field . ' BETWEEN CONVERT(DATETIME, :var' . $count . ', 121) AND CONVERT(DATETIME, :var' . ($count + 1) . ', 121) '; 347 | } else { 348 | $where .= $var->Field . ' BETWEEN :var' . $count . ' AND :var' . ($count + 1) . ' '; 349 | } 350 | 351 | 352 | 353 | $bind['var' . $count] = $var->Operand1; 354 | $count++; 355 | $bind['var' . $count] = $var->Operand2; 356 | 357 | $count++; 358 | } else if (strtoupper($var->Operator) == 'IN' && is_array($var->Operand1)) { 359 | 360 | $variables = ''; 361 | foreach ($var->Operand1 as $op) { 362 | if ($variables != '') 363 | $variables .= ', '; 364 | $variables .= ':var' . $count; 365 | $bind['var' . $count] = $op; 366 | $count++; 367 | } 368 | 369 | $where .= $var->Field . ' ' . $var->Operator . ' (' . $variables . ') '; 370 | } else { 371 | 372 | if ( 373 | $this->Domain->Type == "sqlserver" 374 | && isset($this->EntityDefinition->Properties[$var->Field]) 375 | && $this->EntityDefinition->Properties[$var->Field]->ColumnType == 'datetime' 376 | ) { 377 | $where .= $var->Field . ' ' . $var->Operator . ' CONVERT(DATETIME, :var' . $count . ', 121) '; 378 | } else { 379 | $where .= $var->Field . ' ' . $var->Operator . ' :var' . $count . ' '; 380 | } 381 | 382 | 383 | $bind['var' . $count] = $var->Operand1; 384 | 385 | $count++; 386 | } 387 | } 388 | 389 | if ($where != '') { 390 | $qry .= ' WHERE ' . $where; 391 | } 392 | 393 | if ($orderFields != '') { 394 | $qry .= ' ORDER BY ' . $orderFields; 395 | } 396 | 397 | if (!isset($transaction)) { 398 | $transaction = $this->Connection; 399 | } 400 | 401 | // preparar sentencia 402 | $stmt = $transaction->prepare($qry); 403 | 404 | // ligar variables 405 | foreach ($bind as $v => $value) { 406 | //echo "...binding :" . $v . " with value [" . $value . "]
"; 407 | if (is_int($value)) 408 | $param = PDO::PARAM_INT; 409 | elseif (is_bool($value)) 410 | $param = PDO::PARAM_BOOL; 411 | elseif (is_null($value)) 412 | $param = PDO::PARAM_NULL; 413 | elseif (is_string($value)) 414 | $param = PDO::PARAM_STR; 415 | else 416 | $param = FALSE; 417 | 418 | if ($param) 419 | $stmt->bindValue(":$v", $value, $param); 420 | } 421 | 422 | return $this->ExecuteStatementToFile($stmt, null, $localDataFolder); 423 | } 424 | 425 | public function GetBy($bindings, $orderFields = '', $top = 0, $transaction = null) 426 | { 427 | if ($top == 0) { 428 | if (isset(self::$GlobalTop) && self::$GlobalTop > 0) { 429 | $top = self::$GlobalTop; 430 | } 431 | } 432 | 433 | $select = "SELECT "; 434 | 435 | if ($this->Domain->Type == 'sqlserver' && is_numeric($top) && $top > 0) { 436 | $select .= 'TOP ' . $top . ' '; 437 | } 438 | 439 | $qry = $select . $this->EntityDefinition->NotIgnoredFields . ' FROM ' . $this->EntityDefinition->Table; 440 | 441 | /* @var $var BindVariable */ 442 | $count = 0; 443 | $where = ''; 444 | $bind = array(); 445 | 446 | if ($bindings instanceof BindVariable) { 447 | $bindings = [$bindings]; 448 | } 449 | 450 | foreach ($bindings as $key => $var) { 451 | 452 | if ($count > 0) { 453 | $where .= ' 454 | AND 455 | '; 456 | } 457 | 458 | if (strtoupper($var->Operator) == 'LIKE') { 459 | 460 | // Ver si es campo fecha 461 | if ($this->Domain->Type == "sqlserver") { 462 | $where .= $var->Field . " LIKE :var" . $count . " "; 463 | } else if ($this->Domain->Type == "mysql") { 464 | $where .= $var->Field . " LIKE :var" . $count . " "; 465 | } else { 466 | $where .= $var->Field . " LIKE :var" . $count . " "; 467 | } 468 | 469 | $bind['var' . $count] = $var->Operand1; 470 | $count++; 471 | } else if (strtoupper($var->Operator) == 'BETWEEN') { 472 | 473 | // Ver si es campo fecha 474 | if ( 475 | $this->Domain->Type == "sqlserver" 476 | && isset($this->EntityDefinition->Properties[$var->Field]) 477 | && $this->EntityDefinition->Properties[$var->Field]->ColumnType == 'datetime' 478 | ) { 479 | $where .= $var->Field . ' BETWEEN CONVERT(DATETIME, :var' . $count . ', 121) AND CONVERT(DATETIME, :var' . ($count + 1) . ', 121) '; 480 | } else { 481 | $where .= $var->Field . ' BETWEEN :var' . $count . ' AND :var' . ($count + 1) . ' '; 482 | } 483 | 484 | 485 | 486 | $bind['var' . $count] = $var->Operand1; 487 | $count++; 488 | $bind['var' . $count] = $var->Operand2; 489 | 490 | $count++; 491 | } else if (strtoupper($var->Operator) == 'IN' && is_array($var->Operand1)) { 492 | 493 | $variables = ''; 494 | foreach ($var->Operand1 as $op) { 495 | if ($variables != '') 496 | $variables .= ', '; 497 | $variables .= ':var' . $count; 498 | $bind['var' . $count] = $op; 499 | $count++; 500 | } 501 | 502 | $where .= $var->Field . ' ' . $var->Operator . ' (' . $variables . ') '; 503 | } else { 504 | 505 | if ( 506 | $this->Domain->Type == "sqlserver" 507 | && isset($this->EntityDefinition->Properties[$var->Field]) 508 | && $this->EntityDefinition->Properties[$var->Field]->ColumnType == 'datetime' 509 | ) { 510 | $where .= $var->Field . ' ' . $var->Operator . ' CONVERT(DATETIME, :var' . $count . ', 121) '; 511 | } else { 512 | $where .= $var->Field . ' ' . $var->Operator . ' :var' . $count . ' '; 513 | } 514 | 515 | 516 | $bind['var' . $count] = $var->Operand1; 517 | 518 | $count++; 519 | } 520 | } 521 | 522 | if ($where != '') { 523 | $qry .= ' WHERE ' . $where; 524 | } 525 | 526 | if ($orderFields != '') { 527 | $qry .= ' ORDER BY ' . $orderFields; 528 | } 529 | 530 | if (!isset($transaction)) { 531 | $transaction = $this->Connection; 532 | } 533 | 534 | // preparar sentencia 535 | $stmt = $transaction->prepare($qry); 536 | 537 | // ligar variables 538 | foreach ($bind as $v => $value) { 539 | //echo "...binding :" . $v . " with value [" . $value . "]
"; 540 | if (is_int($value)) 541 | $param = PDO::PARAM_INT; 542 | elseif (is_bool($value)) 543 | $param = PDO::PARAM_BOOL; 544 | elseif (is_null($value)) 545 | $param = PDO::PARAM_NULL; 546 | elseif (is_string($value)) 547 | $param = PDO::PARAM_STR; 548 | else 549 | $param = FALSE; 550 | 551 | if ($param) 552 | $stmt->bindValue(":$v", $value, $param); 553 | } 554 | 555 | $result = $this->ExecuteStatementForObjects($stmt); 556 | 557 | return $result; 558 | } 559 | 560 | public function FindBy($bindings, $orderFields = '', $transaction = null) 561 | { 562 | $select = "SELECT "; 563 | 564 | if ($this->Domain->Type == 'sqlserver') { 565 | $select .= 'TOP 1 '; 566 | } 567 | $qry = $select . $this->EntityDefinition->NotIgnoredFields . ' FROM ' . $this->EntityDefinition->Table; 568 | 569 | /* @var $var BindVariable */ 570 | $count = 0; 571 | $where = ''; 572 | $bind = array(); 573 | foreach ($bindings as $key => $var) { 574 | 575 | if ($count > 0) { 576 | $where .= ' 577 | AND 578 | '; 579 | } 580 | 581 | if ($var->Operator == 'BETWEEN') { 582 | $where .= $var->Field . ' BETWEEN :var' . $count . ' AND :var' . ($count + 1) . ' '; 583 | 584 | $bind['var' . $count] = $var->Operand1; 585 | $count++; 586 | $bind['var' . $count] = $var->Operand2; 587 | } else if (strtoupper($var->Operator) == 'IN' && is_array($var->Operand1)) { 588 | 589 | $variables = ''; 590 | foreach ($var->Operand1 as $op) { 591 | if ($variables == '') 592 | $variables .= ', '; 593 | $variables .= ':var' . $count; 594 | $bind['var' . $count] = $op; 595 | $count++; 596 | } 597 | 598 | $where .= $var->Field . ' ' . $var->Operator . $variables . ' '; 599 | } else { 600 | 601 | if ( 602 | $this->Domain->Type == "sqlserver" 603 | && isset($this->EntityDefinition->Properties[$var->Field]) 604 | && $this->EntityDefinition->Properties[$var->Field]->ColumnType == 'datetime' 605 | ) { 606 | $where .= $var->Field . ' ' . $var->Operator . ' CONVERT(DATETIME, :var' . $count . ', 121) '; 607 | } else { 608 | $where .= $var->Field . ' ' . $var->Operator . ' :var' . $count . ' '; 609 | } 610 | 611 | //$where .= $var->Field . ' ' . $var->Operator . ' :var' . $count . ' '; 612 | $bind['var' . $count] = $var->Operand1; 613 | } 614 | 615 | $count++; 616 | } 617 | 618 | if ($where != '') { 619 | $qry .= ' WHERE ' . $where; 620 | } 621 | 622 | if ($this->Domain->Type == 'oracle') { 623 | if ($where == '') { 624 | $where = ' WHERE ROWNUM <= 1'; 625 | } else { 626 | $where .= ' AND ROWNUM <= 1'; 627 | } 628 | } 629 | 630 | if ($orderFields != '') { 631 | $qry .= ' ORDER BY ' . $orderFields; 632 | } 633 | 634 | if ($this->Domain->Type == 'mysql') 635 | $qry .= ' LIMIT 1'; 636 | 637 | if (!isset($transaction)) { 638 | $transaction = $this->Connection; 639 | } 640 | // preparar sentencia 641 | $stmt = $transaction->prepare($qry); 642 | 643 | // ligar variables 644 | foreach ($bind as $v => $value) { 645 | //echo "...binding :" . $v . " with value [" . $value . "]
"; 646 | if (is_int($value)) 647 | $param = PDO::PARAM_INT; 648 | elseif (is_bool($value)) 649 | $param = PDO::PARAM_BOOL; 650 | elseif (is_null($value)) 651 | $param = PDO::PARAM_NULL; 652 | elseif (is_string($value)) 653 | $param = PDO::PARAM_STR; 654 | else 655 | $param = FALSE; 656 | 657 | if ($param) 658 | $stmt->bindValue(":$v", $value, $param); 659 | } 660 | 661 | return $this->ExecuteStatementForObject($stmt); 662 | } 663 | 664 | public function GetAll($order = "", $transaction = null) 665 | { 666 | $qry = 'SELECT ' . $this->EntityDefinition->NotIgnoredFields . ' FROM ' . $this->EntityDefinition->Table . (($order != '') ? ' ORDER BY ' . $order : ''); 667 | 668 | if (!isset($transaction)) { 669 | $transaction = $this->Connection; 670 | } 671 | 672 | $stmt = $transaction->prepare($qry); 673 | 674 | return $this->ExecuteStatementForObjects($stmt); 675 | } 676 | 677 | public function GetByStmt($stmt) 678 | { 679 | return $this->ExecuteStatementForObjects($stmt); 680 | } 681 | 682 | public function FindByStmt($stmt) 683 | { 684 | return $this->ExecuteStatementForObject($stmt); 685 | } 686 | 687 | public function GetStatementFromFile($filePath) 688 | { 689 | // Abrir el archivo y retornar la query 690 | if (\file_exists(__DIR__ . '/' . $filePath)) { 691 | return \file_get_contents(__DIR__ . '/' . $filePath); 692 | } else { 693 | throw new \Exception("Archivo no existe"); 694 | } 695 | } 696 | 697 | function SumFieldByForeign($fieldName, $foreignKeyName, $foreignKeyValue, $transaction = null) 698 | { 699 | 700 | if (!isset($transaction)) { 701 | $transaction = $this->Connection; 702 | } 703 | 704 | $stmt = $transaction->prepare(' 705 | SELECT SUM(' . $fieldName . ') AS SUMRESULT 706 | FROM ' . $this->EntityDefinition->Table . ' 707 | WHERE ' . $foreignKeyName . ' = :foreignKeyValue 708 | '); 709 | 710 | $stmt->bindParam(':foreignKeyValue', $foreignKeyValue); 711 | return $this->ExecuteScalar($stmt); 712 | } 713 | 714 | function CountByForeign($foreignKeyName, $foreignKeyValue, $transaction = null) 715 | { 716 | if (!isset($transaction)) { 717 | $transaction = $this->Connection; 718 | } 719 | 720 | $stmt = $transaction->prepare(' 721 | SELECT COUNT(1) AS COUNTRESULT 722 | FROM ' . $this->EntityDefinition->Table . ' 723 | WHERE ' . $foreignKeyName . ' = :foreignKeyValue 724 | '); 725 | 726 | $stmt->bindParam(':foreignKeyValue', $foreignKeyValue); 727 | return $this->ExecuteScalar($stmt); 728 | } 729 | 730 | function Count($transaction = null) 731 | { 732 | if (!isset($transaction)) { 733 | $transaction = $this->Connection; 734 | } 735 | 736 | $stmt = $transaction->prepare(' 737 | SELECT COUNT(1) AS COUNTRESULT 738 | FROM ' . $this->EntityDefinition->Table); 739 | 740 | return $this->ExecuteScalar($stmt); 741 | } 742 | 743 | public function CountBy($bindings, $transaction = null) 744 | { 745 | $qry = 'SELECT COUNT(1) AS COUNTRESULT FROM ' . $this->EntityDefinition->Table; 746 | 747 | /* @var $var BindVariable */ 748 | $count = 0; 749 | $where = ''; 750 | $bind = array(); 751 | foreach ($bindings as $key => $var) { 752 | 753 | if ($count > 0) { 754 | $where .= ' 755 | AND 756 | '; 757 | } 758 | 759 | if ($var->Operator == 'BETWEEN') { 760 | $where .= $var->Field . ' BETWEEN :var' . $count . ' AND :var' . ($count + 1) . ' '; 761 | 762 | $bind['var' . $count] = $var->Operand1; 763 | $count++; 764 | $bind['var' . $count] = $var->Operand2; 765 | } else if (strtoupper($var->Operator) == 'IN' && is_array($var->Operand1)) { 766 | 767 | $variables = ''; 768 | foreach ($var->Operand1 as $op) { 769 | if ($variables != '') 770 | $variables .= ', '; 771 | $variables .= ':var' . $count; 772 | $bind['var' . $count] = $op; 773 | $count++; 774 | } 775 | 776 | $where .= $var->Field . ' ' . $var->Operator . ' (' . $variables . ') '; 777 | } else { 778 | $where .= $var->Field . ' ' . $var->Operator . ' :var' . $count . ' '; 779 | $bind['var' . $count] = $var->Operand1; 780 | } 781 | 782 | $count++; 783 | } 784 | 785 | if ($where != '') { 786 | $qry .= ' WHERE ' . $where; 787 | } 788 | 789 | if (!isset($transaction)) { 790 | $transaction = $this->Connection; 791 | } 792 | // preparar sentencia 793 | $stmt = $transaction->prepare($qry); 794 | 795 | // ligar variables 796 | foreach ($bind as $v => $value) { 797 | //echo "...binding :" . $v . " with value [" . $value . "]
"; 798 | if (is_int($value)) 799 | $param = PDO::PARAM_INT; 800 | elseif (is_bool($value)) 801 | $param = PDO::PARAM_BOOL; 802 | elseif (is_null($value)) 803 | $param = PDO::PARAM_NULL; 804 | elseif (is_string($value)) 805 | $param = PDO::PARAM_STR; 806 | else 807 | $param = FALSE; 808 | 809 | if ($param) 810 | $stmt->bindValue(":$v", $value, $param); 811 | } 812 | 813 | return $this->ExecuteScalar($stmt); 814 | } 815 | 816 | public function GetIN($foreignKey, $foreignKeyValue, $orderFields = '', $transaction = null) 817 | { 818 | // Se genera un campo vacio para cargar los KeyValues 819 | $values = ''; 820 | 821 | //Verifico que KeyValue se un arreglo 822 | if (is_array($foreignKeyValue) or is_object($foreignKeyValue)): 823 | //Si es numerico uso la función Implode para convertir el Arreglo en String 824 | if (is_numeric($foreignKeyValue[0])): 825 | $values = implode(', ', $foreignKeyValue); 826 | else: 827 | //Si no es un Arreglo Calculco el total de valores pasados 828 | 829 | $t = count($foreignKeyValue) - 1; 830 | 831 | //Recorro los valores y los incorporo a la variable Values 832 | foreach ($foreignKeyValue as $k => $vl) { 833 | 834 | //Si la Llave ES IGUAL al total de registros no se agrega una coma al final 835 | if ($k == $t) { 836 | $values .= "'" . $vl . "'"; 837 | } else { 838 | $values .= "'" . $vl . "' , "; 839 | } 840 | } 841 | 842 | endif; 843 | else: 844 | $values = $foreignKeyValue; 845 | endif; 846 | 847 | //Se define los arreglos 848 | $qry = ' 849 | SELECT ' . $this->EntityDefinition->NotIgnoredFields . ' 850 | FROM ' . $this->EntityDefinition->Table . ' 851 | WHERE ' . $foreignKey . ' IN (' . $values . ')'; 852 | 853 | 854 | if ($orderFields != '') { 855 | $qry .= ' ORDER BY ' . $orderFields; 856 | } 857 | 858 | if (!isset($transaction)) { 859 | $transaction = $this->Connection; 860 | } 861 | 862 | $stmt = $transaction->prepare($qry); 863 | 864 | return $this->ExecuteStatementForObjects($stmt); 865 | } 866 | 867 | function Max($field, $ignoreBlanks = false, $transaction = null) 868 | { 869 | 870 | $qry = 'SELECT Max(' . $field . ') AS MAXRESULT FROM ' . $this->EntityDefinition->Table; 871 | 872 | if ($ignoreBlanks) { 873 | $qry .= " WHERE " . $field . " IS NOT NULL AND " . $field . " <> ''"; 874 | } 875 | 876 | if (!isset($transaction)) { 877 | $transaction = $this->Connection; 878 | } 879 | 880 | $stmt = $transaction->prepare($qry); 881 | return $this->ExecuteScalar($stmt); 882 | } 883 | 884 | function Min($field, $ignoreBlanks = false, $transaction = null) 885 | { 886 | 887 | $qry = 'SELECT Min(' . $field . ') AS MINRESULT FROM ' . $this->EntityDefinition->Table; 888 | 889 | if ($ignoreBlanks) { 890 | $qry .= " WHERE " . $field . " IS NOT NULL AND " . $field . " <> ''"; 891 | } 892 | 893 | if (!isset($transaction)) { 894 | $transaction = $this->Connection; 895 | } 896 | 897 | $stmt = $transaction->prepare($qry); 898 | return $this->ExecuteScalar($stmt); 899 | } 900 | } 901 | } 902 | -------------------------------------------------------------------------------- Total de líneas: 902 ================================================================================ ================================================================================ ARCHIVO #109: src/Dao/BindVariable.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Dao/BindVariable.php Tamaño: 2.32 KB -------------------------------------------------------------------------------- 1 | Field = $field; 21 | $this->Operator = $operator; 22 | $this->Operand1 = $operand1; 23 | $this->Operand2 = $operand2; 24 | } 25 | 26 | /** 27 | * Crea una condición predefinida para filtrar registros activos. 28 | * 29 | * Retorna una instancia de BindVariable con el campo `IndActivo` igual a 1 30 | * 31 | * @return BindVariable Condición para registros activos (IndActivo = 1). 32 | */ 33 | public static function Activo() { 34 | return new BindVariable('IndActivo', '=', 1); 35 | } 36 | 37 | /** 38 | * Crea una condición predefinida para filtrar registros eliminados. 39 | * 40 | * Retorna una instancia de BindVariable con el campo `IndEliminado` igual a 1 41 | * 42 | * @return BindVariable Condición para registros eliminados (IndEliminado = 1). 43 | */ 44 | public static function Eliminado() { 45 | return new BindVariable('IndEliminado', '=', 1); 46 | } 47 | 48 | /** 49 | * Crea una condición predefinida para filtrar registros NO activos. 50 | * 51 | * Retorna una instancia de BindVariable con el campo `IndActivo` igual a 0 52 | * 53 | * @return BindVariable Condición para registros NO activos (IndActivo = 0). 54 | */ 55 | public static function NoActivo() { 56 | return new BindVariable('IndActivo', '=', 0); 57 | } 58 | 59 | /** 60 | * Crea una condición predefinida para filtrar registros NO eliminados. 61 | * 62 | * Retorna una instancia de BindVariable con el campo `IndEliminado` igual a 0 63 | * 64 | * @return BindVariable Condición para registros NO eliminados (IndEliminado = 0). 65 | */ 66 | public static function NoEliminado() { 67 | return new BindVariable('IndEliminado', '=', 0); 68 | } 69 | } 70 | 71 | } -------------------------------------------------------------------------------- Total de líneas: 71 ================================================================================ ================================================================================ ARCHIVO #110: src/Dao/ConnectionTypeEnum.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Dao/ConnectionTypeEnum.php Tamaño: 411 bytes -------------------------------------------------------------------------------- 1 | Type == 'mysql') { 36 | $conn = new PDO( 37 | "mysql:dbname=" . $dom->Database . ";host=" . $dom->Host . ":" . $dom->Port . ";charset=utf8", 38 | $dom->User, 39 | $dom->Password, 40 | array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'utf8'") 41 | ); 42 | $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 43 | 44 | return $conn; 45 | } else if ($dom->Type == 'sqlserver') { 46 | if ($transactionLevel != null) { 47 | $conn = new PDO( 48 | "sqlsrv:Server=" . $dom->Host . "," . $dom->Port . ";Database=" . $dom->Database . ";Encrypt=true;TrustServerCertificate=true;TransactionIsolation=" . $transactionLevel, 49 | $dom->User, 50 | $dom->Password 51 | ); 52 | } else { 53 | $conn = new PDO( 54 | "sqlsrv:Server=" . $dom->Host . "," . $dom->Port . ";Database=" . $dom->Database . ';Encrypt=true;TrustServerCertificate=true', 55 | $dom->User, 56 | $dom->Password 57 | ); 58 | } 59 | 60 | $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 61 | return $conn; 62 | } else { 63 | return null; 64 | } 65 | } else { 66 | return null; 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- Total de líneas: 70 ================================================================================ ================================================================================ ARCHIVO #112: src/Dao/DefinitionTypeEnum.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Dao/DefinitionTypeEnum.php Tamaño: 453 bytes -------------------------------------------------------------------------------- 1 | getDocComment(); 18 | return self::GetAnnotationsFromDocumentation($classdoc); 19 | 20 | } 21 | 22 | public static function GetPropertyAnnotations(\ReflectionProperty $property, $annotationSeparator = ",") { 23 | 24 | $propdoc = $property->getDocComment(); 25 | return self::GetAnnotationsFromDocumentation($propdoc, $annotationSeparator); 26 | 27 | } 28 | 29 | private static function GetAnnotationsFromDocumentation($propdoc, $annotationSeparator = ",") { 30 | 31 | // Remover los delimitadores 32 | $propdoc = str_replace('/**', '', $propdoc); 33 | $propdoc = str_replace('*/', '', $propdoc); 34 | $propdoc = str_replace("\n *", "\n", $propdoc); 35 | 36 | // Los bloques deben estar separados por comas 37 | $bloques = explode($annotationSeparator, $propdoc); 38 | 39 | $annotations = array(); 40 | 41 | if (isset($bloques)) { 42 | // Revisar si es un valor constante o una asignacion 43 | foreach($bloques as $bloque) { 44 | 45 | $bloque = trim($bloque); 46 | 47 | if (strpos($bloque, '=') === false) { 48 | // no es una asignacion 49 | $annotation = new Annotation(); 50 | if (trim($bloque) != "") { 51 | $annotation->Name = trim($bloque); 52 | $annotation->Value = null; 53 | $annotations[$annotation->Name] = $annotation; 54 | } 55 | } 56 | else { 57 | // es una asignacion 58 | $asignacion = explode('=', $bloque, 2); 59 | 60 | if (isset($asignacion[0])) { 61 | if (trim($asignacion[0]) != "") { 62 | $annotation = new Annotation(); 63 | $annotation->Name = trim($asignacion[0]); 64 | $annotation->Value = trim($asignacion[1]); 65 | $annotations[$annotation->Name] = $annotation; 66 | } 67 | } 68 | } 69 | } 70 | } 71 | 72 | return $annotations; 73 | } 74 | } -------------------------------------------------------------------------------- Total de líneas: 74 ================================================================================ ================================================================================ ARCHIVO #115: src/Dao/Entity/EntityDefinition.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Dao/Entity/EntityDefinition.php Tamaño: 9.28 KB -------------------------------------------------------------------------------- 1 | Add($entityDefinition); 50 | 51 | // Actualizar REDIS 52 | // $redis = RedisSvc::Init(); 53 | 54 | // // Si tenemos redis, actualizamos el valor de la coleccion 55 | // if (isset($redis)) { 56 | // $redis->set("gps-cache-entity-collection", serialize(self::$EntityColletion)); 57 | // $redis->close(); 58 | // } 59 | } 60 | 61 | private static function GetEntityCollection() { 62 | 63 | // if (!isset(self::$EntityColletion)) { 64 | 65 | // // Buscar las definiciones en Redis 66 | // $redis = RedisSvc::Init(); 67 | 68 | // // Si tenemos redis, ver si podemos obtener la configuracion desde ahí 69 | // if (isset($redis)) { 70 | // $definition = $redis->get("gps-cache-entity-collection"); 71 | 72 | // if (isset($definition) && $definition) { 73 | // $info = unserialize($definition); 74 | // $redis->close(); 75 | // } 76 | 77 | // if (isset($info) && ($info)) { 78 | // self::$EntityColletion = $info; 79 | // } 80 | // } 81 | 82 | // Si no fue posible obtener la coleccion, deberemos crear una nueva 83 | if (!isset(self::$EntityColletion)) { 84 | // Creamos una coleccion nueva 85 | self::$EntityColletion = new GenericCollection( 86 | Key: "Entity", // << la propiedad "Entity" de la clase "EntityDefinition" que contiene el nombre de la entidad 87 | DtoName: EntityDefinition::class, 88 | Values: null, 89 | ReflectDto: false // No se debe realizar REFLECTION del DTO, se produciría un bucle infinito 90 | ); 91 | } 92 | // } 93 | 94 | return self::$EntityColletion; 95 | } 96 | 97 | public static function Instance($entityName) { 98 | 99 | // Buscamos la entidad en la colección 100 | $col = self::GetEntityCollection(); 101 | 102 | $entidad = $col->FirstWhere("Entity == '$entityName'"); 103 | 104 | if (!isset($entidad) && $entidad == null) { 105 | // Si no encontramos la entidad, deberemos obtenerla mediante Reflection 106 | //$entidad = EntityDefinition::GetInstance(new \ReflectionClass($entityName)); 107 | $entidad = EntityDefinition::GetInstance($entityName); 108 | 109 | // Debemos agregar la entidad a la coleccion (y actualizar redis) 110 | //self::AddEntityDefinitionToCollection($entidad); 111 | } 112 | 113 | return $entidad; 114 | } 115 | 116 | //public static function GetInstance(\ReflectionClass $entity) { 117 | public static function GetInstance(String $entity) { 118 | 119 | //$reflected = new \ReflectionClass($entity); 120 | 121 | // Instanciar el resultado 122 | $result = new EntityDefinition(); 123 | 124 | $annotations = AnnotationHelper::FromClass($entity); 125 | $reflected = $annotations->Reflected; 126 | 127 | // Buscar atributo de entidad de la clase 128 | $entidad = $annotations->FindAttributeClass(Entity::class); 129 | 130 | $result->Entity = $reflected->getName(); 131 | 132 | // Prefijo de tabla << TODO 133 | $result->TablePrefix = $reflected->getShortName(); 134 | 135 | // Obtener la información respecto de la Entidad 136 | //$annotations = DocComment::GetClassAnnotations($entity); 137 | if (!isset($entidad->attribute->Schema) || $entidad->attribute->Schema == '') { 138 | //$result->Schema = 'dbo'; 139 | $result->Schema = ''; 140 | } 141 | else { 142 | $result->Schema = $entidad->attribute->Schema; 143 | } 144 | 145 | if (!isset($entidad->attribute->TableName) || $entidad->attribute->TableName == '') { 146 | $result->Table = (($result->Schema!='') ? $result->Schema . '.' : '') . $reflected->getShortName(); 147 | } 148 | else { 149 | $result->Table = (($result->Schema!='') ? $result->Schema . '.' : '') . $entidad->attribute->TableName; 150 | } 151 | 152 | if (!isset($entidad->attribute->TablePrefix) || $entidad->attribute->TablePrefix == '') { 153 | $result->TablePrefix = $reflected->getShortName(); 154 | } 155 | else { 156 | $result->TablePrefix = $entidad->attribute->TablePrefix; 157 | } 158 | 159 | if ($result->Table != $result->TablePrefix) 160 | $result->NamedTable = $result->Table . " " . $result->TablePrefix; 161 | else 162 | $result->NamedTable = $result->Table; 163 | 164 | $result->IsAuditable = (isset($entidad->attribute->Auditable) && $entidad->attribute->Auditable); 165 | $result->Display = $entidad->attribute->Display ?? ''; 166 | 167 | // Obtener la información respecto de las propiedades 168 | $propiedades = get_class_vars($reflected->getName()); 169 | $atributosPropiedades = $annotations->GetAttributeProperties(EntityField::class); 170 | 171 | foreach($propiedades as $propiedad=>$valor) { 172 | 173 | $property = PropertyDefinition::GetInstance($atributosPropiedades, $propiedad, new \ReflectionProperty($reflected->getName(), $propiedad)); 174 | 175 | if ($property->IsKey && !isset($result->KeyProperty)) { 176 | $result->KeyProperty = $property; 177 | $result->AutoIncrement = $property->IsAutoIncrement; 178 | 179 | // Asignar el nombre de la propiedad "primary key" que tiene en la base de datos 180 | if (isset($property->ColumnName)) { 181 | $result->Key = $property->ColumnName; 182 | } 183 | else{ 184 | $result->Key = $property->Name; 185 | } 186 | 187 | $result->KeyName = $property->Name; 188 | } 189 | 190 | 191 | 192 | // Si no se especifica el nombre de columna de la BD, sobreescribimos con 193 | // el nombre de la propiedad en la clase (se asume entonces que son iguales) 194 | if (!isset($property->ColumnName) || $property->ColumnName == "") { 195 | $property->ColumnName = $property->Name; 196 | } 197 | 198 | // Agregar a la lista de columnas 199 | if ($result->Fields != "") 200 | $result->Fields .= ", "; 201 | 202 | $result->Fields .= $property->ColumnName . ' AS ' . $property->Name; 203 | 204 | // Agregar a la lista de columnas no ignoradas (para usar en inserts y updates) 205 | if (!$property->Ignore) { 206 | 207 | // NOT IGNORED 208 | if ($result->NotIgnoredFields != "") 209 | $result->NotIgnoredFields .= ", "; 210 | 211 | $result->NotIgnoredFields .= $property->ColumnName; 212 | 213 | // NAMED NOT IGNORED 214 | if ($result->NamedNotIgnoredFields != "") 215 | $result->NamedNotIgnoredFields .= ", "; 216 | 217 | $result->NamedNotIgnoredFields .= $result->TablePrefix . "." . $property->ColumnName . ' AS "' . $property->Name . '"'; 218 | 219 | // NAMED RENAMED NOT IGNORED 220 | if ($result->NamedRenamedNotIgnoredFields != "") 221 | $result->NamedRenamedNotIgnoredFields .= ", "; 222 | 223 | $result->NamedRenamedNotIgnoredFields .= $result->TablePrefix . "." . $property->ColumnName . ' AS "' . $result->TablePrefix . "." . $property->Name . '"'; 224 | 225 | // NAMED 226 | // Agregar a la lista de columnas con nombre (solo las no ignoradas) 227 | if ($result->NamedFields != "") 228 | $result->NamedFields .= ", "; 229 | 230 | $result->NamedFields .= $result->TablePrefix . "." . $property->ColumnName . ' AS ' . $property->Name; 231 | 232 | // NAMED LISTED 233 | // Agregar a la lista de columnas sin nombre (solo las no ignoradas) 234 | if ($result->NamedListedFields != "") 235 | $result->NamedListedFields .= ", "; 236 | 237 | $result->NamedListedFields .= $result->TablePrefix . "." . $property->ColumnName; 238 | } 239 | 240 | // Agregar a la lista de campos de clase 241 | if ($result->ClassFields != "") 242 | $result->ClassFields .= ", "; 243 | 244 | $result->ClassFields .= $property->Name; 245 | 246 | // Agregar la propiedad a la colección 247 | $result->Properties[$property->Name] = $property; 248 | } 249 | 250 | return $result; 251 | } 252 | 253 | function __construct() { 254 | } 255 | } -------------------------------------------------------------------------------- Total de líneas: 255 ================================================================================ ================================================================================ ARCHIVO #116: src/Dao/Entity/IAuditable.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Dao/Entity/IAuditable.php Tamaño: 389 bytes -------------------------------------------------------------------------------- 1 | Name = $propiedad; 40 | 41 | if (isset($atributosPropiedades)) { 42 | $definicion = $atributosPropiedades->FirstWhere("propertyName == '" . $propiedad . "'"); 43 | 44 | if (isset($definicion)) { 45 | $result->IsKey = $definicion->attribute->PrimaryKey; 46 | $result->IsAutoIncrement = $definicion->attribute->AutoIncrement; 47 | $result->ColumnName = ($definicion->attribute->ColumnName != '') ? $definicion->attribute->ColumnName : $propiedad; 48 | $result->ColumnType = $definicion->attribute->DataType; 49 | $result->IsNullable = $definicion->attribute->Nullable; 50 | $result->DefaultWhenNull = $definicion->attribute->DefaultWhenNull; 51 | $result->ForceDateValidation = $definicion->attribute->ForceDateValidation; 52 | $result->Ignore = $definicion->attribute->Ignore; 53 | $result->IsHtml = ($definicion->attribute->ColumnName == 'Html'); 54 | $result->IsAuditable = (isset($definicion->attribute->Auditable) && $definicion->attribute->Auditable); 55 | $result->Display = $definicion->attribute->Display; 56 | $result->DisplayFormat = $definicion->attribute->DisplayFormat; 57 | } 58 | } 59 | 60 | /* 61 | // Obtener la información respecto de la Propiedad 62 | $annotations = DocComment::GetPropertyAnnotations($property); 63 | 64 | foreach($annotations as $annotation) { 65 | 66 | switch(strtolower($annotation->Name)) { 67 | case "key" : $result->IsKey = true; break; 68 | case "autoincrement" : $result->IsAutoIncrement = true; 69 | case "column" : if (isset($annotation->Value)) $result->ColumnName = $annotation->Value; break; 70 | case "columntype" : if (isset($annotation->Value)) $result->ColumnType = $annotation->Value; break; 71 | case "isnullable" : $result->IsNullable = true; 72 | case "defaultwhennull" : if (isset($annotation->Value)) $result->DefaultWhenNull = $annotation->Value; break; 73 | case "ignore" : $result->Ignore = true; 74 | } 75 | 76 | } 77 | */ 78 | 79 | if (!isset($result->ColumnName) || $result->ColumnName == "") { 80 | $result->ColumnName = $result->Name; 81 | } 82 | 83 | return $result; 84 | } 85 | } 86 | -------------------------------------------------------------------------------- Total de líneas: 86 ================================================================================ ================================================================================ ARCHIVO #118: src/Dao/ExecuteDao.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Dao/ExecuteDao.php Tamaño: 6.53 KB -------------------------------------------------------------------------------- 1 | beginTransaction()) { 33 | self::$isTransactionOpened = true; 34 | return $conn; 35 | } 36 | } 37 | else { 38 | return null; 39 | } 40 | } 41 | 42 | public static function CommitTransaction($transaction) { 43 | if ($transaction->commit()) { 44 | $transaction = null; 45 | self::$isTransactionOpened = false; 46 | } 47 | } 48 | 49 | public static function RollbackTransaction($transaction) { 50 | if ($transaction->rollback()) { 51 | $transaction = null; 52 | self::$isTransactionOpened = false; 53 | } 54 | } 55 | 56 | public function ExecuteStatement($stmt, $fetchStyle = \PDO::FETCH_ASSOC) 57 | { 58 | $retorno = $stmt->execute(); 59 | if (!$retorno) 60 | return null; 61 | else 62 | return $stmt->fetchAll($fetchStyle); 63 | } 64 | 65 | public function Execute($stmt) 66 | { 67 | $stmt->execute(); 68 | } 69 | 70 | public function ExecuteStatementForObject($stmt) 71 | { 72 | $stmt->setFetchMode(PDO::FETCH_CLASS, $this->EntityDefinition->Entity); 73 | $stmt->execute(); 74 | $retorno = $stmt->fetchObject($this->EntityDefinition->Entity); 75 | if (!$retorno) 76 | return null; 77 | else 78 | return $retorno; 79 | } 80 | 81 | public function ExecuteStatementForObjectByKeys($stmt,$keys) 82 | { 83 | $stmt->setFetchMode(PDO::FETCH_CLASS, $this->EntityDefinition->Entity); 84 | $stmt->execute($keys); 85 | $retorno = $stmt->fetchObject($this->EntityDefinition->Entity); 86 | if (!$retorno) 87 | return null; 88 | else 89 | return $retorno; 90 | } 91 | 92 | public function ExecuteStatementForObjects($stmt) 93 | { 94 | $stmt->setFetchMode(PDO::FETCH_CLASS, $this->EntityDefinition->Entity); 95 | $stmt->execute(); 96 | $retorno = $stmt->fetchAll(PDO::FETCH_CLASS, $this->EntityDefinition->Entity); 97 | 98 | if (!$retorno) 99 | return null; 100 | else 101 | return $retorno; 102 | } 103 | 104 | public function ExecuteStatementForQueryable($stmt) 105 | { 106 | 107 | $stmt->setFetchMode(PDO::FETCH_OBJ); 108 | $stmt->execute(); 109 | $retorno = $stmt->fetchAll(); 110 | 111 | if (!$retorno) 112 | return null; 113 | else 114 | return $retorno; 115 | } 116 | 117 | public function ExecuteScalar($stmt) { 118 | $stmt->execute(); 119 | return $stmt->fetchColumn(); 120 | } 121 | 122 | public function ExecuteStatementForObjectsToFile($stmt, $filename = null) 123 | { 124 | $stmt->setFetchMode(PDO::FETCH_CLASS, $this->EntityDefinition->Entity); 125 | $stmt->execute(); 126 | 127 | $pathFile = $this->CreateFileSet($stmt, $filename); 128 | 129 | return $pathFile; 130 | } 131 | 132 | public function ExecuteStatementToFile($stmt, $filename = null, $localDataFolder = '') 133 | { 134 | if (isset($localDataFolder) && $localDataFolder != '') { 135 | $this->dir = $localDataFolder; 136 | } 137 | 138 | $stmt->setFetchMode(PDO::FETCH_OBJ); 139 | $stmt->execute(); 140 | 141 | $pathFile = $this->CreateFileSet($stmt, $filename,PDO::FETCH_OBJ); 142 | return $pathFile; 143 | } 144 | 145 | 146 | 147 | private function CreateFileJson($stmt, $filename, $pdoType = PDO::FETCH_CLASS) 148 | { 149 | if (!is_dir($this->dir)) 150 | mkdir($this->dir, 0755, true); 151 | 152 | if (!isset($filename)) 153 | $filename = $this->dir . _guid() . ".json"; 154 | else 155 | $filename = $this->dir . $filename; 156 | 157 | $file = fopen($filename, 'w'); 158 | 159 | fwrite($file, "\xEF\xBB\xBF"); 160 | 161 | fwrite($file, "["); 162 | $primerElemento = true; 163 | 164 | while ($row = $stmt->fetch(PDO::FETCH_CLASS)) { 165 | $json = json_encode($row, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); 166 | if ($primerElemento) 167 | $primerElemento = false; 168 | else 169 | $json = "," . $json; 170 | 171 | fwrite($file, $json); 172 | } 173 | fwrite($file, "]"); 174 | fclose($file); 175 | return $filename; 176 | } 177 | 178 | private function CreateFileSet($stmt, $filename, $pdoType = PDO::FETCH_CLASS) 179 | { 180 | if (!is_dir($this->dir)) 181 | mkdir($this->dir, 0755, true); 182 | 183 | if (!isset($filename)) 184 | $filename = $this->dir . _guid() . ".set"; 185 | else 186 | $filename = $this->dir . $filename; 187 | 188 | $file = fopen($filename, 'w'); 189 | 190 | //fwrite($file, "\xEF\xBB\xBF"); 191 | 192 | while ($row = $stmt->fetch($pdoType)) { 193 | $json = json_encode($row, JSON_UNESCAPED_UNICODE); 194 | fwrite($file, $json."\n"); 195 | } 196 | 197 | fclose($file); 198 | return $filename; 199 | } 200 | 201 | private function CreateFileCsv($stmt, $filename) 202 | { 203 | if (!is_dir($this->dir)) 204 | mkdir($this->dir, 0755, true); 205 | 206 | if (!isset($filename)) 207 | $filename = $this->dir . _guid() . ".csv"; 208 | else 209 | $filename = $this->dir . $filename; 210 | 211 | $file = fopen($filename, 'w'); 212 | 213 | fwrite($file, "\xEF\xBB\xBF"); 214 | 215 | $setHeardes = true; 216 | 217 | while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { 218 | if ($setHeardes) { 219 | $keys = array_keys($row); 220 | fputcsv($file, $keys); 221 | $setHeardes = false; 222 | } 223 | 224 | fputcsv($file, $row); 225 | } 226 | 227 | fclose($file); 228 | return $filename; 229 | } 230 | } 231 | } 232 | -------------------------------------------------------------------------------- Total de líneas: 232 ================================================================================ ================================================================================ ARCHIVO #119: src/Dao/Format.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Dao/Format.php Tamaño: 480 bytes -------------------------------------------------------------------------------- 1 | ColumnType) == 'datetime') { 28 | if ($this->Domain->Type == 'oracle' && strtolower($property->ColumnType) == 'datetime') { 29 | return "TO_DATE(:" . $property->ColumnName . ", 'yyyy-mm-dd hh24:mi:ss')"; 30 | } 31 | else if ($this->Domain->Type == 'sqlserver' && strtolower($property->ColumnType) == 'datetime') { 32 | return "convert(datetime, :" . $property->ColumnName . ", 20)"; 33 | } 34 | } 35 | 36 | // cualquier otro caso 37 | return ':' . $property->ColumnName; 38 | } 39 | 40 | private function Value($property, $entity) { 41 | 42 | $value = $this->ReflectedEntity 43 | ->getProperty($property->Name) 44 | ->getValue($entity); 45 | 46 | if (strtolower($property->ColumnType) == 'datetime') { 47 | 48 | if ($property->ForceDateValidation) { 49 | return _CdateautoDb($value); 50 | } 51 | else { 52 | if (isset($value)) 53 | return new \DateTime($value); 54 | else 55 | return null; 56 | } 57 | } 58 | 59 | // cualquier otro caso 60 | return $value; 61 | 62 | } 63 | 64 | public function Update($entity, $transaction = null, ?IAuditable $auditable = null) { 65 | 66 | // Revisar auditoria 67 | // ----------------------------------------- 68 | if (isset($auditable)) { 69 | try { 70 | $key = $this->EntityDefinition->KeyProperty->Name; 71 | $current = $this->Find($entity->$key); 72 | 73 | $audit = new AuditInfo(Auditable: $auditable, Definition : $this->EntityDefinition, CurrentEntity: $current, NewEntity: $entity); 74 | $audit->Run(); 75 | } 76 | catch (\Exception $ex) {} 77 | } 78 | // ----------------------------------------- 79 | 80 | 81 | if ($this->ReflectedEntity == null) 82 | $this->ReflectedEntity = new \ReflectionClass($this->EntityDefinition->Entity); 83 | 84 | $fields = array(); 85 | $bindings = array(); 86 | $values = array(); 87 | $bindingCasts = array(); // para casos especiales en los cuales se debe interponer algun cast o formateador al campo 88 | $types = array(); 89 | 90 | // Construir la sentencia SQL de actualización 91 | $qry = 'UPDATE '. $this->EntityDefinition->Table.' SET '; 92 | 93 | $idx = 0; 94 | foreach($this->EntityDefinition->Properties as $property) { 95 | 96 | if (!$property->Ignore && !$property->IsKey) { 97 | 98 | $fields[$idx] = $property->ColumnName; 99 | $bindings[$idx] = ':' . $property->ColumnName; 100 | 101 | if ($property->ColumnType == 'int') 102 | $types[$idx] = 'int'; 103 | else 104 | $types[$idx] = ''; 105 | 106 | $bindingCasts[$idx] = $this->Cast($property); 107 | // if ($this->Domain->Type == 'oracle' && strtolower($property->ColumnType) == 'datetime') { 108 | // $bindingCasts[$idx] = "TO_DATE(:" . $property->ColumnName . ", 'yyyy-mm-dd hh24:mi:ss')"; 109 | // } 110 | // else if ($this->Domain->Type == 'sqlserver' && strtolower($property->ColumnType) == 'datetime') { 111 | // $bindingCasts[$idx] = "convert(datetime, :" . $property->ColumnName . ", 20)"; 112 | // } 113 | // else { 114 | // $bindingCasts[$idx] = ':' . $property->ColumnName; 115 | // } 116 | 117 | $values[$idx] = $this->Value($property, $entity); 118 | // $values[$idx] = $this->ReflectedEntity 119 | // ->getProperty($property->Name) 120 | // ->getValue($entity); 121 | 122 | // Agregar instrucción SET a la sentencia 123 | if ($idx > 0) 124 | $qry .= ', '; 125 | 126 | $qry .= $property->ColumnName . ' = ' . $bindingCasts[$idx]; 127 | 128 | $idx++; 129 | } 130 | } 131 | 132 | // Agregar la condición de selección 133 | $qry .= ' WHERE ' . $this->EntityDefinition->Key . ' = :' . $this->EntityDefinition->Key; 134 | 135 | // Preparar la sentencia 136 | if (!isset($transaction)) { 137 | $transaction = $this->Connection; 138 | } 139 | $stmt = $transaction->prepare($qry); 140 | 141 | // Asignar el enlazamiento (bindings) 142 | for( $idxb = 0; $idxb < count($bindings); $idxb++) { 143 | $value = $values[$idxb]; 144 | $bind = $bindings[$idxb]; 145 | 146 | if(is_int($value) || $types[$idxb] == 'int') { 147 | $param = PDO::PARAM_INT; 148 | } 149 | elseif(is_double($value)) { 150 | $param = PDO::PARAM_STR; 151 | } 152 | elseif(is_float($value)) { 153 | $param = PDO::PARAM_STR; 154 | } 155 | elseif(is_bool($value)) { 156 | $param = PDO::PARAM_BOOL; 157 | } 158 | elseif(is_null($value)) { 159 | $param = PDO::PARAM_NULL; 160 | } 161 | elseif(is_string($value)) { 162 | $param = PDO::PARAM_STR; 163 | } 164 | elseif($value instanceof \DateTime) { 165 | $param = PDO::PARAM_STR; 166 | $value = $value->format('Y-m-d H:i:s'); 167 | } 168 | else 169 | $param = FALSE; 170 | 171 | $stmt->bindValue("$bind", $value, $param); 172 | } 173 | 174 | 175 | // Asignar el enlazamiento de la KEY 176 | $keyParam = PDO::PARAM_INT; 177 | $keyBind = ':'.$this->EntityDefinition->Key; 178 | 179 | $keyValue = $this->ReflectedEntity 180 | ->getProperty($this->EntityDefinition->KeyProperty->Name) 181 | ->getValue($entity); 182 | 183 | $stmt->bindValue("$keyBind", $keyValue, $keyParam); 184 | 185 | // Ejecutar la sentencia 186 | $stmt->execute(); 187 | } 188 | 189 | public function Insert($entity, $transaction = null, ?IAuditable $auditable = null) { 190 | 191 | // Revisar auditoria 192 | // ----------------------------------------- 193 | if (isset($auditable)) { 194 | try { 195 | $audit = new AuditInfo(Auditable: $auditable, NewEntity: $entity, Definition: $this->EntityDefinition); 196 | $audit->Run(); 197 | } 198 | catch (\Exception $ex) {} 199 | } 200 | // ----------------------------------------- 201 | 202 | $oracleNewId = 0; 203 | 204 | if ($this->ReflectedEntity == null) 205 | $this->ReflectedEntity = new \ReflectionClass($this->EntityDefinition->Entity); 206 | 207 | $fields = array(); 208 | $bindings = array(); 209 | $values = array(); 210 | $bindingCasts = array(); // para casos especiales en los cuales se debe interponer algun cast o formateador al campo 211 | $types = array(); 212 | 213 | $idx = 0; 214 | 215 | // if ($this->Domain->Type == 'oracle') { 216 | // // Se debe obtener el siguiente elemento en la secuencia 217 | // $oracleNewId = $this->Connection->sequenceNextVal($this->EntityDefinition->Table . "_SEQ"); 218 | 219 | // $fields[0] = $this->EntityDefinition->KeyProperty->ColumnName; 220 | // $bindings[0] = ':' . $this->EntityDefinition->KeyProperty->ColumnName; 221 | // $bindingCasts[0] = ':' . $this->EntityDefinition->KeyProperty->ColumnName; 222 | // $values[0] = $oracleNewId; 223 | // //$types[0] = 'sequence'; 224 | // $types[0] = ''; 225 | // $idx++; 226 | // } 227 | 228 | foreach($this->EntityDefinition->Properties as $property) { 229 | 230 | if (!$property->Ignore && !$property->IsKey) { 231 | 232 | $fields[$idx] = $property->ColumnName; 233 | $bindings[$idx] = ':' . $property->ColumnName; 234 | 235 | // if ($property->ColumnType == 'int') 236 | // $types[$idx] = 'int'; 237 | // else if ($property->ColumnType == 'datetime') 238 | // $types[$idx] = 'datetime'; 239 | // else 240 | $types[$idx] = ''; 241 | 242 | $bindingCasts[$idx] = $this->Cast($property); 243 | // if ($this->Domain->Type == 'oracle' && strtolower($property->ColumnType) == 'datetime') { 244 | // $bindingCasts[$idx] = "TO_DATE(:" . $property->ColumnName . ", 'yyyy-mm-dd hh24:mi:ss')"; 245 | // } 246 | // else if ($this->Domain->Type == 'sqlserver' && strtolower($property->ColumnType) == 'datetime') { 247 | // $bindingCasts[$idx] = "convert(datetime, :" . $property->ColumnName . ", 20)"; 248 | // } 249 | // else { 250 | // $bindingCasts[$idx] = ':' . $property->ColumnName; 251 | // } 252 | 253 | $values[$idx] = $this->Value($property, $entity); 254 | // $values[$idx] = $this->ReflectedEntity 255 | // ->getProperty($property->Name) 256 | // ->getValue($entity); 257 | 258 | $idx++; 259 | } 260 | } 261 | 262 | // Construir la sentencia SQL de inserción 263 | $qry = 'INSERT INTO '. $this->EntityDefinition->Table . ' ('.join(",", $fields).') VALUES ('.join(",", $bindingCasts).')'; 264 | 265 | // Preparar la sentencia 266 | if (!isset($transaction)) { 267 | $transaction = $this->Connection; 268 | } 269 | $stmt = $transaction->prepare($qry); 270 | 271 | // Asignar el enlazamiento (bindings) 272 | for( $idxb = 0; $idxb < count($bindings); $idxb++) { 273 | $value = $values[$idxb]; 274 | $bind = $bindings[$idxb]; 275 | 276 | if(is_int($value) || $types[$idxb] == 'sequence' || $types[$idxb] == 'int') { 277 | $param = PDO::PARAM_INT; 278 | } 279 | elseif(is_double($value)) { 280 | $param = PDO::PARAM_STR; 281 | } 282 | elseif(is_float($value)) { 283 | $param = PDO::PARAM_STR; 284 | } 285 | elseif(is_bool($value)) { 286 | $param = PDO::PARAM_BOOL; 287 | } 288 | elseif(is_null($value)) { 289 | $param = PDO::PARAM_NULL; 290 | } 291 | elseif(is_string($value)) { 292 | $param = PDO::PARAM_STR; 293 | } 294 | elseif($value instanceof \DateTime) { 295 | $param = PDO::PARAM_STR; 296 | $value = $value->format('Y-m-d H:i:s'); 297 | } 298 | else 299 | $param = FALSE; 300 | 301 | $stmt->bindValue("$bind", $value, $param); 302 | } 303 | 304 | // Ejecutar la sentencia y obtener el ID del nuevo registro 305 | /* 306 | if (!self::IsTransactionOpen()) { 307 | $this->Connection->beginTransaction(); 308 | } 309 | */ 310 | $result = $stmt->execute(); 311 | 312 | if ($this->Domain->Type == 'oracle') { 313 | $newID = $oracleNewId; 314 | } 315 | else if ($this->Domain->Type == 'mysql') { 316 | $newID = $transaction->lastInsertId(); 317 | } 318 | else { 319 | $newID = $transaction->lastInsertId(); 320 | } 321 | 322 | /* 323 | if (!self::IsTransactionOpen()) { 324 | $this->Connection->commit(); 325 | } 326 | */ 327 | 328 | if ($newID <= 0) 329 | return null; 330 | 331 | // Asignar el nuevo ID a la entidad 332 | $reflectionClass = new \ReflectionClass($this->EntityDefinition->Entity); 333 | $reflectionClass->getProperty($this->EntityDefinition->KeyName)->setValue($entity, intval($newID)); 334 | 335 | // Retornar la entidad con el nuevo ID asignado a la llave 336 | return $entity; 337 | } 338 | 339 | public function Delete($keyValue, $transaction = null) 340 | { 341 | $qry = 'DELETE FROM '. $this->EntityDefinition->Table .' WHERE '. $this->EntityDefinition->Key. ' = :' . $this->EntityDefinition->Key; 342 | 343 | if (!isset($transaction)) { 344 | $transaction = $this->Connection; 345 | } 346 | $stmt = $transaction->prepare($qry); 347 | 348 | // Asignar la condicion de selección 349 | $keyParam = PDO::PARAM_INT; 350 | $keyBind = ':'.$this->EntityDefinition->Key; 351 | 352 | $stmt->bindValue("$keyBind", $keyValue, $keyParam); 353 | 354 | $stmt->execute(); 355 | } 356 | 357 | public function LogicDelete($keyValue, $transaction = null) { 358 | 359 | $qry = 'UPDATE '. $this->EntityDefinition->Table .' SET IndEliminado = 1 WHERE '. $this->EntityDefinition->Key. ' = :' . $this->EntityDefinition->Key; 360 | 361 | if (!isset($transaction)) { 362 | $transaction = $this->Connection; 363 | } 364 | $stmt = $transaction->prepare($qry); 365 | 366 | // Asignar la condicion de selección 367 | $keyParam = PDO::PARAM_INT; 368 | $keyBind = ':'.$this->EntityDefinition->Key; 369 | 370 | $stmt->bindValue("$keyBind", $keyValue, $keyParam); 371 | 372 | $stmt->execute(); 373 | } 374 | 375 | public function DeleteBy($bindings, $transaction = null) 376 | { 377 | $qry = 'DELETE FROM ' . $this->EntityDefinition->Table; 378 | 379 | /* @var $var BindVariable */ 380 | $count = 0; 381 | $where = ''; 382 | $bind = array(); 383 | foreach ($bindings as $key => $var) { 384 | 385 | if ($count > 0) { 386 | $where .= ' 387 | AND 388 | '; 389 | } 390 | 391 | if ($var->Operator == 'BETWEEN') { 392 | $where .= $var->Field . ' BETWEEN :var' . $count . ' AND :var' . ($count + 1) . ' '; 393 | 394 | $bind['var' . $count] = $var->Operand1; 395 | $count++; 396 | $bind['var' . $count] = $var->Operand2; 397 | } else { 398 | $where .= $var->Field . ' ' . $var->Operator . ' :var' . $count . ' '; 399 | $bind['var' . $count] = $var->Operand1; 400 | } 401 | 402 | $count++; 403 | } 404 | 405 | if ($where != '') { 406 | $qry .= ' WHERE ' . $where; 407 | } else { 408 | throw new \Exception("NO PUDE REALIZAR UNA ELIMINACION DESDE UNA TABLA SIN CONDICIONES DE EXCLUSION -WHERE-"); 409 | return; 410 | } 411 | 412 | // preparar sentencia 413 | if (!isset($transaction)) { 414 | $transaction = $this->Connection; 415 | } 416 | $stmt = $transaction->prepare($qry); 417 | 418 | // ligar variables 419 | foreach ($bind as $v => $value) { 420 | if(is_int($value)) 421 | $param = PDO::PARAM_INT; 422 | elseif(is_bool($value)) 423 | $param = PDO::PARAM_BOOL; 424 | elseif(is_null($value)) 425 | $param = PDO::PARAM_NULL; 426 | elseif(is_string($value)) 427 | $param = PDO::PARAM_STR; 428 | else 429 | $param = FALSE; 430 | 431 | if($param) 432 | $stmt->bindValue(":$v", $value, $param); 433 | } 434 | 435 | $stmt->execute(); 436 | } 437 | 438 | public function LogicDeleteBy($bindings, $transaction = null) 439 | { 440 | $qry = 'UPDATE ' . $this->EntityDefinition->Table . " SET IndEliminado = 1 "; 441 | 442 | /* @var $var BindVariable */ 443 | $count = 0; 444 | $where = ''; 445 | $bind = array(); 446 | foreach ($bindings as $key => $var) { 447 | 448 | if ($count > 0) { 449 | $where .= ' 450 | AND 451 | '; 452 | } 453 | 454 | if ($var->Operator == 'BETWEEN') { 455 | $where .= $var->Field . ' BETWEEN :var' . $count . ' AND :var' . ($count + 1) . ' '; 456 | 457 | $bind['var' . $count] = $var->Operand1; 458 | $count++; 459 | $bind['var' . $count] = $var->Operand2; 460 | } else { 461 | $where .= $var->Field . ' ' . $var->Operator . ' :var' . $count . ' '; 462 | $bind['var' . $count] = $var->Operand1; 463 | } 464 | 465 | $count++; 466 | } 467 | 468 | if ($where != '') { 469 | $qry .= ' WHERE ' . $where; 470 | } else { 471 | throw new \Exception("NO PUDE REALIZAR UNA ELIMINACION DESDE UNA TABLA SIN CONDICIONES DE EXCLUSION -WHERE-"); 472 | return; 473 | } 474 | 475 | // preparar sentencia 476 | if (!isset($transaction)) { 477 | $transaction = $this->Connection; 478 | } 479 | $stmt = $transaction->prepare($qry); 480 | 481 | // ligar variables 482 | foreach ($bind as $v => $value) { 483 | if(is_int($value)) 484 | $param = PDO::PARAM_INT; 485 | elseif(is_bool($value)) 486 | $param = PDO::PARAM_BOOL; 487 | elseif(is_null($value)) 488 | $param = PDO::PARAM_NULL; 489 | elseif(is_string($value)) 490 | $param = PDO::PARAM_STR; 491 | else 492 | $param = FALSE; 493 | 494 | if($param) 495 | $stmt->bindValue(":$v", $value, $param); 496 | } 497 | 498 | $stmt->execute(); 499 | } 500 | } 501 | } 502 | -------------------------------------------------------------------------------- Total de líneas: 502 ================================================================================ ================================================================================ ARCHIVO #122: src/Dao/OperatorEnum.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Dao/OperatorEnum.php Tamaño: 551 bytes -------------------------------------------------------------------------------- 1 | '; 17 | public const GR = '>'; 18 | public const GREQ = '>='; 19 | public const LO = '<'; 20 | public const LOEQ = '<='; 21 | public const BET = 'BETWEEN'; 22 | public const IN = 'IN'; 23 | 24 | } -------------------------------------------------------------------------------- Total de líneas: 24 ================================================================================ ================================================================================ ARCHIVO #123: src/Dao/Queryable.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Dao/Queryable.php Tamaño: 23.83 KB -------------------------------------------------------------------------------- 1 | 25 | */ 26 | class Queryable { 27 | 28 | private static $ConnectionType = null; 29 | private $idxElement = 0; 30 | 31 | public static function Init(string $ConnectionType) { 32 | self::$ConnectionType = $ConnectionType; 33 | } 34 | 35 | private $Definitions = []; 36 | private $FromDefinition = null; 37 | private $JoinDefinitions = null; 38 | private $LeftJoinDefinitions = null; 39 | private $WithDefinitions = null; 40 | private $WhereDefinitions = null; 41 | private $Order = ''; 42 | private int $Top = 0; 43 | private bool $UseDistinct = false; 44 | private $Key = null; 45 | 46 | public function __construct( 47 | ) 48 | { 49 | if (!isset(self::$ConnectionType)) { 50 | throw new \Exception('Debe inicializar la conexión por defecto antes de instanciar esta clase. Ej: Queryable::Init(ConnectionTypeEnum::MYSQL)'); 51 | } 52 | 53 | $this->JoinDefinitions = new GenericCollection(); 54 | $this->LeftJoinDefinitions = new GenericCollection(); 55 | $this->WithDefinitions = new GenericCollection(); 56 | $this->WhereDefinitions = new GenericCollection(); 57 | } 58 | 59 | private function AddDefinition($definition, $definitionType) { 60 | 61 | $definition->Type = $definitionType; 62 | 63 | $this->Definitions[$this->idxElement] = $definition; 64 | $this->idxElement++; 65 | 66 | } 67 | 68 | /** 69 | * @param string $entity 70 | * 71 | * Agrega la entidad principal de la consulta 72 | * 73 | * @return Queryable 74 | */ 75 | public function From(string $entity) { 76 | 77 | $this->FromDefinition = EntityDefinition::Instance($entity); 78 | 79 | return $this; 80 | } 81 | 82 | /** 83 | * @param string $entityClass 84 | * 85 | * Agrega una inclusión Join de todas las entidades hijas con la entidad padre principal. 86 | * La entidad padre debe contener una propiedad que tenga el nombre de la entidad hija en plural. 87 | * Si no existe el nombre, se creará una propiedad nueva. 88 | * 89 | * Ej: 90 | * 91 | * class Mantencion { 92 | * // Key AutoIncrement 93 | * public $IdMantencion = 0; 94 | * public $Descripcion = ''; 95 | * public $IdTipoEstado = ''; 96 | * public $Actividades = array(); << aca se agregará la coleccion JOIN 97 | * } 98 | * 99 | * class Actividad { 100 | * // Key, AutoIncrement 101 | * public $IdActividad = 0; 102 | * public $Description = ''; 103 | * // Foreign=Mantencion 104 | * public $IdMantencion = 0; 105 | * } 106 | * 107 | * $qry = (new Queryable()) 108 | * ->From(Mantencion::class) 109 | * ->Join(Actividad::class); 110 | * 111 | * @return Queryable 112 | */ 113 | public function Join(string $entity, $foreignKey = '', $parentKey = '') { 114 | 115 | $entityDefinition = EntityDefinition::Instance($entity); 116 | 117 | if ($foreignKey != '') 118 | $entityDefinition->CustomForeignKey = $foreignKey; 119 | 120 | if ($parentKey != '') 121 | $entityDefinition->CustomParentKey = $parentKey; 122 | 123 | $this->JoinDefinitions->Add($entityDefinition); 124 | $this->AddDefinition($entityDefinition, DefinitionTypeEnum::JOIN); 125 | 126 | return $this; 127 | } 128 | 129 | 130 | 131 | /** 132 | * @param string $entityClass 133 | * 134 | * Agrega una inclusión LEFT Join de todas las entidades hijas con la entidad padre principal. 135 | * La entidad padre debe contener una propiedad que tenga el nombre de la entidad hija en plural. 136 | * Si no existe el nombre, se creará una propiedad nueva. 137 | * 138 | * Ej: 139 | * 140 | * class Mantencion { 141 | * // Key AutoIncrement 142 | * public $IdMantencion = 0; 143 | * public $Descripcion = ''; 144 | * public $IdTipoEstado = ''; 145 | * public $Actividades = array(); << aca se agregará la coleccion LEFT JOIN 146 | * } 147 | * 148 | * class Actividad { 149 | * // Key, AutoIncrement 150 | * public $IdActividad = 0; 151 | * public $Description = ''; 152 | * // Foreign=Mantencion 153 | * public $IdMantencion = 0; 154 | * } 155 | * 156 | * $qry = (new Queryable()) 157 | * ->From(Mantencion::class) 158 | * ->LeftJoin(Actividad::class); 159 | * 160 | * @return Queryable 161 | */ 162 | public function LeftJoin(string $entity, $foreignKey = '', $parentKey = '') { 163 | 164 | $entityDefinition = EntityDefinition::Instance($entity); 165 | 166 | if ($foreignKey != '') 167 | $entityDefinition->CustomForeignKey = $foreignKey; 168 | 169 | if ($parentKey != '') 170 | $entityDefinition->CustomParentKey = $parentKey; 171 | 172 | $this->LeftJoinDefinitions->Add($entityDefinition); 173 | $this->AddDefinition($entityDefinition, DefinitionTypeEnum::LEFTJOIN); 174 | 175 | return $this; 176 | } 177 | 178 | /** 179 | * @param string $entity 180 | * 181 | * Agrega una inclusión de la entidad parent dentro de la entidad hija principal como un único elemento. 182 | * La entidad principal (hija) debe contener una propiedad que tenga el mismo nombre de la entidad referenciada (padre). 183 | * Si no existe el nombre, se creará una propiedad nueva. 184 | * 185 | * Ej: 186 | * 187 | * class Mantencion { << esta es la entidad hija 188 | * // Key AutoIncrement 189 | * public $IdMantencion = 0; 190 | * public $Descripcion = ''; 191 | * // ForeignKey=TipoEstado 192 | * public $IdTipoEstado = ''; 193 | * public $TipoEstado = null; << aca se agregará el elemento enlazado 194 | * } 195 | * 196 | * class TipoEstado { << esta es la entidad padre 197 | * // Key, AutoIncrement 198 | * public $IdTipoEstado = 0; 199 | * public $Description = ''; 200 | * } 201 | * 202 | * $qry = (new Queryable()) 203 | * ->From('Mantencion') 204 | * ->With('TipoEstado'); 205 | * 206 | * @return Queryable 207 | */ 208 | public function With(string $entity, $foreignKey = '', $parentKey = '') { 209 | 210 | $entityDefinition = EntityDefinition::Instance($entity); 211 | 212 | if ($foreignKey != '') 213 | $entityDefinition->CustomForeignKey = $foreignKey; 214 | 215 | if ($parentKey != '') 216 | $entityDefinition->CustomParentKey = $parentKey; 217 | 218 | $entityDefinition->LeftWith = false; 219 | 220 | $this->WithDefinitions->Add($entityDefinition); 221 | $this->AddDefinition($entityDefinition, DefinitionTypeEnum::WITH); 222 | 223 | return $this; 224 | } 225 | 226 | public function LeftWith(string $entity, $foreignKey = '', $parentKey = '') { 227 | 228 | $entityDefinition = EntityDefinition::Instance($entity); 229 | 230 | if ($foreignKey != '') 231 | $entityDefinition->CustomForeignKey = $foreignKey; 232 | 233 | if ($parentKey != '') 234 | $entityDefinition->CustomParentKey = $parentKey; 235 | 236 | $entityDefinition->LeftWith = true; 237 | 238 | $this->WithDefinitions->Add($entityDefinition); 239 | $this->AddDefinition($entityDefinition, DefinitionTypeEnum::LEFTWITH); 240 | 241 | return $this; 242 | } 243 | 244 | /** 245 | * @param string $condition 246 | * @param ... $params 247 | * 248 | * Agrega una condición de filtro a la entidad principal de la consulta. 249 | * Se pueden definir variables enlazadas con el símbolo "?". Para cada variable enlazada debe existir un parametro en la llamada a la funcion. 250 | * Las llamadas a WHERE se pueden encadenar (la serie de WHERE encadenados se incorporarán con AND) 251 | * 252 | * Ej: 253 | * 254 | * class Mantencion { 255 | * // Key AutoIncrement 256 | * public $IdMantencion = 0; 257 | * public $Descripcion = ''; 258 | * // ForeignKey=TipoEstado 259 | * public $IdTipoEstado = ''; 260 | * } 261 | * 262 | * $qry = (new Queryable()) 263 | * ->From('Mantencion') 264 | * ->Where('IdTipoEstado = ? AND FechaInicioProgramada BETWEEN ? AND ?', 1, $dtInicio, new \DateTime()) 265 | * 266 | * @return Queryable 267 | */ 268 | public function Where($condition, ...$params) { 269 | 270 | $where = array(); 271 | 272 | $where['Condition'] = $condition; 273 | $whereParams = array(); 274 | 275 | if (isset($params)) { 276 | $paramQ = count($params); 277 | $placeQ = substr_count($condition, "?"); 278 | 279 | if ($paramQ != $placeQ) { 280 | throw new \Exception("La cantidad de parametros ($paramQ) no concuerda con la cantidad de variables ($placeQ)"); 281 | } 282 | 283 | 284 | foreach($params as $p) { 285 | array_push($whereParams, $p); 286 | } 287 | } 288 | 289 | $where['Parameters'] = $whereParams; 290 | 291 | $this->WhereDefinitions->Add((object)$where); 292 | 293 | return $this; 294 | } 295 | 296 | public function OrderBy($condition) { 297 | $this->Order = $condition; 298 | return $this; 299 | } 300 | 301 | public function Key($key) { 302 | $this-> FromDefinition -> Key = $key; 303 | return $this; 304 | } 305 | 306 | public function Top(int $recordNumber) { 307 | $this->Top = $recordNumber; 308 | return $this; 309 | } 310 | 311 | public function Distinct() { 312 | $this->UseDistinct = true; 313 | return $this; 314 | } 315 | 316 | /** 317 | * 318 | * Construye la sentencia de consulta en base a los parámetros especificados 319 | * 320 | * 321 | * @return object 322 | */ 323 | public function Build() { 324 | 325 | if (!isset($this->FromDefinition)) { 326 | throw new \Exception("No se ha definido la entidad principal"); 327 | } 328 | 329 | // $joins = $this->GetJoins($this->JoinDefinitions, $this->FromDefinition, false); 330 | // $leftjoins = $this->GetJoins($this->LeftJoinDefinitions, $this->FromDefinition, true); 331 | // $withs = $this->GetWiths($this->WithDefinitions, $this->FromDefinition); 332 | 333 | //$joins->AddRange($withs); 334 | 335 | $qryJoin = ""; 336 | $fieldsJoin = ""; 337 | 338 | // Leer en orden 339 | foreach($this->Definitions as $definition) { 340 | 341 | switch ($definition->Type) { 342 | 343 | case DefinitionTypeEnum::JOIN: 344 | 345 | $join = $this->GetJoin($definition, $this->FromDefinition); 346 | 347 | break; 348 | 349 | case DefinitionTypeEnum::LEFTJOIN: 350 | 351 | $join = $this->GetJoin($definition, $this->FromDefinition, true); 352 | 353 | break; 354 | 355 | case DefinitionTypeEnum::WITH: 356 | 357 | $join = $this->GetWith($definition, $this->FromDefinition); 358 | 359 | break; 360 | 361 | case DefinitionTypeEnum::LEFTWITH: 362 | 363 | $join = $this->GetWith($definition, $this->FromDefinition); 364 | 365 | break; 366 | } 367 | 368 | if ($qryJoin != "") $qryJoin .= "\n"; 369 | $qryJoin .= $join->JoinSentence; 370 | 371 | if ($fieldsJoin != "") 372 | $fieldsJoin .= ",\n\t"; 373 | $fieldsJoin .= $join->JoinFields; 374 | } 375 | 376 | // if ($joins->Count() > 0) { 377 | // foreach($joins as $join) { 378 | // if ($qryJoin != "") $qryJoin .= "\n"; 379 | // $qryJoin .= $join->JoinSentence; 380 | 381 | // if ($fieldsJoin != "") 382 | // $fieldsJoin .= ",\n\t"; 383 | // $fieldsJoin .= $join->JoinFields; 384 | // } 385 | // } 386 | 387 | // if ($leftjoins->Count() > 0) { 388 | // foreach($leftjoins as $join) { 389 | // if ($qryJoin != "") $qryJoin .= "\n"; 390 | // $qryJoin .= $join->JoinSentence; 391 | 392 | // if ($fieldsJoin != "") 393 | // $fieldsJoin .= ",\n\t"; 394 | // $fieldsJoin .= $join->JoinFields; 395 | // } 396 | // } 397 | 398 | // if ($withs->Count() > 0) { 399 | // foreach($withs as $join) { 400 | // if ($qryJoin != "") $qryJoin .= "\n"; 401 | // $qryJoin .= $join->JoinSentence; 402 | 403 | // if ($fieldsJoin != "") 404 | // $fieldsJoin .= ",\n\t"; 405 | // $fieldsJoin .= $join->JoinFields; 406 | // } 407 | // } 408 | 409 | 410 | // SELECT 411 | $top = ""; 412 | if ($this->Top > 0 && self::$ConnectionType == 'sqlserver') { 413 | $top = " TOP " . $this->Top . " "; 414 | } 415 | $distinct = ($this->UseDistinct) ? ' DISTINCT ' : ''; 416 | $qrySelect = "SELECT" . $top . $distinct . "\n\t" . $joinFields = trim(str_replace(", ", ",\n\t", $this->FromDefinition->NamedNotIgnoredFields)); 417 | 418 | // JOIN y WITH fields 419 | if ($fieldsJoin != "") 420 | $qrySelect .= ",\n $fieldsJoin "; 421 | 422 | // FROM 423 | $qrySelect .= "\nFROM\n\t" . $this->FromDefinition->NamedTable; 424 | 425 | // JOIN y WITH 426 | if ($qryJoin != "") 427 | $qrySelect .= "\n" . $qryJoin; 428 | 429 | // WHEREs 430 | $wheres = $this->GetWheres($this->WhereDefinitions); 431 | 432 | $whereSql = ""; 433 | $bindingVars = new GenericCollection(); 434 | 435 | foreach($wheres as $where) { 436 | if ($whereSql != "") 437 | $whereSql .= "\nAND\t"; 438 | 439 | $whereSql .= "(" . $where->Condition . ")"; 440 | $bindingVars->AddRange($where->Bindings); 441 | } 442 | 443 | if ($whereSql != "") 444 | $qrySelect .= "\nWHERE\n\t" . $whereSql; 445 | 446 | if ($this->Order != "") { 447 | $qrySelect .= "\nORDER BY\n\t" . $this->Order; 448 | } 449 | 450 | if ($this->Top > 0 && self::$ConnectionType == 'mysql') { 451 | $qrySelect .= "\nLIMIT " . $this->Top; 452 | } 453 | 454 | return (object)[ 455 | "Statement" => $qrySelect, 456 | "Bindings" => $bindingVars, 457 | "FromDefinition" => $this->FromDefinition, 458 | "JoinDefinitions" => $this->JoinDefinitions, 459 | "LeftJoinDefinitions" => $this->LeftJoinDefinitions, 460 | "WithDefinitions" => $this->WithDefinitions 461 | ]; 462 | } 463 | 464 | private function GetJoins(GenericCollection $joinDefinitions, EntityDefinition $mainEntityDefinition, bool $leftJoin = false) { 465 | 466 | $joins = new GenericCollection(); 467 | 468 | foreach($joinDefinitions as $joinEntityDefinition) { 469 | $joins->Add($this->GetJoin($joinEntityDefinition, $mainEntityDefinition, $leftJoin)); 470 | } 471 | 472 | return $joins; 473 | } 474 | 475 | private function GetJoin(EntityDefinition $joinEntityDefinition, EntityDefinition $mainEntityDefinition, bool $leftJoin = false) { 476 | 477 | // La llave primaria de la tabla referenciada 478 | $primaryKey = $mainEntityDefinition->TablePrefix . "." . $mainEntityDefinition->Key; 479 | $primaryKeyName = $joinEntityDefinition->KeyName; 480 | 481 | // La llave foránea de la tabla principal 482 | //$foreignProperty = $joinEntityDefinition->Properties[$joinEntityDefinition->KeyName]; 483 | $foreignKey = $joinEntityDefinition->TablePrefix . "." . $mainEntityDefinition->Key; 484 | if (isset($joinEntityDefinition->CustomForeignKey) && $joinEntityDefinition->CustomForeignKey != '') { 485 | 486 | // tiene punto de separacion con una entidad? 487 | if (strlen($joinEntityDefinition->CustomForeignKey) != strlen( str_replace('.', '', $joinEntityDefinition->CustomForeignKey))) { 488 | $foreignKey = $joinEntityDefinition->CustomForeignKey; 489 | } 490 | else { 491 | // no tiene... asignamos la entidad principal 492 | $foreignKey = $mainEntityDefinition->TablePrefix . "." . $joinEntityDefinition->CustomForeignKey; 493 | } 494 | } 495 | else { 496 | //$foreignProperty = $mainEntityDefinition->Properties[$primaryKeyName]; 497 | //$foreignKey = $mainEntityDefinition->TablePrefix . "." . $foreignProperty->ColumnName; 498 | } 499 | 500 | if (isset($joinEntityDefinition->CustomParentKey) && $joinEntityDefinition->CustomParentKey != '') { 501 | // tiene punto de separacion con una entidad? 502 | if (strlen($joinEntityDefinition->CustomParentKey) != strlen( str_replace('.', '', $joinEntityDefinition->CustomParentKey))) { 503 | $primaryKey = $joinEntityDefinition->CustomParentKey; 504 | } 505 | else { 506 | // no tiene... asignamos la entidad principal 507 | $primaryKey = $joinEntityDefinition->TablePrefix . "." . $joinEntityDefinition->CustomParentKey; 508 | } 509 | } 510 | 511 | 512 | // $foreignProperty->ColumnName; 513 | //$foreignKey = $mainEntityDefinition->Properties[$joinEntityDefinition->KeyName]->ColumnName; 514 | 515 | // Obtener Campos, se debe ignorar el campo utilizado en la llave foranea, 516 | // dado que la entidad principal ya la está incluyendo 517 | $fields = $joinEntityDefinition->NamedRenamedNotIgnoredFields; 518 | // $fields = str_replace($joinEntityDefinition->TablePrefix . "." . $mainEntityDefinition->Key . " AS \"" . $joinEntityDefinition->TablePrefix . "." . $mainEntityDefinition->KeyName . "\", ", "", $fields); 519 | // $fields = str_replace($joinEntityDefinition->TablePrefix . "." . $mainEntityDefinition->Key . " AS \"" . $joinEntityDefinition->TablePrefix . "." . $mainEntityDefinition->KeyName . "\",", "", $fields); 520 | // $fields = str_replace(", ". $joinEntityDefinition->TablePrefix . "." . $mainEntityDefinition->Key . " AS \"" . $joinEntityDefinition->TablePrefix . "." . $mainEntityDefinition->KeyName . "\"", "", $fields); 521 | 522 | $joinFields = trim(str_replace(", ", ",\n\t", $fields)); 523 | 524 | $reservedWord = ($leftJoin) ? 'LEFT JOIN' : 'JOIN'; 525 | 526 | $joinSentence = "$reservedWord\t" . str_pad($joinEntityDefinition->NamedTable, 20, " ") . " ON " 527 | . $foreignKey . " = " 528 | . $primaryKey; 529 | 530 | return (object)[ 531 | "Entity" => $joinEntityDefinition->Entity, 532 | "JoinFields" => $joinFields, 533 | "JoinSentence" => $joinSentence 534 | ]; 535 | } 536 | 537 | private function GetWiths(GenericCollection $withDefinitions, EntityDefinition $mainEntityDefinition) { 538 | 539 | $withs = new GenericCollection(); 540 | 541 | foreach($withDefinitions as $withEntityDefinition) { 542 | $withs->Add($this->GetWith($withEntityDefinition, $mainEntityDefinition)); 543 | } 544 | 545 | return $withs; 546 | } 547 | 548 | private function GetWith(EntityDefinition $withEntityDefinition, EntityDefinition $mainEntityDefinition) { 549 | 550 | $primaryKey = $mainEntityDefinition->TablePrefix . "." . $withEntityDefinition->Key; 551 | $primaryKeyName = $withEntityDefinition->KeyName; 552 | 553 | // La llave foránea de la tabla principal 554 | //$foreignProperty = $joinEntityDefinition->Properties[$joinEntityDefinition->KeyName]; 555 | $foreignKey = $withEntityDefinition->TablePrefix . "." . $withEntityDefinition->Key; 556 | if (isset($withEntityDefinition->CustomForeignKey) && $withEntityDefinition->CustomForeignKey != '') { 557 | 558 | // tiene punto de separacion con una entidad? 559 | if (strlen($withEntityDefinition->CustomForeignKey) != strlen( str_replace('.', '', $withEntityDefinition->CustomForeignKey))) { 560 | $foreignKey = $withEntityDefinition->CustomForeignKey; 561 | } 562 | else { 563 | // no tiene... asignamos la entidad principal 564 | $foreignKey = $mainEntityDefinition->TablePrefix . "." . $withEntityDefinition->CustomForeignKey; 565 | } 566 | } 567 | else { 568 | //$foreignProperty = $mainEntityDefinition->Properties[$primaryKeyName]; 569 | //$foreignKey = $mainEntityDefinition->TablePrefix . "." . $foreignProperty->ColumnName; 570 | } 571 | 572 | if (isset($withEntityDefinition->CustomParentKey) && $withEntityDefinition->CustomParentKey != '') { 573 | // tiene punto de separacion con una entidad? 574 | if (strlen($withEntityDefinition->CustomParentKey) != strlen( str_replace('.', '', $withEntityDefinition->CustomParentKey))) { 575 | $primaryKey = $withEntityDefinition->CustomParentKey; 576 | } 577 | else { 578 | // no tiene... asignamos la entidad principal 579 | $primaryKey = $withEntityDefinition->TablePrefix . "." . $withEntityDefinition->CustomParentKey; 580 | } 581 | } 582 | 583 | 584 | // Obtener Campos, se debe ignorar el campo utilizado en la llave foranea, 585 | // dado que la entidad principal ya la está incluyendo 586 | $fields = $withEntityDefinition->NamedRenamedNotIgnoredFields; 587 | 588 | $joinFields = trim(str_replace(", ", ",\n\t", $fields)); 589 | 590 | $joinSentence = (($withEntityDefinition->LeftWith) ? 'LEFT ' : '') . "JOIN\t" . str_pad($withEntityDefinition->NamedTable, 20, " ") . " ON " 591 | . $foreignKey . " = " 592 | . $primaryKey; 593 | 594 | return (object)[ 595 | "Entity" => $withEntityDefinition->Entity, 596 | "JoinFields" => $joinFields, 597 | "JoinSentence" => $joinSentence 598 | ]; 599 | } 600 | 601 | private function GetWheres(GenericCollection $whereDefinitions) { 602 | 603 | $wheres = array(); 604 | 605 | $startFrom = 0; 606 | foreach($whereDefinitions as $whereDefinition) { 607 | 608 | $where = $this->GetWhere($whereDefinition, $startFrom); 609 | $startFrom += count($where->Bindings); 610 | 611 | array_push($wheres, $where); 612 | } 613 | 614 | return $wheres; 615 | } 616 | 617 | private function GetWhere($whereDefinition, $startFrom = 0) { 618 | 619 | // Condition, Parameters 620 | // ->Where('Mantencion.IdTipoEstado = ? AND Mantencion.FechaInicioProgramada BETWEEN ? AND ?', 1, $dtInicio, $dtFin) 621 | $where = $whereDefinition->Condition; 622 | 623 | // Primero obtenemos todos los elementos que se requieren reemplazar, 624 | // es decir TablePrefix.Name se debe reemplazar por TablePrefix.ColumnName 625 | // ------------------------------------------------------------------------------------- 626 | // FROM 627 | $where = $this->ReplaceProperties($this->FromDefinition->Properties, $this->FromDefinition->TablePrefix, $where); 628 | 629 | // JOINS 630 | foreach($this->JoinDefinitions as $joinDefinition) { 631 | $where = $this->ReplaceProperties($joinDefinition->Properties, $joinDefinition->TablePrefix, $where); 632 | } 633 | 634 | // Withs 635 | foreach($this->WithDefinitions as $withDefinition) { 636 | $where = $this->ReplaceProperties($withDefinition->Properties, $withDefinition->TablePrefix, $where); 637 | } 638 | 639 | // Ahora, generamos los bindings 640 | $cantidadPlaceholder = substr_count($where, "?"); 641 | $cantidadParametros = count($whereDefinition->Parameters); 642 | $bindings = array(); 643 | 644 | for ($i=$startFrom; ( ($i-$startFrom) < $cantidadPlaceholder) && ( ($i-$startFrom) < $cantidadParametros); $i++) { 645 | $bindingVar = ":var" . $i; 646 | // reemplazamos el placeholder 647 | $where = $this->str_first_replace("?", $bindingVar, $where); 648 | // agregamos la variable binding 649 | array_push($bindings, (object)["BindingVariable" => $bindingVar, "BindingValue" => $whereDefinition->Parameters[$i-$startFrom]]); 650 | } 651 | 652 | // Resultado 653 | return (object)["Condition" => $where, "Bindings" => $bindings]; 654 | } 655 | 656 | private function str_first_replace($search, $replace, $subject) 657 | { 658 | return ($pos=strpos($subject, $search))!==FALSE?substr_replace($subject, $replace, $pos, strlen($search)):$subject; 659 | } 660 | 661 | private function ReplaceProperties(array $properties, string $tablePrefix, string $whereCondition) { 662 | 663 | foreach($properties as $property) { 664 | $whereCondition = str_replace( 665 | $tablePrefix . "." . $property->Name, 666 | $tablePrefix . "." . $property->ColumnName, 667 | $whereCondition 668 | ); 669 | 670 | } 671 | 672 | return $whereCondition; 673 | } 674 | 675 | /* LO QUE QUEREMOS LOGRAR: 676 | 677 | $qry = (new Queryable()) 678 | ->From(Mantencion::class) 679 | ->Join(TipoEstado::class) 680 | ->With(Actividad:class) 681 | ->With(JefeTurno::class) 682 | ->Where('Mantencion.IdTipoEstado = ? AND Mantencion.FechaInicioProgramada BETWEEN ? AND ?', 1, $dtInicio, $dtFin) 683 | ->Build(); 684 | 685 | */ 686 | 687 | } -------------------------------------------------------------------------------- Total de líneas: 687 ================================================================================ ================================================================================ ARCHIVO #124: src/Dates/Date.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Dates/Date.php Tamaño: 20.25 KB -------------------------------------------------------------------------------- 1 | 31, 2 => 28, 3 => 31, 4 => 30, 5 => 31, 6 => 30, 7 => 31, 8 => 31, 9 => 30, 10 => 31, 11 => 30, 12 => 31]; 22 | private $_meses = [ 23 | 1 => 'Enero', 24 | 2 => 'Febrero', 25 | 3 => 'Marzo', 26 | 4 => 'Abril', 27 | 5 => 'Mayo', 28 | 6 => 'Junio', 29 | 7 => 'Julio', 30 | 8 => 'Agosto', 31 | 9 => 'Septiembre', 32 | 10 => 'Octubre', 33 | 11 => 'Noviembre', 34 | 12 => 'Diciembre' 35 | ]; 36 | 37 | 38 | 39 | /// Obtiene las cantidad de dias que tiene el mes según el año 40 | public function DiasMes(int $mes, int $año) 41 | { 42 | 43 | if ($mes < 1 || $mes > 12) 44 | return 0; 45 | 46 | if ($mes == 2) { // febrero 47 | $mod_año = Modulo::Calc($año, 4); 48 | 49 | return ($mod_año->Resto == 0) ? $this->_diasMes[$mes] + 1 : $this->_diasMes[$mes]; 50 | } else { 51 | return $this->_diasMes[$mes]; 52 | } 53 | } 54 | 55 | public function MesDelAño(?DateTime $fecha) 56 | { 57 | if(!isset($fecha)) 58 | $fecha = $this; 59 | 60 | $mes = (int)$fecha->format('n'); 61 | return $this->_meses[$mes]; 62 | } 63 | 64 | public function WeekDay($SundayStartsOnZero = false) 65 | { 66 | 67 | $diaSemana = $this->format('w') * 1; 68 | $diaSemana = $diaSemana + (($SundayStartsOnZero) ? 0 : 1); 69 | 70 | return $diaSemana; 71 | } 72 | 73 | public static function FromNumericDate($idTurno) 74 | { 75 | $fecha = substr($idTurno, 0, 4) 76 | . '-' . substr($idTurno, 4, 2) 77 | . '-' . substr($idTurno, 6, 2) 78 | . ' ' . substr($idTurno, 8, 2) 79 | . ':' . substr($idTurno, 10, 2); 80 | 81 | return new self($fecha); 82 | } 83 | 84 | public static function Hoy(?int $offset = null) 85 | { 86 | if ($offset != null) { 87 | $fecha = new self('now', 'UTC'); 88 | $intervalo = 'PT' . abs($offset) . 'H'; 89 | 90 | if ($offset > 0) 91 | $fecha->add(new DateInterval($intervalo)); 92 | else 93 | $fecha->sub(new DateInterval($intervalo)); 94 | // Se instancia de nuevo para que se mantenga la zona horaria por defecto 95 | return new self($fecha->format('Y-m-d H:i:s')); 96 | } else 97 | return new self(); 98 | } 99 | 100 | 101 | public function __construct($time = 'now', $timezone = 'America/Santiago') 102 | { 103 | parent::__construct($time, new \DateTimeZone($timezone)); 104 | } 105 | 106 | public function __toString() 107 | { 108 | return $this->format('Y-m-d H:i:s'); 109 | } 110 | 111 | public static function IsValidDateFast(string $dateString, string $format = 'Y-m-d'): bool 112 | { 113 | // Suprimimos los errores para no generar warnings en cada iteración. 114 | // Esto es solo para rendimiento, la lógica sigue siendo la misma. 115 | $date = @DateTime::createFromFormat($format, $dateString); 116 | 117 | // Asegurarse de que se creó un objeto DateTime y que el string original 118 | // coincide con el string formateado del objeto (para evitar desbordamientos). 119 | return $date && $date->format($format) === $dateString; 120 | } 121 | 122 | /** 123 | * Convierte un número serial de fecha de Excel a un timestamp Unix en PHP. 124 | * Esta función es la misma que te proporcioné anteriormente. 125 | * 126 | * @param float $excelDate El número serial de fecha de Excel (puede tener decimales para la hora). 127 | * @return int|false Un timestamp Unix (entero) o false si la entrada no es válida. 128 | */ 129 | private static function ExcelSerialDateToUnixTimestamp(float $excelDate) 130 | { 131 | if ($excelDate < 1) { 132 | return false; 133 | } 134 | 135 | $daysOffset = 25569; 136 | 137 | if ($excelDate < 61) { 138 | $daysOffset--; 139 | } 140 | 141 | $unixDays = $excelDate - $daysOffset; 142 | $timestamp = round($unixDays * 86400); 143 | 144 | // Para evitar errores con timestamps fuera de rango en sistemas de 32 bits 145 | if ($timestamp > PHP_INT_MAX || $timestamp < ~PHP_INT_MAX) { // ~PHP_INT_MAX es el mínimo negativo 146 | return false; 147 | } 148 | 149 | return (int) $timestamp; 150 | } 151 | 152 | public static function ConvertExcelDateToYMD(float $excelDate) 153 | { 154 | $timestamp = self::ExcelSerialDateToUnixTimestamp($excelDate); 155 | if ($timestamp === false) { 156 | return false; 157 | } 158 | return date('Y-m-d', $timestamp); 159 | } 160 | 161 | public static function ConvertExcelDateTimeToYMDHIS(float $excelDate) 162 | { 163 | $timestamp = self::ExcelSerialDateToUnixTimestamp($excelDate); 164 | if ($timestamp === false) { 165 | return false; 166 | } 167 | return date('Y-m-d H:i:s', $timestamp); 168 | } 169 | 170 | public function addInterval( 171 | int $years = 0, 172 | int $months = 0, 173 | int $days = 0, 174 | int $hours = 0, 175 | int $minutes = 0, 176 | int $seconds = 0 177 | ) { 178 | 179 | // Valores actuales de la fecha 180 | // como intervalo de tiempos 181 | $fechaActual = new Interval( 182 | Years: $this->format('Y') * 1, 183 | Months: $this->format('m') * 1, 184 | Days: $this->format('d') * 1, 185 | Hours: $this->format('H') * 1, 186 | Minutes: $this->format('i') * 1, 187 | Seconds: $this->format('s') * 1 188 | ); 189 | 190 | // Intervalo a agregar 191 | $add = new Interval( 192 | Years: $years, 193 | Months: $months, 194 | Days: $days, 195 | Hours: $hours, 196 | Minutes: $minutes, 197 | Seconds: $seconds 198 | ); 199 | 200 | 201 | // Regularizar los elementos a agregar desde los segundos hacia adelante 202 | // 203 | 204 | // Segundos a agregar 205 | if ($add->Seconds > 0) { 206 | 207 | // agregar los segundos solicitados 208 | $fechaActual->Seconds += $add->Seconds; 209 | 210 | // Si pasa de 60 segundos, aumentar los minutos a agregar y sólo dejar los segundos que restan 211 | if ($fechaActual->Seconds >= 60) { 212 | $modulo = Modulo::Calc($fechaActual->Seconds, 60); 213 | 214 | $add->Minutes += $modulo->Cociente; 215 | $fechaActual->Seconds = $modulo->Resto; 216 | } 217 | } 218 | 219 | // Minutos a agregar 220 | if ($add->Minutes > 0) { 221 | 222 | // agregar los minutos solicitados 223 | $fechaActual->Minutes += $add->Minutes; 224 | 225 | // Si pasa de 60 minutos, aumentar las horas a agregar 226 | if ($fechaActual->Minutes >= 60) { 227 | $modulo = Modulo::Calc($fechaActual->Minutes, 60); 228 | 229 | $add->Hours += $modulo->Cociente; 230 | $fechaActual->Minutes = $modulo->Resto; 231 | } 232 | } 233 | 234 | // Horas a agregar 235 | if ($add->Hours > 0) { 236 | 237 | // Agregar las horas solicitadas 238 | $fechaActual->Hours += $add->Hours; 239 | 240 | // Si pasa de 24 horas, aumentar los días a agregar 241 | if ($fechaActual->Hours >= 24) { 242 | 243 | $modulo = Modulo::Calc($fechaActual->Hours, 24); 244 | 245 | $add->Days += $modulo->Cociente; 246 | $fechaActual->Hours = $modulo->Resto; 247 | } 248 | } 249 | 250 | // Dias a agregar 251 | // Obs: tomar en cuenta al pasar por febrero, si el año es bisiesto 252 | if ($add->Days > 0) { 253 | 254 | $currentDay = $this->format('d') * 1; 255 | $currentMonth = $this->format('m') * 1; 256 | $currentYear = $this->format('Y') * 1; 257 | 258 | // dias a agregar 259 | $remanente = $add->Days; 260 | 261 | // agregar dias mes por mes 262 | while ($remanente > 0) { 263 | 264 | // obtener los dias disponibles del mes actual 265 | $disponible = $this->DiasMes($currentMonth, $currentYear) - $currentDay + 1; 266 | 267 | if ($disponible > $remanente) { 268 | // terminamos 269 | $currentDay += $remanente; 270 | $remanente = 0; 271 | } else { 272 | $currentDay = 1; 273 | $currentMonth++; 274 | 275 | if ($currentMonth > 12) { 276 | $currentMonth = 1; 277 | $currentYear++; 278 | } 279 | 280 | $remanente = $remanente - $disponible; 281 | } 282 | } 283 | 284 | $fechaActual->Days = $currentDay; 285 | $fechaActual->Months = $currentMonth; 286 | $fechaActual->Years = $currentYear; 287 | } 288 | 289 | // Meses a agregar 290 | // Obs: la fecha actual ya se encuentra actualizada en la pasada de los días, si se agregó alguno 291 | if ($add->Months > 0) { 292 | // se agregan meses, tener cuidado en la cantidad de días que tiene cada uno 293 | $remanente = $add->Months; 294 | 295 | while ($remanente > 0) { 296 | 297 | $remanente--; 298 | 299 | // agregamos 1 mes 300 | if ($fechaActual->Months == 12) { // diciembre tiene 31 días y enero también, así que agregamos 1 al año y dejamos en enero el mes actual 301 | $fechaActual->Months = 1; 302 | $fechaActual->Years++; 303 | } else { 304 | // verificamos si en el siguiente mes, se puede tener el mismo día actual 305 | $diasMesSiguiente = $this->DiasMes($fechaActual->Months + 1, $fechaActual->Years); 306 | 307 | // Tenemos el día actual en el siguiente mes, entonces sólo aumentamos el mes 308 | if ($fechaActual->Days <= $diasMesSiguiente) { 309 | $fechaActual->Months++; 310 | } 311 | // Si no tenemos el día en el siguiente mes, tenemos que dejar el día según 312 | // la diferencia y hacer que el bucle se ejecute de nuevo para agregar el mes 313 | else { 314 | $fechaActual->Days = $fechaActual->Days - $diasMesSiguiente; 315 | // aseguramos una ejecución adicional del ciclo para que agregue el mes 316 | $remanente++; 317 | } 318 | } 319 | } 320 | } 321 | 322 | // Año a agregar 323 | // Obs: si estamos en año bisiesto y la fecha actual es 29-Febrero, se agrega el año pero se cambia al 1-Marzo, dado que el siguiente año no es bisiesto 324 | if ($add->Years > 0) { 325 | 326 | $remanente = $add->Years; 327 | 328 | while ($remanente > 0) { 329 | 330 | if ($fechaActual->Months == 2 && $fechaActual->Days == 29) { 331 | $fechaActual->Years++; 332 | $fechaActual->Months = 3; 333 | $fechaActual->Days = 1; 334 | } else { 335 | $fechaActual->Years++; 336 | } 337 | 338 | $remanente--; 339 | } 340 | } 341 | 342 | return new Date( 343 | $fechaActual->Years . '-' . 344 | $fechaActual->Months . '-' . 345 | $fechaActual->Days . ' ' . 346 | $fechaActual->Hours . ':' . 347 | $fechaActual->Minutes . ':' . 348 | $fechaActual->Seconds 349 | ); 350 | } 351 | 352 | 353 | public function subInterval( 354 | int $years = 0, 355 | int $months = 0, 356 | int $days = 0, 357 | int $hours = 0, 358 | int $minutes = 0, 359 | int $seconds = 0 360 | ) { 361 | 362 | // Valores actuales de la fecha 363 | // como intervalo de tiempos 364 | $fechaActual = new Interval( 365 | Years: $this->format('Y') * 1, 366 | Months: $this->format('m') * 1, 367 | Days: $this->format('d') * 1, 368 | Hours: $this->format('H') * 1, 369 | Minutes: $this->format('i') * 1, 370 | Seconds: $this->format('s') * 1 371 | ); 372 | 373 | // Intervalo a sustraer 374 | $sub = new Interval( 375 | Years: $years, 376 | Months: $months, 377 | Days: $days, 378 | Hours: $hours, 379 | Minutes: $minutes, 380 | Seconds: $seconds 381 | ); 382 | 383 | 384 | // Regularizar los elementos a sustraer desde los segundos hacia adelante 385 | // 386 | 387 | // Segundos a sustraer 388 | if ($sub->Seconds > 0) { 389 | 390 | // sustraer los segundos solicitados 391 | $fechaActual->Seconds -= $sub->Seconds; 392 | 393 | // Si baja de 0 segundos, sustraer los minutos a y sólo dejar los segundos que restan 394 | if ($fechaActual->Seconds < 0) { 395 | $modulo = Modulo::Calc(abs($fechaActual->Seconds) + 60, 60); 396 | 397 | $sub->Minutes += $modulo->Cociente; 398 | $fechaActual->Seconds = 60 - $modulo->Resto; 399 | } 400 | } 401 | 402 | 403 | // Minutos a agregar 404 | if ($sub->Minutes > 0) { 405 | 406 | // agregar los minutos solicitados 407 | $fechaActual->Minutes -= $sub->Minutes; 408 | 409 | // Si baja de 0 minutos, sustraer las horas 410 | if ($fechaActual->Minutes < 0) { 411 | $modulo = Modulo::Calc(abs($fechaActual->Minutes) + 60, 60); 412 | 413 | $sub->Hours += $modulo->Cociente; 414 | $fechaActual->Minutes = 60 - $modulo->Resto; 415 | } 416 | } 417 | 418 | 419 | // Horas a agregar 420 | if ($sub->Hours > 0) { 421 | 422 | // Agregar las horas solicitadas 423 | $fechaActual->Hours -= $sub->Hours; 424 | 425 | // Si pasa de 24 horas, aumentar los días a agregar 426 | if ($fechaActual->Hours < 0) { 427 | 428 | $modulo = Modulo::Calc(abs($fechaActual->Hours) + 24, 24); 429 | 430 | $sub->Days += $modulo->Cociente; 431 | $fechaActual->Hours = 24 - $modulo->Resto; 432 | } 433 | } 434 | 435 | 436 | // Dias a sustraer 437 | // Obs: tomar en cuenta al pasar por febrero, si el año es bisiesto 438 | if ($sub->Days > 0) { 439 | 440 | // dias a sustraer 441 | $remanente = $sub->Days; 442 | 443 | // sustraer dias mes por mes 444 | while ($remanente > 0) { 445 | 446 | if ($remanente < $fechaActual->Days) { 447 | // terminamos 448 | $fechaActual->Days -= $remanente; 449 | $remanente = 0; 450 | } else { 451 | 452 | $remanente -= $fechaActual->Days; 453 | 454 | // quitar los dias y dejar en el ultimo dia del mes anterior 455 | if ($fechaActual->Months == 1) { 456 | $fechaActual->Months = 12; 457 | $fechaActual->Years--; 458 | $fechaActual->Days = 31; 459 | } else { 460 | $fechaActual->Months--; 461 | $fechaActual->Days = $this->DiasMes($fechaActual->Months, $fechaActual->Years); 462 | } 463 | } 464 | } 465 | } 466 | 467 | 468 | // Meses a sustraer 469 | // Obs: la fecha actual ya se encuentra actualizada en la pasada de los días, si se sustrajo alguno 470 | if ($sub->Months > 0) { 471 | 472 | // se sustraen meses, tener cuidado en la cantidad de días que tiene cada uno 473 | $remanente = $sub->Months; 474 | 475 | while ($remanente > 0) { 476 | 477 | $remanente--; 478 | 479 | // sustraemos 1 mes 480 | if ($fechaActual->Months == 1) { // diciembre tiene 31 días y enero también, así que sustraemos 1 al año y dejamos en diciembre el mes actual 481 | $fechaActual->Months = 12; 482 | $fechaActual->Years--; 483 | } else { 484 | // verificamos si en el mes anterior, se puede tener el mismo día actual 485 | $diasMesAnterior = $this->DiasMes($fechaActual->Months - 1, $fechaActual->Years); 486 | 487 | // Tenemos el día actual en el mes anterior, entonces sólo sustraemos el mes 488 | if ($fechaActual->Days <= $diasMesAnterior) { 489 | $fechaActual->Months--; 490 | } 491 | // Si no tenemos el día en el mes anterior, esteblecemos 492 | // el dia como el maximo dia perimitido del mes anterior 493 | else { 494 | $fechaActual->Months--; 495 | $fechaActual->Days = $diasMesAnterior; 496 | } 497 | } 498 | } 499 | } 500 | 501 | 502 | 503 | // Año a sustraer 504 | // Obs: si estamos en año bisiesto y la fecha actual es 29-Febrero, se sustrae el año pero se cambia al 1-Marzo, dado que el año anterior no es bisiesto 505 | if ($sub->Years > 0) { 506 | 507 | $remanente = $sub->Years; 508 | 509 | while ($remanente > 0) { 510 | 511 | if ($fechaActual->Months == 2 && $fechaActual->Days == 29) { 512 | $fechaActual->Years--; 513 | $fechaActual->Months = 3; 514 | $fechaActual->Days = 1; 515 | } else { 516 | $fechaActual->Years--; 517 | } 518 | 519 | $remanente--; 520 | } 521 | } 522 | 523 | 524 | return new Date( 525 | $fechaActual->Years . '-' . 526 | $fechaActual->Months . '-' . 527 | $fechaActual->Days . ' ' . 528 | $fechaActual->Hours . ':' . 529 | $fechaActual->Minutes . ':' . 530 | $fechaActual->Seconds 531 | ); 532 | } 533 | 534 | public function hourDiff(Date $compareDate) 535 | { 536 | 537 | $diferencia = $this->diff($compareDate); 538 | $delta = abs(round($diferencia->days * 24 + $diferencia->h + ($diferencia->i / 60) + ($diferencia->s / 3600), 2)); 539 | 540 | if ($diferencia->invert == 0) { // $tarea->Display->DtInicioReal < $tarea->Display->DtInicioTarea) { 541 | $delta = $delta * -1; 542 | } 543 | 544 | return $delta; 545 | } 546 | 547 | public static function ObtenerDiferenciaTiempo(?string $fechaInicio = null, ?string $fechaFin = null): string { 548 | 549 | if (!isset($fechaInicio) || $fechaInicio == "" || !isset($fechaFin) || $fechaFin == "") { 550 | return " "; 551 | } 552 | 553 | return self::ObtenerDiferenciaTiempoFromDate( 554 | new DateTime($fechaInicio), 555 | new DateTime($fechaFin) 556 | ); 557 | } 558 | 559 | public static function ObtenerDiferenciaTiempoFromDate(?DateTime $fechaInicio = null, ?DateTime $fechaFin = null): string { 560 | 561 | if (!isset($fechaInicio) || !isset($fechaFin)) { 562 | return " "; 563 | } 564 | 565 | // Asegurarse de que fechaInicio sea siempre la más antigua 566 | if ($fechaInicio > $fechaFin) { 567 | $temp = $fechaInicio; 568 | $fechaInicio = $fechaFin; 569 | $fechaFin = $temp; 570 | } 571 | 572 | $intervalo = $fechaInicio->diff($fechaFin); 573 | 574 | // Calcular la diferencia total en segundos y minutos para facilitar las comparaciones 575 | $segundosTotales = $intervalo->days * 86400 + $intervalo->h * 3600 + $intervalo->i * 60 + $intervalo->s; 576 | $minutosTotales = floor($segundosTotales / 60); 577 | 578 | // Condición: Menor a 1 minuto 579 | if ($segundosTotales < 60) { 580 | return $segundosTotales . " segs."; 581 | } 582 | 583 | // Condición: Mayor o igual a 1 min pero menor a 10 min 584 | if ($minutosTotales < 10) { 585 | // Para obtener un decimal en minutos, calculamos directamente desde segundos 586 | $minutosConDecimal = round($segundosTotales / 60, 1); 587 | return $minutosConDecimal . " mins"; 588 | } 589 | 590 | // Condición: Mayor o igual a 10 min y menor a 1 hora (60 minutos) 591 | // Usamos $minutosTotales para asegurar que no incluya segundos si la condición es estricta para minutos enteros. 592 | if ($minutosTotales < 60) { 593 | return $minutosTotales . " minutos"; 594 | } 595 | 596 | // Condición: Mayor a 1 hora pero menor o igual a 61 minutos 597 | // Aquí parece haber una pequeña confusión en la descripción "menor o igual a 61 minutos" 598 | // para una condición "mayor a 1 hora". 599 | // Interpretando como: "Si es exactamente 1 hora, y hasta 1 hora y 1 minuto (61 minutos en total)" 600 | // Si la intención es "si el resultado es 1 hora y algunos segundos, pero el total no excede 61 minutos", 601 | // entonces esta condición se superpondría con la anterior. 602 | // La interpretación más lógica para "Mayor a 1 hora pero menor o igual a 61 minutos" sería: 603 | // Si la diferencia es de 1 hora y 0 minutos, hasta 1 hora y 1 minuto. 604 | // Usaremos los atributos del objeto DateInterval para mayor claridad. 605 | if ($intervalo->h == 1 && $intervalo->i <= 1) { // 1 hora y hasta 1 minuto 606 | return $intervalo->h . " hora"; // No considerar los minutos 607 | } 608 | 609 | // Condición: Mayor a 61 minutos (o si las condiciones anteriores no se cumplieron) 610 | // Esto cubrirá cualquier duración de 1 hora y 2 minutos en adelante, o más de 1 hora. 611 | $horas = $intervalo->h + ($intervalo->days * 24); // Asegurarse de incluir días en horas 612 | $minutosRestantes = $intervalo->i; 613 | 614 | return $horas . ($intervalo->h == 1 ? " hora " : " horas " ) . $minutosRestantes . " mins"; 615 | } 616 | 617 | } 618 | -------------------------------------------------------------------------------- Total de líneas: 618 ================================================================================ ================================================================================ ARCHIVO #125: src/Dates/Interval.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Dates/Interval.php Tamaño: 2.48 KB -------------------------------------------------------------------------------- 1 | 0) { 42 | $qHoras = $horas[0]; 43 | $remanente = isset($horas[1]) ? $horas[1] : ''; 44 | } 45 | } 46 | 47 | // ¿vienen minutos? 48 | $qMinutos = ''; 49 | if (strpos($remanente, 'M') !== false) { 50 | $minutos = explode('M', $remanente); 51 | if (is_array($minutos) && count($minutos) > 0) { 52 | $qMinutos = $minutos[0]; 53 | $remanente = isset($minutos[1]) ? $minutos[1] : ''; 54 | } 55 | } 56 | 57 | // ¿vienen segundos? 58 | $qSegundos = ''; 59 | if (strpos($remanente, 'S') !== false) { 60 | $segundos = explode('S', $remanente); 61 | if (is_array($segundos) && count($segundos) > 0) { 62 | $qSegundos = $segundos[0]; 63 | } 64 | } 65 | 66 | if (is_numeric($qHoras)) { 67 | $qHoras = round($qHoras, 0); 68 | } 69 | else { 70 | $qHoras = 0; 71 | } 72 | 73 | if (is_numeric($qMinutos)) { 74 | $qMinutos = round($qMinutos, 0); 75 | } 76 | else { 77 | $qMinutos = 0; 78 | } 79 | 80 | if (is_numeric($qSegundos)) { 81 | $qSegundos = round($qSegundos, 0); 82 | } 83 | else { 84 | $qSegundos = 0; 85 | } 86 | 87 | $interval = $qHoras . 'H' . $qMinutos . 'M' . $qSegundos . 'S'; 88 | 89 | try { 90 | $result = new \DateInterval('PT' . $interval); 91 | } 92 | catch (\Exception $ex) { 93 | return null; 94 | } 95 | 96 | return $result; 97 | 98 | } 99 | } -------------------------------------------------------------------------------- Total de líneas: 99 ================================================================================ ================================================================================ ARCHIVO #126: src/Document/GenericDocument.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Document/GenericDocument.php Tamaño: 6.98 KB -------------------------------------------------------------------------------- 1 | DocumentDefinition = $documentDefinition; 27 | $this->DocumentDefinitionClass = get_class($documentDefinition); 28 | $this->DocumentClass = get_class($this); 29 | 30 | $this->Data = $data; 31 | } 32 | 33 | /** 34 | * Obtiene el enlace codificado que contiene la información de definicion de este documento 35 | */ 36 | public function GetEncodedLink() { 37 | 38 | $params = get_object_vars($this->DocumentDefinition); 39 | 40 | // Recorrer las propiedades y los valores 41 | $link = ''; 42 | foreach($params as $prop => $value) { 43 | if ($link != '') { 44 | $link .= ','; 45 | } 46 | 47 | $link .= $prop . "=" . trim($value); 48 | } 49 | 50 | return Encoder::Instance()->Encode($link); 51 | } 52 | 53 | /** 54 | * Agrega una clase al diccionario de tipos 55 | * Esto permite generar el tipo correcto desde el link codificado 56 | * 57 | * @param string $documentClassname 58 | * @param string $documentDefinitionclassName 59 | * @param string $className 60 | */ 61 | public static function AddToDictionary($documentType, $documentClassname, $documentDefinitionclassName) { 62 | self::$DocumentTypeDictionary[$documentType] = [$documentClassname, $documentDefinitionclassName]; 63 | } 64 | 65 | /** 66 | * Retorna un objeto anónimo con los valores encontrados en el link 67 | * 68 | * @param string $encodedLink 69 | * 70 | * @return GenericDocument 71 | */ 72 | public static function NewFromEncodedLink($encodedLink) { 73 | 74 | $link = Encoder::Instance()->Decode($encodedLink); 75 | 76 | // Crear un arreglo con los parámetros 77 | $paramList = array(); 78 | $params = explode(',', $link); 79 | 80 | foreach($params as $keypar) { 81 | $par = explode('=', $keypar); 82 | 83 | if (isset($par[0]) && isset($par[1])) { 84 | $paramList[$par[0]] = $par[1] == '' ? null : $par[1]; 85 | } 86 | } 87 | 88 | // Crear un nuevo objeto para la definición del documento 89 | // 90 | $documentDefinition = null; 91 | 92 | if (isset($paramList['DocumentType'])) { 93 | 94 | // Buscar el objeto en el diccionario 95 | if (isset(self::$DocumentTypeDictionary[$paramList['DocumentType']])) { 96 | 97 | $documentDeclaration = self::$DocumentTypeDictionary[$paramList['DocumentType']]; 98 | 99 | $documentClassName = $documentDeclaration[0]; 100 | $definitionClassName = $documentDeclaration[1]; 101 | 102 | $documentDefinition = new $definitionClassName($paramList); 103 | 104 | if (isset($paramList['Filename'])) { 105 | $documentDefinition->Filename = $paramList['Filename']; 106 | } 107 | 108 | $document = new $documentClassName($documentDefinition); 109 | } 110 | } 111 | else { 112 | throw new \Exception('El tipo de documento no ha sido definido'); 113 | } 114 | 115 | return $document; 116 | } 117 | 118 | public static function GenerateRandomFilename(string $extension = null, $prefix = '', $longFilename = false) { 119 | 120 | $filename = uniqid($prefix, $longFilename); 121 | 122 | if (isset($extension)) { 123 | $filename .= '.' . $extension; 124 | } 125 | 126 | return $filename; 127 | } 128 | 129 | public function SetContent($data) { 130 | $this->Data = $data; 131 | } 132 | 133 | public function GetDocumentDefinition() { 134 | 135 | return $this->DocumentDefinition; 136 | 137 | } 138 | 139 | /** 140 | * Obtiene la carpeta donde se almacenará el documento, según lógica basada en el DocumentDefinition 141 | */ 142 | abstract function GetFolder(); 143 | 144 | /** 145 | * Obtiene el nombre del archivo 146 | */ 147 | abstract function GetFilename(); 148 | 149 | /** 150 | * Obtiene la ruta del archivo en formato URL 151 | */ 152 | abstract function GetUrl(); 153 | 154 | abstract function GetHttpUrl(); 155 | 156 | 157 | public function GetPath() { 158 | 159 | // Obtener la carpeta de almacenamiento del archivo 160 | // 161 | $folderpath = $this->GetFolder(); 162 | 163 | // Obtener el nombre del archivo 164 | // 165 | $filename = $this->GetFilename(); 166 | 167 | // Generar la ruta del archivo 168 | // 169 | $filepath = $folderpath . '/' . $filename; 170 | 171 | return $filepath; 172 | } 173 | 174 | 175 | 176 | /** 177 | * Abre el archivo correspondiente al documento y retorna el contenido 178 | * 179 | */ 180 | public function LoadDocument($binary = true) { 181 | 182 | // Chequear que el archivo exista 183 | // 184 | $filepath = $this->GetPath(); 185 | 186 | if (file_exists($filepath)) { 187 | $file = null; 188 | 189 | if ($binary) 190 | $file = fopen($filepath, 'rb'); 191 | else 192 | $file = fopen($filepath, 'r'); 193 | 194 | if ($file) { 195 | $contents = fread($file, filesize($filepath)); 196 | fclose($file); 197 | 198 | return $contents; 199 | } 200 | 201 | else { 202 | return null; 203 | } 204 | 205 | } 206 | else { 207 | return null; 208 | } 209 | } 210 | 211 | /** 212 | * Guarda el archivo correspondiente al documento en la ruta definida 213 | * 214 | * @param bool $sobreescribir Sobrescribir el archivo si existe 215 | * @param bool $base64Image Guardar el archivo como imagen desde un origen en base64 216 | * 217 | */ 218 | public function SaveDocument($sobreescribir = false, $base64Image = false, $createFolders = true) { 219 | 220 | // Chequear que la data exista 221 | // 222 | if (!isset($this->Data) || $this->Data == '') { 223 | throw new \Exception('El documento no contiene información para guardar'); 224 | } 225 | 226 | // Chequear que la carpeta de destino existe 227 | // 228 | $folderPath = $this->GetFolder($this->DocumentDefinition); 229 | 230 | if (!file_exists($folderPath)) { 231 | if ($createFolders) { 232 | mkdir($folderPath, 0775, true); 233 | } 234 | } 235 | 236 | // Chequear que el archivo NO exista 237 | // 238 | $filepath = $this->GetPath(); 239 | 240 | if (file_exists($filepath) && !$sobreescribir) { 241 | throw new \Exception('El archivo ya existe'); 242 | } 243 | else { 244 | if ($base64Image) { 245 | // Escribir la imagen 246 | $imageData = base64_decode($this->Data); 247 | $source = imagecreatefromstring($imageData); 248 | $rotate = imagerotate($source, 0, 0); // if want to rotate the image 249 | $imageSave = imagejpeg($rotate, $filepath, 100); 250 | 251 | imagedestroy($source); 252 | } 253 | else { 254 | file_put_contents($filepath, $this->Data); 255 | } 256 | } 257 | } 258 | 259 | } -------------------------------------------------------------------------------- Total de líneas: 259 ================================================================================ ================================================================================ ARCHIVO #127: src/Document/GenericDocumentDefinition.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Document/GenericDocumentDefinition.php Tamaño: 548 bytes -------------------------------------------------------------------------------- 1 | _Headers = getallheaders(); 31 | } 32 | 33 | private static $Instance = null; 34 | 35 | protected static function Create() { 36 | return new Headers(); 37 | } 38 | 39 | final protected static function GetInstance() { 40 | return self::$Instance; 41 | } 42 | 43 | final protected static function SetInstance($instance) { 44 | self::$Instance = $instance; 45 | } 46 | 47 | public function __get($key) { 48 | 49 | if (isset($this->_Headers[$key])) { 50 | return $this->_Headers[$key]; 51 | } 52 | else { 53 | return ''; 54 | } 55 | } 56 | 57 | public function Get($key) { 58 | if (isset($this->_Headers[$key])) { 59 | return $this->_Headers[$key]; 60 | } 61 | else { 62 | return ''; 63 | } 64 | } 65 | } -------------------------------------------------------------------------------- Total de líneas: 65 ================================================================================ ================================================================================ ARCHIVO #131: src/Environment/Ini.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Environment/Ini.php Tamaño: 1.28 KB -------------------------------------------------------------------------------- 1 | Name[$Name] = ini_get($Name); 39 | ini_set($Name, $Value); 40 | } 41 | 42 | public function Rollback(string $Name) { 43 | if (isset($this->Name[$Name]) && $this->Name[$Name] != null) { 44 | ini_set($Name, $this->Name[$Name]); 45 | } 46 | else { 47 | throw new \Exception('Se intenta restaurar un valor de INI no cambiado previamente'); 48 | } 49 | } 50 | 51 | public function SetTimeLimit($seconds) { 52 | set_time_limit($seconds); 53 | } 54 | } -------------------------------------------------------------------------------- Total de líneas: 54 ================================================================================ ================================================================================ ARCHIVO #132: src/Environment/IniEnum.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Environment/IniEnum.php Tamaño: 553 bytes -------------------------------------------------------------------------------- 1 | debugMessage; 25 | } 26 | } -------------------------------------------------------------------------------- Total de líneas: 26 ================================================================================ ================================================================================ ARCHIVO #137: src/Exceptions/BusinessException.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Exceptions/BusinessException.php Tamaño: 2.38 KB -------------------------------------------------------------------------------- 1 | getTrace(); 26 | // $debugTrace = debug_backtrace(); 27 | // $calling_method = $trace[1]['function']; 28 | // $calling_class = $trace[1]['class']; 29 | 30 | if ($debugMessage == '') { 31 | switch($code) { 32 | case ExceptionCodesEnum::ERR_INVALID_PARAMETER: $debugMessage = 'El parámetro es inválido'; break; 33 | case ExceptionCodesEnum::ERR_MISSING_FILES: $debugMessage = 'No se han especificado archivos'; break; 34 | case ExceptionCodesEnum::ERR_MISSING_PARAMETER: $debugMessage = 'Falta el parámetro requerido'; break; 35 | case ExceptionCodesEnum::ERR_NO_SESSION: $debugMessage = 'No existe la sesión, o la sesión ha caducado'; break; 36 | } 37 | } 38 | 39 | if ($message == '') { 40 | $message = self::$DefaultMessage; 41 | } 42 | else { 43 | // Para el tipo de error ERROR_WITHVIEW, dejamos en manos de la función llamante el despliegue del error 44 | if ($code != ExceptionCodesEnum::ERR_WITHVIEW) { 45 | // Si la primera letra del mensaje es mayuscula, adicionamos el punto seguido y un espacio 46 | $first = substr($message, 0, 1); 47 | 48 | if (str_contains(self::$CapitalChars, $first)) { 49 | $message = '. ' . $message; 50 | } 51 | else { 52 | // caso contrario, solamente separamos con una coma 53 | $message = ', ' . $message; 54 | } 55 | $message = self::$DefaultMessage . $message; 56 | } 57 | } 58 | 59 | parent::__construct(message: $message, code: $code); 60 | } 61 | 62 | public function getDebugMessage() { 63 | return $this->debugMessage; 64 | } 65 | } -------------------------------------------------------------------------------- Total de líneas: 65 ================================================================================ ================================================================================ ARCHIVO #138: src/Exceptions/ExceptionCodesEnum.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Exceptions/ExceptionCodesEnum.php Tamaño: 866 bytes -------------------------------------------------------------------------------- 1 | Load($filepath); 21 | } 22 | } 23 | 24 | private function Load($file) { 25 | 26 | // Abrir el json 27 | $content = file_get_contents($file); 28 | $this->Json = json_decode($content, false, 512, JSON_FORCE_OBJECT); 29 | 30 | } 31 | 32 | public function IsNewEnabled($data) { 33 | 34 | $result = true; // por defecto SI 35 | $entity = $this->SearchEntity($data->Entity); 36 | 37 | if (isset($entity) && isset($entity->Definition) && $entity->Definition->NewEnabled == false) { 38 | $result = false; 39 | } 40 | 41 | return $result; 42 | } 43 | 44 | private function SearchEntity($entity) { 45 | 46 | $result = null; 47 | 48 | if (isset($this->Json) && isset($this->Json->Entities)) { 49 | $found = null; 50 | foreach($this->Json->Entities as $ent) { 51 | if ($ent->Schema == $entity->Schema && $ent->Entity == $entity->Table) { 52 | $found = $ent; 53 | break; 54 | } 55 | } 56 | 57 | if (isset($found)) { 58 | $result = $found; 59 | } 60 | } 61 | 62 | return $result; 63 | } 64 | } -------------------------------------------------------------------------------- Total de líneas: 64 ================================================================================ ================================================================================ ARCHIVO #142: src/Generator/Engine.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Generator/Engine.php Tamaño: 80.64 KB -------------------------------------------------------------------------------- 1 | Dominio = $dominios[$entityDomain]; 48 | } 49 | } 50 | 51 | public function Generate($overwrite = false) { 52 | 53 | $source = __DIR__; 54 | $dest = $_SERVER['OLDPWD'] . "/"; 55 | 56 | $error = false; 57 | 58 | error_reporting(0); 59 | 60 | echo "\n"; 61 | echo "Generación de código iniciada\n"; 62 | echo "-----------------------------\n"; 63 | 64 | // Obtener la lista de tablas 65 | $tablas = explode(',', $this->entityTable); 66 | 67 | // Validación de conexión 68 | $stmt = $this->ValidateConnection(); 69 | 70 | if (!isset($stmt) || $stmt == null) { 71 | return false; 72 | } 73 | 74 | // Procesar las tablas 75 | foreach($tablas as $tabla) { 76 | 77 | $table = trim($tabla); 78 | 79 | $schema = $this->GetSchema($table); 80 | $validated = $this->Validate(Table: $table, Overwrite: $overwrite, Stmt: $stmt, Dest: $dest); 81 | 82 | if (!$validated) 83 | continue; 84 | 85 | // Obtener los campos de la tabla 86 | // 87 | $fields = $this->GetTableFields(Table: $table, Conn: $stmt); 88 | 89 | // Convertir los campos 90 | // 91 | $fieldContent = $this->ConvertFields($fields); 92 | 93 | // Generar los archivos 94 | // 95 | $files = [ 96 | "Dto" => [ 97 | "TemplatePath" => $source . '/Templates/Dto.php', 98 | "DestinationFolder" => $dest . 'Application/BLL/DataTransferObjects/' . $this->entityNamespace, 99 | "Destination" => $dest . 'Application/BLL/DataTransferObjects/' . $this->entityNamespace . '/' . $schema->Table . 'Dto.php', 100 | "Fields" => $fieldContent, 101 | "Preserve" => false 102 | ], 103 | "DtoT" => [ 104 | "TemplatePath" => $source . '/Templates/DtoT.php', 105 | "DestinationFolder" => $dest . 'Application/BLL/DataTransferObjects/' . $this->entityNamespace, 106 | "Destination" => $dest . 'Application/BLL/DataTransferObjects/' . $this->entityNamespace . '/' . $schema->Table . 'DtoT.php', 107 | "Fields" => $fieldContent, 108 | "Preserve" => true 109 | ], 110 | "Svc" => [ 111 | "TemplatePath" => $source . '/Templates/Svc.php', 112 | "DestinationFolder" => $dest . 'Application/BLL/Services/' . $this->entityNamespace, 113 | "Destination" => $dest . 'Application/BLL/Services/' . $this->entityNamespace . '/' . $schema->Table . 'Svc.php', 114 | "Fields" => $fieldContent, 115 | "Preserve" => false 116 | ], 117 | "SvcT" => [ 118 | "TemplatePath" => $source . '/Templates/SvcT.php', 119 | "DestinationFolder" => $dest . 'Application/BLL/Services/' . $this->entityNamespace, 120 | "Destination" => $dest . 'Application/BLL/Services/' . $this->entityNamespace . '/' . $schema->Table . 'SvcT.php', 121 | "Fields" => $fieldContent, 122 | "Preserve" => true 123 | ], 124 | "Ent" => [ 125 | "TemplatePath" => $source . '/Templates/Ent.php', 126 | "DestinationFolder" => $dest . 'Application/Dao/Entities/' . $this->entityNamespace, 127 | "Destination" => $dest . 'Application/Dao/Entities/' . $this->entityNamespace . '/' . $schema->Table . '.php', 128 | "Fields" => $fieldContent, 129 | "Preserve" => false 130 | ], 131 | "EntT" => [ 132 | "TemplatePath" => $source . '/Templates/EntT.php', 133 | "DestinationFolder" => $dest . 'Application/Dao/Entities/' . $this->entityNamespace, 134 | "Destination" => $dest . 'Application/Dao/Entities/' . $this->entityNamespace . '/' . $schema->Table . 'T.php', 135 | "Fields" => $fieldContent, 136 | "Preserve" => true 137 | ], 138 | "Dao" => [ 139 | "TemplatePath" => $source . '/Templates/Dao.php', 140 | "DestinationFolder" => $dest . 'Application/Dao/Services/' . $this->entityNamespace, 141 | "Destination" => $dest . 'Application/Dao/Services/' . $this->entityNamespace . '/' . $schema->Table . 'Dao.php', 142 | "Fields" => $fieldContent, 143 | "Preserve" => false 144 | ], 145 | "DaoT" => [ 146 | "TemplatePath" => $source . '/Templates/DaoT.php', 147 | "DestinationFolder" => $dest . 'Application/Dao/Services/' . $this->entityNamespace, 148 | "Destination" => $dest . 'Application/Dao/Services/' . $this->entityNamespace . '/' . $schema->Table . 'DaoT.php', 149 | "Fields" => $fieldContent, 150 | "Preserve" => true 151 | ] 152 | ]; 153 | 154 | // Generar los archivos 155 | // 156 | foreach($files as $file) { 157 | $this->GenerateFileFromEval(File: $file, Table: $schema, Fields: $fields, VWFields: null, ForeignKeys: null); 158 | //$this->GenerateFile(File: $file, Table: $schema); 159 | } 160 | } 161 | 162 | echo "\n"; 163 | echo "-----------------------------\n"; 164 | 165 | if ($error) { 166 | echo "Generación de código finalizada con error\n"; 167 | } 168 | else { 169 | echo "Generación de código finalizada OK\n"; 170 | } 171 | 172 | echo "\n"; 173 | } 174 | 175 | public function Mantenedor($overwrite = false) { 176 | 177 | $source = __DIR__; 178 | $dest = $_SERVER['OLDPWD'] . "/"; 179 | 180 | $error = false; 181 | 182 | error_reporting(0); 183 | 184 | echo "\n"; 185 | echo "Generación de código iniciada\n"; 186 | echo "-----------------------------\n"; 187 | 188 | // Obtener la lista de tablas 189 | $tablas = explode(',', $this->entityTable); 190 | 191 | // Validación de conexión 192 | $stmt = $this->ValidateConnection(); 193 | 194 | if (!isset($stmt) || $stmt == null) { 195 | return false; 196 | } 197 | 198 | // Obtener configuracion personalizada si existe 199 | $config = new Config($dest . 'Application/Configuration/generator.config.json'); 200 | 201 | // Procesar las tablas 202 | foreach($tablas as $tabla) { 203 | 204 | $table = trim($tabla); 205 | 206 | $schema = $this->GetSchema($table); 207 | $validated = $this->ValidateMantenedores(Table: $table, Overwrite: $overwrite, Stmt: $stmt, Dest: $dest); 208 | 209 | if (!$validated) 210 | continue; 211 | 212 | // Obtener las llaves foraneas 213 | $foreignKeys = $this->GetSqlServerForeignKeys(Conn: $stmt); 214 | 215 | // Obtener los campos de la tabla 216 | // 217 | $fields = $this->GetTableFields(Table: $table, Conn: $stmt, ForeignKeys: $foreignKeys); 218 | 219 | // Obtener los campos de la vista 220 | // 221 | $vwName = ""; 222 | if ( !(substr($schema->Table, 0, 4) == 'Tipo') ) { 223 | $names = explode('.', $table); 224 | if (count($names) == 1) { 225 | $vwName = 'VW'.$table; 226 | } 227 | else if (count($names) > 1) { 228 | $vwName = $names[0] . "." . 'VW' . $names[1]; 229 | } 230 | } 231 | 232 | if ($vwName != "") 233 | $vwFields = $this->GetTableFields(Table: $vwName, Conn: $stmt); 234 | else 235 | $vwFields = $fields; 236 | 237 | 238 | 239 | // Convertir los campos 240 | // 241 | /* 242 | $dataFields = $this->JsonDataFields($fields); 243 | $jsonDataFields = $dataFields[0]; 244 | $listDataFields = $dataFields[1]; 245 | $use = $dataFields[2]; 246 | $formRows = $dataFields[3]; 247 | $formCustom = $dataFields[4]; 248 | 249 | $jsonCustomButtons = $this->JsonCustomButtons($schema, $foreignKeys); 250 | $customButtons = $jsonCustomButtons[0]; 251 | $customBundles = $jsonCustomButtons[1]; 252 | $customFunctions = $jsonCustomButtons[2]; 253 | 254 | $vwGridElements = $this->VWGridFields($vwFields, $schema->Table); 255 | $vwGridColumns = $vwGridElements[0]; 256 | $vwGridButtons = $vwGridElements[1]; 257 | $vwFieldsList = $vwGridElements[2]; 258 | $vwFieldsCustom = $vwGridElements[3]; 259 | 260 | $dtoFields = str_replace('formData.', '$registro->', $jsonDataFields); 261 | $searchFields = $this->JsonSearchFields($fields, false, $foreignKeys, $schema); 262 | 263 | $jsonSearchFields = $searchFields[0]; 264 | $bindingFields = $searchFields[1]; 265 | $searchRows = $searchFields[2]; 266 | $searchCustom = $searchFields[3]; 267 | $getbyMethods = $searchFields[4]; 268 | */ 269 | 270 | 271 | 272 | $filesEval = [ 273 | "ApiControllerT" => [ 274 | "TemplatePath" => $source . '/Templates/Mantenedores/ApiControllerT.php', 275 | "DestinationFolder" => $dest . 'Application/Controllers/Api/Mantenedores/' . $this->entityNamespace, 276 | "Destination" => $dest . 'Application/Controllers/Api/Mantenedores/' . $this->entityNamespace . '/' . $schema->Table . 'ControllerT.php', 277 | "Preserve" => false 278 | ], 279 | "ApiController" => [ 280 | "TemplatePath" => $source . '/Templates/Mantenedores/ApiController.php', 281 | "DestinationFolder" => $dest . 'Application/Controllers/Api/Mantenedores/' . $this->entityNamespace, 282 | "Destination" => $dest . 'Application/Controllers/Api/Mantenedores/' . $this->entityNamespace . '/' . $schema->Table . 'Controller.php', 283 | "Preserve" => false 284 | ], 285 | "BusinessObjectT" => [ 286 | "TemplatePath" => $source . '/Templates/Mantenedores/BusinessObjectT.php', 287 | "DestinationFolder" => $dest . 'Application/BLL/BusinessObjects/Mantenedores/' . $this->entityNamespace, 288 | "Destination" => $dest . 'Application/BLL/BusinessObjects/Mantenedores/' . $this->entityNamespace . '/' . $schema->Table . 'BOT.php', 289 | "Preserve" => true 290 | ], 291 | "BusinessObject" => [ 292 | "TemplatePath" => $source . '/Templates/Mantenedores/BusinessObject.php', 293 | "DestinationFolder" => $dest . 'Application/BLL/BusinessObjects/Mantenedores/' . $this->entityNamespace, 294 | "Destination" => $dest . 'Application/BLL/BusinessObjects/Mantenedores/' . $this->entityNamespace . '/' . $schema->Table . 'BO.php', 295 | "Preserve" => false 296 | ], 297 | "ViewController" => [ 298 | "TemplatePath" => $source . '/Templates/Mantenedores/ViewController.php', 299 | "DestinationFolder" => $dest . 'Application/Controllers/Mantenedores/' . $this->entityNamespace, 300 | "Destination" => $dest . 'Application/Controllers/Mantenedores/' . $this->entityNamespace . '/' . $schema->Table . 'Controller.php', 301 | "Preserve" => false 302 | ], 303 | "ViewControllerT" => [ 304 | "TemplatePath" => $source . '/Templates/Mantenedores/ViewControllerT.php', 305 | "DestinationFolder" => $dest . 'Application/Controllers/Mantenedores/' . $this->entityNamespace, 306 | "Destination" => $dest . 'Application/Controllers/Mantenedores/' . $this->entityNamespace . '/' . $schema->Table . 'ControllerT.php', 307 | "Preserve" => true 308 | ], 309 | "ScriptJST" => [ 310 | "TemplatePath" => $source . '/Templates/Mantenedores/ScriptJST.js', 311 | "DestinationFolder" => $dest . 'public/scripts/mantenedores/' . strtolower($this->entityNamespace), 312 | "Destination" => $dest . 'public/scripts/mantenedores/' . strtolower($this->entityNamespace) . '/' . strtolower($schema->Table) . 'T.js', 313 | "Preserve" => false 314 | ], 315 | "ScriptJS" => [ 316 | "TemplatePath" => $source . '/Templates/Mantenedores/ScriptJS.js', 317 | "DestinationFolder" => $dest . 'public/scripts/mantenedores/' . strtolower($this->entityNamespace), 318 | "Destination" => $dest . 'public/scripts/mantenedores/' . strtolower($this->entityNamespace) . '/' . strtolower($schema->Table) . '.js', 319 | "Preserve" => false 320 | ], 321 | "ServiceJST" => [ 322 | "TemplatePath" => $source . '/Templates/Mantenedores/ServiceJST.js', 323 | "DestinationFolder" => $dest . 'public/services/mantenedores/' . $this->entityNamespace, 324 | "Destination" => $dest . 'public/services/mantenedores/' . $this->entityNamespace . '/' . $schema->Table . 'SvcT.js', 325 | "Preserve" => false 326 | ], 327 | "ServiceJS" => [ 328 | "TemplatePath" => $source . '/Templates/Mantenedores/ServiceJS.js', 329 | "DestinationFolder" => $dest . 'public/services/mantenedores/' . $this->entityNamespace, 330 | "Destination" => $dest . 'public/services/mantenedores/' . $this->entityNamespace . '/' . $schema->Table . 'Svc.js', 331 | "Preserve" => false 332 | ], 333 | "VerGridT" => [ 334 | "TemplatePath" => $source . '/Templates/Mantenedores/verGridT.php', 335 | "DestinationFolder" => $dest . 'Application/Views/Mantenedores/' . $this->entityNamespace . '/' . $schema->Table, 336 | "Destination" => $dest . 'Application/Views/Mantenedores/' . $this->entityNamespace . '/' . $schema->Table . '/verGridT.php', 337 | "Preserve" => true 338 | ], 339 | "VerGridAsPopUpView" => [ 340 | "TemplatePath" => $source . '/Templates/Mantenedores/verGridAsPopUpView.php', 341 | "DestinationFolder" => $dest . 'Application/Views/Mantenedores/' . $this->entityNamespace . '/' . $schema->Table, 342 | "Destination" => $dest . 'Application/Views/Mantenedores/' . $this->entityNamespace . '/' . $schema->Table . '/verGridAsPopUpView.php', 343 | "Preserve" => false 344 | ], 345 | "VerView" => [ 346 | "TemplatePath" => $source . '/Templates/Mantenedores/verView.php', 347 | "DestinationFolder" => $dest . 'Application/Views/Mantenedores/' . $this->entityNamespace . '/' . $schema->Table, 348 | "Destination" => $dest . 'Application/Views/Mantenedores/' . $this->entityNamespace . '/' . $schema->Table . '/verView.php', 349 | "Preserve" => false, 350 | ], 351 | "VerGridView" => [ 352 | "TemplatePath" => $source . '/Templates/Mantenedores/verGridView.php', 353 | "DestinationFolder" => $dest . 'Application/Views/Mantenedores/' . $this->entityNamespace . '/' . $schema->Table, 354 | "Destination" => $dest . 'Application/Views/Mantenedores/' . $this->entityNamespace . '/' . $schema->Table . '/verGridView.php', 355 | "Preserve" => false 356 | ], 357 | "PopUpView" => [ 358 | "TemplatePath" => $source . '/Templates/Mantenedores/popupView.php', 359 | "DestinationFolder" => $dest . 'Application/Views/Mantenedores/' . $this->entityNamespace . '/' . $schema->Table, 360 | "Destination" => $dest . 'Application/Views/Mantenedores/' . $this->entityNamespace . '/' . $schema->Table . '/popupView.php', 361 | "Preserve" => false 362 | ], 363 | ]; 364 | 365 | // Ver si existe el campo IndEliminado 366 | $existeIndEliminado = false; 367 | 368 | foreach($fields as $name => $field) { 369 | if (strtolower($name) == 'indeliminado') { 370 | $existeIndEliminado = true; 371 | break; 372 | } 373 | } 374 | 375 | // Generar los archivos 376 | // 377 | foreach($filesEval as $file) { 378 | $this->GenerateFileFromEval( 379 | File: $file, Table: $schema, Fields: $fields, VWFields: $vwFields, 380 | ForeignKeys: $foreignKeys, ExisteIndEliminado: $existeIndEliminado, 381 | Config: $config 382 | ); 383 | } 384 | 385 | // Actualizar los bundles 386 | if ($this->ActualizarBundles($schema->Table, $this->entityNamespace, $dest . 'Application/Configuration/bundles.config.json')) { 387 | echo "\n"; 388 | echo "Se actualizaron los registros en bundles.config.json\n"; 389 | echo "\n"; 390 | } 391 | } 392 | 393 | echo "\n"; 394 | echo "-----------------------------\n"; 395 | 396 | if ($error) { 397 | echo "Generación de mantenedor finalizada con error\n"; 398 | } 399 | else { 400 | echo "Generación de mantenedor finalizada OK\n"; 401 | } 402 | 403 | echo "\n"; 404 | } 405 | 406 | private function CargarConfiguracion($filepath) { 407 | 408 | } 409 | 410 | private function ActualizarBundles($element, $namespace, $location) { 411 | 412 | if (!file_exists($location)) { 413 | return; 414 | } 415 | 416 | $json = file_get_contents($location); 417 | $bundles = json_decode($json, true); 418 | $changed = false; 419 | 420 | if (!isset($bundles['mantenedor' . $element . 'JS'])) { 421 | $bundles['mantenedor' . $element . 'JS'] = [ 422 | 'IdBundle' => 'mantenedor' . $element . 'JS', 423 | 'Tipo' => "javascript", 424 | 'Versionado' => true, 425 | 'BundleLocation' => "scripts", 426 | 'Sources' => [ 427 | 0 => [ 428 | "Folder" => "mantenedores/" . strtolower($namespace), 429 | "File" => strtolower($element) . '.js' 430 | ], 431 | 1 => [ 432 | "Folder" => "mantenedores/" . strtolower($namespace), 433 | "File" => strtolower($element) . 'T.js' 434 | ] 435 | ] 436 | ]; 437 | 438 | $changed = true; 439 | } 440 | else { 441 | $bundle = $bundles['mantenedor' . $element . 'JS']; 442 | $sources = $bundle['Sources']; 443 | 444 | $existeJS = false; 445 | $existeJST = false; 446 | 447 | foreach($sources as $source) { 448 | $existeJS = $existeJS || ($source['Folder'] == "mantenedores/" . strtolower($namespace) && $source['File'] == strtolower($element) . '.js'); 449 | $existeJST = $existeJST || ($source['Folder'] == "mantenedores/" . strtolower($namespace) && $source['File'] == strtolower($element) . 'T.js'); 450 | } 451 | 452 | if (!$existeJS) { 453 | $sources[] = [ 454 | "Folder" => "mantenedores/" . strtolower($namespace), 455 | "File" => strtolower($element) . '.js' 456 | ]; 457 | 458 | $changed = true; 459 | } 460 | 461 | if (!$existeJST) { 462 | $sources[] = [ 463 | "Folder" => "mantenedores/" . strtolower($namespace), 464 | "File" => strtolower($element) . 'T.js' 465 | ]; 466 | 467 | $changed = true; 468 | } 469 | 470 | $bundle['Sources'] = $sources; 471 | $bundles['mantenedor' . $element . 'JS'] = $bundle; 472 | } 473 | 474 | if ($changed) { 475 | $newJson = json_encode($bundles, JSON_UNESCAPED_SLASHES); 476 | file_put_contents($location, $newJson); 477 | return true; 478 | } 479 | else { 480 | return false; 481 | } 482 | 483 | } 484 | 485 | private function GenerateFileFromEval($File, object $Table, $Fields, $VWFields, $ForeignKeys, $ExisteIndEliminado = false, $Config= null) { 486 | 487 | $template = $File['TemplatePath']; 488 | $folder = $File['DestinationFolder']; 489 | $destination = $File['Destination']; 490 | $preserve = $File['Preserve']; 491 | $content = ""; 492 | 493 | if ($preserve) { 494 | if (file_exists($destination)) { 495 | return; 496 | } 497 | } 498 | 499 | $vwTable = ( substr($Table->Table, 0, 4) == 'Tipo' ) ? $Table->Table : 'VW' . $Table->Table; 500 | 501 | // Evaluar el archivo 502 | $data = (object) [ 503 | "Template" => $template, 504 | "DestinationFolder" => $destination, 505 | "Entity" => $Table, 506 | "VWEntity" => $vwTable, 507 | "Fields" => $Fields, 508 | "VWFields" => $VWFields, 509 | "ForeignKeys" => $ForeignKeys, 510 | "Namespace" => $this->entityNamespace, 511 | "EntityName" => $Table->Table, 512 | "LowerEntityName" => lcfirst($Table->Table), 513 | "ExisteIndEliminado" => $ExisteIndEliminado, 514 | "Config" => $Config 515 | ]; 516 | 517 | ob_start(); 518 | include( $template ); 519 | $content = ob_get_contents(); 520 | ob_end_clean(); 521 | 522 | // Verificar si existe la carpeta de destino 523 | // 524 | if (!file_exists($folder)) { 525 | mkdir( 526 | $folder, 527 | 0775, 528 | true 529 | ); 530 | } 531 | 532 | // Escribir el archivo (preservar los traits) 533 | // 534 | file_put_contents($destination, $content); 535 | //echo $content; 536 | 537 | return; 538 | } 539 | 540 | private function GenerateFile($File, object $Table) { 541 | 542 | $template = $File['TemplatePath']; 543 | $folder = $File['DestinationFolder']; 544 | $destination = $File['Destination']; 545 | $fields = $File['Fields']; 546 | $jsonDataFields = $File['JsonDataFields']; 547 | $dtoFields = $File['DtoFields']; 548 | $use = $File['Use']; 549 | $listDataFields = $File['ListDataFields']; 550 | $jsonSearchFields = $File['JsonSearchFields']; 551 | $bindingFields = $File['BindingFields']; 552 | $preserve = $File['Preserve']; 553 | $searchRows = $File['SearchRows']; 554 | $searchCustom = $File['SearchCustom']; 555 | $formRows = $File['FormRows']; 556 | $formCustom = $File['FormCustom']; 557 | $vwGridColumns = $File['VWGridColumns']; 558 | $vwGridButtons = $File['VWGridButtons']; 559 | $vwFieldsList = $File['VWFieldsList']; 560 | $vwFieldCustom = $File['VWFieldCustom']; 561 | $customButtons = $File['CustomButtons']; 562 | $customBundles = $File['CustomBundles']; 563 | $customFunctions = $File['CustomFunctions']; 564 | $getbyMethods = $File['GetByMethods']; 565 | 566 | // Revisar si se debe preservar el archivo, y si este existe 567 | // 568 | if ($preserve) { 569 | if (file_exists($destination)) { 570 | return; 571 | } 572 | } 573 | 574 | $vwTable = ( substr($Table->Table, 0, 4) == 'Tipo' ) ? $Table->Table : 'VW' . $Table->Table; 575 | 576 | // Obtener el contenido de la plantilla 577 | // 578 | $content = file_get_contents($template); 579 | 580 | // Reemplazar la metadata 581 | // 582 | // NAMESPACE 583 | $content = str_replace('<>', $this->entityNamespace, $content); 584 | $content = str_replace('<>', $this->entityDomain, $content); 585 | $content = str_replace('<>', $Table->Table, $content); 586 | $content = str_replace('<>', $vwTable, $content); 587 | $content = str_replace('<>', $fields[0], $content); 588 | $content = str_replace('<>', $fields[1], $content); 589 | 590 | $content = str_replace('<>', $vwGridColumns, $content); 591 | $content = str_replace('<>', $vwGridButtons, $content); 592 | $content = str_replace('<>', $vwFieldsList, $content); 593 | $content = str_replace('<>', $vwFieldCustom, $content); 594 | 595 | $content = str_replace('<>', $getbyMethods, $content); 596 | 597 | $content = str_replace('<>', $jsonDataFields, $content); 598 | $content = str_replace('<>', $dtoFields, $content); 599 | $content = str_replace('<>', $use, $content); 600 | $content = str_replace('<>', $searchRows, $content); 601 | $content = str_replace('<>', $searchCustom, $content); 602 | $content = str_replace('<>', $formRows, $content); 603 | $content = str_replace('<>', $formCustom, $content); 604 | 605 | $content = str_replace('<>', $listDataFields, $content); 606 | $content = str_replace('<>', $bindingFields, $content); 607 | $content = str_replace('<>', $jsonSearchFields, $content); 608 | $content = str_replace('<>', $Table->Schema, $content); 609 | 610 | $content = str_replace('<>', $customButtons, $content); 611 | $content = str_replace('<>', $customBundles, $content); 612 | $content = str_replace('<>', $customFunctions, $content); 613 | 614 | $content = str_replace('<>', strtolower($this->entityNamespace), $content); 615 | $content = str_replace('<>', strtolower($this->entityDomain), $content); 616 | $content = str_replace('<>', strtolower($Table->Table), $content); 617 | $content = str_replace('<>', strtolower($Table->Schema), $content); 618 | 619 | // Verificar si existe la carpeta de destino 620 | // 621 | if (!file_exists($folder)) { 622 | mkdir( 623 | $folder, 624 | 0775, 625 | true 626 | ); 627 | } 628 | 629 | // Escribir el archivo (preservar los traits) 630 | // 631 | file_put_contents($destination, $content); 632 | } 633 | 634 | private function ValidateConnection() { 635 | 636 | $error = false; 637 | 638 | error_reporting(0); 639 | 640 | echo $this->fillRight("Verificando conexión a la BD...", ' ', 55); 641 | 642 | // Intentar una conexión a la DB 643 | // 644 | $databaseOK = true; 645 | $stmt = null; 646 | try { 647 | $stmt = DataConfig::GetPDOConnection($this->entityDomain); 648 | 649 | if (!isset($stmt)) 650 | $databaseOK = false; 651 | else { 652 | echo "[OK]\n"; 653 | } 654 | } 655 | catch (\Exception $e) { 656 | $databaseOK = false; 657 | } 658 | 659 | if (!$databaseOK) { 660 | echo "[ERROR]\n"; 661 | echo "La conexión a la BD ha fallado\n"; 662 | $error = true; 663 | } 664 | 665 | echo "\n"; 666 | 667 | if (!$error) { 668 | return $stmt; 669 | } 670 | else 671 | return null; 672 | } 673 | 674 | private function GetSchema(string $Table) { 675 | $Schema = ''; 676 | $split = explode('.', $Table); 677 | 678 | if (is_array($split) && count($split) > 1) { 679 | $Schema = $split[0]; 680 | $TableName = $split[1]; 681 | } 682 | else { 683 | $TableName = $Table; 684 | } 685 | 686 | return (object) [ 687 | 'Schema' => $Schema, 688 | 'Table' => $TableName, 689 | 'FullName' => $Table 690 | ]; 691 | } 692 | 693 | private function Validate(string $Table, bool $Overwrite, $Stmt, $Dest) { 694 | 695 | $schema = $this->GetSchema($Table); 696 | 697 | $error = false; 698 | echo $this->fillRight("TABLA: " . $schema->Table, ' ', 55); 699 | echo "\n"; 700 | echo $this->fillRight("-", '-', 25); 701 | echo "\n"; 702 | 703 | // PASO 1 704 | // Comprobar la existencia de la tabla 705 | // 706 | if (!$error) { 707 | 708 | echo $this->fillRight("Verificando existencia de la tabla...", ' ', 55); 709 | 710 | if (!$this->TableExists($Stmt, $schema->FullName)) { 711 | echo "[ERROR]\n"; 712 | echo "La tabla [" . $Table . "] no existe en la base de datos asignada al dominio [" . $this->entityDomain . "]\n"; 713 | $error = true; 714 | } 715 | else { 716 | echo "[OK]\n"; 717 | } 718 | } 719 | 720 | // PASO 2 721 | // Definir los nombres de carpetas generar y revisar si ya existen 722 | // 723 | if (!$error) { 724 | 725 | echo $this->fillRight("Verificando carpetas de destino...", ' ', 55); 726 | 727 | // Definición de carpetas 728 | // 729 | $folders = array(); 730 | $folders['Application'] = $Dest . 'Application'; 731 | $folders['Application/BLL'] = $folders['Application'] . '/BLL'; 732 | $folders['Application/BLL/DataTransferObjects'] = $folders['Application/BLL'] . '/DataTransferObjects'; 733 | $folders['Application/BLL/Services'] = $folders['Application/BLL'] . '/Services'; 734 | $folders['Application/Dao'] = $folders['Application'] . '/Dao'; 735 | $folders['Application/Dao/Entities'] = $folders['Application'] . '/Dao/Entities'; 736 | 737 | $notfound = ""; 738 | foreach($folders as $nombre => $ruta) { 739 | 740 | if (!file_exists($ruta)) { 741 | if ($notfound != '') 742 | $notfound .= ', '; 743 | 744 | $notfound .= $nombre; 745 | } 746 | } 747 | 748 | if ($notfound != '') { 749 | echo "[ERROR]\n"; 750 | echo "Las siguientes carpetas no han sido encontradas:\n" . $notfound . "\n"; 751 | $error = true; 752 | } 753 | else { 754 | echo "[OK]\n"; 755 | } 756 | 757 | } 758 | 759 | // PASO 4 760 | // Revisar si existen los archivos en el destino 761 | // 762 | if (!$error && !$Overwrite) { 763 | 764 | echo $this->fillRight("Verificando clases de destino...", ' ', 55); 765 | 766 | // Definición de clases 767 | // 768 | $files = array(); 769 | $files['Dto'] = $Dest . 'Application/BLL/DataTransferObjects/' . $this->entityNamespace . '/' . $schema->Table . 'Dto.php'; 770 | $files['Svc'] = $Dest . 'Application/BLL/Services/' . $this->entityNamespace . '/' . $schema->Table . 'Svc.php'; 771 | $files['Ent'] = $Dest . 'Application/Dao/Entities/' . $this->entityNamespace . '/' . $schema->Table . '.php'; 772 | $files['Dao'] = $Dest . 'Application/Dao/' . $this->entityNamespace . '/' . $schema->Table . 'Dao.php'; 773 | 774 | $found = ""; 775 | foreach($files as $nombre => $ruta) { 776 | 777 | if (file_exists($ruta)) { 778 | if ($found != '') 779 | $found .= ', '; 780 | 781 | $found .= $ruta; 782 | } 783 | } 784 | 785 | if ($found != '') { 786 | echo "[ERROR]\n"; 787 | echo "Los siguientes archivos ya existen:\n" . $found . "\n"; 788 | echo "Debe eliminar los archivos o especificar el parámetro 'overwrite' en la llamada\n"; 789 | $error = true; 790 | } 791 | else { 792 | echo "[OK]\n"; 793 | } 794 | 795 | } 796 | 797 | echo "\n"; 798 | 799 | return !$error; 800 | } 801 | 802 | private function ValidateMantenedores(string $Table, bool $Overwrite, $Stmt, $Dest) { 803 | 804 | $schema = $this->GetSchema($Table); 805 | 806 | $error = false; 807 | echo $this->fillRight("TABLA: " . $schema->Table, ' ', 55); 808 | echo "\n"; 809 | echo $this->fillRight("-", '-', 25); 810 | echo "\n"; 811 | 812 | // PASO 1 813 | // Comprobar la existencia de la tabla 814 | // 815 | if (!$error) { 816 | 817 | echo $this->fillRight("Verificando existencia de la tabla...", ' ', 55); 818 | 819 | if (!$this->TableExists($Stmt, $schema->FullName)) { 820 | echo "[ERROR]\n"; 821 | echo "La tabla [" . $Table . "] no existe en la base de datos asignada al dominio [" . $this->entityDomain . "]\n"; 822 | $error = true; 823 | } 824 | else { 825 | echo "[OK]\n"; 826 | } 827 | } 828 | 829 | // PASO 2 830 | // Definir los nombres de carpetas generar y revisar si ya existen 831 | // 832 | if (!$error) { 833 | 834 | echo $this->fillRight("Verificando carpetas de destino...", ' ', 55); 835 | 836 | // Definición de carpetas 837 | // 838 | $folders = array(); 839 | $folders['public'] = $Dest . 'public'; 840 | $folders['public/scripts'] = $folders['public'] . '/scripts'; 841 | $folders['public/scripts/mantenedores'] = $folders['public/scripts'] . '/mantenedores'; 842 | $folders['public/services'] = $folders['public'] . '/services'; 843 | $folders['public/services/mantenedores'] = $folders['public/services'] . '/mantenedores'; 844 | $folders['Application'] = $Dest . 'Application'; 845 | $folders['Application/Controllers'] = $folders['Application'] . '/Controllers'; 846 | $folders['Application/Controllers/Mantenedores'] = $folders['Application/Controllers'] . '/Mantenedores'; 847 | $folders['Application/Controllers/Api'] = $folders['Application/Controllers'] . '/Api'; 848 | $folders['Application/Controllers/Api/Mantenedores'] = $folders['Application/Controllers/Api'] . '/Mantenedores'; 849 | 850 | $notfound = ""; 851 | foreach($folders as $nombre => $ruta) { 852 | 853 | if (!file_exists($ruta)) { 854 | if ($notfound != '') 855 | $notfound .= ', '; 856 | 857 | $notfound .= $nombre; 858 | } 859 | } 860 | 861 | if ($notfound != '') { 862 | echo "[ERROR]\n"; 863 | echo "Las siguientes carpetas no han sido encontradas:\n" . $notfound . "\n"; 864 | $error = true; 865 | } 866 | else { 867 | echo "[OK]\n"; 868 | } 869 | 870 | } 871 | 872 | // PASO 4 873 | // Revisar si existen los archivos en el destino 874 | // 875 | if (!$error && !$Overwrite) { 876 | 877 | echo $this->fillRight("Verificando clases de destino...", ' ', 55); 878 | 879 | // Definición de clases 880 | // 881 | $files = array(); 882 | $files['ServiceJS'] = $Dest . 'public/services/mantenedores/' . $this->entityNamespace . '/' . $schema->Table . 'Svc.js'; 883 | $files['ScriptJS'] = $Dest . 'public/scripts/mantenedores/' . strtolower($this->entityNamespace) . '/' . strtolower($schema->Table) . '.js'; 884 | $files['ViewController'] = $Dest . 'Application/Controllers/Mantenedores/' . $this->entityNamespace . '/' . $schema->Table . 'Controller.php'; 885 | $files['ApiController'] = $Dest . 'Application/Controllers/Api/Mantenedores/' . $this->entityNamespace . '/' . $schema->Table . 'Controller.php'; 886 | 887 | $found = ""; 888 | foreach($files as $nombre => $ruta) { 889 | 890 | if (file_exists($ruta)) { 891 | if ($found != '') 892 | $found .= ', '; 893 | 894 | $found .= $ruta; 895 | } 896 | } 897 | 898 | if ($found != '') { 899 | echo "[ERROR]\n"; 900 | echo "Los siguientes archivos ya existen:\n" . $found . "\n"; 901 | echo "Debe eliminar los archivos o especificar el parámetro 'overwrite' en la llamada\n"; 902 | $error = true; 903 | } 904 | else { 905 | echo "[OK]\n"; 906 | } 907 | 908 | } 909 | 910 | echo "\n"; 911 | 912 | return !$error; 913 | } 914 | 915 | /** 916 | * Check if a table exists in the current database. 917 | * 918 | * @param PDO $pdo PDO instance connected to a database. 919 | * @param string $table Table to search for. 920 | * @return bool TRUE if table exists, FALSE if no table found. 921 | */ 922 | private function TableExists($pdo, $table) { 923 | 924 | $qry = ''; 925 | switch($this->Dominio->Type) { 926 | case 'mysql': 927 | $qry = "SELECT 1 FROM $table LIMIT 1"; 928 | break; 929 | case 'sqlserver': 930 | $qry = "SELECT TOP 1 * FROM $table"; 931 | break; 932 | default: 933 | $qry = "SELECT 1 FROM $table LIMIT 1"; 934 | break; 935 | } 936 | 937 | // Try a select statement against the table 938 | // Run it in try/catch in case PDO is in ERRMODE_EXCEPTION. 939 | try { 940 | $result = $pdo->query($qry); 941 | } catch (\Exception $e) { 942 | // We got an exception == table not found 943 | return false; 944 | } 945 | 946 | // Result is either boolean FALSE (no table found) or PDOStatement Object (table found) 947 | return $result !== FALSE; 948 | } 949 | 950 | private function fillRight($origin, $fillChar, $totalLength) { 951 | 952 | $currentLength = strlen($origin); 953 | $difference = $totalLength - $currentLength; 954 | 955 | if ($difference == 0) { 956 | return $origin; 957 | } 958 | else if ($difference < 0) { 959 | return substr($origin, 0, $totalLength); 960 | } 961 | else { 962 | return $origin . str_repeat($fillChar, $difference); 963 | } 964 | } 965 | 966 | private function GetTableFields(string $Table, $Conn, $ForeignKeys = null) { 967 | 968 | $schema = $this->GetSchema($Table); 969 | $fields = null; 970 | 971 | switch ($this->Dominio->Type) { 972 | case 'mysql': 973 | $fields = $this->GetMySqlFields(Table: $Table, Conn: $Conn); 974 | break; 975 | case 'sqlserver': 976 | $fields = $this->GetSqlServerFields(Table: $schema->FullName, Conn: $Conn, ForeignKeys: $ForeignKeys); 977 | break; 978 | default: 979 | return []; 980 | } 981 | 982 | return $fields; 983 | } 984 | 985 | private function GetMySqlFields(string $Table, $Conn) { 986 | 987 | $qry = " 988 | DESCRIBE $Table 989 | "; 990 | 991 | $stmt = $Conn->prepare($qry); 992 | 993 | $stmt->setFetchMode(\PDO::FETCH_ASSOC); 994 | $stmt->execute(); 995 | $columns = $stmt->fetchAll(\PDO::FETCH_ASSOC); 996 | 997 | $Fields = []; 998 | $first = true; 999 | 1000 | foreach($columns as $col) { 1001 | 1002 | // metadata 1003 | $name = $col['Field']; 1004 | $dbtype = $col['Type']; 1005 | $nullable = ($col['Null'] == 'YES'); 1006 | 1007 | if (substr($Table, 0, 2) == 'VW') { 1008 | $primaryKey = $first; 1009 | } 1010 | else { 1011 | $primaryKey = ($col['Key'] == 'PRI'); 1012 | } 1013 | 1014 | $autoincrement = ($col['Extra'] == 'auto_increment'); 1015 | $uniqueKey = ($col['Key'] == 'UNI'); 1016 | 1017 | // tipo estandar 1018 | // quitar todo lo que esta despues del parentesis 1019 | $parentesis = strpos($dbtype, '('); 1020 | 1021 | if ($parentesis !== false) { 1022 | $stdtype = substr($dbtype, 0, $parentesis); 1023 | } 1024 | else { 1025 | $stdtype = $dbtype; 1026 | } 1027 | 1028 | switch($stdtype) { 1029 | case 'decimal': 1030 | $phptype = 'float'; 1031 | $type = 'decimal'; 1032 | break; 1033 | case 'tinyint': 1034 | case 'int': 1035 | case 'bigint': 1036 | $phptype = 'int'; 1037 | $type = 'int'; 1038 | break; 1039 | case 'varchar': 1040 | case 'char': 1041 | $phptype = 'string'; 1042 | $type = 'string'; 1043 | break; 1044 | case 'date': 1045 | case 'datetime': 1046 | $phptype = 'string'; 1047 | $type = 'datetime'; 1048 | break; 1049 | default: 1050 | $phptype = 'string'; 1051 | $type = 'string'; 1052 | break; 1053 | } 1054 | 1055 | $Fields[$name] = (object) [ 1056 | 'Name' => $name, 1057 | 'DataType' => $type, 1058 | 'PhpDataType' => $phptype, 1059 | 'PrimaryKey' => $primaryKey, 1060 | 'UniqueKey' => $uniqueKey, 1061 | 'Nullable' => $nullable, 1062 | 'AutoIncrement' => $autoincrement, 1063 | ]; 1064 | 1065 | $first = false; 1066 | } 1067 | 1068 | return $Fields; 1069 | 1070 | } 1071 | 1072 | private function GetSqlServerForeignKeys($Conn) { 1073 | 1074 | $qry = " 1075 | SELECT 1076 | obj.name AS IdForeingKey, 1077 | sch.name AS SourceSchema, 1078 | tab1.name AS SourceTable, 1079 | CONCAT(sch.name, '.', tab1.name) AS SourceTableName, 1080 | col1.name AS SourceColumn, 1081 | sch2.name as TargetSchema, 1082 | tab2.name as TargetTable, 1083 | CONCAT(sch2.name, '.', tab2.name) AS TargetTableName, 1084 | col2.name AS TargetColumn 1085 | FROM sys.foreign_key_columns fkc 1086 | INNER JOIN sys.objects obj 1087 | ON obj.object_id = fkc.constraint_object_id 1088 | INNER JOIN sys.tables tab1 1089 | ON tab1.object_id = fkc.parent_object_id 1090 | INNER JOIN sys.schemas sch 1091 | ON tab1.schema_id = sch.schema_id 1092 | INNER JOIN sys.columns col1 1093 | ON col1.column_id = parent_column_id AND col1.object_id = tab1.object_id 1094 | INNER JOIN sys.tables tab2 1095 | ON tab2.object_id = fkc.referenced_object_id 1096 | INNER JOIN sys.columns col2 1097 | ON col2.column_id = referenced_column_id AND col2.object_id = tab2.object_id 1098 | INNER JOIN sys.schemas sch2 1099 | ON tab2.schema_id = sch2.schema_id 1100 | ORDER BY sch.name 1101 | "; 1102 | 1103 | $stmt = $Conn->prepare($qry); 1104 | 1105 | $stmt->setFetchMode(\PDO::FETCH_ASSOC); 1106 | $stmt->execute(); 1107 | $keys = $stmt->fetchAll(\PDO::FETCH_ASSOC); 1108 | 1109 | $foreignKeys = []; 1110 | 1111 | foreach ($keys as $key) { 1112 | $foreignKeys[$key['SourceTableName'] . '.' . $key['SourceColumn']] = (object)$key; 1113 | } 1114 | 1115 | return $foreignKeys; 1116 | } 1117 | 1118 | private function GetSqlServerFields(string $Table, $Conn, $ForeignKeys = null) { 1119 | 1120 | // Verificar si la tabla contiene el nombre del esquema 1121 | $tableName = $Table; 1122 | $schema = ''; 1123 | 1124 | if (strpos($Table, '.') !== false) { 1125 | $parts = explode('.', $Table); 1126 | $schema = $parts[0]; 1127 | $tableName = $parts[1]; 1128 | } 1129 | 1130 | $qry = "EXEC sp_columns @table_name = N'" . $tableName . "'"; 1131 | 1132 | if ($schema != '') { 1133 | $qry .= ", @table_owner = N'" . $schema . "'"; 1134 | } 1135 | 1136 | $stmt = $Conn->prepare($qry); 1137 | 1138 | $stmt->setFetchMode(\PDO::FETCH_ASSOC); 1139 | $stmt->execute(); 1140 | $columns = $stmt->fetchAll(\PDO::FETCH_ASSOC); 1141 | 1142 | $pkqry = " 1143 | exec sp_primary_keys_rowset $tableName 1144 | "; 1145 | 1146 | $stmt = $Conn->prepare($pkqry); 1147 | 1148 | $stmt->setFetchMode(\PDO::FETCH_ASSOC); 1149 | $stmt->execute(); 1150 | $primary = $stmt->fetchAll(\PDO::FETCH_ASSOC); 1151 | 1152 | if (isset($primary) && isset($primary[0]) && isset($primary[0]['COLUMN_NAME'])) { 1153 | $fieldPK = $primary[0]['COLUMN_NAME']; 1154 | } 1155 | else { 1156 | $fieldPK = ''; 1157 | } 1158 | 1159 | $Fields = []; 1160 | 1161 | $maxFieldLen = 0; 1162 | $maxTypeLen = 0; 1163 | $maxEqLen = 0; 1164 | 1165 | foreach($columns as $col) { 1166 | 1167 | $fieldLen = 0; 1168 | $typeLen = 0; 1169 | $eqLen = 0; 1170 | 1171 | // metadata 1172 | $name = $col['COLUMN_NAME']; 1173 | $dbtype = trim(str_replace('identity', '', $col['TYPE_NAME'])); 1174 | $nullable = ($col['IS_NULLABLE'] == 'YES'); 1175 | $primaryKey = ($col['COLUMN_NAME'] == $fieldPK); 1176 | $autoincrement = (strpos($col['TYPE_NAME'], 'identity') !== false); 1177 | $uniqueKey = false; 1178 | $length = $col['LENGTH']; 1179 | $precision = $col['PRECISION']; 1180 | 1181 | // tipo estandar 1182 | // quitar todo lo que esta despues del parentesis 1183 | $parentesis = strpos($dbtype, '('); 1184 | 1185 | if ($parentesis !== false) { 1186 | $stdtype = substr($dbtype, 0, $parentesis); 1187 | } 1188 | else { 1189 | $stdtype = $dbtype; 1190 | } 1191 | 1192 | switch($stdtype) { 1193 | case 'decimal': 1194 | $phptype = 'float'; 1195 | $type = 'decimal'; 1196 | $eq = "0"; 1197 | break; 1198 | case 'tinyint': 1199 | case 'int': 1200 | case 'bigint': 1201 | $phptype = 'int'; 1202 | $type = 'int'; 1203 | $eq = "0"; 1204 | break; 1205 | case 'varchar': 1206 | case 'nvarchar': 1207 | case 'char': 1208 | $phptype = 'string'; 1209 | $type = 'string'; 1210 | $eq = "''"; 1211 | break; 1212 | case 'date': 1213 | case 'datetime': 1214 | $phptype = 'string'; 1215 | $type = 'datetime'; 1216 | $eq = "''"; 1217 | break; 1218 | default: 1219 | $phptype = 'string'; 1220 | $type = 'string'; 1221 | $eq = "''"; 1222 | break; 1223 | } 1224 | 1225 | $fieldLen = strlen($name); 1226 | $typeLen = strLen($phptype); 1227 | 1228 | // obtener las foraneas 1229 | if (isset($ForeignKeys) && isset($ForeignKeys[$Table . '.' . $name])) { 1230 | $foreign = $ForeignKeys[$Table . '.' . $name]; 1231 | } 1232 | else { 1233 | $foreign = null; 1234 | } 1235 | 1236 | if ($nullable) { 1237 | $nl = '?'; 1238 | $eq = 'null'; 1239 | $typeLen++; // el null le agrega 1 caracter '?' 1240 | } 1241 | else { 1242 | $nl = ''; 1243 | } 1244 | 1245 | $eqLen = strlen($eq); 1246 | 1247 | if ($fieldLen > $maxFieldLen) { 1248 | $maxFieldLen = $fieldLen; 1249 | } 1250 | if ($typeLen > $maxTypeLen) { 1251 | $maxTypeLen = $typeLen; 1252 | } 1253 | if ($eqLen > $maxEqLen) { 1254 | $maxEqLen = $eqLen; 1255 | } 1256 | 1257 | $reference = ""; 1258 | $svcName = ""; 1259 | $svcVariable = ""; 1260 | $fileReferenceSvc = ""; 1261 | $fileReferenceDto = ""; 1262 | 1263 | if (!($primaryKey) && substr($name, 0, 2) == 'Id') { 1264 | // buscar las referencias para el "use" 1265 | $reference = substr($name, 2); 1266 | 1267 | // Obs: usamos la version "VW" de la tabla referenciada, o sea la vista a menos que sea una tabla "Tipo" 1268 | if (substr($reference, 0, 4) == 'Tipo') { 1269 | $svcVariable = strtolower(substr($reference, 0, 1)) . substr($reference, 1); 1270 | $svcName = $reference; 1271 | } 1272 | else { 1273 | $svcVariable = 'vw' . $reference; 1274 | $svcName = 'VW' . $reference; 1275 | } 1276 | 1277 | $preference = (isset($foreign)) ? $foreign : null; 1278 | 1279 | $fileReferenceSvc = $this->FindFileReference($svcName . "Svc.php", $_SERVER['OLDPWD'] . "/Application/BLL/Services", $preference); 1280 | $fileReferenceDto = $this->FindFileReference($svcName . "Dto.php", $_SERVER['OLDPWD'] . "/Application/BLL/DataTransferObjects", $preference); 1281 | } 1282 | 1283 | $Fields[$name] = (object) [ 1284 | 'Name' => $name, 1285 | 'DataType' => $type, 1286 | 'PhpDataType' => $phptype, 1287 | 'PhpDataType' => $phptype, 1288 | 'Length' => $length, 1289 | 'Precision' => $precision, 1290 | 'PrimaryKey' => $primaryKey, 1291 | 'UniqueKey' => $uniqueKey, 1292 | 'Nullable' => $nullable, 1293 | 'AutoIncrement' => $autoincrement, 1294 | 'ForeignKey' => $foreign, 1295 | 'EQ' => $eq, 1296 | 'NL' => $nl, 1297 | 'Reference' => $reference, 1298 | 'FileRefSvc' => $fileReferenceSvc, 1299 | 'FileRefDto' => $fileReferenceDto, 1300 | 'SvcName' => $svcName, 1301 | 'SvcVariable' => $svcVariable 1302 | ]; 1303 | 1304 | } 1305 | 1306 | foreach($Fields as $name => $field) { 1307 | 1308 | $declaracion = str_pad($field->NL . $field->PhpDataType, $maxTypeLen, ' ') . "\t" . "$" . str_pad($field->Name, $maxFieldLen, ' ') . "\t= " . $field->EQ; 1309 | $presentacion = "$" . str_pad($field->Name, $maxFieldLen, ' ') . "\t= " . $field->EQ; 1310 | 1311 | // Revisar si este SELECT tendrá sucesores 1312 | $sucesores = $this->Sucesores($field, $Fields, $ForeignKeys, $schema); 1313 | // Revisar si este SELECT tendrá algún antecesor 1314 | $antecesor = $this->Antecesor($field, $Fields, $ForeignKeys, $schema); 1315 | 1316 | $field->FieldLength = $maxFieldLen; 1317 | $field->TypeLength = $maxTypeLen; 1318 | $field->EqLength = $maxEqLen; 1319 | $field->Declaration = $declaracion; 1320 | $field->Presentation = $presentacion; 1321 | $field->Sucesores = $sucesores; 1322 | $field->Antecesor = $antecesor; 1323 | 1324 | $Fields[$name] = $field; 1325 | } 1326 | 1327 | return $Fields; 1328 | } 1329 | 1330 | private function ConvertFields($fields) { 1331 | 1332 | $fieldContent = ""; 1333 | $fieldFullContent = ""; 1334 | 1335 | foreach($fields as $field) { 1336 | 1337 | if ($fieldContent != "") { 1338 | $fieldContent .= "\n"; 1339 | } 1340 | if ($fieldFullContent != "") { 1341 | $fieldFullContent .= "\n"; 1342 | } 1343 | 1344 | $annotation = ""; 1345 | if ($field->DataType == 'datetime') { 1346 | if ($annotation != '') 1347 | $annotation .= ', '; 1348 | $annotation .= "DataType: 'datetime'"; 1349 | } // PrimaryKey: true 1350 | 1351 | if ($field->PrimaryKey) { 1352 | if ($annotation != '') 1353 | $annotation .= ', '; 1354 | $annotation .= "PrimaryKey: true"; 1355 | } 1356 | 1357 | if ($annotation != "") { 1358 | $fieldFullContent .= "\t#[EntityField(" . $annotation . ")]\n"; 1359 | } 1360 | 1361 | $dataType = $field->PhpDataType; 1362 | 1363 | if ($field->Nullable) { 1364 | $dataType = '?' . $dataType; 1365 | } 1366 | 1367 | $fieldContent .= "\t\tpublic $dataType $" . $field->Name; 1368 | $fieldFullContent .= "\tpublic $dataType $" . $field->Name; 1369 | 1370 | if ($field->DataType == 'datetime' || $field->Nullable) { 1371 | $fieldContent .= " = null,"; 1372 | $fieldFullContent .= " = null;"; 1373 | } 1374 | else if ($field->DataType == 'string') { 1375 | $fieldContent .= " = '',"; 1376 | $fieldFullContent .= " = '';"; 1377 | } 1378 | else { 1379 | $fieldContent .= " = 0,"; 1380 | $fieldFullContent .= " = 0;"; 1381 | } 1382 | } 1383 | 1384 | $fieldContentLen = strlen($fieldContent); 1385 | if (substr($fieldContent, $fieldContentLen-1, 1) == ',') { 1386 | $fieldContent = substr($fieldContent, 0, $fieldContentLen-1); 1387 | } 1388 | 1389 | return [$fieldContent, $fieldFullContent]; 1390 | 1391 | } 1392 | 1393 | private function VWGridFields($fields, $table) { 1394 | 1395 | $fieldContent = ""; 1396 | $fieldList = ""; 1397 | $fieldCustom = ""; 1398 | 1399 | $existeIndVigente = false; 1400 | 1401 | foreach($fields as $field) { 1402 | 1403 | if ($fieldList != "") { 1404 | $fieldList .= ", "; 1405 | } 1406 | $fieldList .= "$" . $field->Name; 1407 | 1408 | // si es llave no lo deberíamos mostrar en la grilla 1409 | if ($field->PrimaryKey || substr($field->Name, 0, 2) == 'Id') { 1410 | continue; 1411 | } 1412 | 1413 | if ($fieldContent != "") { 1414 | $fieldContent .= ",\n"; 1415 | } 1416 | 1417 | if ($fieldCustom != "") { 1418 | $fieldCustom .= "\n"; 1419 | } 1420 | 1421 | if ($field->Name == 'IndVigente') { 1422 | $existeIndVigente = true; 1423 | } 1424 | 1425 | // Columnas especiales 1426 | if (substr($field->Name, 0, 3) == 'Ind') { 1427 | $fieldContent .= "\t\t'<>' => new TableCell(\n"; 1428 | $fieldContent .= "\t\t\tPropertyName: \"<>\",\n"; 1429 | $fieldContent .= "\t\t\tLabel: \"<>\",\n"; 1430 | $fieldContent .= "\t\t\tBodyClasses: ['text-center'],\n"; 1431 | $fieldContent .= "\t\t\tFormatFunction: function(\$element, \$cell) {\n"; 1432 | $fieldContent .= "\t\t\t\treturn new Label(\n"; 1433 | $fieldContent .= "\t\t\t\t LabelStyle : (\$element-><> == 1) ? LabelStyleEnum::LABEL_SUCCESS : LabelStyleEnum::LABEL_LIGHT,\n"; 1434 | $fieldContent .= "\t\t\t\t LabelSize: LabelSizeEnum::LABEL_LARGE,\n"; 1435 | $fieldContent .= "\t\t\t\t Content: (\$element-><> == 1) ? 'SI' : 'NO'\n"; 1436 | $fieldContent .= "\t\t\t\t);\n"; 1437 | $fieldContent .= "\t\t\t}\n"; 1438 | $fieldContent .= "\t\t)"; 1439 | $fieldContent = str_replace('<>', $field->Name, $fieldContent); 1440 | } 1441 | // columna estandar 1442 | else { 1443 | $fieldContent .= "\t\t'<>' => new TableCell(\n"; 1444 | $fieldContent .= "\t\t\tPropertyName: \"<>\",\n"; 1445 | $fieldContent .= "\t\t\tLabel: \"<>\",\n"; 1446 | $fieldContent .= "\t\t\t// Descomentar esta propiedad para agregar una función de formateo a la columna\n"; 1447 | $fieldContent .= "\t\t\t//FormatFunction: function(\$element, \$cell) {\n"; 1448 | $fieldContent .= "\t\t\t\t//return \$element-><>;\n"; 1449 | $fieldContent .= "\t\t\t//}\n"; 1450 | $fieldContent .= "\t\t)"; 1451 | $fieldContent = str_replace('<>', $field->Name, $fieldContent); 1452 | } 1453 | 1454 | $fieldCustom .= "\t\t\$newArray[] = \$cells['" . $field->Name . "'];"; 1455 | 1456 | } // foreach($fields as $field) 1457 | 1458 | $buttonContent = ""; 1459 | //$buttonContent .= "\$buttons = [];\n"; 1460 | 1461 | // si tenemos indvigente, creamos el boton de cambio 1462 | // obs: desactivado por ahora, hasta que esté terminado 1463 | if ($existeIndVigente && false) { 1464 | 1465 | // PONER VIGENTE 1466 | $buttonContent .= "// Creamos el boton 'IndVigente'\n"; 1467 | $buttonContent .= "\$buttons[] = new TableButton(\n"; 1468 | $buttonContent .= "\tChild: new FaIcon('fa-check'),\n"; 1469 | $buttonContent .= "\tKey: 'btnVigente<>',\n"; 1470 | $buttonContent .= "\tOnClickClass: 'btn-vigente-<>',\n"; 1471 | $buttonContent .= "\tButtonStyle: ButtonStyleEnum::BUTTON_SUCCESS,\n"; 1472 | $buttonContent .= "\tDisplayFunctionMode: DisplayFunctionModeEnum::HIDE_MODE,\n"; 1473 | $buttonContent .= "\tEvents: [new TableButtonOnClickEvent()],\n"; 1474 | $buttonContent .= "\tDisplayFunction : function (\$button, \$usuario, \$perfil, \$roles, \$element) { return (\$element->IndVigente == 0);},\n"; 1475 | $buttonContent .= "\t//EnabledFunction : function (\$button, \$usuario, \$perfil, \$roles, \$element) {}\n"; 1476 | $buttonContent .= ");\n"; 1477 | 1478 | // PONER NO VIGENTE 1479 | $buttonContent .= "// Creamos el boton 'IndVigente'\n"; 1480 | $buttonContent .= "\$buttons[] = new TableButton(\n"; 1481 | $buttonContent .= "\tChild: new FaIcon('fa-times'),\n"; 1482 | $buttonContent .= "\tKey: 'btnNoVigente<>',\n"; 1483 | $buttonContent .= "\tOnClickClass: 'btn-no-vigente-<>',\n"; 1484 | $buttonContent .= "\tButtonStyle: ButtonStyleEnum::BUTTON_WARNING,\n"; 1485 | $buttonContent .= "\tEvents: [new TableButtonOnClickEvent()],\n"; 1486 | $buttonContent .= "\tDisplayFunction : function (\$button, \$usuario, \$perfil, \$roles, \$element) { return (\$element->IndVigente == 1);},\n"; 1487 | $buttonContent .= "\t//EnabledFunction : function (\$button, \$usuario, \$perfil, \$roles, \$element) {}\n"; 1488 | $buttonContent .= ");\n"; 1489 | } 1490 | 1491 | $buttonContent .= "// Creamos el boton 'Editar' y el boton 'Eliminar'\n"; 1492 | $buttonContent .= "\$buttons[] = new TableButton(\n"; 1493 | $buttonContent .= "\tChild: new FaIcon('fa-edit'),\n"; 1494 | $buttonContent .= "\tKey: 'btnEditar<>',\n"; 1495 | $buttonContent .= "\tOnClickClass: 'btn-editar-<>',\n"; 1496 | $buttonContent .= "\tButtonStyle: ButtonStyleEnum::BUTTON_WARNING,\n"; 1497 | $buttonContent .= "\tEvents: [new TableButtonOnClickEvent()],\n"; 1498 | $buttonContent .= "\t//DisplayFunction : function (\$button, \$usuario, \$perfil, \$roles, \$element) {},\n"; 1499 | $buttonContent .= "\t//EnabledFunction : function (\$button, \$usuario, \$perfil, \$roles, \$element) {}\n"; 1500 | $buttonContent .= ");\n"; 1501 | $buttonContent .= "\$buttons[] = new TableButton(\n"; 1502 | $buttonContent .= "\tKey: 'btnEliminar<>',\n"; 1503 | $buttonContent .= "\tChild: new FaIcon('fa-trash'),\n"; 1504 | $buttonContent .= "\tOnClickClass: 'btn-eliminar-<>',\n"; 1505 | $buttonContent .= "\tButtonStyle: ButtonStyleEnum::BUTTON_DANGER,\n"; 1506 | $buttonContent .= "\tEvents: [new TableButtonOnClickEvent()],\n"; 1507 | $buttonContent .= "\t//DisplayFunction : function (\$button, \$usuario, \$perfil, \$roles, \$element) {},\n"; 1508 | $buttonContent .= "\t//EnabledFunction : function (\$button, \$usuario, \$perfil, \$roles, \$element) {}\n"; 1509 | $buttonContent .= ");\n"; 1510 | 1511 | $buttonContent = str_replace('<>', $table, $buttonContent); 1512 | $buttonContent = str_replace('<>', strtolower($table), $buttonContent); 1513 | 1514 | return [$fieldContent, $buttonContent, $fieldList, $fieldCustom]; 1515 | } 1516 | 1517 | private function JsonCustomButtons($schema, $foreignKeys) { 1518 | 1519 | $fk = []; 1520 | $buttons = ""; 1521 | $bundles = ""; 1522 | $functions = ""; 1523 | 1524 | foreach ($foreignKeys as $source => $key) { 1525 | if ($key->TargetTableName == $schema->FullName) { 1526 | $fk[$source] = $key; 1527 | } 1528 | } 1529 | 1530 | foreach ($fk as $source => $key) { 1531 | if ($buttons != "") { 1532 | $buttons .= "\n\n"; 1533 | } 1534 | 1535 | $buttons .= "\t\t\$buttons[] = new TableButton(\n"; 1536 | $buttons .= "\t\t Child: new FaIcon('fa-users'),\n"; 1537 | $buttons .= "\t\t Key: 'btnEditar" . $key->SourceTable . "s',\n"; 1538 | $buttons .= "\t\t OnClickClass: 'btn-editar-" . strtolower($key->SourceTable) . "s',\n"; 1539 | $buttons .= "\t\t ButtonStyle: ButtonStyleEnum::BUTTON_PRIMARY,\n"; 1540 | $buttons .= "\t\t Events: [new TableButtonOnClickEvent()],\n"; 1541 | $buttons .= "\t\t);"; 1542 | 1543 | if ($bundles != "") { 1544 | $bundles .= "\n"; 1545 | } 1546 | 1547 | $bundles .= "@@IncludeScriptBundle(mantenedor" . $key->SourceTable . "JS)"; 1548 | 1549 | if ($functions != "") { 1550 | $functions .= "\n\n"; 1551 | } 1552 | 1553 | $functions .= "function btnEditar" . $key->SourceTable . "s_OnClick(rowInfo) {\n"; 1554 | $functions .= " " . $key->SourceTable . "AsPopUp({Registro" . $key->SourceTable . "Buscar : JSON.stringify({" . $key->SourceColumn . " : rowInfo.RowData.pk})});\n"; 1555 | $functions .= "}"; 1556 | 1557 | } 1558 | 1559 | $stop = 1; 1560 | return [$buttons, $bundles, $functions]; 1561 | } 1562 | 1563 | private function JsonDataFields($fields) { 1564 | 1565 | $fieldContent = ""; 1566 | $dataPopup = ""; 1567 | $usePopup = ""; 1568 | $formRows = ""; 1569 | $formCustom = ""; 1570 | 1571 | $maxLen = 0; 1572 | foreach($fields as $field) { 1573 | if (strlen($field->Name) > $maxLen) $maxLen = strlen($field->Name); 1574 | } 1575 | 1576 | foreach($fields as $field) { 1577 | 1578 | if ($fieldContent != "") { 1579 | $fieldContent .= ",\n"; 1580 | } 1581 | if ($formCustom != "") { 1582 | $formCustom .= "\n"; 1583 | } 1584 | 1585 | $qtySpaces = $maxLen - strlen($field->Name); 1586 | $spaces = str_repeat(' ', $qtySpaces); 1587 | 1588 | $fieldContent .= "\t\t\t\t" . $field->Name . $spaces . " : formData." . $field->Name; 1589 | $formCustom .= "\t\t\$row[] = \$frmGroup->Rows[0]['" . $field->Name . "'];"; 1590 | 1591 | if (!($field->PrimaryKey)) { 1592 | 1593 | if (substr($field->Name, 0, 2) == 'Id') { 1594 | 1595 | $reference = substr($field->Name, 2); 1596 | 1597 | if ($dataPopup != "") { 1598 | $dataPopup .= "\n"; 1599 | } 1600 | 1601 | // Es una tabla foranea, generamos el codigo para traer el dato para el popup de nuevo, de filtro y de edicion 1602 | // Obs: usamos la version "VW" de la tabla referenciada, o sea la vista a menos que sea una tabla "Tipo" 1603 | 1604 | if (substr($reference, 0, 4) == 'Tipo') { 1605 | $svcVariable = strtolower(substr($reference, 0, 1)) . substr($reference, 1); 1606 | $svcName = $reference; 1607 | } 1608 | else { 1609 | $svcVariable = 'vw' . $reference; 1610 | $svcName = 'VW' . $reference; 1611 | } 1612 | 1613 | $preference = (isset($field->ForeignKey)) ? $field->ForeignKey : null; 1614 | 1615 | $fileReferenceSvc = $this->FindFileReference($svcName . "Svc.php", $_SERVER['OLDPWD'] . "/Application/BLL/Services", $preference); 1616 | $fileReferenceDto = $this->FindFileReference($svcName . "Dto.php", $_SERVER['OLDPWD'] . "/Application/BLL/DataTransferObjects", $preference); 1617 | 1618 | if ($fileReferenceSvc != "") { 1619 | if ($usePopup != "") 1620 | $usePopup .= "\n"; 1621 | 1622 | $usePopup .= "use " . $fileReferenceSvc . '\\' . $svcName . "Svc;\n"; 1623 | } 1624 | 1625 | if ($fileReferenceDto != "") { 1626 | if ($usePopup != "") 1627 | $usePopup .= "\n"; 1628 | 1629 | $usePopup .= "use " . $fileReferenceDto . '\\' . $svcName . "Dto;"; 1630 | } 1631 | 1632 | $dataPopup .= "\t\t" . '$' . $svcVariable . 'Svc = new ' . $svcName . 'Svc(ConnectionEnum::DEFAULT);' . "\n"; 1633 | $dataPopup .= "\t\t" . '$data' . $reference . ' = $' . $svcVariable . 'Svc->GetAll(avoidNull: false, order: "Descripcion");' . "\n"; 1634 | $dataPopup .= "\t\t" . '$data' . $reference . '->Add(' . "\n"; 1635 | $dataPopup .= "\t\t" . ' item: new ' . $svcName . 'Dto( Id' . $reference . ': -1, Descripcion: "Sin Selección"),' . "\n"; 1636 | $dataPopup .= "\t\t" . ' first: true' . "\n"; 1637 | $dataPopup .= "\t\t" . '); ' . "\n"; 1638 | $dataPopup .= "\n"; 1639 | $dataPopup .= "\t\t" . '$data["Listado' . $reference . '"] = $data' . $reference . ';' . "\n"; 1640 | 1641 | // Genero los rowGroup para el formulario 1642 | if ($formRows != "") { 1643 | $formRows .= "\n"; 1644 | } 1645 | 1646 | $formRows .= "\t\t\t\t'" . $field->Name . "' => new FormRowFieldSelect(" . "\n"; 1647 | $formRows .= "\t\t\t\t\tPropertyName : '" . $field->Name . "',\n"; 1648 | $formRows .= "\t\t\t\t\tLabel : '" . substr($field->Name, 2) . "',\n"; 1649 | $formRows .= "\t\t\t\t\tRequired : true," . "\n"; 1650 | $formRows .= "\t\t\t\t\tColspan : 4," . "\n"; 1651 | $formRows .= "\t\t\t\t\tSelectDefinition : new FormRowFieldSelectDefinition(" . "\n"; 1652 | $formRows .= "\t\t\t\t\t\tKey : '" . $field->Name . "',\n"; 1653 | $formRows .= "\t\t\t\t\t\tTriggerChangeOnload : true," . "\n"; 1654 | $formRows .= "\t\t\t\t\t\tDescription : 'Descripcion'," . "\n"; 1655 | $formRows .= "\t\t\t\t\t\tValues : " . '$data->Listado' . substr($field->Name, 2) . ",\n"; 1656 | $formRows .= "\t\t\t\t\t\tMultipleSelection : false," . "\n"; 1657 | $formRows .= "\t\t\t\t\t\tDisplaySearch : false," . "\n"; 1658 | $formRows .= "\t\t\t\t\t\tSelectedValue : -1," . "\n"; 1659 | $formRows .= "\t\t\t\t\t)," . "\n"; 1660 | $formRows .= "\t\t\t\t),"; 1661 | 1662 | } 1663 | else if (substr($field->Name, 0, 3) == 'Ind') { 1664 | // Es un checkbox 1665 | 1666 | // Genero los rowGroup para el formulario 1667 | if ($formRows != "") { 1668 | $formRows .= "\n"; 1669 | } 1670 | 1671 | $formRows .= "\t\t\t\t'" . $field->Name . "' => new FormRowFieldCheck(\n"; 1672 | $formRows .= "\t\t\t\t\tPropertyName: '" . $field->Name . "',\n"; 1673 | $formRows .= "\t\t\t\t\tLabel: ' ',\n"; 1674 | $formRows .= "\t\t\t\t\tTitle: '" . substr($field->Name, 3) . "',\n"; 1675 | $formRows .= "\t\t\t\t\tRequired: false,\n"; 1676 | $formRows .= "\t\t\t\t\tColspan: 4\n"; 1677 | $formRows .= "\t\t\t\t),\n"; 1678 | } 1679 | else { 1680 | // Generar el formulario 1681 | // 1682 | if ($field->DataType == 'datetime') { 1683 | 1684 | // Genero los rowGroup para el formulario 1685 | if ($formRows != "") { 1686 | $formRows .= "\n"; 1687 | } 1688 | 1689 | $formRows .= "\t\t\t\t'" . $field->Name . "' => new FormRowFieldDate(\n"; 1690 | $formRows .= "\t\t\t\t\tPropertyName: '" . $field->Name . "',\n"; 1691 | $formRows .= "\t\t\t\t\tLabel: '" . $field->Name . "',\n"; 1692 | $formRows .= "\t\t\t\t\tFieldType: FormRowFieldTypeEnum::INPUT_DATE,\n"; 1693 | $formRows .= "\t\t\t\t\tColspan: 4\n"; 1694 | $formRows .= "\t\t\t\t),"; 1695 | 1696 | } 1697 | else if (substr($field->Name, 0, 2) != "Id") { 1698 | 1699 | // Genero los rowGroup para el formulario 1700 | if ($formRows != "") { 1701 | $formRows .= "\n"; 1702 | } 1703 | 1704 | $formRows .= "\t\t\t\t'" . $field->Name . "' => new FormRowFieldText(\n"; 1705 | $formRows .= "\t\t\t\t\tPropertyName: '" . $field->Name . "',\n"; 1706 | $formRows .= "\t\t\t\t\tLabel: '" . $field->Name . "',\n"; 1707 | $formRows .= "\t\t\t\t\tColspan: 4\n"; 1708 | $formRows .= "\t\t\t\t),"; 1709 | } 1710 | } 1711 | } 1712 | else { 1713 | // Genero el elemento para el ID de la tabla (hidden) 1714 | if ($formRows != "") { 1715 | $formRows .= "\n"; 1716 | } 1717 | 1718 | $formRows .= "\t\t\t\t'" . $field->Name . "' => new FormRowFieldHidden(\n"; 1719 | $formRows .= "\t\t\t\t\tPropertyName: '" . $field->Name . "',\n"; 1720 | $formRows .= "\t\t\t\t),"; 1721 | } 1722 | } 1723 | 1724 | return [$fieldContent, $dataPopup, $usePopup, $formRows, $formCustom]; 1725 | } 1726 | 1727 | private function FindFileReference($filename, $basedir, $preferedFolder = null) { 1728 | 1729 | $dir_iterator = new RecursiveDirectoryIterator($basedir); 1730 | $iterator = new RecursiveIteratorIterator($dir_iterator, RecursiveIteratorIterator::CHILD_FIRST); 1731 | 1732 | $found = []; 1733 | foreach ($iterator as $file) { 1734 | $filenamefound = $file->getFilename(); 1735 | if ($filenamefound == $filename) { 1736 | $found[] = $file; 1737 | } 1738 | } 1739 | 1740 | if (count($found) > 1) { 1741 | $referenceFound = null; 1742 | // buscar el que sea la preferencia 1743 | if (isset($preferedFolder)) { 1744 | foreach ($found as $reference) { 1745 | if ( str_contains($reference->getPathName(), $preferedFolder->TargetSchema . '/')) { 1746 | $referenceFound = $reference; 1747 | break; 1748 | } 1749 | } 1750 | 1751 | if (isset($referenceFound)) { 1752 | $found = []; 1753 | $found[] = $referenceFound; 1754 | } 1755 | } 1756 | } 1757 | 1758 | if (count($found) == 1) { 1759 | // buscar la ruta en Application 1760 | $f = $found[0]; 1761 | $ruta = $f->getPath(); 1762 | $ruta = str_replace('/', '\\', $ruta); 1763 | $pos = strpos($ruta, 'Application'); 1764 | 1765 | if ($pos >= 0) { 1766 | return substr($ruta, $pos); 1767 | } 1768 | else { 1769 | return null; 1770 | } 1771 | } 1772 | } 1773 | 1774 | private function JsonSearchFields($fields, $useLowerCase = false, $foreignKeys, $schema) { 1775 | 1776 | $jsContent = ""; 1777 | $bindings = ""; 1778 | $searchRows = ""; 1779 | $searchCustom = ""; 1780 | $getbyMethods = ""; 1781 | 1782 | $maxLen = 0; 1783 | foreach($fields as $field) { 1784 | if (strlen($field->Name) > $maxLen) $maxLen = strlen($field->Name); 1785 | } 1786 | 1787 | $maxLen += 5; // agregar el "Desde" o "Hasta" 1788 | 1789 | foreach($fields as $field) { 1790 | 1791 | if ($field->PrimaryKey) { 1792 | continue; 1793 | } 1794 | 1795 | $qtySpaces = $maxLen - strlen($field->Name); 1796 | 1797 | if ($jsContent != "") { 1798 | $jsContent .= ",\n"; 1799 | } 1800 | 1801 | if ($field->DataType == 'datetime') { 1802 | 1803 | $spaces = str_repeat(' ', $qtySpaces - 5); 1804 | 1805 | // Genero el listado de javascript para el entity 1806 | $jsContent .= "\t\t\t\t" . $field->Name . "Desde" . $spaces . " : formData." . ($useLowerCase ? strtolower($field->Name) : $field->Name) . "desde,\n"; 1807 | $jsContent .= "\t\t\t\t" . $field->Name . "Hasta" . $spaces . " : formData." . ($useLowerCase ? strtolower($field->Name) : $field->Name) . "hasta"; 1808 | 1809 | // Genero el listado de bindings para el BO en funcion "Buscar" 1810 | if ($bindings != "") { 1811 | $bindings .= "\n"; 1812 | } 1813 | 1814 | $bindings .= "\t\t" . 'if (isset($filtros->' . $field->Name . 'Desde) && $filtros->' . $field->Name . 'Desde != "" ) {' . "\n"; 1815 | $bindings .= "\t\t\t" . '$bindings[] = new BindVariable("' . $field->Name . '", ">=", $filtros->' . $field->Name . 'Desde);' . "\n"; 1816 | $bindings .= "\t\t\t" . '$bindings[] = new BindVariable("' . $field->Name . '", "<=", $filtros->' . $field->Name . 'Hasta);' . "\n"; 1817 | $bindings .= "\t\t" . "}" . "\n"; 1818 | 1819 | // Genero los rowGroup para la vista de filtros 1820 | if ($searchRows != "") { 1821 | $searchRows .= "\n"; 1822 | } 1823 | 1824 | $searchRows .= "\t\t\t\t'" . $field->Name . "' => new FormRowFieldDate(\n"; 1825 | $searchRows .= "\t\t\t\t\tPropertyName: '" . $field->Name . "Desde',\n"; 1826 | $searchRows .= "\t\t\t\t\tLabel: '" . $field->Name . " Desde',\n"; 1827 | $searchRows .= "\t\t\t\t\tFieldType: FormRowFieldTypeEnum::INPUT_DATE,\n"; 1828 | $searchRows .= "\t\t\t\t\tColspan: 2\n"; 1829 | $searchRows .= "\t\t\t\t),\n"; 1830 | 1831 | $searchRows .= "\t\t\t\t'" . $field->Name . "' => new FormRowFieldDate(\n"; 1832 | $searchRows .= "\t\t\t\t\tPropertyName: '" . $field->Name . "Hasta',\n"; 1833 | $searchRows .= "\t\t\t\t\tLabel: '" . $field->Name . " Hasta',\n"; 1834 | $searchRows .= "\t\t\t\t\tFieldType: FormRowFieldTypeEnum::INPUT_DATE,\n"; 1835 | $searchRows .= "\t\t\t\t\tColspan: 2\n"; 1836 | $searchRows .= "\t\t\t\t),\n"; 1837 | 1838 | if ($searchCustom != "") { 1839 | $searchCustom .= "\n"; 1840 | } 1841 | $searchCustom .= "\t\t" . '$row[] = $rowGroup->Rows[0]["' . $field->Name . '"];'; 1842 | 1843 | } 1844 | else if ($field->DataType == 'string') { 1845 | 1846 | // Genero el listado de javascript para el entity 1847 | $spaces = str_repeat(' ', $qtySpaces); 1848 | $jsContent .= "\t\t\t\t" . $field->Name . $spaces . " : formData." . strtolower($field->Name); 1849 | 1850 | // Genero el listado de bindings para el BO en funcion "Buscar" 1851 | if ($bindings != "") { 1852 | $bindings .= "\n"; 1853 | } 1854 | 1855 | $bindings .= "\t\t" . 'if (isset($filtros->' . $field->Name . ') && $filtros->' . $field->Name . ' != "" ) {' . "\n"; 1856 | $bindings .= "\t\t\t" . '$bindings[] = new BindVariable("' . $field->Name . '", "LIKE", $filtros->' . $field->Name . ');' . "\n"; 1857 | $bindings .= "\t\t" . "}" . "\n"; 1858 | 1859 | // Genero los rowGroup para la vista de filtros 1860 | if ($searchRows != "") { 1861 | $searchRows .= "\n"; 1862 | } 1863 | 1864 | $searchRows .= "\t\t\t\t'" . $field->Name . "' => new FormRowFieldText(\n"; 1865 | $searchRows .= "\t\t\t\t\tPropertyName: '" . $field->Name . "',\n"; 1866 | $searchRows .= "\t\t\t\t\tLabel: '" . $field->Name . "',\n"; 1867 | $searchRows .= "\t\t\t\t\tColspan: 2\n"; 1868 | $searchRows .= "\t\t\t\t),\n"; 1869 | 1870 | if ($searchCustom != "") { 1871 | $searchCustom .= "\n"; 1872 | } 1873 | $searchCustom .= "\t\t" . '$row[] = $rowGroup->Rows[0]["' . $field->Name . '"];'; 1874 | } 1875 | else { 1876 | 1877 | // Genero el listado de javascript para el entity 1878 | $spaces = str_repeat(' ', $qtySpaces); 1879 | $jsContent .= "\t\t\t\t" . $field->Name . $spaces . " : formData." . ($useLowerCase ? strtolower($field->Name) : $field->Name) . " *1"; 1880 | 1881 | 1882 | if (substr($field->Name, 0, 2) == "Id") { 1883 | 1884 | // Genero el listado de bindings para el BO en funcion "Buscar" 1885 | if ($bindings != "") { 1886 | $bindings .= "\n"; 1887 | } 1888 | 1889 | $bindings .= "\t\t" . 'if (isset($filtros->' . $field->Name . ') && $filtros->' . $field->Name . ' != "" && $filtros->' . $field->Name . ' != "-1") {' . "\n"; 1890 | $bindings .= "\t\t\t" . '$bindings[] = new BindVariable("' . $field->Name . '", "=", $filtros->' . $field->Name . ');' . "\n"; 1891 | $bindings .= "\t\t" . "}" . "\n"; 1892 | 1893 | if (isset($field->ForeignKey)) { 1894 | if ($getbyMethods!= "") $getbyMethods.= "\n"; 1895 | 1896 | $getbyMethods .= "\t#[Route(Methods: ['POST'], RequireSession:false)]\n"; 1897 | $getbyMethods .= "\t#[ReturnActionResult]\n"; 1898 | $getbyMethods .= "\tpublic function GetBy_" . $field->ForeignKey->TargetSchema . "_" . $field->ForeignKey->TargetTable . "(\$Id) {\n"; 1899 | $getbyMethods .= "\t\t\$svc = new " . $field->ForeignKey->SourceTable . "Svc(ConnectionEnum::DEFAULT);\n"; 1900 | $getbyMethods .= "\t\t\$bindings = [new BindVariable('" . $field->ForeignKey->TargetColumn . "', '=', \$Id)];\n"; 1901 | $getbyMethods .= "\t\t\$elementos = \$svc->GetBy(bindings: \$bindings, avoidNull: true);\n"; 1902 | $getbyMethods .= "\t\t\$elementos->Add(item: new " . $field->ForeignKey->SourceTable . "Dto(Id" . $field->ForeignKey->SourceTable . ": -1, Descripcion: 'Sin Selección'),first: true);\n"; 1903 | $getbyMethods .= "\t\treturn \$elementos;\n"; 1904 | $getbyMethods .= "\t}\n"; 1905 | } 1906 | 1907 | // Genero los rowGroup para la vista de filtros 1908 | if ($searchRows != "") { 1909 | $searchRows .= "\n"; 1910 | } 1911 | 1912 | // Revisar si este SELECT tendrá sucesores 1913 | $sucesores = $this->Sucesores($field, $fields, $foreignKeys, $schema); 1914 | // Revisar si este SELECT tendrá algún antecesor 1915 | $antecesor = $this->Antecesor($field, $fields, $foreignKeys, $schema); 1916 | 1917 | 1918 | $searchRows .= "\t\t\t\t'" . $field->Name . "' => new FormRowFieldSelect(" . "\n"; 1919 | $searchRows .= "\t\t\t\t\tPropertyName : '" . $field->Name . "',\n"; 1920 | $searchRows .= "\t\t\t\t\tLabel : '" . substr($field->Name, 2) . "',\n"; 1921 | $searchRows .= "\t\t\t\t\tRequired : true," . "\n"; 1922 | $searchRows .= "\t\t\t\t\tColspan : 2," . "\n"; 1923 | $searchRows .= "\t\t\t\t\tSelectDefinition : new FormRowFieldSelectDefinition(" . "\n"; 1924 | $searchRows .= "\t\t\t\t\t\tKey : '" . $field->Name . "',\n"; 1925 | 1926 | $searchRows .= "\t\t\t\t\t\tDescription : 'Descripcion'," . "\n"; 1927 | 1928 | if (isset($antecesor)) { 1929 | $searchRows .= "\t\t\t\t\t\tValues : [],\n"; 1930 | $searchRows .= "\t\t\t\t\t\tTriggerChangeOnload : true," . "\n"; 1931 | $searchRows .= "\t\t\t\t\t\tLinkToList : '" . $antecesor->TargetColumn . "',\n"; 1932 | $searchRows .= "\t\t\t\t\t\tJSRefreshService : ['" . $antecesor->SourceTable . "Svc', 'getby_" . strtolower(str_replace('.', '_', $antecesor->TargetTableName)) . "'],\n"; 1933 | } 1934 | else { 1935 | $searchRows .= "\t\t\t\t\t\tValues : " . '$data->Listado' . substr($field->Name, 2) . ",\n"; 1936 | $searchRows .= "\t\t\t\t\t\tTriggerChangeOnload : true," . "\n"; 1937 | } 1938 | $searchRows .= "\t\t\t\t\t\tMultipleSelection : false," . "\n"; 1939 | $searchRows .= "\t\t\t\t\t\tDisplaySearch : false," . "\n"; 1940 | $searchRows .= "\t\t\t\t\t\tSelectedValue : -1," . "\n"; 1941 | $searchRows .= "\t\t\t\t\t)," . "\n"; 1942 | 1943 | if (isset($sucesores) && count($sucesores) > 0) { 1944 | $searchRows .= "\t\t\t\t\tEvents: [\n"; 1945 | $searchRows .= "\t\t\t\t\t new FormOnChangeEvent(\n"; 1946 | $searchRows .= "\t\t\t\t\t Actions: [\n"; 1947 | $searchRows .= "\t\t\t\t\t new RefreshListAction(\n"; 1948 | 1949 | $keys = ""; 1950 | foreach($sucesores as $suc) { 1951 | if ($keys != "") $keys .= ","; 1952 | $keys .= 'Id' . $suc->SourceTable; 1953 | } 1954 | 1955 | $searchRows .= "\t\t\t\t\t TargetElementKeys: ['" . $keys . "']\n"; 1956 | $searchRows .= "\t\t\t\t\t ),\n"; 1957 | $searchRows .= "\t\t\t\t\t ]\n"; 1958 | $searchRows .= "\t\t\t\t\t )\n"; 1959 | $searchRows .= "\t\t\t\t\t],\n"; 1960 | } 1961 | 1962 | $searchRows .= "\t\t\t\t)," . "\n"; 1963 | 1964 | if ($searchCustom != "") { 1965 | $searchCustom .= "\n"; 1966 | } 1967 | $searchCustom .= "\t\t" . '$row[] = $rowGroup->Rows[0]["' . $field->Name . '"];'; 1968 | } 1969 | 1970 | } 1971 | } 1972 | 1973 | $jsContentLen = strlen($jsContent); 1974 | if (substr($jsContent, $jsContentLen-1, 1) == ',') { 1975 | $jsContent = substr($jsContent, 0, $jsContentLen-1); 1976 | } 1977 | 1978 | return [$jsContent, $bindings, $searchRows, $searchCustom, $getbyMethods]; 1979 | } 1980 | 1981 | private function Sucesores($field, $fields, $foreignKeys, $schema) { 1982 | 1983 | $sucesores = []; 1984 | 1985 | foreach($foreignKeys as $key) { 1986 | //if ($key->TargetColumn == $field->Name && $key->SourceTable == substr($field->Name, 2)) { 1987 | if ($key->SourceTable != $schema->Table && $key->TargetColumn == $field->Name && isset($fields["Id" . $key->SourceTable])) { 1988 | $sucesores[] = $key; 1989 | } 1990 | } 1991 | 1992 | return $sucesores; 1993 | } 1994 | 1995 | private function Antecesor($field, $fields, $foreignKeys, $schema) { 1996 | 1997 | $antecesor = null; 1998 | 1999 | foreach($foreignKeys as $key) { 2000 | if ($key->SourceTable == substr($field->Name, 2)) { 2001 | $antecesor = $key; 2002 | break; 2003 | } 2004 | } 2005 | 2006 | return $antecesor; 2007 | } 2008 | 2009 | } -------------------------------------------------------------------------------- Total de líneas: 2009 ================================================================================ ================================================================================ ARCHIVO #143: src/Generator/Templates/Dao.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Generator/Templates/Dao.php Tamaño: 552 bytes -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Código generado automáticamente 4 | * Generador de Código de Intouch 5 | * Autor: Claudio Alfonso González Almeyda 6 | */ 7 | 8 | namespace Application\Dao\Services\Namespace?>; 9 | 10 | use Application\Dao\Entities\Namespace?>\EntityName?>; 11 | use Intouch\Framework\Dao\GenericDao; 12 | 13 | class EntityName?>Dao extends GenericDao 14 | { 15 | use EntityName?>DaoT; 16 | 17 | function __construct($domain) 18 | { 19 | parent::__construct( 20 | EntityName?>::class, 21 | $domain 22 | ); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- Total de líneas: 25 ================================================================================ ================================================================================ ARCHIVO #144: src/Generator/Templates/DaoT.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Generator/Templates/DaoT.php Tamaño: 235 bytes -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Código generado automáticamente 4 | * Generador de Código de Intouch 5 | * Autor: Claudio Alfonso González Almeyda 6 | */ 7 | 8 | namespace Application\Dao\Services\Namespace?>; 9 | 10 | trait EntityName?>DaoT 11 | { 12 | 13 | } 14 | -------------------------------------------------------------------------------- Total de líneas: 14 ================================================================================ ================================================================================ ARCHIVO #145: src/Generator/Templates/Dto.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Generator/Templates/Dto.php Tamaño: 441 bytes -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Código generado automáticamente 4 | * Generador de Código de Intouch 5 | * Autor: Claudio Alfonso González Almeyda 6 | */ 7 | 8 | namespace Application\BLL\DataTransferObjects\Namespace?>; 9 | 10 | class EntityName?>Dto 11 | { 12 | use EntityName?>DtoT; 13 | 14 | public function __construct( 15 | Fields as $name => $field) { 17 | ?> 18 | public Declaration?>, 19 | 22 | ) { 23 | 24 | } 25 | } -------------------------------------------------------------------------------- Total de líneas: 25 ================================================================================ ================================================================================ ARCHIVO #146: src/Generator/Templates/DtoT.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Generator/Templates/DtoT.php Tamaño: 461 bytes -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Código generado automáticamente 4 | * Generador de Código de Intouch 5 | * Autor: Claudio Alfonso González Almeyda 6 | */ 7 | 8 | namespace Application\BLL\DataTransferObjects\Namespace?>; 9 | 10 | trait EntityName?>DtoT 11 | { 12 | function __get($name) { 13 | switch($name) { 14 | default: return null; 15 | } 16 | } 17 | 18 | function __set($name, $value) { 19 | switch($name) { 20 | default: return null; 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- Total de líneas: 23 ================================================================================ ================================================================================ ARCHIVO #147: src/Generator/Templates/Ent.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Generator/Templates/Ent.php Tamaño: 837 bytes -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Código generado automáticamente 4 | * Generador de Código de Intouch 5 | * Autor: Claudio Alfonso González Almeyda 6 | */ 7 | 8 | namespace Application\Dao\Entities\Namespace?>; 9 | 10 | use Intouch\Framework\Annotation\Attributes\Entity; 11 | use Intouch\Framework\Annotation\Attributes\EntityField; 12 | 13 | #[Entity(Schema: 'Entity->Schema?>')] 14 | class EntityName?> 15 | { 16 | use EntityName?>T; 17 | 18 | Fields as $name => $field) { 20 | 21 | if ($field->PrimaryKey) { 22 | ?> 23 | #[EntityField(PrimaryKey: true)] 24 | DataType == 'date' || $field->DataType == 'datetime') { 27 | ?> 28 | #[EntityField(DataType: 'datetime')] 29 | 32 | public Declaration?>; 33 | 36 | 37 | function __construct() 38 | { 39 | } 40 | } -------------------------------------------------------------------------------- Total de líneas: 40 ================================================================================ ================================================================================ ARCHIVO #148: src/Generator/Templates/EntT.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Generator/Templates/EntT.php Tamaño: 288 bytes -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Código generado automáticamente 4 | * Generador de Código de Intouch 5 | * Autor: Claudio Alfonso González Almeyda 6 | */ 7 | 8 | namespace Application\Dao\Entities\Namespace?>; 9 | 10 | use Intouch\Framework\Annotation\Attributes\EntityField; 11 | 12 | trait EntityName?>T 13 | { 14 | } -------------------------------------------------------------------------------- Total de líneas: 14 ================================================================================ ================================================================================ ARCHIVO #149: src/Generator/Templates/Mantenedores/ApiController.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Generator/Templates/Mantenedores/ApiController.php Tamaño: 6.59 KB -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Código generado automáticamente 4 | * Generador de Código de Intouch 5 | * Autor: Claudio Alfonso González Almeyda 6 | */ 7 | 8 | namespace Application\Controllers\Api\Mantenedores\Namespace?>; 9 | 10 | use Application\BLL\BusinessObjects\Mantenedores\Namespace?>\EntityName?>BO; 11 | use Application\BLL\DataTransferObjects\Namespace?>\EntityName?>Dto; 12 | use Application\BLL\DataTransferObjects\Namespace?>\VWEntityName?>Dto; 13 | use Application\BLL\Services\Namespace?>\EntityName?>Svc; 14 | use Application\BLL\Services\Namespace?>\VWEntityName?>Svc; 15 | use Application\Configuration\ConnectionEnum; 16 | use Application\Resources\AssetManagerFactory; 17 | use Intouch\Framework\Annotation\Attributes\ReturnActionResult; 18 | use Intouch\Framework\Annotation\Attributes\ReturnActionViewResult; 19 | use Intouch\Framework\Annotation\Attributes\Route; 20 | use Intouch\Framework\Controllers\BaseController; 21 | use Intouch\Framework\Dao\BindVariable; 22 | use Intouch\Framework\Exceptions\BusinessException; 23 | use Intouch\Framework\Exceptions\ExceptionCodesEnum; 24 | use Intouch\Framework\View\Display; 25 | 26 | #[Route(Authorization: 'ALLOW_ALL', RequireSession: false)] 27 | class EntityName?>Controller extends BaseController { 28 | 29 | use EntityName?>ControllerT; 30 | 31 | public function __construct() { 32 | parent::__construct(assetManagerFactory: new AssetManagerFactory()); 33 | } 34 | 35 | #[Route(Methods: ['POST'],Authorization: 'ALLOW_ALL', RequireSession: false)] 36 | #[ReturnActionResult] 37 | public function SePuedeEliminarEntityName?>($IdEntityName?>) { 38 | 39 | $LowerEntityName?>BO = new EntityName?>BO(); 40 | return $LowerEntityName?>BO->SePuedeEliminarEntityName?>($IdEntityName?>); 41 | } 42 | 43 | #[Route(Methods: ['POST'],Authorization: 'ALLOW_ALL', RequireSession: false)] 44 | #[ReturnActionResult] 45 | public function EliminarEntityName?>($IdEntityName?>) { 46 | 47 | $LowerEntityName?>BO = new EntityName?>BO(); 48 | return $LowerEntityName?>BO->EliminarEntityName?>($IdEntityName?>); 49 | } 50 | 51 | #[Route(Methods: ['POST'],Authorization: 'ALLOW_ALL', RequireSession: false)] 52 | #[ReturnActionViewResult] 53 | public function PopUpEntityName?>($IdEntityName?>, $NombreIdPadre, $ValorIdPadre) { 54 | 55 | $LowerEntityName?>BO = new EntityName?>BO(); 56 | $data = $LowerEntityName?>BO->ObtenerDataEntityName?>($IdEntityName?>, $NombreIdPadre, $ValorIdPadre); 57 | 58 | $view = Display::GetRenderer('Mantenedores/Namespace?>/EntityName?>')->RenderView('popup', $data); 59 | return $view; 60 | } 61 | 62 | #[Route(Methods: ['POST'])] 63 | #[ReturnActionResult] 64 | public function GuardarEntityName?>($EntityName?>Registro) { 65 | 66 | $LowerEntityName?>BO = new EntityName?>BO(); 67 | 68 | try { 69 | if ( !isset($EntityName?>Registro->IdEntityName?>) || $EntityName?>Registro->IdEntityName?> == 0) { 70 | $LowerEntityName?>BO->GuardarNuevoEntityName?>($EntityName?>Registro); 71 | } 72 | else { 73 | $LowerEntityName?>BO->GuardarEntityName?>($EntityName?>Registro); 74 | } 75 | } 76 | catch (\Exception $ex) { 77 | throw new BusinessException(ExceptionCodesEnum::ERR_DATA_INSERT, ' al guardar el registro'); 78 | } 79 | 80 | return 0; 81 | } 82 | 83 | #[Route(Methods: ['POST'], Authorization: 'ALLOW_ALL', RequireSession: false)] 84 | #[ReturnActionViewResult] 85 | public function BuscarEntityName?>($RegistroEntityName?>Buscar) { 86 | 87 | $LowerEntityName?>BO = new EntityName?>BO(); 88 | $EntityName?>s = $LowerEntityName?>BO->BuscarEntityName?>($RegistroEntityName?>Buscar); 89 | 90 | $view = Display::GetRenderer('Mantenedores/Namespace?>/EntityName?>')->RenderView('verGrid', $EntityName?>s); 91 | return $view; 92 | } 93 | 94 | #[Route(Methods: ['POST'], Authorization: 'ALLOW_ALL', RequireSession: false)] 95 | #[ReturnActionViewResult] 96 | public function BuscarEntityName?>AsPopUp($RegistroEntityName?>Buscar) { 97 | 98 | $data = new \stdClass(); 99 | $LowerEntityName?>BO = new EntityName?>BO(); 100 | $LowerEntityName?>s = $LowerEntityName?>BO->BuscarEntityName?>($RegistroEntityName?>Buscar); 101 | 102 | if ($RegistroEntityName?>Buscar != 'api') { 103 | // Se asume que el ID que viene es del registro padre 104 | $vars = get_object_vars($RegistroEntityName?>Buscar); 105 | 106 | $varName = ""; 107 | $varValue = null; 108 | 109 | foreach($vars as $name => $value) { 110 | $varName = $name; 111 | $varValue = $value; 112 | break; 113 | } 114 | 115 | $data->Elementos = $LowerEntityName?>s; 116 | $data->Filtros = $RegistroEntityName?>Buscar; 117 | $data->IdPadre = $varName; 118 | $data->ValuePadre = $varValue; 119 | } 120 | 121 | $view = Display::GetRenderer('Mantenedores/Namespace?>/EntityName?>')->RenderView('verGridAsPopUp', $data); 122 | return $view; 123 | } 124 | 125 | Fields as $name => $field) { 129 | 130 | if (isset($field->ForeignKey) && isset($inclusiones[$field->ForeignKey->TargetSchema . '_' . $field->ForeignKey->TargetTable])) { 131 | continue; 132 | } 133 | 134 | $inclusiones[$field->ForeignKey->TargetSchema . '_' . $field->ForeignKey->TargetTable] = 1; 135 | 136 | if (isset($field->ForeignKey)) { 137 | ?> 138 | 139 | #[Route(Methods: ['POST'], RequireSession:false)] 140 | #[ReturnActionResult] 141 | public function GetBy_ForeignKey->TargetSchema?>_ForeignKey->TargetTable?> ($Id) { 142 | $svc = new VWForeignKey->SourceTable?>Svc(ConnectionEnum::DEFAULT); 143 | $bindings = [ 144 | new BindVariable('ForeignKey->TargetColumn?>', '=', $Id) 145 | ]; 146 | $elementos = $svc->GetBy(bindings: $bindings, orderFields: 'Descripcion', avoidNull: true); 147 | $elementos->Add( 148 | item: new VWForeignKey->SourceTable?>Dto( 149 | IdForeignKey->SourceTable?>: -1, 150 | Descripcion: 'Sin Selección' 151 | ), 152 | first: true 153 | ); 154 | return $elementos; 155 | } 156 | 160 | } -------------------------------------------------------------------------------- Total de líneas: 160 ================================================================================ ================================================================================ ARCHIVO #150: src/Generator/Templates/Mantenedores/ApiControllerT.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Generator/Templates/Mantenedores/ApiControllerT.php Tamaño: 261 bytes -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Código generado automáticamente 4 | * Generador de Código de Intouch 5 | * Autor: Claudio Alfonso González Almeyda 6 | */ 7 | 8 | namespace Application\Controllers\Api\Mantenedores\Namespace?>; 9 | 10 | trait EntityName?>ControllerT 11 | { 12 | 13 | } -------------------------------------------------------------------------------- Total de líneas: 13 ================================================================================ ================================================================================ ARCHIVO #151: src/Generator/Templates/Mantenedores/BusinessObject.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Generator/Templates/Mantenedores/BusinessObject.php Tamaño: 10.19 KB -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Código generado automáticamente 4 | * Generador de Código de Intouch 5 | * Autor: Claudio Alfonso González Almeyda 6 | */ 7 | 8 | namespace Application\BLL\BusinessObjects\Mantenedores\Namespace?>; 9 | 10 | use Application\BLL\Services\Namespace?>\EntityName?>Svc; 11 | use Application\BLL\Services\Namespace?>\VWEntityName?>Svc; 12 | use Application\BLL\DataTransferObjects\Namespace?>\EntityName?>Dto; 13 | use Application\BLL\DataTransferObjects\Namespace?>\VWEntityName?>Dto; 14 | use Application\Configuration\ConnectionEnum; 15 | use Intouch\Framework\BLL\Service\GenericSvc; 16 | use Intouch\Framework\Dao\BindVariable; 17 | use Intouch\Framework\Exceptions\BusinessException; 18 | use Intouch\Framework\Exceptions\ExceptionCodesEnum; 19 | use ReflectionClass; 20 | 21 | Fields as $name => $field) { 28 | 29 | if ($declarations != "") { 30 | $declarations .= ",\n"; 31 | } 32 | $declarations .= "\t\t\t\t" . str_pad($name, $field->FieldLength, ' ') . "\t: \$registro->" . $name; 33 | 34 | if (strtolower($name) == "indeliminado") { 35 | if ($declarations2 != "") { 36 | $declarations2 .= ",\n"; 37 | } 38 | $declarations2 .= "\t\t\t\t" . str_pad($name, $field->FieldLength, ' ') . "\t: 0"; 39 | } 40 | else if (strtolower($name) == "indvigente") { 41 | if ($declarations2 != "") { 42 | $declarations2 .= ",\n"; 43 | } 44 | $declarations2 .= "\t\t\t\t" . str_pad($name, $field->FieldLength, ' ') . "\t: 1"; 45 | } 46 | else { 47 | if ($declarations2 != "") { 48 | $declarations2 .= ",\n"; 49 | } 50 | $declarations2 .= "\t\t\t\t" . str_pad($name, $field->FieldLength, ' ') . "\t: \$registro->" . $name; 51 | } 52 | 53 | if (strtolower($name) == "indeliminado") { 54 | if ($declarations3 != "") { 55 | $declarations3 .= ",\n"; 56 | } 57 | $declarations3 .= "\t\t\t\t" . str_pad($name, $field->FieldLength, ' ') . "\t: 0"; 58 | } 59 | else { 60 | if ($declarations3 != "") { 61 | $declarations3 .= ",\n"; 62 | } 63 | $declarations3 .= "\t\t\t\t" . str_pad($name, $field->FieldLength, ' ') . "\t: \$registro->" . $name; 64 | } 65 | 66 | 67 | if ($field->FileRefSvc != "" && $field->SvcName != "VW".$data->EntityName) { 68 | ?> 69 | use FileRefSvc?>\SvcName?>Svc; 70 | FileRefDto != "" && $field->SvcName != "VW".$data->EntityName) { 73 | ?> 74 | use FileRefDto?>\SvcName?>Dto; 75 | 79 | 80 | class EntityName?>BO 81 | { 82 | 83 | use EntityName?>BOT; 84 | 85 | public function GuardarEntityName?>($registro) { 86 | 87 | $LowerEntityName?>Svc = new EntityName?>Svc(ConnectionEnum::DEFAULT); 88 | 89 | try { 90 | 91 | GenericSvc::BeginMultipleOperations(ConnectionEnum::DEFAULT); 92 | 93 | $Entity->Table)?> = new EntityName?>Dto( 94 | 95 | 96 | ); 97 | 98 | $LowerEntityName?>Svc->Update($Entity->Table)?>); 99 | 100 | GenericSvc::SaveMultipleOperations(); 101 | 102 | return true; 103 | } 104 | catch(\Exception $e){ 105 | GenericSvc::UndoMultipleOperations(); 106 | throw $e; 107 | } 108 | } 109 | 110 | public function GuardarNuevoEntityName?>($registro) { 111 | 112 | $LowerEntityName?>Svc = new EntityName?>Svc(ConnectionEnum::DEFAULT); 113 | 114 | try { 115 | 116 | GenericSvc::BeginMultipleOperations(ConnectionEnum::DEFAULT); 117 | 118 | // Asegurarse de generar un registro nuevo 119 | $registro->IdEntityName?> = 0; 120 | 121 | $Entity->Table)?> = new EntityName?>Dto( 122 | 123 | 124 | ); 125 | 126 | $nuevoEntityName?> = $LowerEntityName?>Svc->Insert($Entity->Table)?>); 127 | 128 | if (!isset($nuevoEntityName?>) || $nuevoEntityName?>->IdEntityName?> <= 0) { 129 | GenericSvc::UndoMultipleOperations(); 130 | throw new \Exception("Ha ocurrido un problema al intentar guardar el registro", 1); 131 | } 132 | 133 | 134 | GenericSvc::SaveMultipleOperations(); 135 | 136 | return true; 137 | } 138 | catch(\Exception $e){ 139 | GenericSvc::UndoMultipleOperations(); 140 | throw $e; 141 | } 142 | } 143 | 144 | public function BuscarEntityName?>($filtros) { 145 | 146 | // Por defecto, buscamos la información para la grilla en la 147 | // vista que pudiera existir, en caso contrario, buscamos 148 | // la información en la tabla 149 | // Obs: Para las "Vistas de base de datos" que llenen la grilla, 150 | // se debe cumplir la convención de que contendrá un JOIN 151 | // para cada llave foránea y un campo con la descripción 152 | // de la tabla destino que será el nombre de la llave 153 | // sin anteponer "Id". 154 | // 155 | // Por ejemplo, si la tabla actual es Cliente, y tiene una 156 | // llave foránea IdEmpresa (que por convención pertenece a 157 | // una tabla llamada "Empresa"), entonces se asumirá que 158 | // existe una vista VWCliente que será como sigue: // 159 | // CREATE VIEW VWCliente AS 160 | // SELECT 161 | // c.IdCliente, c.xxxxxxxxxx ...., e.IdEmpresa, e.Descripcion as Empresa 162 | // FROM Cliente c 163 | // JOIN Empresa e ON c.IdEmpresa = e.IdEmpresa 164 | 165 | $LowerEntityName?>Svc = new VWEntity?>Svc(ConnectionEnum::DEFAULT); 166 | 167 | $bindings = []; 168 | 169 | ExisteIndEliminado) { 171 | ?> 172 | 173 | if ($this->OcultarEliminadosEnBusqueda) { 174 | $bindings[] = new BindVariable("IndEliminado", "=", 0); 175 | } 176 | Fields as $name => $field) { 181 | 182 | if (substr($name, 0, 3) == 'Ind') { 183 | continue; 184 | } 185 | 186 | if ($field->DataType == 'datetime') { 187 | ?> 188 | 189 | if (isset($filtros->Desde) && $filtros->Desde != "" ) { 190 | $bindings[] = new BindVariable("", ">=", $filtros->Desde); 191 | } 192 | 193 | if (isset($filtros->Hasta) && $filtros->Hasta != "" ) { 194 | $bindings[] = new BindVariable("", "<=", $filtros->Hasta); 195 | } 196 | DataType == 'string') { 199 | ?> 200 | 201 | if (isset($filtros->) && $filtros-> != "" ) { 202 | $bindings[] = new BindVariable("", "LIKE", '%' . $filtros-> . '%'); 203 | } 204 | 208 | 209 | if (isset($filtros->) && $filtros-> != "-1" ) { 210 | $bindings[] = new BindVariable("", "=", $filtros->); 211 | } 212 | 216 | 217 | $result = $LowerEntityName?>Svc->GetBy( 218 | bindings: $bindings, 219 | avoidNull: true 220 | ); 221 | 222 | return $result; 223 | } 224 | 225 | public function SePuedeEliminarEntityName?>($IdEntityName?>) { 226 | 227 | $mensaje = ""; 228 | $mensajes = $this->ValidarEliminarEntityName?>($IdEntityName?>); 229 | 230 | if (count($mensajes) > 0) { 231 | $mensaje = implode('
', $mensajes); 232 | } 233 | 234 | return $mensaje; 235 | } 236 | 237 | public function EliminarEntityName?>($IdEntityName?>) { 238 | 239 | GenericSvc::BeginMultipleOperations(ConnectionEnum::DEFAULT); 240 | 241 | try { 242 | 243 | // Eliminamos en cascada 244 | $this->EliminarElementosDependientesEntityName?>($IdEntityName?>); 245 | 246 | $LowerEntityName?>Svc = new EntityName?>Svc(ConnectionEnum::DEFAULT); 247 | 248 | if ($this->EliminacionLogica) { 249 | $LowerEntityName?>Svc->LogicDelete($IdEntityName?>); 250 | } 251 | else { 252 | $LowerEntityName?>Svc->Delete($IdEntityName?>); 253 | } 254 | 255 | GenericSvc::SaveMultipleOperations(); 256 | 257 | } 258 | catch (\Exception $e) { 259 | GenericSvc::UndoMultipleOperations(); 260 | throw new BusinessException(ExceptionCodesEnum::ERR_DATA_DELETE, 'al intentar eliminar el registro de EntityName?>'); 261 | } 262 | 263 | return ''; 264 | } 265 | 266 | public function ObtenerDataEntityName?>($IdEntityName?> = 0, $NombreIdPadre = '', $ValorIdPadre = -1) { 267 | 268 | $data = []; 269 | 270 | if ($IdEntityName?> <> 0) { 271 | // Obtener el elemento principal 272 | $LowerEntityName?>Svc = new EntityName?>Svc(ConnectionEnum::DEFAULT); 273 | $elemento = $LowerEntityName?>Svc->Find($IdEntityName?>); 274 | $data['Elemento'] = $elemento; 275 | } 276 | else { 277 | if ($NombreIdPadre != '' && $ValorIdPadre > 0) { 278 | $elemento = new EntityName?>Dto( 279 | IdEntityName?>: 0 280 | ); 281 | 282 | $ref = new ReflectionClass(EntityName?>Dto::class); 283 | $ref->getProperty($NombreIdPadre)->setValue($elemento, $ValorIdPadre); 284 | 285 | $data['Elemento'] = $elemento; 286 | } 287 | else { 288 | $data['Elemento'] = new EntityName?>Dto( 289 | IdEntityName?>: 0 290 | ); 291 | } 292 | } 293 | 294 | Fields as $name => $field) { 296 | 297 | if ($field->Reference != '' && $field->SvcName != 'VW'.$data->EntityName) { 298 | ?> 299 | $SvcVariable?>Svc = new SvcName?>Svc(ConnectionEnum::DEFAULT); 300 | $dataReference?> = $SvcVariable?>Svc->GetAll(avoidNull: true, order: "Descripcion"); 301 | $dataReference?>->Add( 302 | item: new SvcName?>Dto( IdReference?>: -1, Descripcion: "Sin Selección"), 303 | first: true 304 | ); 305 | 306 | $data["ListadoReference?>"] = $dataReference?>; 307 | 308 | 312 | 313 | return (object)$data; 314 | } 315 | 316 | } -------------------------------------------------------------------------------- Total de líneas: 316 ================================================================================ ================================================================================ ARCHIVO #152: src/Generator/Templates/Mantenedores/BusinessObjectT.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Generator/Templates/Mantenedores/BusinessObjectT.php Tamaño: 1.82 KB -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Código generado automáticamente 4 | * Generador de Código de Intouch 5 | * Autor: Claudio Alfonso González Almeyda 6 | */ 7 | 8 | namespace Application\BLL\BusinessObjects\Mantenedores\Namespace?>; 9 | 10 | use Application\Configuration\ConnectionEnum; 11 | use Intouch\Framework\Dao\BindVariable; 12 | 13 | trait EntityName?>BOT 14 | { 15 | public $EliminacionLogica = ExisteIndEliminado) ? "true" : "false"?>; 16 | public $OcultarEliminadosEnBusqueda = ExisteIndEliminado) ? "true" : "false"?>; 17 | 18 | public function ValidarEliminarEntityName?>($IdEntityName?>) : array { 19 | 20 | $mensajes = []; 21 | 22 | // EJEMPLO DE USO 23 | // 24 | // $vehiculosSvc = new VehiculoSvc(ConnectionEnum::DEFAULT); 25 | // $cantidadVehiculos = $vehiculosSvc->CountBy([ 26 | // new BindVariable('IndVigente', '=', 1), 27 | // new BindVariable('IdEntityName?>', '=', $IdEntityName?>) 28 | // ]); 29 | // 30 | // if (isset($cantidadVehiculos) && $cantidadVehiculos > 0) { 31 | // if ($cantidadVehiculos == 1) { 32 | // $mensajes[] = "Existen " . $cantidadVehiculos . " vehículo asociado a este EntityName)?>. Será eliminado al eliminar al EntityName)?>.
"; 33 | // } 34 | // else { 35 | // $mensajes[] = "Existen " . $cantidadVehiculos . " vehículos asociados a este EntityName)?>. Serán eliminados al eliminar al EntityName)?>.
"; 36 | // } 37 | // } 38 | 39 | return $mensajes; 40 | } 41 | 42 | public function EliminarElementosDependientesEntityName?>($IdEntityName?>) { 43 | 44 | // Ejemplo de uso 45 | // (new VehiculoBO())->EliminarByEntityName?>($IdEntityName?>); 46 | 47 | return; 48 | } 49 | } -------------------------------------------------------------------------------- Total de líneas: 49 ================================================================================ ================================================================================ ARCHIVO #153: src/Generator/Templates/Mantenedores/ViewController.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Generator/Templates/Mantenedores/ViewController.php Tamaño: 1.35 KB -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Código generado automáticamente 4 | * Generador de Código de Intouch 5 | * Autor: Claudio Alfonso González Almeyda 6 | */ 7 | 8 | namespace Application\Controllers\Mantenedores\Namespace?>; 9 | 10 | use Application\BLL\BusinessObjects\Mantenedores\Namespace?>\EntityName?>BO; 11 | use Application\BLL\Services\Namespace?>\EntityName?>Svc; 12 | use Application\Configuration\ConnectionEnum; 13 | use Application\Resources\AssetManagerFactory; 14 | use Intouch\Framework\Annotation\Attributes\ReturnViewResult; 15 | use Intouch\Framework\Annotation\Attributes\Route; 16 | use Intouch\Framework\Controllers\BaseController; 17 | use Intouch\Framework\View\Display; 18 | use Intouch\Framework\Dao\BindVariable; 19 | 20 | #[Route(Authorization: 'ALLOW_ALL', RequireSession: false)] 21 | class EntityName?>Controller extends BaseController 22 | { 23 | use EntityName?>ControllerT; 24 | 25 | public function __construct() { 26 | parent::__construct(assetManagerFactory: new AssetManagerFactory()); 27 | } 28 | 29 | #[Route(Authorization: 'ALLOW_ALL', RequireSession: false)] 30 | #[ReturnViewResult] 31 | public function Ver() { 32 | 33 | // Mostramos la vista con los filtros 34 | $LowerEntityName?>BO = new EntityName?>BO(); 35 | $data = $LowerEntityName?>BO->ObtenerDataEntityName?>(); 36 | 37 | return $this->RenderView('ver', $data); 38 | } 39 | } -------------------------------------------------------------------------------- Total de líneas: 39 ================================================================================ ================================================================================ ARCHIVO #154: src/Generator/Templates/Mantenedores/ViewControllerT.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Generator/Templates/Mantenedores/ViewControllerT.php Tamaño: 257 bytes -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Código generado automáticamente 4 | * Generador de Código de Intouch 5 | * Autor: Claudio Alfonso González Almeyda 6 | */ 7 | 8 | namespace Application\Controllers\Mantenedores\Namespace?>; 9 | 10 | trait EntityName?>ControllerT 11 | { 12 | 13 | } -------------------------------------------------------------------------------- Total de líneas: 13 ================================================================================ ================================================================================ ARCHIVO #155: src/Generator/Templates/Mantenedores/popupView.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Generator/Templates/Mantenedores/popupView.php Tamaño: 9.67 KB -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Código generado automáticamente 4 | * Generador de Código de Intouch 5 | * Autor: Claudio Alfonso González Almeyda 6 | */ 7 | 8 | 9 | use Application\Views\Mantenedores\Namespace?>\EntityName?>\verGridT; 10 | use Intouch\Framework\View\Display; 11 | use Intouch\Framework\View\DisplayDefinitions\FormButton; 12 | use Intouch\Framework\View\DisplayDefinitions\FormRowFieldCheck; 13 | use Intouch\Framework\View\DisplayDefinitions\FormRowFieldContent; 14 | use Intouch\Framework\View\DisplayDefinitions\FormRowFieldDate; 15 | use Intouch\Framework\View\DisplayDefinitions\FormRowFieldHidden; 16 | use Intouch\Framework\View\DisplayDefinitions\FormRowFieldSelect; 17 | use Intouch\Framework\View\DisplayDefinitions\FormRowFieldSelectDefinition; 18 | use Intouch\Framework\View\DisplayDefinitions\FormRowFieldText; 19 | use Intouch\Framework\View\DisplayDefinitions\FormRowFieldTypeEnum; 20 | use Intouch\Framework\View\DisplayDefinitions\FormRowGroup; 21 | use Intouch\Framework\View\DisplayEventActions\RefreshListAction; 22 | use Intouch\Framework\View\DisplayEvents\FormButtonOnClickEvent; 23 | use Intouch\Framework\View\DisplayEvents\FormOnChangeEvent; 24 | use Intouch\Framework\Widget\ActionButton; 25 | use Intouch\Framework\Widget\Container; 26 | use Intouch\Framework\Widget\Definitions\ActionButton\ButtonStyleEnum; 27 | use Intouch\Framework\Widget\Definitions\Container\Edge; 28 | use Intouch\Framework\Widget\Definitions\PopUpModal\ColorLineStyleEnum; 29 | use Intouch\Framework\Widget\Panel; 30 | use Intouch\Framework\Widget\PopUpContent; 31 | use Intouch\Framework\Widget\Text; 32 | 33 | $display = new Display(); 34 | 35 | $editMode = (isset($data) && isset($data->Elemento) && ($data->Elemento->IdEntityName?>) > 0); 36 | 37 | $btnGuardarText = ($editMode) ? 'Guardar Cambios' : 'Guardar Nuevo'; 38 | $btnStyle = ($editMode) ? ButtonStyleEnum::BUTTON_WARNING : ButtonStyleEnum::BUTTON_PRIMARY; 39 | $lineStyle = ($editMode) ? ColorLineStyleEnum::LINE_WARNING : ColorLineStyleEnum::LINE_SUCCESS; 40 | 41 | $popupTitle = ($editMode) ? 'Editar' : 'Nuevo'; 42 | $popupSubTitle = ($editMode) ? 'Editar EntityName?>' : 'Nuevo EntityName?>'; 43 | 44 | $display->AddButton( 45 | new FormButton( 46 | Key : 'btnGuardarEntityName?>', 47 | FormKey : 'frmEntityName?>', 48 | Child : new Text($btnGuardarText), 49 | ButtonStyle : $btnStyle, 50 | Events : [ 51 | new FormButtonOnClickEvent() 52 | ] 53 | ) 54 | ); 55 | 56 | $frmGroups = []; 57 | $frmGroups[] = new FormRowGroup( 58 | Key: 'IdEntityName?>', 59 | Rows: [ 60 | [ 61 | // La llave se integra como un campo oculto 62 | 'IdEntityName?>' => new FormRowFieldHidden( 63 | PropertyName: 'IdEntityName?>', 64 | ), 65 | Fields as $name => $field) { 70 | if ($field->PrimaryKey) { 71 | continue; 72 | } 73 | if (substr($name, 0, 2) == 'Id') { 74 | $listbox[$name] = 1; 75 | } 76 | } 77 | 78 | 79 | foreach($data->Fields as $name => $field) { 80 | if ($field->PrimaryKey) { 81 | continue; 82 | } 83 | 84 | // Clases para validaciones 85 | $attr = ""; 86 | $required = ($field->Nullable) ? "true" : "false"; 87 | 88 | switch ($field->DataType) { 89 | case "string": 90 | if (strtolower(substr($name, 0, 3)) == 'rut') { 91 | if ($attr != "") $attr .= ","; 92 | $attr .= "['validar-rut', true]"; 93 | } 94 | break; 95 | case "int": 96 | if ($attr != "") $attr .= ","; 97 | $attr .= "['validar-entero', true]"; 98 | case "float": 99 | if ($attr != "") $attr .= ","; 100 | $attr .= "['validar-decimal', true]"; 101 | } 102 | 103 | $attr = "[" . $attr . "]"; 104 | 105 | if (strtolower($name) == 'indeliminado') { 106 | ?> 107 | '' => new FormRowFieldHidden( 108 | PropertyName: '' 109 | ), 110 | 114 | '' => (isset($data->Elemento) && ($data->Elemento->IdEntityName?> > 0)) 115 | ? new FormRowFieldCheck( 116 | PropertyName: '', 117 | Label: ' ', 118 | Title: '', 119 | Required: false, 120 | Colspan: 4 121 | ) 122 | : new FormRowFieldHidden( 123 | PropertyName: '' 124 | ), 125 | Entity->Table; 129 | ?> 130 | '' => (verGridT::MostrarComoHidden('', $data)) 131 | ? new FormRowFieldHidden( 132 | PropertyName: '' 133 | ) 134 | : new FormRowFieldSelect( 135 | PropertyName : '', 136 | Label : '', 137 | Required : , 138 | Colspan : 4, 139 | SelectDefinition : new FormRowFieldSelectDefinition( 140 | Key : '', 141 | Description : 'Descripcion', 142 | Antecesor)) { 144 | ?> 145 | Values : (isset($data->Elemento) && ($data->Elemento-> > 0)) ? $data->ListadoName, 2)?> : [], 146 | TriggerChangeOnload : (isset($data->Elemento) && ($data->Elemento-> >= 0)), 147 | LinkToList : 'Antecesor->TargetColumn?>', 148 | JSRefreshService : ['Antecesor->SourceTable?>Svc', 'getby_Antecesor->TargetTableName))?>'], 149 | 154 | Values : $data->ListadoName, 2)?>, 155 | TriggerChangeOnload : (isset($data->Elemento) && ($data->Elemento-> == 0)), 156 | 159 | MultipleSelection : false, 160 | DisplaySearch : false, 161 | SelectedValue : -1, 162 | ), 163 | Events: [ 164 | Sucesores) && count($field->Sucesores) > 0) { 167 | 168 | foreach($field->Sucesores as $suc) { 169 | 170 | if (isset($listbox['Id' . $suc->SourceTable]) && 'Id' . $suc->SourceTable != $field->Name) { 171 | if ($keys != "") { 172 | $keys .= ","; 173 | } 174 | $keys .= "'Id" . $suc->SourceTable . "'"; 175 | } 176 | } 177 | } 178 | 179 | if ($keys != "") { 180 | ?> 181 | new FormOnChangeEvent( 182 | Actions: [ 183 | new RefreshListAction( 184 | TargetElementKeys: [] 185 | ), 186 | ] 187 | ) 188 | 191 | ], 192 | ), 193 | 197 | '' => new FormRowFieldCheck( 198 | PropertyName: '', 199 | Label: ' ', 200 | Title: '', 201 | Required: false, 202 | Colspan: 4 203 | ), 204 | DataType == 'datetime') { 207 | ?> 208 | '' => new FormRowFieldDate( 209 | PropertyName: '', 210 | Label: '', 211 | FieldType: FormRowFieldTypeEnum::INPUT_DATE, 212 | Colspan: 4 213 | ), 214 | 218 | '' => new FormRowFieldText( 219 | PropertyName: '', 220 | Label: '', 221 | Required: , 222 | Attributes: , 223 | Colspan: 4 224 | ), 225 | 230 | 231 | ] 232 | ] 233 | ); 234 | 235 | $frmGroups = verGridT::GetFormOrderAndVisibility($frmGroups[0], $data); 236 | 237 | $display->AddFormFromObject( 238 | formKey : 'frmEntityName?>', 239 | keyFieldName : 'IdEntityName?>', 240 | object : $data->Elemento, 241 | fillData: true, 242 | rowGroups: $frmGroups 243 | ); 244 | 245 | $popUp = new PopUpContent( 246 | Key : 'popupEntityName?>', 247 | ColorLineStyle : $lineStyle, 248 | Title : $popupTitle, 249 | DismissButtonText : 'Cancelar', 250 | DismissButtonStyle : ButtonStyleEnum::BUTTON_DEFAULT, 251 | SubTitle : $popupSubTitle, 252 | Buttons : [ 253 | $display->Widgets()['btnGuardarEntityName?>'], 254 | ], 255 | Content : new Container( 256 | Classes: ['view-content'], 257 | Styles: [], 258 | Children: [ 259 | $display->Widgets()['frmEntityName?>'] 260 | ] 261 | ) 262 | ); 263 | 264 | $popUp->Draw(); 265 | 266 | $display->DrawScripts(addLoadEvent:false); 267 | ?> 268 | 269 | -------------------------------------------------------------------------------- Total de líneas: 290 ================================================================================ ================================================================================ ARCHIVO #156: src/Generator/Templates/Mantenedores/verGridAsPopUpView.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Generator/Templates/Mantenedores/verGridAsPopUpView.php Tamaño: 5.78 KB -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Código generado automáticamente 4 | * Generador de Código de Intouch 5 | * Autor: Claudio Alfonso González Almeyda 6 | */ 7 | 8 | use Application\Views\Mantenedores\Namespace?>\EntityName?>\verGridT; 9 | use Intouch\Framework\BLL\Filters\DataTableSettingsFilterDto; 10 | use Intouch\Framework\View\Display; 11 | use Intouch\Framework\View\DisplayDefinitions\Button; 12 | use Intouch\Framework\View\DisplayDefinitions\TableButton; 13 | use Intouch\Framework\View\DisplayDefinitions\DisplayFunctionModeEnum; 14 | use Intouch\Framework\View\DisplayDefinitions\TableCell; 15 | use Intouch\Framework\View\DisplayEvents\ButtonOnClickEvent; 16 | use Intouch\Framework\View\DisplayEvents\TableButtonOnClickEvent; 17 | use Intouch\Framework\Widget\Container; 18 | use Intouch\Framework\Widget\Definitions\ActionButton\ButtonStyleEnum; 19 | use Intouch\Framework\Widget\Definitions\Container\Edge; 20 | use Intouch\Framework\Widget\FaIcon; 21 | use Intouch\Framework\Widget\Label; 22 | use Intouch\Framework\Widget\Definitions\Label\LabelSizeEnum; 23 | use Intouch\Framework\Widget\Definitions\Label\LabelStyleEnum; 24 | use Intouch\Framework\Widget\Definitions\PopUpModal\ColorLineStyleEnum; 25 | use Intouch\Framework\Widget\Html; 26 | use Intouch\Framework\Widget\PopUpContent; 27 | use Intouch\Framework\Widget\Text; 28 | 29 | $display = new Display(); 30 | 31 | // Creación del botón "NUEVO" 32 | $display->AddButton( 33 | new Button( 34 | Key: 'btnNuevoEntityName?>', 35 | Child: new Text('Nuevo'), 36 | ButtonStyle : ButtonStyleEnum::BUTTON_PRIMARY, 37 | Events: [ 38 | new ButtonOnClickEvent() 39 | ] 40 | ) 41 | ); 42 | 43 | $cells = [ 44 | VWFields as $name => $field) { 46 | if ($name=='IndEliminado' || substr($name, 0, 2) == 'Id') { 47 | continue; 48 | } 49 | 50 | if (substr($name, 0, 3) == 'Ind') { 51 | ?> 52 | '' => new TableCell( 53 | PropertyName: "", 54 | Label: "¿?", 55 | BodyClasses: ['text-center'], 56 | FormatFunction: function($element, $cell) { 57 | return new Label( 58 | LabelStyle : ($element-> == 1) ? LabelStyleEnum::LABEL_SUCCESS : LabelStyleEnum::LABEL_LIGHT, 59 | LabelSize: LabelSizeEnum::LABEL_LARGE, 60 | Content: ($element-> == 1) ? 'SI' : 'NO' 61 | ); 62 | } 63 | ), 64 | DataType == 'date') { 67 | ?> 68 | '' => new TableCell( 69 | PropertyName: "", 70 | Label: "", 71 | // Descomentar esta propiedad para agregar una función de formateo a la columna 72 | //FormatFunction: function($element, $cell) { 73 | //return $element->; 74 | //} 75 | ), 76 | DataType == 'datetime') { 79 | ?> 80 | '' => new TableCell( 81 | PropertyName: "", 82 | Label: "", 83 | // Descomentar esta propiedad para agregar una función de formateo a la columna 84 | //FormatFunction: function($element, $cell) { 85 | //return $element->; 86 | //} 87 | ), 88 | 92 | '' => new TableCell( 93 | PropertyName: "", 94 | Label: "", 95 | // Descomentar esta propiedad para agregar una función de formateo a la columna 96 | //FormatFunction: function($element, $cell) { 97 | //return $element->; 98 | //} 99 | ), 100 | 104 | ]; 105 | 106 | Fields as $name => $field) { 111 | if ($campos != '') { 112 | $campos .= ','; 113 | } 114 | $campos .= "'" . $name . "'"; 115 | } 116 | ?> 117 | 118 | $cells = verGridT::GetCellOrderAndVisibility($cells, $data); 119 | 120 | // Ver si se customizan las celdas 121 | foreach ($cells as $cell) { 122 | verGridT::CustomCell($cell); 123 | } 124 | 125 | $buttons = []; 126 | 127 | $customButtons = verGridT::GetCustomButtons($buttons, null, true); 128 | 129 | if (count($customButtons) > 0) { 130 | foreach($customButtons as $cb) { 131 | array_push($buttons, $cb); 132 | } 133 | } 134 | 135 | 136 | // Creamos el boton 'Editar' y el boton 'Eliminar' 137 | $buttons[] = new TableButton( 138 | Child: new FaIcon('fa-edit'), 139 | Key: 'btnEditarEntityName?>', 140 | OnClickClass: 'btn-editar-EntityName)?>', 141 | ButtonStyle: ButtonStyleEnum::BUTTON_WARNING, 142 | Events: [new TableButtonOnClickEvent()], 143 | //DisplayFunction : function ($button, $usuario, $perfil, $roles, $element) {}, 144 | //EnabledFunction : function ($button, $usuario, $perfil, $roles, $element) {} 145 | ); 146 | $buttons[] = new TableButton( 147 | Key: 'btnEliminarEntityName?>', 148 | Child: new FaIcon('fa-trash'), 149 | OnClickClass: 'btn-eliminar-EntityName)?>', 150 | ButtonStyle: ButtonStyleEnum::BUTTON_DANGER, 151 | Events: [new TableButtonOnClickEvent()], 152 | //DisplayFunction : function ($button, $usuario, $perfil, $roles, $element) {}, 153 | //EnabledFunction : function ($button, $usuario, $perfil, $roles, $element) {} 154 | ); 155 | 156 | 157 | // Creamos la grilla 158 | $display->AddTableFromCollection( 159 | tableKey: 'tbEntityName?>', 160 | RowIdFieldName: 'IdEntityName?>', 161 | RowAttributeNames: [], 162 | Data: $data->Elementos, 163 | Buttons: $buttons, 164 | CellDefinitions: $cells, 165 | TablaSimple: true, 166 | CustomDataTable: new DataTableSettingsFilterDto( 167 | HideAllButtons: true 168 | ) 169 | ); 170 | 171 | $children = []; 172 | 173 | // 5: Dibujar grilla 174 | $children[] = new Container( 175 | Margin: new Edge(Bottom: 8), 176 | Classes: ['text-right'], 177 | Children: [ 178 | $display->Widgets()['btnNuevoEntityName?>'] 179 | ], 180 | ); 181 | 182 | $children[] = $display->Widgets()['tbEntityName?>']; 183 | 184 | 185 | // Agregar los ID del padre 186 | $padre = new Container( 187 | Children: [ 188 | new Html(''), 189 | new Html('') 190 | ], 191 | ); 192 | $children[] = $padre; 193 | 194 | (new PopUpContent( 195 | Key: 'LowerEntityName?>-grid-as-popup', 196 | ColorLineStyle: ColorLineStyleEnum::LINE_PRIMARY, 197 | Title: 'EntityName?>s', 198 | SubTitle: 'Administrar EntityName?>s', 199 | DismissButtonText: 'Cerrar', 200 | DismissButtonStyle: ButtonStyleEnum::BUTTON_DEFAULT, 201 | Content: new Container(Children: $children) 202 | ))->Draw(); 203 | 204 | $display->DrawScripts( 205 | addLoadEvent: false 206 | ); 207 | 208 | -------------------------------------------------------------------------------- Total de líneas: 208 ================================================================================ ================================================================================ ARCHIVO #157: src/Generator/Templates/Mantenedores/verGridT.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Generator/Templates/Mantenedores/verGridT.php Tamaño: 7.90 KB -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Código generado automáticamente 4 | * Generador de Código de Intouch 5 | * Autor: Claudio Alfonso González Almeyda 6 | */ 7 | 8 | namespace Application\Views\Mantenedores\Namespace?>\EntityName?>; 9 | 10 | use Intouch\Framework\View\DisplayDefinitions\FormRowGroup; 11 | use Intouch\Framework\View\DisplayDefinitions\TableButton; 12 | use Intouch\Framework\View\DisplayEvents\TableButtonOnClickEvent; 13 | use Intouch\Framework\View\DisplayDefinitions\TogglePlacementEnum; 14 | use Intouch\Framework\Widget\Definitions\ActionButton\ButtonStyleEnum; 15 | use Intouch\Framework\Widget\FaIcon; 16 | use Intouch\Framework\Widget\PageHeader; 17 | 18 | class verGridT { 19 | 20 | public $NewEnabled = true; 21 | public $EditEnabled = true; 22 | public $DeleteEnabled = true; 23 | 24 | // Utilice esta función para: 25 | // -> Establecer el orden de las columnas de la grilla 26 | // -> Establecer si la columna aparecerá o no (si no la agrega a la variable $newArray, no irá en la grilla) 27 | public static function GetCellOrderAndVisibility($cells, $data = null) : array { 28 | $newArray = []; 29 | 30 | VWFields as $name => $field) { 33 | 34 | if (substr($name, 0, 2) != 'Id') { 35 | ?> 36 | $newArray[] = $cells['']; 37 | 41 | 42 | return $newArray; 43 | } 44 | 45 | public static function GetFormOrderAndVisibility($frmGroup, $data) : array { 46 | 47 | $result = []; 48 | 49 | // Crear form groups 50 | $newfrmGroup = new FormRowGroup( 51 | Key: 'frmgrp-EntityName)?>', 52 | Rows: [] 53 | ); 54 | 55 | // Nueva fila 56 | $row = []; 57 | 58 | Fields as $name => $field) { 60 | ?> 61 | $row[] = $frmGroup->Rows[0]['']; 62 | 65 | 66 | // Agregar la fila al rowgroup 67 | $newfrmGroup->Rows[] = $row; 68 | $result[] = $newfrmGroup; 69 | 70 | return $result; 71 | } 72 | 73 | public static function GetSearchFormOrderAndVisibility($rowGroup) : array { 74 | 75 | $result = []; 76 | 77 | // Crear form groups 78 | $newrowGroup = new FormRowGroup( 79 | Key: 'rowgrp-EntityName)?>', 80 | Rows: [] 81 | ); 82 | 83 | // Nueva fila 84 | $row = []; 85 | 86 | Fields as $name => $field) { 88 | if ($field->PrimaryKey) { 89 | continue; 90 | } 91 | 92 | if (substr($name, 0, 3) == 'Ind') { 93 | continue; 94 | } 95 | 96 | if ($field->DataType == 'datetime') { 97 | ?> 98 | $row[] = $rowGroup->Rows[0]['Desde']; 99 | $row[] = $rowGroup->Rows[0]['Hasta']; 100 | 104 | $row[] = $rowGroup->Rows[0]['']; 105 | 109 | 110 | // Agregar la fila al rowgroup 111 | $newrowGroup->Rows[] = $row; 112 | $result[] = $newrowGroup; 113 | 114 | return $result; 115 | } 116 | 117 | // Utilice esta función para modificar una o más columnas de la grilla 118 | // Cualquier cambio realizado en la celda se reflejará en la grilla 119 | // no se requiere devolver ningún valor. 120 | public static function CustomCell($cell) { 121 | 122 | if (substr($cell->PropertyName, 0, 3) == 'Ind') { 123 | $cell->Label = '¿' . substr($cell->PropertyName, 3) . '?'; 124 | } 125 | 126 | switch ($cell->PropertyName) { 127 | 128 | case "EJEMPLO_DE_USO" : 129 | 130 | // Modificar las clases de la celda 131 | // --------------------------------------------------------------- 132 | // $cell->BodyClasses = [ 133 | // //"text-bold", 134 | // //"one-line-text", 135 | // //"text-center", 136 | // //"text-left", 137 | // //"text-right", 138 | // ]; 139 | 140 | // Modificar los estilos de la celda 141 | // --------------------------------------------------------------- 142 | // $cell->BodyStyles = [ 143 | // //['font-weight', '600'], 144 | // ]; 145 | 146 | // Modificar completamente el contenido de la celda 147 | // --------------------------------------------------------------- 148 | // $cell->FormatFunction = function($element, $cell) { 149 | // // Moneda: 150 | // // return _mon($element->Nombre); 151 | // 152 | // // Porcentaje 153 | // // return _perc($element->Nombre, 0); 154 | // 155 | // // Decimal 156 | // // return _dec($element->Nombre, 0); 157 | // 158 | // // Etiqueta 159 | // // return new Label( 160 | // // Content: $element->Nombre, 161 | // // LabelSize: LabelSizeEnum::LABEL_LARGE, 162 | // // LabelStyle: LabelStyleEnum::LABEL_INFO 163 | // // ); 164 | // 165 | // // Fecha 166 | // // $cell->FormatFunction = function($element, $cell) { 167 | // // if (isset($element->Fecha) && $element->Fecha != "") { 168 | // // $dt = new DateTime($element->Fecha); 169 | // // return $dt->format('d-m-Y'); 170 | // // } 171 | // // else { 172 | // // return ""; 173 | // // } 174 | // // }; 175 | // 176 | // // Fecha y Hora 177 | // // $cell->FormatFunction = function($element, $cell) { 178 | // // if (isset($element->Fecha) && $element->Fecha != "") { 179 | // // $dt = new DateTime($element->Fecha); 180 | // // return new TitleDescription( 181 | // // Title: $dt->format('d-m-Y'), 182 | // // Description: $dt->format('H:i') . "hrs." 183 | // // ); 184 | // // } 185 | // // else { 186 | // // return ""; 187 | // // } 188 | // // }; 189 | // 190 | // }; 191 | 192 | return; 193 | 194 | default: return; 195 | } 196 | } 197 | 198 | // Utilice esta función para modificar una o más columnas de la grilla 199 | // Cualquier cambio realizado en la celda se reflejará en la grilla 200 | // no se requiere devolver ningún valor. 201 | public static function CustomField($field) { 202 | 203 | switch ($field->PropertyName) { 204 | 205 | case "EJEMPLO_DE_USO" : 206 | 207 | return; 208 | 209 | default: return; 210 | } 211 | } 212 | 213 | public static function GetCustomButtons($buttons = [], $filtros = null, $isPopup = false) { 214 | 215 | if (isset($filtros)) { 216 | 217 | } 218 | 219 | if ($isPopup) { 220 | return $buttons; 221 | } 222 | 223 | // Botones de sub editores 224 | ForeignKeys as $source => $key) { 227 | if ($key->TargetTableName == $data->Entity->FullName) { 228 | ?> 229 | $buttons[] = new TableButton( 230 | Child: new FaIcon('fa-users'), 231 | Key: 'btnEditarSourceTable?>s', 232 | OnClickClass: 'btn-editar-SourceTable)?>s', 233 | ButtonStyle: ButtonStyleEnum::BUTTON_PRIMARY, 234 | TogglePopUp: true, 235 | ToggleText: 'Administrar SourceTable?>s', 236 | TogglePlacement: TogglePlacementEnum::TOP, 237 | Events: [new TableButtonOnClickEvent()], 238 | ); 239 | 243 | 244 | return $buttons; 245 | } 246 | 247 | public static function MostrarComoHidden($fieldName, $data) { 248 | 249 | if ($fieldName == $data->NombreIdPadre) { 250 | return true; 251 | } 252 | 253 | switch ($fieldName) { 254 | default: 255 | return false; 256 | } 257 | 258 | } 259 | 260 | public static function GetHeader() { 261 | 262 | return new PageHeader( 263 | Title: 'Registro de EntityName?>', 264 | Description: 'Seleccione un elemento para editar, o agregue elementos nuevos' 265 | ); 266 | 267 | } 268 | } -------------------------------------------------------------------------------- Total de líneas: 268 ================================================================================ ================================================================================ ARCHIVO #158: src/Generator/Templates/Mantenedores/verGridView.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Generator/Templates/Mantenedores/verGridView.php Tamaño: 4.93 KB -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Código generado automáticamente 4 | * Generador de Código de Intouch 5 | * Autor: Claudio Alfonso González Almeyda 6 | */ 7 | 8 | use Application\Views\Mantenedores\Namespace?>\EntityName?>\verGridT; 9 | use Intouch\Framework\BLL\Filters\DataTableSettingsFilterDto; 10 | use Intouch\Framework\View\Display; 11 | use Intouch\Framework\View\DisplayDefinitions\TableButton; 12 | use Intouch\Framework\View\DisplayDefinitions\TogglePlacementEnum; 13 | use Intouch\Framework\View\DisplayDefinitions\DisplayFunctionModeEnum; 14 | use Intouch\Framework\View\DisplayDefinitions\TableCell; 15 | use Intouch\Framework\View\DisplayEvents\TableButtonOnClickEvent; 16 | use Intouch\Framework\Widget\Container; 17 | use Intouch\Framework\Widget\Definitions\ActionButton\ButtonStyleEnum; 18 | use Intouch\Framework\Widget\FaIcon; 19 | use Intouch\Framework\Widget\Label; 20 | use Intouch\Framework\Widget\Definitions\Label\LabelSizeEnum; 21 | use Intouch\Framework\Widget\Definitions\Label\LabelStyleEnum; 22 | 23 | $display = new Display(); 24 | 25 | $cells = [ 26 | VWFields as $name => $field) { 32 | if ($name=='IndEliminado' || substr($name, 0, 2) == 'Id') { 33 | continue; 34 | } 35 | 36 | if (substr($name, 0, 3) == 'Ind') { 37 | ?> 38 | '' => new TableCell( 39 | PropertyName: "", 40 | Label: "¿?", 41 | BodyClasses: ['text-center'], 42 | FormatFunction: function($element, $cell) { 43 | return new Label( 44 | LabelStyle : ($element-> == 1) ? LabelStyleEnum::LABEL_SUCCESS : LabelStyleEnum::LABEL_LIGHT, 45 | LabelSize: LabelSizeEnum::LABEL_LARGE, 46 | Content: ($element-> == 1) ? 'SI' : 'NO' 47 | ); 48 | } 49 | ), 50 | DataType == 'date') { 53 | ?> 54 | '' => new TableCell( 55 | PropertyName: "", 56 | Label: "", 57 | // Descomentar esta propiedad para agregar una función de formateo a la columna 58 | //FormatFunction: function($element, $cell) { 59 | //return $element->; 60 | //} 61 | ), 62 | DataType == 'datetime') { 65 | ?> 66 | '' => new TableCell( 67 | PropertyName: "", 68 | Label: "", 69 | // Descomentar esta propiedad para agregar una función de formateo a la columna 70 | //FormatFunction: function($element, $cell) { 71 | //return $element->; 72 | //} 73 | ), 74 | 78 | '' => new TableCell( 79 | PropertyName: "", 80 | Label: "", 81 | // Descomentar esta propiedad para agregar una función de formateo a la columna 82 | //FormatFunction: function($element, $cell) { 83 | //return $element->; 84 | //} 85 | ), 86 | 90 | ]; 91 | 92 | Fields as $name => $field) { 97 | if ($campos != '') { 98 | $campos .= ','; 99 | } 100 | $campos .= "'" . $name . "'"; 101 | } 102 | 103 | ?> 104 | 105 | $cells = verGridT::GetCellOrderAndVisibility($cells); 106 | 107 | // Ver si se customizan las celdas 108 | foreach ($cells as $cell) { 109 | verGridT::CustomCell($cell); 110 | } 111 | 112 | $buttons = []; 113 | 114 | $customButtons = verGridT::GetCustomButtons(); 115 | 116 | if (count($customButtons) > 0) { 117 | foreach($customButtons as $cb) { 118 | array_push($buttons, $cb); 119 | } 120 | } 121 | 122 | // Creamos el boton 'Editar' y el boton 'Eliminar' 123 | $buttons[] = new TableButton( 124 | Child: new FaIcon('fa-edit'), 125 | Key: 'btnEditarEntityName?>', 126 | OnClickClass: 'btn-editar-EntityName)?>', 127 | ButtonStyle: ButtonStyleEnum::BUTTON_WARNING, 128 | TogglePopUp: true, 129 | ToggleText: 'Editar EntityName?>', 130 | TogglePlacement: TogglePlacementEnum::TOP, 131 | Events: [new TableButtonOnClickEvent()], 132 | //DisplayFunction : function ($button, $usuario, $perfil, $roles, $element) {}, 133 | //EnabledFunction : function ($button, $usuario, $perfil, $roles, $element) {} 134 | ); 135 | $buttons[] = new TableButton( 136 | Key: 'btnEliminarEntityName?>', 137 | Child: new FaIcon('fa-trash'), 138 | OnClickClass: 'btn-eliminar-EntityName)?>', 139 | ButtonStyle: ButtonStyleEnum::BUTTON_DANGER, 140 | TogglePopUp: true, 141 | ToggleText: 'Eliminar EntityName?>', 142 | TogglePlacement: TogglePlacementEnum::TOP, 143 | Events: [new TableButtonOnClickEvent()], 144 | //DisplayFunction : function ($button, $usuario, $perfil, $roles, $element) {}, 145 | //EnabledFunction : function ($button, $usuario, $perfil, $roles, $element) {} 146 | ); 147 | 148 | 149 | // Creamos la grilla 150 | $display->AddTableFromCollection( 151 | tableKey: 'tbEntityName?>', 152 | RowIdFieldName: 'IdEntityName?>', 153 | RowAttributeNames: [], 154 | Data: $data, 155 | Buttons: $buttons, 156 | CellDefinitions: $cells, 157 | TablaSimple: false, 158 | CustomDataTable: new DataTableSettingsFilterDto( 159 | HideAllButtons: true 160 | ) 161 | ); 162 | 163 | $children = []; 164 | 165 | // 5: Dibujar grilla 166 | $children[] = $display->Widgets()['tbEntityName?>']; 167 | 168 | (new Container( 169 | Children: $children 170 | ))->Draw(); 171 | 172 | $display->DrawScripts( 173 | addLoadEvent: false 174 | ); 175 | -------------------------------------------------------------------------------- Total de líneas: 175 ================================================================================ ================================================================================ ARCHIVO #159: src/Generator/Templates/Mantenedores/verView.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Generator/Templates/Mantenedores/verView.php Tamaño: 7.77 KB -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Código generado automáticamente 4 | * Generador de Código de Intouch 5 | * Autor: Claudio Alfonso González Almeyda 6 | */ 7 | 8 | use Application\Views\Mantenedores\Namespace?>\EntityName?>\verGridT; 9 | use Intouch\Framework\View\Display; 10 | use Intouch\Framework\View\DisplayDefinitions\Button; 11 | use Intouch\Framework\View\DisplayDefinitions\FormButton; 12 | use Intouch\Framework\View\DisplayDefinitions\FormRowFieldText; 13 | use Intouch\Framework\View\DisplayDefinitions\FormRowFieldDate; 14 | use Intouch\Framework\View\DisplayDefinitions\FormRowFieldTypeEnum; 15 | use Intouch\Framework\View\DisplayDefinitions\FormRowFieldSelect; 16 | use Intouch\Framework\View\DisplayDefinitions\FormRowFieldSelectDefinition; 17 | use Intouch\Framework\View\DisplayDefinitions\FormRowGroup; 18 | use Intouch\Framework\View\DisplayEvents\ButtonOnClickEvent; 19 | use Intouch\Framework\View\DisplayEvents\FormButtonOnClickEvent; 20 | use Intouch\Framework\Widget\Container; 21 | use Intouch\Framework\Widget\Definitions\ActionButton\ButtonStyleEnum; 22 | use Intouch\Framework\Widget\PageHeader; 23 | use Intouch\Framework\Widget\Panel; 24 | use Intouch\Framework\Widget\Text; 25 | use Intouch\Framework\Widget\TitleDescription; 26 | use Intouch\Framework\View\DisplayEventActions\RefreshListAction; 27 | use Intouch\Framework\View\DisplayEvents\FormOnChangeEvent; 28 | 29 | 30 | ?> 31 | 32 | @@Layout(authenticated) 33 | @@IncludeScriptBundle(mantenedorEntityName?>JS) 34 | ForeignKeys as $source => $key) { 37 | if ($key->TargetTableName == $data->Entity->FullName) { 38 | $stop = 1; 39 | ?> 40 | @@IncludeScriptBundle(mantenedorSourceTable?>JS) 41 | 45 | 46 | 47 | 48 | // Encabezado de la página 49 | // 50 | $pageHeader = verGridT::GetHeader(); 51 | $pageHeader->Draw(); 52 | 53 | $display = new Display(); 54 | //DismissButtonStyle : ButtonStyleEnum::BUTTON_DEFAULT 55 | $display->AddButton( 56 | new FormButton( 57 | Key: 'btnBuscarEntityName?>', 58 | FormKey: 'frmencabezado', 59 | Child: new Text('Buscar'), 60 | ButtonStyle: ButtonStyleEnum::BUTTON_INFO, 61 | Classes: ['pull-right'], 62 | Events: [ 63 | new FormButtonOnClickEvent() 64 | ] 65 | ) 66 | ); 67 | 68 | $display->AddButton( 69 | new FormButton( 70 | Key: 'btnLimpiarEntityName?>', 71 | FormKey: 'frmencabezado', 72 | Child: new Text('Limpiar Filtros'), 73 | ButtonStyle: ButtonStyleEnum::BUTTON_DEFAULT, 74 | Styles: [ ['margin-right', '8px'] ], 75 | Classes: ['pull-right'], 76 | Events: [ 77 | new FormButtonOnClickEvent() 78 | ] 79 | ) 80 | ); 81 | 82 | 83 | // preparar los registros 84 | $rowGroups = []; 85 | $rowGroups[] = new FormRowGroup( 86 | Key: 'grp-informacion-EntityName)?>', 87 | Rows: [ 88 | [ 89 | Fields as $name => $field) { 94 | if ($field->PrimaryKey) { 95 | continue; 96 | } 97 | if (substr($name, 0, 2) == 'Id') { 98 | $listbox[$name] = 1; 99 | } 100 | } 101 | 102 | foreach($data->Fields as $name => $field) { 103 | 104 | if ($field->PrimaryKey || $field->Name == 'Id'.$data->EntityName) { 105 | continue; 106 | } 107 | 108 | if ($field->DataType == 'datetime') { 109 | ?> 110 | 'Desde' => new FormRowFieldDate( 111 | PropertyName: 'Desde', 112 | Label: ' Desde', 113 | FieldType: FormRowFieldTypeEnum::INPUT_DATE, 114 | Colspan: 2 115 | ), 116 | 'Hasta' => new FormRowFieldDate( 117 | PropertyName: 'Hasta', 118 | Label: ' Hasta', 119 | FieldType: FormRowFieldTypeEnum::INPUT_DATE, 120 | Colspan: 2 121 | ), 122 | DataType == 'string') { 125 | ?> 126 | '' => new FormRowFieldText( 127 | PropertyName: '', 128 | Label: '', 129 | Colspan: 2 130 | ), 131 | Name, 0, 2) == "Id") { 134 | ?> 135 | '' => new FormRowFieldSelect( 136 | PropertyName : '', 137 | Label : 'Name, 2)?>', 138 | Colspan : 2, 139 | SelectDefinition : new FormRowFieldSelectDefinition( 140 | Key : '', 141 | Description : 'Descripcion', 142 | Antecesor)) { 144 | ?> 145 | Values : [], 146 | TriggerChangeOnload : false, 147 | LinkToList : 'Antecesor->TargetColumn?>', 148 | JSRefreshService : ['Antecesor->SourceTable?>Svc', 'getby_Antecesor->TargetTableName))?>'], 149 | 153 | Values : $data->ListadoName, 2)?>, 154 | TriggerChangeOnload : true, 155 | 158 | MultipleSelection : false, 159 | DisplaySearch : false, 160 | SelectedValue : -1, 161 | ), 162 | Events: [ 163 | Sucesores) && count($field->Sucesores) > 0) { 166 | 167 | foreach($field->Sucesores as $suc) { 168 | 169 | if (isset($listbox['Id' . $suc->SourceTable]) && 'Id' . $suc->SourceTable != $field->Name) { 170 | if ($keys != "") { 171 | $keys .= ","; 172 | } 173 | $keys .= "'Id" . $suc->SourceTable . "'"; 174 | } 175 | } 176 | } 177 | 178 | if ($keys != "") { 179 | ?> 180 | new FormOnChangeEvent( 181 | Actions: [ 182 | new RefreshListAction( 183 | TargetElementKeys: [] 184 | ), 185 | ] 186 | ) 187 | 190 | ], 191 | ), 192 | 197 | ] 198 | ] 199 | ); 200 | 201 | $rowGroups = verGridT::GetSearchFormOrderAndVisibility($rowGroups[0]); 202 | 203 | // Crear el formulario 204 | $display->AddFormFromObject( 205 | formKey: 'frmencabezado', 206 | object: $data, 207 | fillData: false, 208 | keyFieldName: 'IdEntityName?>', 209 | rowGroups: $rowGroups 210 | ); 211 | 212 | // Creación del botón "NUEVO" 213 | Config->IsNewEnabled($data)) { 215 | ?> 216 | $display->AddButton( 217 | new Button( 218 | Key: 'btnNuevoEntityName?>', 219 | Child: new Text('Nuevo'), 220 | Classes: ['pull-right'], 221 | ButtonStyle : ButtonStyleEnum::BUTTON_PRIMARY, 222 | Events: [ 223 | new ButtonOnClickEvent() 224 | ] 225 | ) 226 | ); 227 | 230 | 231 | ( 232 | new Container( 233 | Classes: ['view-content'], 234 | Styles: [], 235 | Children: [ 236 | new Panel( 237 | Body: new Container( 238 | Children:[ 239 | $display->Widgets()['frmencabezado'], 240 | $display->Widgets()['btnBuscarEntityName?>'], 241 | $display->Widgets()['btnLimpiarEntityName?>'], 242 | ] 243 | ), 244 | ), 245 | new Panel( 246 | Header: 247 | new Container( 248 | Children: [ 249 | (isset($display->Widgets()['btnNuevoEntityName?>']) ? $display->Widgets()['btnNuevoEntityName?>'] : null), 250 | new TitleDescription( 251 | Title: 'Resultado', 252 | Description: 'Listado de: EntityName?>' 253 | ) 254 | ] 255 | ), 256 | Body: new Container( 257 | Key: 'formulario-LowerEntityName?>', 258 | Children:[ 259 | ] 260 | ), 261 | ) 262 | ] 263 | ) 264 | )->Draw(); 265 | 266 | $display->DrawScripts(); 267 | -------------------------------------------------------------------------------- Total de líneas: 267 ================================================================================ ================================================================================ ARCHIVO #160: src/Generator/Templates/Svc.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Generator/Templates/Svc.php Tamaño: 842 bytes -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Código generado automáticamente 4 | * Generador de Código de Intouch 5 | * Autor: Claudio Alfonso González Almeyda 6 | */ 7 | 8 | namespace Application\BLL\Services\Namespace?>; 9 | 10 | use Application\Dao\Services\Namespace?>\EntityName?>Dao; 11 | use Application\BLL\DataTransferObjects\Namespace?>\EntityName?>Dto; 12 | use Application\Dao\Entities\Namespace?>\EntityName?>; 13 | use Intouch\Framework\BLL\Service\GenericSvc; 14 | use Intouch\Framework\Mapper\Mapper; 15 | 16 | class EntityName?>Svc extends GenericSvc 17 | { 18 | use EntityName?>SvcT; 19 | 20 | function __construct($domain) 21 | { 22 | parent::__construct( 23 | EntityName?>Dto::class, 24 | EntityName?>::class, 25 | new EntityName?>Dao($domain) 26 | ); 27 | } 28 | 29 | } -------------------------------------------------------------------------------- Total de líneas: 29 ================================================================================ ================================================================================ ARCHIVO #161: src/Generator/Templates/SvcT.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Generator/Templates/SvcT.php Tamaño: 266 bytes -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Código generado automáticamente 4 | * Generador de Código de Intouch 5 | * Autor: Claudio Alfonso González Almeyda 6 | */ 7 | 8 | namespace Application\BLL\Services\Namespace?>; 9 | 10 | trait EntityName?>SvcT 11 | { 12 | public $innerMappings = []; 13 | 14 | } -------------------------------------------------------------------------------- Total de líneas: 14 ================================================================================ ================================================================================ ARCHIVO #162: src/Generator/TemplatesOld/Dao.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Generator/TemplatesOld/Dao.php Tamaño: 481 bytes -------------------------------------------------------------------------------- 1 | >; 9 | 10 | use Application\Dao\Entities\<>\<>; 11 | use Intouch\Framework\Dao\GenericDao; 12 | 13 | class <>Dao extends GenericDao 14 | { 15 | use <>DaoT; 16 | 17 | function __construct($domain) 18 | { 19 | parent::__construct( 20 | <>::class, 21 | $domain 22 | ); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- Total de líneas: 25 ================================================================================ ================================================================================ ARCHIVO #163: src/Generator/TemplatesOld/DaoT.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Generator/TemplatesOld/DaoT.php Tamaño: 208 bytes -------------------------------------------------------------------------------- 1 | >; 9 | 10 | trait <>DaoT 11 | { 12 | 13 | } 14 | -------------------------------------------------------------------------------- Total de líneas: 14 ================================================================================ ================================================================================ ARCHIVO #164: src/Generator/TemplatesOld/Dto.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Generator/TemplatesOld/Dto.php Tamaño: 300 bytes -------------------------------------------------------------------------------- 1 | >; 9 | 10 | class <>Dto 11 | { 12 | use <>DtoT; 13 | 14 | public function __construct( 15 | <> 16 | ) { 17 | 18 | } 19 | } -------------------------------------------------------------------------------- Total de líneas: 19 ================================================================================ ================================================================================ ARCHIVO #165: src/Generator/TemplatesOld/DtoT.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Generator/TemplatesOld/DtoT.php Tamaño: 438 bytes -------------------------------------------------------------------------------- 1 | >; 9 | 10 | trait <>DtoT 11 | { 12 | function __get($name) { 13 | 14 | switch($name) { 15 | 16 | default: return null; 17 | } 18 | } 19 | 20 | function __set($name, $value) { 21 | 22 | switch($name) { 23 | 24 | default: return null; 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- Total de líneas: 27 ================================================================================ ================================================================================ ARCHIVO #166: src/Generator/TemplatesOld/Ent.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Generator/TemplatesOld/Ent.php Tamaño: 425 bytes -------------------------------------------------------------------------------- 1 | >; 9 | 10 | use Intouch\Framework\Annotation\Attributes\Entity; 11 | use Intouch\Framework\Annotation\Attributes\EntityField; 12 | 13 | #[Entity(Schema: '<>')] 14 | class <> 15 | { 16 | use <>T; 17 | 18 | <> 19 | 20 | function __construct() 21 | { 22 | } 23 | } -------------------------------------------------------------------------------- Total de líneas: 23 ================================================================================ ================================================================================ ARCHIVO #167: src/Generator/TemplatesOld/EntT.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Generator/TemplatesOld/EntT.php Tamaño: 261 bytes -------------------------------------------------------------------------------- 1 | >; 9 | 10 | use Intouch\Framework\Annotation\Attributes\EntityField; 11 | 12 | trait <>T 13 | { 14 | } -------------------------------------------------------------------------------- Total de líneas: 14 ================================================================================ ================================================================================ ARCHIVO #168: src/Generator/TemplatesOld/Mantenedores/ApiController.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Generator/TemplatesOld/Mantenedores/ApiController.php Tamaño: 3.40 KB -------------------------------------------------------------------------------- 1 | >; 9 | 10 | use Application\BLL\BusinessObjects\Mantenedores\<>\<>BO; 11 | use Application\BLL\DataTransferObjects\<>\<>Dto; 12 | use Application\BLL\Services\<>\<>Svc; 13 | use Application\Configuration\ConnectionEnum; 14 | use Application\Resources\AssetManagerFactory; 15 | use Intouch\Framework\Annotation\Attributes\ReturnActionResult; 16 | use Intouch\Framework\Annotation\Attributes\ReturnActionViewResult; 17 | use Intouch\Framework\Annotation\Attributes\Route; 18 | use Intouch\Framework\Controllers\BaseController; 19 | use Intouch\Framework\Dao\BindVariable; 20 | use Intouch\Framework\Exceptions\BusinessException; 21 | use Intouch\Framework\Exceptions\ExceptionCodesEnum; 22 | use Intouch\Framework\View\Display; 23 | 24 | #[Route(Authorization: 'ALLOW_ALL', RequireSession: false)] 25 | class <>Controller extends BaseController { 26 | 27 | use <>ControllerT; 28 | 29 | public function __construct() { 30 | parent::__construct(assetManagerFactory: new AssetManagerFactory()); 31 | } 32 | 33 | #[Route(Methods: ['POST'],Authorization: 'ALLOW_ALL', RequireSession: false)] 34 | #[ReturnActionResult] 35 | public function Eliminar<>($Id<>) { 36 | 37 | $<>BO = new <>BO(); 38 | return $<>BO->Eliminar<>($Id<>); 39 | } 40 | 41 | #[Route(Methods: ['POST'],Authorization: 'ALLOW_ALL', RequireSession: false)] 42 | #[ReturnActionViewResult] 43 | public function PopUp<>($Id<>) { 44 | 45 | $<>BO = new <>BO(); 46 | $data = $<>BO->ObtenerData<>($Id<>); 47 | 48 | $view = Display::GetRenderer('Mantenedores/<>/<>')->RenderView('popup', $data); 49 | return $view; 50 | } 51 | 52 | #[Route(Methods: ['POST'])] 53 | #[ReturnActionResult] 54 | public function Guardar<>($<>Registro) { 55 | 56 | $<>BO = new <>BO(); 57 | 58 | try { 59 | if ( !isset($<>Registro->Id<>) || $<>Registro->Id<> == 0) { 60 | $<>BO->GuardarNuevo<>($<>Registro); 61 | } 62 | else { 63 | $<>BO->Guardar<>($<>Registro); 64 | } 65 | } 66 | catch (\Exception $ex) { 67 | throw new BusinessException(ExceptionCodesEnum::ERR_DATA_INSERT, ' al guardar el registro'); 68 | } 69 | 70 | return 0; 71 | } 72 | 73 | #[Route(Methods: ['POST'],Authorization: 'ALLOW_ALL', RequireSession: false)] 74 | #[ReturnActionViewResult] 75 | public function Buscar<>($Registro<>Buscar) { 76 | 77 | $<>BO = new <>BO(); 78 | $<>s = $<>BO->Buscar<>($Registro<>Buscar); 79 | 80 | $view = Display::GetRenderer('Mantenedores/<>/<>')->RenderView('verGrid', $<>s); 81 | return $view; 82 | } 83 | 84 | #[Route(Methods: ['POST'],Authorization: 'ALLOW_ALL', RequireSession: false)] 85 | #[ReturnActionViewResult] 86 | public function Buscar<>AsPopUp($Registro<>Buscar) { 87 | 88 | $<>BO = new <>BO(); 89 | $<>s = $<>BO->Buscar<>($Registro<>Buscar); 90 | 91 | $view = Display::GetRenderer('Mantenedores/<>/<>')->RenderView('verGridAsPopUp', $<>s); 92 | return $view; 93 | } 94 | 95 | <> 96 | 97 | } -------------------------------------------------------------------------------- Total de líneas: 97 ================================================================================ ================================================================================ ARCHIVO #169: src/Generator/TemplatesOld/Mantenedores/ApiControllerT.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Generator/TemplatesOld/Mantenedores/ApiControllerT.php Tamaño: 234 bytes -------------------------------------------------------------------------------- 1 | >; 9 | 10 | trait <>ControllerT 11 | { 12 | 13 | } -------------------------------------------------------------------------------- Total de líneas: 13 ================================================================================ ================================================================================ ARCHIVO #170: src/Generator/TemplatesOld/Mantenedores/BusinessObject.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Generator/TemplatesOld/Mantenedores/BusinessObject.php Tamaño: 4.49 KB -------------------------------------------------------------------------------- 1 | >; 9 | 10 | use Application\BLL\Services\<>\<>Svc; 11 | use Application\BLL\Services\<>\VW<>Svc; 12 | use Application\BLL\DataTransferObjects\<>\<>Dto; 13 | use Application\BLL\DataTransferObjects\<>\VW<>Dto; 14 | use Application\Configuration\ConnectionEnum; 15 | use Intouch\Framework\BLL\Service\GenericSvc; 16 | use Intouch\Framework\Dao\BindVariable; 17 | use Intouch\Framework\Exceptions\BusinessException; 18 | use Intouch\Framework\Exceptions\ExceptionCodesEnum; 19 | 20 | <> 21 | 22 | class <>BO 23 | { 24 | 25 | use <>BOT; 26 | 27 | public function Guardar<>($registro) { 28 | 29 | $<>Svc = new <>Svc(ConnectionEnum::DEFAULT); 30 | 31 | try { 32 | 33 | GenericSvc::BeginMultipleOperations(ConnectionEnum::DEFAULT); 34 | 35 | $<> = new <>Dto( 36 | <> 37 | ); 38 | 39 | $<>Svc->Update($<>); 40 | 41 | GenericSvc::SaveMultipleOperations(); 42 | 43 | return true; 44 | } 45 | catch(\Exception $e){ 46 | GenericSvc::UndoMultipleOperations(); 47 | throw $e; 48 | } 49 | } 50 | 51 | public function GuardarNuevo<>($registro) { 52 | 53 | $<>Svc = new <>Svc(ConnectionEnum::DEFAULT); 54 | 55 | try { 56 | 57 | GenericSvc::BeginMultipleOperations(ConnectionEnum::DEFAULT); 58 | 59 | // Asegurarse de generar un registro nuevo 60 | $registro->Id<> = 0; 61 | 62 | $<> = new <>Dto( 63 | <> 64 | ); 65 | 66 | $nuevo<> = $<>Svc->Insert($<>); 67 | 68 | if (!isset($nuevo<>) || $nuevo<>->Id<> <= 0) { 69 | GenericSvc::UndoMultipleOperations(); 70 | throw new \Exception("Ha ocurrido un problema al intentar guardar el registro", 1); 71 | } 72 | 73 | 74 | GenericSvc::SaveMultipleOperations(); 75 | 76 | return true; 77 | } 78 | catch(\Exception $e){ 79 | GenericSvc::UndoMultipleOperations(); 80 | throw $e; 81 | } 82 | } 83 | 84 | public function Buscar<>($filtros) { 85 | 86 | // Por defecto, buscamos la información para la grilla en la 87 | // vista que pudiera existir, en caso contrario, buscamos 88 | // la información en la tabla 89 | // Obs: Para las "Vistas de base de datos" que llenen la grilla, 90 | // se debe cumplir la convención de que contendrá un JOIN 91 | // para cada llave foránea y un campo con la descripción 92 | // de la tabla destino que será el nombre de la llave 93 | // sin anteponer "Id". 94 | // 95 | // Por ejemplo, si la tabla actual es Cliente, y tiene una 96 | // llave foránea IdEmpresa (que por convención pertenece a 97 | // una tabla llamada "Empresa"), entonces se asumirá que 98 | // existe una vista VWCliente que será como sigue: // 99 | // CREATE VIEW VWCliente AS 100 | // SELECT 101 | // c.IdCliente, c.xxxxxxxxxx ...., e.IdEmpresa, e.Descripcion as Empresa 102 | // FROM Cliente c 103 | // JOIN Empresa e ON c.IdEmpresa = e.IdEmpresa 104 | 105 | $<>Svc = new <>Svc(ConnectionEnum::DEFAULT); 106 | 107 | $bindings = []; 108 | <> 109 | 110 | $result = $<>Svc->GetBy( 111 | bindings: $bindings, 112 | avoidNull: true 113 | ); 114 | 115 | return $result; 116 | } 117 | 118 | public function Eliminar<>($Id<>) { 119 | 120 | try { 121 | $<>Svc = new <>Svc(ConnectionEnum::DEFAULT); 122 | //$<>Svc->Delete($Id<>); 123 | } 124 | catch (\Exception $e) { 125 | throw new BusinessException(ExceptionCodesEnum::ERR_DATA_DELETE, 'al intentar eliminar el registro de <>'); 126 | } 127 | 128 | return ''; 129 | } 130 | 131 | public function ObtenerData<>($Id<> = 0) { 132 | 133 | $data = []; 134 | 135 | if ($Id<> <> 0) { 136 | // Obtener el elemento principal 137 | $<>Svc = new <>Svc(ConnectionEnum::DEFAULT); 138 | $elemento = $<>Svc->Find($Id<>); 139 | $data['Elemento'] = $elemento; 140 | } 141 | else { 142 | $data['Elemento'] = new <>Dto( 143 | Id<>: 0 144 | ); 145 | } 146 | 147 | <> 148 | 149 | return (object)$data; 150 | } 151 | 152 | } -------------------------------------------------------------------------------- Total de líneas: 152 ================================================================================ ================================================================================ ARCHIVO #171: src/Generator/TemplatesOld/Mantenedores/BusinessObjectT.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Generator/TemplatesOld/Mantenedores/BusinessObjectT.php Tamaño: 230 bytes -------------------------------------------------------------------------------- 1 | >; 9 | 10 | trait <>BOT 11 | { 12 | 13 | } -------------------------------------------------------------------------------- Total de líneas: 13 ================================================================================ ================================================================================ ARCHIVO #172: src/Generator/TemplatesOld/Mantenedores/Prueba.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Generator/TemplatesOld/Mantenedores/Prueba.php Tamaño: 595 bytes -------------------------------------------------------------------------------- 1 | Template . "\n"; 10 | echo "Namespace: " . $data->Namespace . "\n"; 11 | 12 | ?> 13 | namespace Application\Dao\Services\<>; 14 | 15 | use Application\Dao\Entities\<>\<>; 16 | use Intouch\Framework\Dao\GenericDao; 17 | 18 | class <>Dao extends GenericDao 19 | { 20 | use <>DaoT; 21 | 22 | function __construct($domain) 23 | { 24 | parent::__construct( 25 | <>::class, 26 | $domain 27 | ); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- Total de líneas: 30 ================================================================================ ================================================================================ ARCHIVO #173: src/Generator/TemplatesOld/Mantenedores/ViewController.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Generator/TemplatesOld/Mantenedores/ViewController.php Tamaño: 1.22 KB -------------------------------------------------------------------------------- 1 | >; 9 | 10 | use Application\BLL\BusinessObjects\Mantenedores\<>\<>BO; 11 | use Application\BLL\Services\<>\<>Svc; 12 | use Application\Configuration\ConnectionEnum; 13 | use Application\Resources\AssetManagerFactory; 14 | use Intouch\Framework\Annotation\Attributes\ReturnViewResult; 15 | use Intouch\Framework\Annotation\Attributes\Route; 16 | use Intouch\Framework\Controllers\BaseController; 17 | use Intouch\Framework\View\Display; 18 | use Intouch\Framework\Dao\BindVariable; 19 | 20 | #[Route(Authorization: 'ALLOW_ALL', RequireSession: false)] 21 | class <>Controller extends BaseController 22 | { 23 | use <>ControllerT; 24 | 25 | public function __construct() { 26 | parent::__construct(assetManagerFactory: new AssetManagerFactory()); 27 | } 28 | 29 | #[Route(Authorization: 'ALLOW_ALL', RequireSession: false)] 30 | #[ReturnViewResult] 31 | public function Ver() { 32 | 33 | // Mostramos la vista con los filtros 34 | $<>BO = new <>BO(); 35 | $data = $<>BO->ObtenerData<>(); 36 | 37 | return $this->RenderView('ver', $data); 38 | } 39 | } -------------------------------------------------------------------------------- Total de líneas: 39 ================================================================================ ================================================================================ ARCHIVO #174: src/Generator/TemplatesOld/Mantenedores/ViewControllerT.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Generator/TemplatesOld/Mantenedores/ViewControllerT.php Tamaño: 230 bytes -------------------------------------------------------------------------------- 1 | >; 9 | 10 | trait <>ControllerT 11 | { 12 | 13 | } -------------------------------------------------------------------------------- Total de líneas: 13 ================================================================================ ================================================================================ ARCHIVO #175: src/Generator/TemplatesOld/Mantenedores/popupView.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Generator/TemplatesOld/Mantenedores/popupView.php Tamaño: 3.21 KB -------------------------------------------------------------------------------- 1 | >\<>\verGridT; 10 | use Intouch\Framework\View\Display; 11 | use Intouch\Framework\View\DisplayDefinitions\FormButton; 12 | use Intouch\Framework\View\DisplayDefinitions\FormRowFieldCheck; 13 | use Intouch\Framework\View\DisplayDefinitions\FormRowFieldContent; 14 | use Intouch\Framework\View\DisplayDefinitions\FormRowFieldDate; 15 | use Intouch\Framework\View\DisplayDefinitions\FormRowFieldHidden; 16 | use Intouch\Framework\View\DisplayDefinitions\FormRowFieldSelect; 17 | use Intouch\Framework\View\DisplayDefinitions\FormRowFieldSelectDefinition; 18 | use Intouch\Framework\View\DisplayDefinitions\FormRowFieldText; 19 | use Intouch\Framework\View\DisplayDefinitions\FormRowFieldTypeEnum; 20 | use Intouch\Framework\View\DisplayDefinitions\FormRowGroup; 21 | use Intouch\Framework\View\DisplayEventActions\RefreshListAction; 22 | use Intouch\Framework\View\DisplayEvents\FormButtonOnClickEvent; 23 | use Intouch\Framework\View\DisplayEvents\FormOnChangeEvent; 24 | use Intouch\Framework\Widget\ActionButton; 25 | use Intouch\Framework\Widget\Container; 26 | use Intouch\Framework\Widget\Definitions\ActionButton\ButtonStyleEnum; 27 | use Intouch\Framework\Widget\Definitions\Container\Edge; 28 | use Intouch\Framework\Widget\Definitions\PopUpModal\ColorLineStyleEnum; 29 | use Intouch\Framework\Widget\Panel; 30 | use Intouch\Framework\Widget\PopUpContent; 31 | use Intouch\Framework\Widget\Text; 32 | 33 | $display = new Display(); 34 | 35 | $editMode = (isset($data) && isset($data->Elemento) && ($data->Elemento->Id<>) > 0); 36 | 37 | $btnGuardarText = ($editMode) ? 'Guardar Cambios' : 'Guardar Nuevo'; 38 | $btnStyle = ($editMode) ? ButtonStyleEnum::BUTTON_WARNING : ButtonStyleEnum::BUTTON_PRIMARY; 39 | $lineStyle = ($editMode) ? ColorLineStyleEnum::LINE_WARNING : ColorLineStyleEnum::LINE_SUCCESS; 40 | 41 | $popupTitle = ($editMode) ? 'Editar' : 'Nuevo'; 42 | $popupSubTitle = ($editMode) ? 'Editar <>' : 'Nuevo <>'; 43 | 44 | $display->AddButton( 45 | new FormButton( 46 | Key : 'btnGuardar<>', 47 | FormKey : 'frm<>', 48 | Child : new Text($btnGuardarText), 49 | ButtonStyle : $btnStyle, 50 | Events : [ 51 | new FormButtonOnClickEvent() 52 | ] 53 | ) 54 | ); 55 | 56 | $frmGroups = []; 57 | $frmGroups[] = new FormRowGroup( 58 | Key: 'Id<> ', 59 | Rows: [ 60 | [ 61 | <> 62 | ] 63 | ] 64 | ); 65 | 66 | $frmGroups = verGridT::GetFormOrderAndVisibility($frmGroups[0]); 67 | 68 | $display->AddFormFromObject( 69 | formKey : 'frm<>', 70 | keyFieldName : 'Id<>', 71 | object : $data->Elemento, 72 | fillData: true, 73 | rowGroups: $frmGroups 74 | ); 75 | 76 | $popUp = new PopUpContent( 77 | Key : 'popup<>', 78 | ColorLineStyle : $lineStyle, 79 | Title : $popupTitle, 80 | DismissButtonText : 'Cancelar', 81 | DismissButtonStyle : ButtonStyleEnum::BUTTON_DEFAULT, 82 | SubTitle : $popupSubTitle, 83 | Buttons : [ 84 | $display->Widgets()['btnGuardar<>'], 85 | ], 86 | Content : new Container( 87 | Classes: ['view-content'], 88 | Styles: [], 89 | Children: [ 90 | $display->Widgets()['frm<>'] 91 | ] 92 | ) 93 | ); 94 | 95 | $popUp->Draw(); 96 | 97 | $display->DrawScripts(addLoadEvent:false); 98 | ?> -------------------------------------------------------------------------------- Total de líneas: 98 ================================================================================ ================================================================================ ARCHIVO #176: src/Generator/TemplatesOld/Mantenedores/verGridAsPopUpView.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Generator/TemplatesOld/Mantenedores/verGridAsPopUpView.php Tamaño: 2.74 KB -------------------------------------------------------------------------------- 1 | >\<>\verGridT; 9 | use Intouch\Framework\BLL\Filters\DataTableSettingsFilterDto; 10 | use Intouch\Framework\View\Display; 11 | use Intouch\Framework\View\DisplayDefinitions\Button; 12 | use Intouch\Framework\View\DisplayDefinitions\TableButton; 13 | use Intouch\Framework\View\DisplayDefinitions\DisplayFunctionModeEnum; 14 | use Intouch\Framework\View\DisplayDefinitions\TableCell; 15 | use Intouch\Framework\View\DisplayEvents\ButtonOnClickEvent; 16 | use Intouch\Framework\View\DisplayEvents\TableButtonOnClickEvent; 17 | use Intouch\Framework\Widget\Container; 18 | use Intouch\Framework\Widget\Definitions\ActionButton\ButtonStyleEnum; 19 | use Intouch\Framework\Widget\Definitions\Container\Edge; 20 | use Intouch\Framework\Widget\FaIcon; 21 | use Intouch\Framework\Widget\Label; 22 | use Intouch\Framework\Widget\Definitions\Label\LabelSizeEnum; 23 | use Intouch\Framework\Widget\Definitions\Label\LabelStyleEnum; 24 | use Intouch\Framework\Widget\Definitions\PopUpModal\ColorLineStyleEnum; 25 | use Intouch\Framework\Widget\PopUpContent; 26 | use Intouch\Framework\Widget\Text; 27 | 28 | $display = new Display(); 29 | 30 | // Creación del botón "NUEVO" 31 | $display->AddButton( 32 | new Button( 33 | Key: 'btnNuevo<>', 34 | Child: new Text('Nuevo'), 35 | ButtonStyle : ButtonStyleEnum::BUTTON_PRIMARY, 36 | Events: [ 37 | new ButtonOnClickEvent() 38 | ] 39 | ) 40 | ); 41 | 42 | $cells = [ 43 | <> 44 | ]; 45 | 46 | $cells = verGridT::GetCellOrderAndVisibility($cells); 47 | 48 | // Ver si se customizan las celdas 49 | foreach ($cells as $cell) { 50 | verGridT::CustomCell($cell); 51 | } 52 | 53 | $buttons = []; 54 | 55 | $customButtons = verGridT::GetCustomButtons(); 56 | 57 | if (count($customButtons) > 0) { 58 | foreach($customButtons as $cb) { 59 | array_push($buttons, $cb); 60 | } 61 | } 62 | 63 | <> 64 | 65 | // Creamos la grilla 66 | $display->AddTableFromCollection( 67 | tableKey: 'tb<>', 68 | RowIdFieldName: 'Id<>', 69 | RowAttributeNames: [<>], 70 | Data: $data, 71 | Buttons: $buttons, 72 | CellDefinitions: $cells, 73 | TablaSimple: true, 74 | CustomDataTable: new DataTableSettingsFilterDto( 75 | HideAllButtons: true 76 | ) 77 | ); 78 | 79 | $children = []; 80 | 81 | // 5: Dibujar grilla 82 | $children[] = new Container( 83 | Margin: new Edge(Bottom: 8), 84 | Classes: ['text-right'], 85 | Children: [ 86 | $display->Widgets()['btnNuevo<>'] 87 | ], 88 | ); 89 | 90 | $children[] = $display->Widgets()['tb<>']; 91 | 92 | (new PopUpContent( 93 | Key: '<>-grid-as-popup', 94 | ColorLineStyle: ColorLineStyleEnum::LINE_PRIMARY, 95 | Title: '<>s', 96 | SubTitle: 'Administrar <>s', 97 | DismissButtonText: 'Cerrar', 98 | DismissButtonStyle: ButtonStyleEnum::BUTTON_DEFAULT, 99 | Content: new Container(Children: $children) 100 | ))->Draw(); 101 | 102 | $display->DrawScripts( 103 | addLoadEvent: false 104 | ); 105 | -------------------------------------------------------------------------------- Total de líneas: 105 ================================================================================ ================================================================================ ARCHIVO #177: src/Generator/TemplatesOld/Mantenedores/verGridT.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Generator/TemplatesOld/Mantenedores/verGridT.php Tamaño: 6.04 KB -------------------------------------------------------------------------------- 1 | >\<>; 9 | 10 | use Intouch\Framework\View\DisplayDefinitions\FormRowGroup; 11 | use Intouch\Framework\View\DisplayDefinitions\TableButton; 12 | use Intouch\Framework\View\DisplayEvents\TableButtonOnClickEvent; 13 | use Intouch\Framework\Widget\Definitions\ActionButton\ButtonStyleEnum; 14 | use Intouch\Framework\Widget\FaIcon; 15 | use Intouch\Framework\Widget\PageHeader; 16 | 17 | class verGridT { 18 | 19 | // Utilice esta función para: 20 | // -> Establecer el orden de las columnas de la grilla 21 | // -> Establecer si la columna aparecerá o no (si no la agrega a la variable $newArray, no irá en la grilla) 22 | public static function GetCellOrderAndVisibility($cells) : array { 23 | $newArray = []; 24 | 25 | <> 26 | 27 | return $newArray; 28 | } 29 | 30 | public static function GetFormOrderAndVisibility($frmGroup) : array { 31 | 32 | $result = []; 33 | 34 | // Crear form groups 35 | $newfrmGroup = new FormRowGroup( 36 | Key: 'frmgrp-<>', 37 | Rows: [] 38 | ); 39 | 40 | // Nueva fila 41 | $row = []; 42 | 43 | <> 44 | 45 | // Agregar la fila al rowgroup 46 | $newfrmGroup->Rows[] = $row; 47 | $result[] = $newfrmGroup; 48 | 49 | return $result; 50 | } 51 | 52 | public static function GetSearchFormOrderAndVisibility($rowGroup) : array { 53 | 54 | $result = []; 55 | 56 | // Crear form groups 57 | $newrowGroup = new FormRowGroup( 58 | Key: 'rowgrp-<>', 59 | Rows: [] 60 | ); 61 | 62 | // Nueva fila 63 | $row = []; 64 | 65 | <> 66 | 67 | // Agregar la fila al rowgroup 68 | $newrowGroup->Rows[] = $row; 69 | $result[] = $newrowGroup; 70 | 71 | return $result; 72 | } 73 | 74 | // Utilice esta función para modificar una o más columnas de la grilla 75 | // Cualquier cambio realizado en la celda se reflejará en la grilla 76 | // no se requiere devolver ningún valor. 77 | public static function CustomCell($cell) { 78 | 79 | if (substr($cell->PropertyName, 0, 3) == 'Ind') { 80 | $cell->Label = '¿' . substr($cell->PropertyName, 3) . '?'; 81 | } 82 | 83 | switch ($cell->PropertyName) { 84 | 85 | case "EJEMPLO_DE_USO" : 86 | 87 | // Modificar las clases de la celda 88 | // --------------------------------------------------------------- 89 | // $cell->BodyClasses = [ 90 | // //"text-bold", 91 | // //"one-line-text", 92 | // //"text-center", 93 | // //"text-left", 94 | // //"text-right", 95 | // ]; 96 | 97 | // Modificar los estilos de la celda 98 | // --------------------------------------------------------------- 99 | // $cell->BodyStyles = [ 100 | // //['font-weight', '600'], 101 | // ]; 102 | 103 | // Modificar completamente el contenido de la celda 104 | // --------------------------------------------------------------- 105 | // $cell->FormatFunction = function($element, $cell) { 106 | // // Moneda: 107 | // // return _mon($element->Nombre); 108 | // 109 | // // Porcentaje 110 | // // return _perc($element->Nombre, 0); 111 | // 112 | // // Decimal 113 | // // return _dec($element->Nombre, 0); 114 | // 115 | // // Etiqueta 116 | // // return new Label( 117 | // // Content: $element->Nombre, 118 | // // LabelSize: LabelSizeEnum::LABEL_LARGE, 119 | // // LabelStyle: LabelStyleEnum::LABEL_INFO 120 | // // ); 121 | // 122 | // // Fecha 123 | // // $cell->FormatFunction = function($element, $cell) { 124 | // // if (isset($element->Fecha) && $element->Fecha != "") { 125 | // // $dt = new DateTime($element->Fecha); 126 | // // return $dt->format('d-m-Y'); 127 | // // } 128 | // // else { 129 | // // return ""; 130 | // // } 131 | // // }; 132 | // 133 | // // Fecha y Hora 134 | // // $cell->FormatFunction = function($element, $cell) { 135 | // // if (isset($element->Fecha) && $element->Fecha != "") { 136 | // // $dt = new DateTime($element->Fecha); 137 | // // return new TitleDescription( 138 | // // Title: $dt->format('d-m-Y'), 139 | // // Description: $dt->format('H:i') . "hrs." 140 | // // ); 141 | // // } 142 | // // else { 143 | // // return ""; 144 | // // } 145 | // // }; 146 | // 147 | // }; 148 | 149 | return; 150 | 151 | default: return; 152 | } 153 | } 154 | 155 | // Utilice esta función para modificar una o más columnas de la grilla 156 | // Cualquier cambio realizado en la celda se reflejará en la grilla 157 | // no se requiere devolver ningún valor. 158 | public static function CustomField($field) { 159 | 160 | switch ($field->PropertyName) { 161 | 162 | case "EJEMPLO_DE_USO" : 163 | 164 | return; 165 | 166 | default: return; 167 | } 168 | } 169 | 170 | public static function GetCustomButtons($buttons = []) { 171 | 172 | $result = []; 173 | 174 | foreach($buttons as $btn) { 175 | $result[] = $btn; 176 | } 177 | 178 | return $result; 179 | } 180 | 181 | public static function GetHeader() { 182 | 183 | return new PageHeader( 184 | Title: 'Registro de <>', 185 | Description: 'Seleccione un elemento para editar, o agregue elementos nuevos' 186 | ); 187 | 188 | } 189 | } -------------------------------------------------------------------------------- Total de líneas: 189 ================================================================================ ================================================================================ ARCHIVO #178: src/Generator/TemplatesOld/Mantenedores/verGridView.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Generator/TemplatesOld/Mantenedores/verGridView.php Tamaño: 1.81 KB -------------------------------------------------------------------------------- 1 | >\<>\verGridT; 9 | use Intouch\Framework\BLL\Filters\DataTableSettingsFilterDto; 10 | use Intouch\Framework\View\Display; 11 | use Intouch\Framework\View\DisplayDefinitions\TableButton; 12 | use Intouch\Framework\View\DisplayDefinitions\DisplayFunctionModeEnum; 13 | use Intouch\Framework\View\DisplayDefinitions\TableCell; 14 | use Intouch\Framework\View\DisplayEvents\TableButtonOnClickEvent; 15 | use Intouch\Framework\Widget\Container; 16 | use Intouch\Framework\Widget\Definitions\ActionButton\ButtonStyleEnum; 17 | use Intouch\Framework\Widget\FaIcon; 18 | use Intouch\Framework\Widget\Label; 19 | use Intouch\Framework\Widget\Definitions\Label\LabelSizeEnum; 20 | use Intouch\Framework\Widget\Definitions\Label\LabelStyleEnum; 21 | 22 | $display = new Display(); 23 | 24 | $cells = [ 25 | <> 26 | ]; 27 | 28 | $cells = verGridT::GetCellOrderAndVisibility($cells); 29 | 30 | // Ver si se customizan las celdas 31 | foreach ($cells as $cell) { 32 | verGridT::CustomCell($cell); 33 | } 34 | 35 | $buttons = []; 36 | 37 | // agregar aquí botones adicionales que deben agregarse a la grilla 38 | // 39 | <> 40 | 41 | // Permitir al usuario seleccionar qué botones mostrar 42 | $buttons = verGridT::GetCustomButtons($buttons); 43 | 44 | 45 | <> 46 | 47 | // Creamos la grilla 48 | $display->AddTableFromCollection( 49 | tableKey: 'tb<>', 50 | RowIdFieldName: 'Id<>', 51 | RowAttributeNames: [<>], 52 | Data: $data, 53 | Buttons: $buttons, 54 | CellDefinitions: $cells, 55 | TablaSimple: false, 56 | CustomDataTable: new DataTableSettingsFilterDto( 57 | HideAllButtons: true 58 | ) 59 | ); 60 | 61 | $children = []; 62 | 63 | // 5: Dibujar grilla 64 | $children[] = $display->Widgets()['tb<>']; 65 | 66 | (new Container( 67 | Children: $children 68 | ))->Draw(); 69 | 70 | $display->DrawScripts( 71 | addLoadEvent: false 72 | ); 73 | -------------------------------------------------------------------------------- Total de líneas: 73 ================================================================================ ================================================================================ ARCHIVO #179: src/Generator/TemplatesOld/Mantenedores/verView.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Generator/TemplatesOld/Mantenedores/verView.php Tamaño: 3.73 KB -------------------------------------------------------------------------------- 1 | >\<>\verGridT; 28 | 29 | 30 | ?> 31 | 32 | @@Layout(authenticated) 33 | @@IncludeScriptBundle(mantenedor<>JS) 34 | <> 35 | 36 | Draw(); 50 | 51 | $display = new Display(); 52 | //DismissButtonStyle : ButtonStyleEnum::BUTTON_DEFAULT 53 | $display->AddButton( 54 | new FormButton( 55 | Key: 'btnBuscar<>', 56 | FormKey: 'frmencabezado', 57 | Child: new Text('Buscar'), 58 | ButtonStyle: ButtonStyleEnum::BUTTON_INFO, 59 | Classes: ['pull-right'], 60 | Events: [ 61 | new FormButtonOnClickEvent() 62 | ] 63 | ) 64 | ); 65 | 66 | // preparar los registros 67 | $rowGroups = []; 68 | $rowGroups[] = new FormRowGroup( 69 | Key: 'grp-informacion-<>', 70 | Rows: [ 71 | [ 72 | <> 73 | ] 74 | ] 75 | ); 76 | 77 | $rowGroups = verGridT::GetSearchFormOrderAndVisibility($rowGroups[0]); 78 | 79 | // Crear el formulario 80 | $display->AddFormFromObject( 81 | formKey: 'frmencabezado', 82 | object: $data, 83 | fillData: false, 84 | keyFieldName: 'Id<>', 85 | rowGroups: $rowGroups 86 | ); 87 | 88 | // Creación del botón "NUEVO" 89 | $display->AddButton( 90 | new Button( 91 | Key: 'btnNuevo<>', 92 | Child: new Text('Nuevo'), 93 | Classes: ['pull-right'], 94 | ButtonStyle : ButtonStyleEnum::BUTTON_PRIMARY, 95 | Events: [ 96 | new ButtonOnClickEvent() 97 | ] 98 | ) 99 | ); 100 | 101 | ( 102 | new Container( 103 | Classes: ['view-content'], 104 | Styles: [], 105 | Children: [ 106 | new Panel( 107 | Body: new Container( 108 | Children:[ 109 | $display->Widgets()['frmencabezado'], 110 | $display->Widgets()['btnBuscar<>'] 111 | ] 112 | ), 113 | ), 114 | new Panel( 115 | Header: 116 | new Container( 117 | Children: [ 118 | $display->Widgets()['btnNuevo<>'], 119 | new TitleDescription( 120 | Title: 'Resultado', 121 | Description: 'Listado de: <>' 122 | ) 123 | ] 124 | ), 125 | Body: new Container( 126 | Key: 'formulario-<>', 127 | Children:[ 128 | ] 129 | ), 130 | ) 131 | ] 132 | ) 133 | )->Draw(); 134 | 135 | $display->DrawScripts(); 136 | -------------------------------------------------------------------------------- Total de líneas: 136 ================================================================================ ================================================================================ ARCHIVO #180: src/Generator/TemplatesOld/Svc.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Generator/TemplatesOld/Svc.php Tamaño: 707 bytes -------------------------------------------------------------------------------- 1 | >; 9 | 10 | use Application\Dao\Services\<>\<>Dao; 11 | use Application\BLL\DataTransferObjects\<>\<>Dto; 12 | use Application\Dao\Entities\<>\<>; 13 | use Intouch\Framework\BLL\Service\GenericSvc; 14 | use Intouch\Framework\Mapper\Mapper; 15 | 16 | class <>Svc extends GenericSvc 17 | { 18 | use <>SvcT; 19 | 20 | function __construct($domain) 21 | { 22 | parent::__construct( 23 | <>Dto::class, 24 | <>::class, 25 | new <>Dao($domain) 26 | ); 27 | } 28 | 29 | } -------------------------------------------------------------------------------- Total de líneas: 29 ================================================================================ ================================================================================ ARCHIVO #181: src/Generator/TemplatesOld/SvcT.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Generator/TemplatesOld/SvcT.php Tamaño: 239 bytes -------------------------------------------------------------------------------- 1 | >; 9 | 10 | trait <>SvcT 11 | { 12 | public $innerMappings = []; 13 | 14 | } -------------------------------------------------------------------------------- Total de líneas: 14 ================================================================================ ================================================================================ ARCHIVO #182: src/IdeHelpers/_ide_helper_redis.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/IdeHelpers/_ide_helper_redis.php Tamaño: 5.10 KB -------------------------------------------------------------------------------- 1 | 0 || $errors['error_count'] > 0) { 130 | // Esto indica que el parseo tuvo problemas aunque un objeto pudo haber sido creado. 131 | // En un caso estricto como este, es mejor retornar null. 132 | return null; 133 | } 134 | 135 | return $dt; 136 | } 137 | 138 | 139 | // function _CdateautoDb($valor) : null | Datetime { 140 | 141 | // $in = str_replace('/', '-', $valor); 142 | // $outputFormat = "Y-m-d H:i:s"; 143 | 144 | // $pos = strpos($in, '-'); 145 | // $out = null; 146 | 147 | // switch (strlen($valor)) { 148 | // case 10: $out = _CdateDb($in, null, (($pos == 4) ? "Y-m-d" : "d-m-Y"), $outputFormat); break; 149 | // case 16: $out = _CdateDb($in, null, (($pos == 4) ? "Y-m-d H:i" : "d-m-Y H:i"), $outputFormat); break; 150 | // case 19: $out = _CdateDb($in, null, (($pos == 4) ? "Y-m-d H:i:s" : "d-m-Y H:i:s"), $outputFormat); break; 151 | // default: $out = null; break; 152 | // } 153 | 154 | // return $out; 155 | // } 156 | 157 | // function _CdateDb($valor, $default = null, $format = "Y-m-d H:i:s", $outputFormat = "Y-m-d H:i:s") : null | Datetime { 158 | 159 | // if (!isset($valor) || trim($valor) == "") { 160 | // return null; 161 | // } 162 | // else { 163 | // $dt = Datetime::createFromFormat($format, trim($valor)); 164 | // return $dt; 165 | // } 166 | // } 167 | 168 | function _Cdateauto($valor, $format = "", $outputFormat = "Y-m-d H:i:s", $default = null) { 169 | 170 | $valor = str_replace('T', ' ', $valor); 171 | $valor = str_replace('Z', '', $valor); 172 | 173 | $in = str_replace('/', '-', $valor); 174 | $pos = strpos($in, '-'); 175 | $out = $default; 176 | 177 | if ($format == "") { 178 | switch (strlen($valor)) { 179 | case 10: $out = _Cdate($in, $default, (($pos == 4) ? "Y-m-d" : "d-m-Y"), $outputFormat); break; 180 | case 16: $out = _Cdate($in, $default, (($pos == 4) ? "Y-m-d H:i" : "d-m-Y H:i"), $outputFormat); break; 181 | case 19: $out = _Cdate($in, $default, (($pos == 4) ? "Y-m-d H:i:s" : "d-m-Y H:i:s"), $outputFormat); break; 182 | default: $out = $default; break; 183 | } 184 | } 185 | else { 186 | $out = _Cdate($in, $default, $format, $outputFormat); 187 | } 188 | 189 | return $out; 190 | } 191 | 192 | function _Cdate($valor, $default = null, $format = "Y-m-d H:i:s", $outputFormat = "Y-m-d H:i:s") { 193 | if (!isset($valor) || trim($valor) == "") { 194 | return $default; 195 | } 196 | else { 197 | $dt = Datetime::createFromFormat($format, trim($valor)); 198 | return (!isset($dt)) ? null : $dt->format($outputFormat); 199 | } 200 | } 201 | 202 | function _first($element){ 203 | if(isset($element) && is_array($element) && !empty($element) ){ 204 | return $element[0]; 205 | }else{ 206 | return null; 207 | } 208 | } 209 | 210 | function __($idRestriction) { 211 | 212 | if (isset(Session::Instance()->usuario->Perfil)) { 213 | return RestrictionConfig::CalcularAccion($idRestriction, Session::Instance()->usuario->Perfil); 214 | } 215 | else { 216 | return ""; 217 | } 218 | 219 | } 220 | 221 | /** 222 | * Agrega un nuevo string a un string existente, con un separador. 223 | */ 224 | function _att($original, $attach, $separator) { 225 | 226 | if ($original != '') { 227 | $original .= $separator; 228 | } 229 | 230 | $original .= $attach; 231 | 232 | return $original; 233 | } 234 | 235 | function _nxt(string $letra = '') { 236 | $colLetras = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']; 237 | 238 | // ubicar la letra actual 239 | $idxLetra = 0; 240 | if ($letra != '') { 241 | foreach($colLetras as $idx => $item) { 242 | if (strtoupper($letra) == $item) { 243 | $idxLetra = $idx + 1; 244 | break; 245 | } 246 | } 247 | } 248 | 249 | return $colLetras[$idxLetra]; 250 | } 251 | 252 | function _mon($ammount, $decimals = 0) { 253 | 254 | if ($ammount == '') return ''; 255 | 256 | return '$ ' . number_format( 257 | round($ammount, $decimals), 258 | $decimals, ",", "." 259 | ); 260 | } 261 | 262 | function _mill($ammount, $decimals = 0, $divider = 1000000, $sufix = 'mill') { 263 | 264 | if ($ammount == '') return ''; 265 | 266 | $abs = abs($ammount / $divider); 267 | $mill = ($ammount / $divider); 268 | 269 | if ($abs < 10) { 270 | $mill = $ammount; 271 | $sufix = ''; 272 | } 273 | 274 | return '$ ' . number_format( 275 | $mill, $decimals, 276 | ",", "." 277 | ) . (($sufix != '') ? ' ' . $sufix : ''); 278 | } 279 | 280 | function _rut($rut) 281 | { 282 | if ($rut == "") { 283 | return $rut; 284 | } 285 | 286 | $rut = _norut($rut); 287 | $rut = number_format(substr($rut, 0, -1), 0, "", ".") . '-' . substr($rut, strlen($rut) - 1, 1); 288 | 289 | return $rut; 290 | } 291 | 292 | function _norut($rut) 293 | { 294 | $rut = str_replace(chr(10), '', $rut); 295 | $rut = str_replace(chr(13), '', $rut); 296 | $rut = str_replace('.', '', $rut); 297 | $rut = str_replace('-', '', $rut); 298 | return $rut; 299 | } 300 | 301 | function _nulcol(GenericCollection|null $collection, $dtoName, $key) { 302 | 303 | if (!isset($collection)) { 304 | return new GenericCollection( 305 | DtoName: $dtoName, 306 | Key: $key, 307 | Values: [] 308 | ); 309 | } 310 | else { 311 | return $collection; 312 | } 313 | } 314 | 315 | function _num($number) { 316 | return _dec($number, 0); 317 | } 318 | 319 | function _dec($number, $decimals = 0) { 320 | return number_format( 321 | round($number, $decimals), 322 | $decimals, ",", "." 323 | ); 324 | } 325 | 326 | function _perc($number, $decimals = 0) { 327 | return number_format( 328 | round($number, $decimals), 329 | $decimals, ",", "." 330 | ) . '%'; 331 | } 332 | 333 | function _perm($idRestriction) { 334 | 335 | if (isset(Session::Instance()->usuario->Perfil)) { 336 | return RestrictionConfig::CalcularAccion($idRestriction, Session::Instance()->usuario->Perfil); 337 | } 338 | else { 339 | return ""; 340 | } 341 | } 342 | 343 | function _msg($messageID, $idioma = null) { 344 | return Mensaje::ObtenerMensaje($messageID, $idioma); 345 | } 346 | 347 | function _opt($messageID, $optionValue, $selected=true) { 348 | return ""; 349 | } 350 | 351 | function _inp($id, $messageID, $type = 'text', $name = '', $value = '', $required = true, $class = 'form-control') { 352 | 353 | if ($name == '') 354 | $name = $id; 355 | 356 | return ""; 357 | } 358 | 359 | function _nul($input = null, $default = '') { 360 | return isset($input) ? $input : $default; 361 | } 362 | 363 | function _in(string $input, string $searchItems) { 364 | $parts = explode(',', $searchItems); 365 | 366 | foreach($parts as $part) { 367 | if ( trim($part) == $input) 368 | return true; 369 | } 370 | 371 | return false; 372 | } 373 | 374 | function _nularr($array = null, $index = '', $default = '') { 375 | 376 | if (isset($array)) { 377 | if (isset($array[$index])) { 378 | return $array[$index]; 379 | } 380 | else { 381 | return $default; 382 | } 383 | } 384 | else { 385 | return $default; 386 | } 387 | 388 | } 389 | 390 | function _hasAttr($classname, $attribute) { 391 | $reflector = new \ReflectionClass($classname); 392 | $hasAttr = count($reflector->getAttributes($attribute)) > 0; 393 | 394 | return $hasAttr; 395 | } 396 | 397 | function _getAttrArgs($classname, $attribute) { 398 | 399 | $reflector = new \ReflectionClass($classname); 400 | $attributes = $reflector->getAttributes($attribute); 401 | 402 | if (count($attributes) > 0) { 403 | $args = $attributes[0]->getArguments(); 404 | return $args; 405 | } 406 | else { 407 | return null; 408 | } 409 | } 410 | 411 | function _getClassAttrs($classname, $attribute) { 412 | $reflector = new \ReflectionClass($classname); 413 | return $reflector->getAttributes($attribute); 414 | } 415 | 416 | function _guid() { 417 | 418 | return generateUuidV4Standard(); 419 | //return vsprintf('%s%s-%s-4000-8%.3s-%s%s%s0',str_split(dechex( microtime(true) * 1000 ) . bin2hex( random_bytes(8) ),4)); 420 | } 421 | 422 | /** 423 | * Genera un UUID de la Versión 4 (aleatorio) conforme a la RFC 4122. 424 | * 425 | * @return string Un UUID v4 con el formato estándar (ej: xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx). 426 | * @throws Exception Si no se pueden generar suficientes bytes aleatorios. 427 | */ 428 | function generateUuidV4Standard(): string 429 | { 430 | // Genera 16 bytes (128 bits) de datos aleatorios criptográficamente seguros. 431 | $data = random_bytes(16); 432 | 433 | // Establece los bits de la versión (4) en el sexto byte. 434 | // El nibble más significativo del byte 6 debe ser 0100 (4 en hexadecimal). 435 | // Esto se logra con una operación AND para limpiar los 4 bits superiores 436 | // y una operación OR para establecer el valor 0x40 (0100 0000 binario). 437 | $data[6] = chr(ord($data[6]) & 0x0f | 0x40); 438 | 439 | // Establece los bits de la variante (RFC 4122) en el octavo byte. 440 | // Los 2 bits más significativos del byte 8 deben ser 10 (esto se traduce a 8, 9, A o B en hex). 441 | // Se logra con una operación AND para limpiar los 2 bits superiores 442 | // y una operación OR para establecer el valor 0x80 (1000 0000 binario). 443 | $data[8] = chr(ord($data[8]) & 0x3f | 0x80); 444 | 445 | // Formatea los bytes en la cadena UUID estándar. 446 | // bin2hex convierte los bytes binarios a su representación hexadecimal. 447 | // str_split divide la cadena hexadecimal en bloques. 448 | // vsprintf formatea esos bloques en el patrón del UUID. 449 | return vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($data), 4)); 450 | } 451 | 452 | function JoinObjects( 453 | string $ParentKey = '', 454 | string $ChildrenKey = '', 455 | $ParentObj = null, 456 | $ChildrenObj = null, 457 | bool $Count = false, 458 | ) 459 | { 460 | $response = null; 461 | $cc = 0; 462 | 463 | // Se Verifica que el padre y el hijo no vengan vacios 464 | if(is_object($ParentObj) && is_object($ChildrenObj)): 465 | 466 | //Si vienen todos los datos se inicia el cruce de información 467 | foreach($ChildrenObj as $CObject){ 468 | 469 | if($ParentObj->{$ParentKey} == $CObject->{$ChildrenKey}): 470 | if($Count == true){ 471 | $cc++; 472 | }else{ 473 | $response = $CObject; 474 | } 475 | 476 | 477 | endif; 478 | 479 | } 480 | endif; 481 | 482 | if($Count == true){ 483 | return $cc; 484 | }else{ 485 | return $response; 486 | } 487 | 488 | 489 | 490 | 491 | } 492 | 493 | 494 | function _mv($from, $to) 495 | { 496 | // Try to rename (move) the file first 497 | if (rename($from, $to)) { 498 | return true; // File moved successfully on the same filesystem 499 | } else { 500 | // If rename fails, it's likely due to a cross-device link. 501 | // Attempt to copy the file and then delete the original. 502 | if (copy($from, $to)) { 503 | // File copied successfully, now delete the original 504 | if (unlink($from)) { 505 | return true; // File moved successfully across devices 506 | } else { 507 | // Error deleting original file after successful copy 508 | error_log("Error: Failed to delete original file '$from' after successful copy to '$to'."); 509 | return false; 510 | } 511 | } else { 512 | // Error copying file. This could also be a permissions issue or disk space. 513 | error_log("Error: Failed to copy file from '$from' to '$to'. Original rename also failed (possible 'Invalid cross-device link')."); 514 | return false; 515 | } 516 | } 517 | } 518 | -------------------------------------------------------------------------------- Total de líneas: 518 ================================================================================ ================================================================================ ARCHIVO #184: src/Loaders.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Loaders.php Tamaño: 5.39 KB -------------------------------------------------------------------------------- 1 | decodeMultiple($jsonData, DominioDto::class); 36 | 37 | // Verificar que exista el dominio obligatorio "default" 38 | foreach($dominios as $key=>$dominio) { 39 | if ($key == 'default') { 40 | $existeDefault = true; 41 | break; 42 | } 43 | } 44 | } 45 | else { 46 | return Display::GetRenderer()->RenderWsResult(1, "", "No se ha encontrado el archivo de configuracion de dominios de conexion: dominios.config.json"); 47 | } 48 | 49 | // Lanzar excepcion si no se ha encontrado el dominio "default" 50 | if (!$existeDefault) { 51 | return Display::GetRenderer()->RenderWsResult(1, "", "No se ha encontrado el dominio 'default' en la configuracion de dominios de conexion"); 52 | } 53 | 54 | $GLOBALS['conn_domains'] = $dominios; 55 | return Display::GetRenderer()->RenderWsResult(0, "", ""); 56 | } 57 | 58 | public static function CargarMensajes($mensajesFilePath) { 59 | $mensajes = array(); 60 | 61 | // Leer el archivo de configuracion 62 | if (file_exists($mensajesFilePath)) { 63 | $jsonData = file_get_contents($mensajesFilePath); 64 | 65 | // Eliminar los comentarios del archivo json 66 | $jsonData = preg_replace('/\s*(?!<\")\/\*[^\*]+\*\/(?!\")\s*/', '', $jsonData); 67 | 68 | $mensajes = json_decode($jsonData, true); 69 | 70 | $GLOBALS['conn_mensajes'] = $mensajes; 71 | return Display::GetRenderer()->RenderWsResult(0, "", ""); 72 | } 73 | else { 74 | return Display::GetRenderer()->RenderWsResult(1, "", "No se ha encontrado el archivo de configuracion de los mensajes del sistema"); 75 | } 76 | } 77 | 78 | public static function CargarFuncionalidades($funcionalidadesFilePath) { 79 | 80 | // Leer el archivo de configuracion 81 | if (file_exists($funcionalidadesFilePath)) { 82 | $jsonData = file_get_contents($funcionalidadesFilePath); 83 | 84 | // Eliminar los comentarios del archivo json 85 | $jsonData = preg_replace('/\s*(?!<\")\/\*[^\*]+\*\/(?!\")\s*/', '', $jsonData); 86 | 87 | $jsonDecoder = new JsonDecoder(); 88 | 89 | $funcionalidades = $jsonDecoder->decodeMultiple($jsonData, FuncionalidadDto::class); 90 | 91 | foreach($funcionalidades as $funcionalidad) { 92 | //$test = $this->RenderStrings("@@{MnuDetenciones, Detenciones}"); 93 | 94 | if (isset($funcionalidad->Descripcion) && $funcionalidad->Descripcion != "") { 95 | $funcionalidad->Descripcion = Display::GetRenderer('Core')->RenderStrings($funcionalidad->Descripcion); 96 | } 97 | } 98 | 99 | $GLOBALS['funcionalidades'] = $funcionalidades; 100 | $GLOBALS['menu'] = array_filter($funcionalidades, 'self::FilterFuncionalidadMenu'); 101 | $GLOBALS['routes_enforced'] = array_filter($funcionalidades, 'self::FilterFuncionalidadEnforced'); 102 | $GLOBALS['routes_redirected'] = array_filter($funcionalidades, 'self::FilterFuncionalidadRedirected'); 103 | $GLOBALS['routes_allowed'] = array_filter($funcionalidades, 'self::FilterFuncionalidadAllowed'); 104 | 105 | return Display::GetRenderer()->RenderWsResult(0, "", ""); 106 | } 107 | else { 108 | return Display::GetRenderer()->RenderWsResult(0, "", "No se ha encontrado el archivo de configuracion de funcionalidades"); 109 | } 110 | } 111 | 112 | // funciones de filtrado 113 | // 114 | private static function FilterFuncionalidadMenu($funcionalidad) { 115 | return ($funcionalidad->IsMenu == '1' || $funcionalidad->IsMenu == '2'); 116 | } 117 | 118 | private static function FilterFuncionalidadNoMenu($funcionalidad) { 119 | return ($funcionalidad->IsMenu == 0); 120 | } 121 | 122 | private static function FilterFuncionalidadEnforced($funcionalidad) { 123 | return ($funcionalidad->AuthorizationAction == 'Enforce' && $funcionalidad->Tipo != "SEPARADOR" && $funcionalidad->Tipo != "TITULO"); 124 | } 125 | 126 | private static function FilterFuncionalidadRedirected($funcionalidad) { 127 | return ($funcionalidad->AuthorizationAction == 'Redirect' && $funcionalidad->Tipo != "SEPARADOR" && $funcionalidad->Tipo != "TITULO"); 128 | } 129 | 130 | private static function FilterFuncionalidadAllowed($funcionalidad) { 131 | return ($funcionalidad->AuthorizationAction == 'Allow' && $funcionalidad->Tipo != "SEPARADOR" && $funcionalidad->Tipo != "TITULO"); 132 | } 133 | } -------------------------------------------------------------------------------- Total de líneas: 133 ================================================================================ ================================================================================ ARCHIVO #185: src/MailHelper/Attachment.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/MailHelper/Attachment.php Tamaño: 479 bytes -------------------------------------------------------------------------------- 1 | isSMTP(); 41 | $mail->Host = self::$MailConfig->SmtpServer; 42 | $mail->SMTPAuth = true; 43 | $mail->Username = self::$MailConfig->SmtpUser; 44 | $mail->Password = self::$MailConfig->SmtpPassword; 45 | $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS; 46 | $mail->Port = self::$MailConfig->SmtpPort; 47 | 48 | //Recipients 49 | // 50 | foreach ($this->Message->Recipients as $recipient) { 51 | if ($recipient instanceof Recipient) { 52 | 53 | switch($recipient->Type) { 54 | case RecipientTypeEnum::FROM_RECIPIENT: 55 | $mail->setFrom($recipient->Address, $recipient->Name); 56 | break; 57 | case RecipientTypeEnum::REPLY_TO_RECIPIENT: 58 | $mail->addReplyTo($recipient->Address, $recipient->Name); 59 | break; 60 | case RecipientTypeEnum::TO_RECIPIENT: 61 | $mail->addAddress($recipient->Address, $recipient->Name); 62 | break; 63 | case RecipientTypeEnum::CC_RECIPIENT: 64 | $mail->addCC($recipient->Address, $recipient->Name); 65 | break; 66 | case RecipientTypeEnum::BCC_RECIPIENT: 67 | $mail->addBCC($recipient->Address, $recipient->Name); 68 | } 69 | 70 | } 71 | } 72 | 73 | //Content 74 | // 75 | $mail->isHTML($this->Message->IsHtml); 76 | $mail->Subject = $this->Message->Subject; 77 | $mail->Body = $this->Message->Body; 78 | $mail->AltBody = $this->Message->AltBody; 79 | 80 | // Attachments 81 | // 82 | if (isset($this->Attachments)) { 83 | foreach($this->Attachments as $attachment) { 84 | if ($attachment instanceof Attachment) { 85 | $mail->addAttachment( 86 | path: $attachment->FilePath, 87 | name: $attachment->FileName, 88 | disposition: isset($attachment->AttachmentType) ? $attachment->AttachmentType : 'attachment' 89 | ); 90 | } 91 | } 92 | } 93 | 94 | $mail->send(); 95 | 96 | return true; 97 | } 98 | catch (Exception $e) { 99 | return false; 100 | } 101 | } 102 | 103 | public static function SendMultiple( 104 | Message $Message, 105 | array $Replacements 106 | ) { 107 | 108 | $enviosCorrectos = []; 109 | $enviosIncorrectos = []; 110 | $cantidadEnviosCorrectos = 0; 111 | $cantidadEnviosIncorrectos = 0; 112 | 113 | // Obtener el subject y body originales con los tokens sin reemplazar 114 | $originalBody = $Message->Body; 115 | $originalAltBody = $Message->AltBody; 116 | $originalSubject = $Message->Subject; 117 | 118 | // Componer correo para cada recipiente 119 | // 120 | $cantRep = count($Replacements); 121 | $idxRep = 1; 122 | foreach($Replacements as $rep) { 123 | 124 | if ($rep instanceof ComposeReplacement && $rep->Recipient->Type == RecipientTypeEnum::TO_RECIPIENT) { 125 | 126 | // Reemplazar los tokens 127 | $newBody = $originalBody; 128 | $newAltBody = $originalAltBody; 129 | $newSubject = $originalSubject; 130 | 131 | // Generar un nuevo mensaje 132 | foreach ($rep->Tokens as $token) { 133 | if (is_array($token) && count($token) == 2) { //los tokens deben ser arreglos [buscar, reemplazar] 134 | $newBody = str_replace($token[0], $token[1], $newBody); 135 | $newAltBody = str_replace($token[0], $token[1], $newAltBody); 136 | $newSubject = str_replace($token[0], $token[1], $newSubject); 137 | } 138 | } 139 | 140 | $newRecipients = []; 141 | array_push($newRecipients, $rep->Recipient); 142 | foreach($Message->Recipients as $recip) { 143 | array_push($newRecipients, $recip); 144 | } 145 | 146 | $nuevoMail = new Mail( 147 | Message: new Message( 148 | Recipients: $newRecipients, 149 | IsHtml: $Message->IsHtml, 150 | Subject: $newSubject, 151 | Body: $newBody, 152 | AltBody: $newAltBody 153 | ), 154 | Attachments: (isset($rep->Attachments) && is_array($rep->Attachments)) ? $rep->Attachments : [] 155 | ); 156 | 157 | try { 158 | 159 | $sendResult = $nuevoMail->Send(); 160 | 161 | if ($sendResult) { 162 | $cantidadEnviosCorrectos++; 163 | array_push($enviosCorrectos, $rep->Recipient); 164 | } 165 | else { 166 | $cantidadEnviosIncorrectos++; 167 | array_push($enviosIncorrectos, $rep->Recipient); 168 | } 169 | } 170 | catch (\Exception $ex) { 171 | $cantidadEnviosIncorrectos++; 172 | array_push($enviosIncorrectos, $rep->Recipient); 173 | } 174 | 175 | // Esperar 1 segundo para el siguiente envio si hay más correos que enviar 176 | // 177 | if ($idxRep < $cantRep) 178 | sleep(1); 179 | 180 | $idxRep++; 181 | } 182 | } 183 | 184 | $result = new ResultMultipleSend( 185 | EnviosCorrectos : $enviosCorrectos, 186 | EnviosIncorrectos : $enviosIncorrectos, 187 | CantidadEnviosCorrectos : $cantidadEnviosCorrectos, 188 | CantidadEnviosIncorrectos : $cantidadEnviosIncorrectos 189 | ); 190 | 191 | return $result; 192 | } 193 | 194 | } 195 | 196 | -------------------------------------------------------------------------------- Total de líneas: 196 ================================================================================ ================================================================================ ARCHIVO #189: src/MailHelper/MailConfig.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/MailHelper/MailConfig.php Tamaño: 475 bytes -------------------------------------------------------------------------------- 1 | format('H') * 1; 19 | } 20 | else { 21 | $hora = (new \DateTime())->format('H') * 1; 22 | } 23 | 24 | if ($hora >= 0 && $hora < 12) { 25 | return "muy buenos días"; 26 | } 27 | else if ($hora >= 12 && $hora < 20) { 28 | return "muy buenas tardes"; 29 | } 30 | else { 31 | return "muy buenas noches"; 32 | } 33 | } 34 | 35 | } -------------------------------------------------------------------------------- Total de líneas: 35 ================================================================================ ================================================================================ ARCHIVO #191: src/MailHelper/Message.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/MailHelper/Message.php Tamaño: 496 bytes -------------------------------------------------------------------------------- 1 | get("cache-mapping")); 44 | 45 | if (isset($info) && ($info)) { 46 | $mapping = $info; 47 | } 48 | } 49 | 50 | if ($mapping == null) { 51 | $mappingFilePath = __DIR__."/../../mapping.config.json"; 52 | 53 | // Leer el archivo de configuracion 54 | if (file_exists($mappingFilePath)) { 55 | $jsonData = file_get_contents($mappingFilePath); 56 | 57 | // Eliminar los comentarios del archivo json 58 | $jsonData = preg_replace('/\s*(?!<\")\/\*[^\*]+\*\/(?!\")\s*/', '', $jsonData); 59 | 60 | if (!isset($jsonData) || $jsonData == null) { 61 | } 62 | else { 63 | $jsonDecoder = new JsonDecoder(); 64 | $info = $jsonDecoder->decodeMultiple($jsonData, Map::class); 65 | 66 | if (isset($info)) { 67 | $mapping = new GenericCollection( 68 | Key : "IdMapping", 69 | DtoName : Map::class, 70 | Values : $info 71 | ); 72 | } 73 | } 74 | } 75 | 76 | // Intentar obtener mapeos automáticos por CONVENCION (Entities > Dtos) 77 | $DTOfolder = __DIR__."/../../BLL/DataTransferObjects"; 78 | $EntityFolder = __DIR__."/../../Dao/Entities"; 79 | 80 | $idxMap = 0; 81 | if (isset($mapping)) { 82 | $idxMap = $mapping->Max('IdMapping') + 1; 83 | } 84 | 85 | if (file_exists($DTOfolder) && file_exists($EntityFolder)) { 86 | $rii = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($EntityFolder)); 87 | $files = array(); 88 | 89 | foreach ($rii as $file) { 90 | if ($file->isDir()){ 91 | continue; 92 | } 93 | 94 | $entityName = str_replace(".php", "", $file->getFilename()); 95 | $entityRoute = str_replace($file->getFilename(), "", self::ClearPath($file->getPathname(), "Entities/")); 96 | $entityPath = str_replace("/", "\\", $entityRoute); 97 | 98 | // Ver si existe una DTO con el nombre de la entity 99 | $dtoName = $entityName . "Dto"; 100 | 101 | if (file_exists($DTOfolder . "/" . $entityRoute . $dtoName . ".php")) { 102 | $entityClass = "Dao\\Entities\\" . $entityPath . $entityName; 103 | $dtoClass = "BLL\\DataTransferObjects\\" . $entityPath . $dtoName; 104 | } 105 | 106 | if (isset($entityClass) && $entityClass != "" && isset($dtoClass) && $dtoClass != "") { 107 | // Ver si la definicion ya está cargada 108 | if (isset($mapping)) { 109 | $ent = $mapping->Where("SourceClass = '$entityClass'")->First(); 110 | $dto = $mapping->Where("TargetClass = '$dtoClass'")->First(); 111 | } 112 | else { 113 | $ent = null; 114 | $dto = null; 115 | } 116 | 117 | // Si no existe, lo agregamos al mapeo 118 | if (!isset($ent) && !isset($dto)) { 119 | $mp = new Map(); 120 | $mp->IdMapping = $idxMap; 121 | $mp->SourceClass = $entityClass; 122 | $mp->TargetClass = $dtoClass; 123 | $mp->Swappable = true; 124 | 125 | $mapping->Add($mp, false); 126 | $idxMap++; 127 | } 128 | } 129 | } 130 | 131 | $mapping->Reindex(); 132 | } 133 | 134 | // Si obtuvimos el mapping, lo guardamos en REDIS 135 | if (isset($mapping) && ($mapping->Count() > 0)) { 136 | $redis->set("cache-mapping", serialize($mapping)); 137 | $redis->close(); 138 | } 139 | } 140 | else { 141 | $redis->close(); 142 | } 143 | 144 | // Es obligatorio lograr obtener la configuracion 145 | if (!isset($mapping)) { 146 | http_response_code(500); 147 | echo "No se ha encontrado el mapping en redis ni en el archivo de mappings: mapping.config.json"; 148 | die(); 149 | } 150 | 151 | return $mapping; 152 | } 153 | } -------------------------------------------------------------------------------- Total de líneas: 153 ================================================================================ ================================================================================ ARCHIVO #196: src/Mapper/Mapper.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Mapper/Mapper.php Tamaño: 21.20 KB -------------------------------------------------------------------------------- 1 | ObjectExecutions = 0; 42 | $this->ObjectTime = 0; 43 | $this->PropertyExecutions = 0; 44 | $this->PropertyTime = 0; 45 | $this->CollectionExecutions = 0; 46 | $this->CollectionTime = 0; 47 | 48 | $this->FindMappingExecutions = 0; 49 | $this->FindMappingTime = 0; 50 | } 51 | 52 | public static function GetInstance() { 53 | 54 | // Implementa Singleton 55 | if (!isset(self::$Instance)) { 56 | self::$Instance = new Mapper(); 57 | } 58 | 59 | return self::$Instance; 60 | } 61 | 62 | public static function GetMapping() { 63 | if (!isset(self::$GlobalMapping)) { 64 | self::$GlobalMapping = Map::ObtenerMappings(); 65 | } 66 | 67 | return self::$GlobalMapping; 68 | } 69 | 70 | private function findMapping($sourceClass) { 71 | 72 | // Monitorear 73 | $this->FindMappingExecutions++; 74 | 75 | $dtStart = microtime(true); 76 | 77 | $mapping = $this->Mapping; 78 | 79 | // Buscar el mapping en forma normal desde el sourceclass 80 | $map = $mapping->Where("SourceClass = '$sourceClass'")->First(); 81 | 82 | if (isset($map)) { 83 | // Monitorear 84 | $dtEnd = microtime(true); 85 | $this->FindMappingTime += round( ($dtEnd - $dtStart) * 1000, 8)/1000; 86 | 87 | // si no encontramos un mapping, buscamos la referencia en forma 88 | // inversa, si es que el mapping soporta swap 89 | return $map->TargetClass; 90 | } 91 | else { 92 | $map = $mapping->Where("Swappable == true")->Where("TargetClass = '$sourceClass'")->First(); 93 | 94 | if (isset($map)) { 95 | // Monitorear 96 | $dtEnd = microtime(true); 97 | $this->FindMappingTime += round( ($dtEnd - $dtStart) * 1000, 8)/1000; 98 | 99 | // el nuevo objeto lo define el sourceclass (la referencia está invertida en el mapping) 100 | return $map->SourceClass; 101 | } 102 | } 103 | 104 | // Monitorear 105 | $dtEnd = microtime(true); 106 | $this->FindMappingTime += round( ($dtEnd - $dtStart) * 1000, 8)/1000; 107 | return null; 108 | } 109 | 110 | private function newObjectFromMapping($sourceClass) { 111 | 112 | $map = $this->findMapping($sourceClass); 113 | 114 | if (isset($map)) { 115 | return new $map(); 116 | } 117 | else { 118 | return null; 119 | } 120 | } 121 | 122 | private function mapProperty($propValue) { 123 | 124 | if (is_object($propValue)) { 125 | return null; 126 | 127 | // Revisar si está en el mapping 128 | // $propClass = get_class($propValue); 129 | // $newObject = $this->newObjectFromMapping($propClass, $mapping); 130 | 131 | // if (isset($newObject)) { 132 | // $this->mapObject($propValue, $newObject, $mapping, $createProperties); 133 | // return $newObject; 134 | // } 135 | // else { 136 | // return null; 137 | // } 138 | 139 | } 140 | else if (is_array($propValue)) { 141 | 142 | return null; 143 | 144 | // $objects = array(); 145 | 146 | // foreach($propValue as $object) { 147 | // $newObject = $this->mapProperty($object, $mapping, true); 148 | // array_push($objects, $newObject); 149 | // } 150 | 151 | // return $objects; 152 | } 153 | else { 154 | return Utils::sanearVariables($propValue); 155 | } 156 | 157 | return null; 158 | } 159 | 160 | private function mapArray(array & $propValues, $createProperties = true) { 161 | 162 | if (!is_array($propValues)) { 163 | return null; 164 | } 165 | 166 | $result = array(); 167 | 168 | foreach($propValues as $prop) { 169 | // Atachar la propiedad (la funcion map decidirá a qué mapeador llamar según el tipo de la propiedad) 170 | $newProp = $this->map($prop, null, $createProperties); 171 | array_push($result, $newProp); 172 | } 173 | 174 | return $result; 175 | } 176 | 177 | private function mapObject(& $source, $createProperties = true) { 178 | 179 | if (!is_object($source)) { 180 | return null; 181 | } 182 | 183 | // Revisar si está en el mapping 184 | $propClass = get_class($source); 185 | $newObject = $this->newObjectFromMapping($propClass); 186 | 187 | // Si logramos generar el objeto de destino, mapeamos todas las propiedades que 188 | // podamos encontrar desde el objeto de origen 189 | if (isset($newObject)) { 190 | 191 | $sourceFields = get_object_vars($source); 192 | $targetFields = get_object_vars($newObject); 193 | 194 | // Mapeamos todas las propiedades del objeto 195 | foreach ($sourceFields as $propName => $propValue) { 196 | // Ver si existe la propiedad en el objeto destino 197 | // o si se ha solicitado crear propiedades inexistentes en el destino 198 | if ($createProperties || isset($targetFields[$propName])) { 199 | $newObject->$propName = $this->map($propValue, null, $createProperties); 200 | } 201 | } 202 | 203 | return $newObject; 204 | } 205 | else { 206 | return null; 207 | } 208 | /* 209 | // Obtener las propiedades del objeto de origen 210 | $sourceClass = get_class($source); 211 | $sourceFields = get_object_vars($source); 212 | 213 | // Buscar el objeto de destino 214 | 215 | // Obtener las propiedades del objeto de destino 216 | $targetClass = get_class($target); 217 | $targetProps = get_class_vars($targetClass); 218 | 219 | foreach ($sourceFields as $propName => $propValue) { 220 | // Ver si existe la propiedad en el objeto destino 221 | // o si se ha solicitado crear propiedades inexistentes en el destino 222 | if ($createProperties || isset($targetProps[$propName])) { 223 | // Atachar la propiedad 224 | $target->$propName = $this->mapProperty($propValue, $mapping, $createProperties); 225 | } 226 | } 227 | 228 | return $target; 229 | */ 230 | } 231 | 232 | private function mapCollection(GenericCollection & $source, $createProperties = true, $key = "") { 233 | 234 | if (!isset($source)) { 235 | return null; 236 | } 237 | 238 | // Si no se especifica la llave de la collecion de destino, 239 | // se debe utilizar la llave de la coleccion de origen 240 | if ($key == "") { 241 | $key = $source->GetKey(); 242 | } 243 | 244 | // Obtener el mapeo del arreglo de objetos 245 | $result = $this->mapArray($source->Values, $createProperties); 246 | 247 | if (isset($result)) { 248 | // Obtener la clase de destino para generar la colección 249 | $targetClass = $this->findMapping($source->GetDtoName()); 250 | 251 | return new GenericCollection( 252 | Key : $key, 253 | DtoName : $targetClass, 254 | Values : $result 255 | ); 256 | } 257 | else { 258 | return null; 259 | } 260 | } 261 | 262 | public function map(& $source, $mapping = null, $createProperties = true, $key="", $scapeStrings = false, $avoidNull = false) { 263 | 264 | if (!isset($source)) { 265 | if (!($avoidNull)) { 266 | return null; 267 | } 268 | else { 269 | return []; 270 | } 271 | } 272 | 273 | if (!isset($this->Mapping)) 274 | $this->Mapping = self::GetMapping(); 275 | 276 | if (isset($mapping)) { 277 | $this->Mapping->AddRange($mapping); 278 | } 279 | 280 | if (is_array($source)) { 281 | return $this->mapArray($source, $createProperties); 282 | } 283 | else if ($source instanceof GenericCollection) { 284 | return $this->mapCollection($source, $createProperties, $key); 285 | } 286 | else if (is_object($source)) { 287 | return $this->mapObject($source, $createProperties); 288 | } 289 | else { 290 | //$dtPropertyStart = microtime(true); 291 | 292 | if ($scapeStrings) 293 | return Utils::sanearVariables($source); 294 | else 295 | return $source; 296 | //$var = $this->mapProperty($source); 297 | //$dtPropertyEnd = microtime(true); 298 | 299 | // $this->PropertyExecutions++; 300 | // $this->PropertyTime += round( ($dtPropertyEnd - $dtPropertyStart) * 1000, 8)/1000; 301 | } 302 | 303 | } 304 | 305 | 306 | private static function autoMapper($sourceObject, $targetObject, $nosanear = false, $honorPrefix = '', $useTargetProperties = false, array $innerMappings = []) 307 | { 308 | if ($useTargetProperties) { 309 | $vars_clase = get_class_vars(get_class($targetObject)); 310 | } 311 | else { 312 | $vars_clase = get_object_vars($sourceObject); 313 | } 314 | 315 | $prefixLen = 0; 316 | if ($honorPrefix != '') { 317 | $prefixLen = strlen($honorPrefix); 318 | } 319 | 320 | foreach ($vars_clase as $sKey => $value) { 321 | 322 | $key = $sKey; 323 | $destKey = $sKey; 324 | 325 | $useProp = true; 326 | if ($honorPrefix != '') { 327 | // Se deben utilizar solamente aquellas propiedades con el prefix indicado y quitarlo 328 | if ($useTargetProperties || substr($key, 0, $prefixLen) == $honorPrefix) { 329 | $useProp = true; 330 | 331 | if ($useTargetProperties) { 332 | $key = $honorPrefix . '.' . $sKey; 333 | } 334 | else { 335 | $destKey = self::removePrefix($sKey); 336 | } 337 | } 338 | else { 339 | $useProp = false; 340 | } 341 | } 342 | 343 | // if ($removePrefix) { 344 | // $key = self::removePrefix($sKey); 345 | // } 346 | 347 | if ($useProp) { 348 | 349 | // ver si tenemos que mapear la propiedad como objeto 350 | $mapInner = null; 351 | 352 | if (isset($innerMappings[$destKey])) { 353 | $mapInner = $innerMappings[$destKey]; 354 | } 355 | 356 | if (property_exists($sourceObject, $key)) { 357 | 358 | if (isset($sourceObject->{$key})) { 359 | 360 | if (isset($mapInner) && is_object($sourceObject->{$key})) { 361 | $source = $sourceObject->{$key}; 362 | $target = new $mapInner; 363 | $targetObject->{$destKey} = self::autoMapper($source, $target, $nosanear); 364 | } 365 | else if (isset($mapInner) && is_array($sourceObject->{$key})) { 366 | $propArray = []; 367 | foreach($sourceObject->{$key} as $source) { 368 | $target = new $mapInner; 369 | array_push($propArray, self::autoMapper($source, $target, $nosanear)); 370 | } 371 | $targetObject->{$destKey} = $propArray; 372 | } 373 | else { 374 | $targetObject->$destKey = Utils::sanearVariables($sourceObject->{$key}, (strtoupper($key) == 'HTML') || $nosanear, $mapInner); 375 | } 376 | } 377 | } 378 | else if (isset($sourceObject->{$key})) { 379 | 380 | if (isset($mapInner) && is_object($sourceObject->{$key})) { 381 | $source = $sourceObject->{$key}; 382 | $target = new $mapInner; 383 | $targetObject->$destKey = self::autoMapper($source, $target, $nosanear); 384 | } 385 | else if (isset($mapInner) && is_array($sourceObject->{$key})) { 386 | $propArray = []; 387 | foreach($sourceObject->{$key} as $source) { 388 | $target = new $mapInner; 389 | array_push($propArray, self::autoMapper($source, $target, $nosanear)); 390 | } 391 | $targetObject->$destKey = $propArray; 392 | } 393 | else { 394 | $targetObject->$destKey = Utils::sanearVariables($sourceObject->{$key}, (strtoupper($key) == 'HTML') || $nosanear, $mapInner); 395 | } 396 | } 397 | } 398 | } 399 | 400 | return $targetObject; 401 | } 402 | 403 | private static function removePrefix($key) { 404 | 405 | // encontrar la posición del punto de separacion 406 | $parts = explode('.', $key); 407 | 408 | if (count($parts) > 1) 409 | return $parts[count($parts)-1]; 410 | else 411 | return $key; 412 | } 413 | 414 | public static function ToDto($entity, $dtoName, $innerMappings = [], $nosanear = false) 415 | { 416 | if ($entity === null) 417 | return null; 418 | 419 | return self::autoMapper( 420 | sourceObject: $entity, 421 | targetObject: new $dtoName, 422 | innerMappings: $innerMappings, 423 | nosanear: $nosanear) 424 | ; 425 | } 426 | 427 | public static function ToEntity($dto, $entityName, $removePrefix = false, $nosanear = false) 428 | { 429 | if ($dto === null) 430 | return null; 431 | 432 | return self::autoMapper($dto, new $entityName, $nosanear); 433 | } 434 | 435 | public static function TransposeToArray($dtoArray, $columnId, $columnName) : array { 436 | 437 | if ($dtoArray == null || count($dtoArray) == 0) 438 | return []; 439 | 440 | // Crear las columnas que tendrá el arreglo resultante 441 | $columns = []; 442 | foreach($dtoArray as $dto) { 443 | if (isset($dto->$columnName)) { 444 | if (!isset($columns[$dto->$columnName])) { 445 | $columns[$dto->$columnName] = $dto->$columnName; 446 | } 447 | } 448 | } 449 | 450 | // Crear las filas que tendrá el arreglo resultante 451 | $pivot = $dtoArray[0]; 452 | $props = get_object_vars($pivot); 453 | 454 | $rows = []; 455 | foreach($props as $prop => $value) { 456 | $rows[] = $prop; 457 | } 458 | 459 | $output = []; 460 | foreach($dtoArray as $dto) { 461 | 462 | foreach($rows as $row) { 463 | 464 | if ($row == $columnId || $row == $columnName || strtolower($row) == 'periodo') { 465 | continue; 466 | } 467 | 468 | $id = $dto->$columnId; 469 | $field = $dto->$columnName; 470 | 471 | if (!isset($output[$row])) { 472 | $output[$row] = []; 473 | } 474 | 475 | $output[$row][$field] = $dto->$row; 476 | 477 | } 478 | 479 | } 480 | 481 | return $output; 482 | } 483 | 484 | public static function GroupToDtos($items, $groupingColumnName, $indexColumnName, $dtoName) : array { 485 | 486 | $dtos = []; 487 | 488 | foreach($items as $dto) { 489 | 490 | if (!isset($dtos[$dto->$groupingColumnName])) { 491 | $dtos[$dto->$groupingColumnName] = []; 492 | } 493 | 494 | if (isset($indexColumnName) && $indexColumnName != '') { 495 | $dtos[$dto->$groupingColumnName][$dto->$indexColumnName] = $dto; 496 | } 497 | else { 498 | $dtos[$dto->$groupingColumnName][] = $dto; 499 | } 500 | } 501 | 502 | $result = []; 503 | foreach($dtos as $group) { 504 | $item = new GenericCollection( 505 | Key: $indexColumnName, 506 | DtoName: $dtoName, 507 | Values: $group 508 | ); 509 | 510 | $item->Reindex(); 511 | $r = $item->First(); 512 | $result[] = $item; 513 | } 514 | 515 | return $result; 516 | } 517 | 518 | public static function TransposeToDtos($dtoArray, $columnId, $columnName, $dtoName) : GenericCollection { 519 | 520 | $elements = self::TransposeToArray($dtoArray, $columnId, $columnName); 521 | $result = []; 522 | 523 | foreach($elements as $column => $element) { 524 | 525 | $item = new $dtoName(); 526 | $item->$columnName = $column; 527 | 528 | foreach($element as $field => $val) { 529 | $item->$field = $val; 530 | } 531 | 532 | $result[] = $item; 533 | } 534 | 535 | $data = new GenericCollection( 536 | DtoName: $dtoName, 537 | Key: $columnName, 538 | Values: $result 539 | ); 540 | 541 | return $data; 542 | 543 | } 544 | 545 | public static function ToDtos($entityArray, $dtoName, $innerMappings = [], $avoidNull = false, $nosanear = false, $aplicarTope = true, $ramSinTope = IniEnum::MEM_2G) 546 | { 547 | if ($entityArray == null || count($entityArray) == 0) { 548 | if (!($avoidNull)) { 549 | return null; 550 | } 551 | } 552 | 553 | $cant = isset($entityArray) ? count($entityArray) : 0; 554 | 555 | if ($cant < 3000) { 556 | // no hacemos nada 557 | } 558 | else if ($cant < 5000) { 559 | // aumentar RAM 560 | Ini::Instance()->Change(IniEnum::MEMORY_LIMIT, IniEnum::MEM_256M); 561 | } 562 | else if ($cant < 10000) { 563 | Ini::Instance()->Change(IniEnum::MEMORY_LIMIT, IniEnum::MEM_512M); 564 | } 565 | else if ($cant < 30000) { 566 | Ini::Instance()->Change(IniEnum::MEMORY_LIMIT, IniEnum::MEM_1G); 567 | } 568 | else { 569 | if ($aplicarTope) { 570 | // demasiados registros!! 571 | throw new Exception('La consulta ha retornado demasiados registros: ' . $cant); 572 | } 573 | else { 574 | Ini::Instance()->Change(IniEnum::MEMORY_LIMIT, $ramSinTope); 575 | } 576 | } 577 | 578 | $dtos = array(); 579 | 580 | if (isset($entityArray) && count($entityArray) > 0) { 581 | foreach($entityArray as $entity) { 582 | array_push($dtos, self::autoMapper( 583 | sourceObject: $entity, 584 | targetObject: new $dtoName, 585 | innerMappings: $innerMappings, 586 | nosanear: $nosanear 587 | )); 588 | } 589 | } 590 | else { 591 | if (!($avoidNull)) { 592 | return null; 593 | } 594 | else { 595 | $dtos = []; 596 | } 597 | } 598 | 599 | //$entityDefinition = EntityDefinition::GetInstance(new \ReflectionClass($entity)); 600 | if (!isset($entity)) { 601 | // crear un objeto 602 | $entity = new $dtoName(); 603 | } 604 | 605 | $entityDefinition = EntityDefinition::Instance(get_class($entity)); 606 | 607 | return new GenericCollection( 608 | Values : $dtos, 609 | Key : $entityDefinition->Key, 610 | DtoName : $dtoName 611 | ); 612 | } 613 | 614 | public static function ToEntities($dtoArray, $entityName, $honorPrefix = '', $useTargetProperties = false, $nosanear = false) 615 | { 616 | if ($dtoArray == null) 617 | return null; 618 | 619 | $entities = array(); 620 | 621 | foreach($dtoArray as $dto) { 622 | array_push($entities, self::autoMapper($dto, new $entityName, $nosanear, $honorPrefix, $useTargetProperties)); 623 | } 624 | 625 | return $entities; 626 | } 627 | 628 | public static function EvaluateKeyMultilevel($value, $key) { 629 | 630 | // Ver la cantidad de niveles 631 | $existePunto = strpos($key, '.'); 632 | $existeFlecha = strpos($key, '->'); 633 | 634 | if ($existePunto === false && $existeFlecha === false) { 635 | //no hay mas niveles, devolver la evaluación directa 636 | return $value->$key; 637 | } 638 | else { 639 | $separador = ($existePunto === false) ? '->' : '.'; 640 | 641 | // Obtener el objeto principal 642 | $parts = explode($separador, $key); 643 | $mainPart = $parts[0]; 644 | 645 | $mainSeccion = $value->$mainPart; 646 | 647 | // Obtener el siguiente nivel 648 | $levelKey = self::EvaluateKeyMultilevel($mainSeccion, $parts[1]); 649 | 650 | return $levelKey; 651 | } 652 | 653 | } 654 | 655 | public static function Convert($sourceObject, $className, array $dictionary, array $convert = [], string $inputFormat = 'd/m/Y', $outputFormat = 'Y-m-d') { 656 | 657 | $targetObject = new $className; 658 | $vars = get_object_vars($sourceObject); 659 | 660 | foreach ($vars as $sKey => $value) { 661 | 662 | $key = $sKey; 663 | 664 | if (!isset($dictionary[$key])) { 665 | $destKey = $key; 666 | } 667 | else { 668 | $destKey = $dictionary[$key]; 669 | } 670 | 671 | if (in_array($key, $convert)) { 672 | 673 | if (!isset($value) || $value == '') { 674 | $value = null; 675 | } 676 | else { 677 | $fec = Date::createFromFormat($inputFormat, $value); 678 | $value = $fec->format($outputFormat); 679 | } 680 | } 681 | 682 | $targetObject->$destKey = $value; 683 | } 684 | 685 | return $targetObject; 686 | } 687 | 688 | public static function ConvertMultiple(array $sourceObjects, $className, array $dictionary, array $convert = [], string $inputFormat = 'd/m/Y', $outputFormat = 'Y-m-d') { 689 | 690 | $result = []; 691 | 692 | foreach($sourceObjects as $object) { 693 | $result[] = self::Convert($object, $className, $dictionary, $convert, $inputFormat, $outputFormat); 694 | } 695 | 696 | return $result; 697 | 698 | } 699 | 700 | 701 | 702 | } 703 | -------------------------------------------------------------------------------- Total de líneas: 703 ================================================================================ ================================================================================ ARCHIVO #197: src/Mapping/BaseMapper.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Mapping/BaseMapper.php Tamaño: 697 bytes -------------------------------------------------------------------------------- 1 | $value) { 23 | 24 | if (isset($this->sourceObject->$var)) { 25 | $new->$var = $this->sourceObject->$var; 26 | } 27 | } 28 | 29 | return $new; 30 | } 31 | } -------------------------------------------------------------------------------- Total de líneas: 31 ================================================================================ ================================================================================ ARCHIVO #198: src/Mapping/Reflect.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Mapping/Reflect.php Tamaño: 654 bytes -------------------------------------------------------------------------------- 1 | $value) { 21 | 22 | $result[] = (object)[ 23 | 'PropertyName' => $var, 24 | 'Value' => $value, 25 | ]; 26 | } 27 | 28 | return $result; 29 | } 30 | } -------------------------------------------------------------------------------- Total de líneas: 30 ================================================================================ ================================================================================ ARCHIVO #199: src/Math/Modulo.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Math/Modulo.php Tamaño: 1012 bytes -------------------------------------------------------------------------------- 1 | cociente; 22 | case "Resto" : return $this->resto; 23 | default : return null; 24 | } 25 | } 26 | 27 | private function __construct(int $cociente, int $resto) 28 | { 29 | $this->cociente = $cociente; 30 | $this->resto = $resto; 31 | } 32 | 33 | public static function Calc(int $dividendo = 0, int $divisor = 1) { 34 | 35 | if ($divisor == 0) return null; 36 | 37 | $_resto = $dividendo % $divisor; 38 | $_cociente = ($dividendo - $_resto) / $divisor; 39 | 40 | return new Modulo( 41 | cociente: $_cociente, resto: $_resto 42 | ); 43 | } 44 | } -------------------------------------------------------------------------------- Total de líneas: 44 ================================================================================ ================================================================================ ARCHIVO #200: src/Mensajes/Mensaje.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Mensajes/Mensaje.php Tamaño: 7.58 KB -------------------------------------------------------------------------------- 1 | idioma)) 36 | $language = Session::Instance()->idioma; 37 | else 38 | $language = DEFAULT_LANGUAGE; 39 | } 40 | 41 | if (!isset(Session::Instance()->producto)) 42 | $producto = DEFAULT_PRODUCT; 43 | else 44 | $producto = Session::Instance()->producto; 45 | 46 | if (isset(self::$replacements[$producto])) { 47 | $producto = self::$replacements[$producto]; 48 | } 49 | 50 | $key = $producto . '_' . $language; 51 | 52 | //$mensajes = null; 53 | if (strpos($messageID, ",") !== false) { 54 | $split = explode(',', $messageID); 55 | $messageID = $split[0]; 56 | } 57 | 58 | $mensajes = self::ObtenerMensajes($messageID); 59 | 60 | // Existe el contenido en memoria? 61 | if (!isset($mensajes)) { 62 | return "No se han definido mensajes"; 63 | } 64 | 65 | if (isset($mensajes->$key)) { 66 | return $mensajes->$key; 67 | } 68 | else { 69 | if ( is_array($mensajes) && isset($mensajes[$producto . '_en'])) { 70 | return $mensajes[$producto . '_en']; 71 | } 72 | else { 73 | return null; 74 | } 75 | } 76 | } 77 | 78 | public static function ObtenerMensajes($messageID) { 79 | 80 | $mensajes = MensajeConfig::Instance(); 81 | 82 | if (isset($mensajes[$messageID])) { 83 | // Completar idioma que no esté definido 84 | $idiomas = self::ObtenerIdiomas(); 85 | $productos = self::ObtenerProductos(); 86 | 87 | foreach($productos as $producto) { 88 | foreach($idiomas as $idioma => $nombreIdioma) { 89 | $buscado = $producto . '_' . $idioma; 90 | if (!isset($mensajes[$messageID]->$buscado)) 91 | $mensajes[$messageID]->$buscado = ""; 92 | } 93 | } 94 | 95 | return $mensajes[$messageID]; 96 | } 97 | else { 98 | $result = array(); 99 | $idiomas = self::ObtenerIdiomas(); 100 | $productos = self::ObtenerProductos(); 101 | 102 | foreach($productos as $producto) { 103 | foreach($idiomas as $idioma => $nombreIdioma) { 104 | $result[$producto . '_' . $idioma] = ""; 105 | } 106 | } 107 | 108 | return $result; 109 | } 110 | } 111 | 112 | public static function MensajeDefinidoCompleto($messageID) { 113 | $mens = self::ObtenerMensajes($messageID); 114 | $mensajes =(array)$mens; 115 | 116 | if (isset($mensajes) && count($mensajes) > 0) { 117 | foreach($mensajes as $mensaje) { 118 | if (trim($mensaje) == "") { 119 | return false; 120 | } 121 | } 122 | } 123 | else { 124 | return false; 125 | } 126 | 127 | return true; 128 | } 129 | 130 | public static function ActualizarMensaje($messageID, $entries, $idioma) { 131 | 132 | $mensajes = MensajeConfig::Instance(); 133 | 134 | // Obtener todos los mensajes 135 | if (isset($mensajes)) { 136 | 137 | foreach($entries as $entry) { 138 | $locale = $entry[0]; 139 | $mensaje = $entry[1]; 140 | 141 | if (!isset($mensajes[$messageID])) { 142 | $mensajes[$messageID] = new \stdClass(); 143 | } 144 | 145 | $mensajes[$messageID]->$locale = $mensaje; 146 | } 147 | 148 | $json = json_encode($mensajes); 149 | 150 | // Actualizar el archivo de mensajes 151 | $mensajesFilePath = SITE_ROOT . "/Application/Configuration/mensajes.config.json"; 152 | file_put_contents($mensajesFilePath, $json); 153 | 154 | // Volver a cargar la matriz de mensajes en memoria 155 | Loaders::CargarMensajes($mensajesFilePath); 156 | } 157 | else { 158 | return false; 159 | } 160 | 161 | self::ActualizarIdiomaFuncionalidades($idioma, $locale); 162 | 163 | return true; 164 | } 165 | 166 | public static function ActualizarIdiomaFuncionalidades($idioma, $locale) { 167 | 168 | // Por si se han tocado textos de menú, es necesario recargar las funcionalidades del usuario 169 | // para que tome los nuevos valores definidos en los mensajes 170 | Loaders::CargarFuncionalidades(__DIR__ . "/../../funcionalidades.config.json"); 171 | 172 | $usuario = (isset(Session::Instance()->usuario)) ? Session::Instance()->usuario : null; 173 | 174 | if (isset($usuario)) { 175 | $perfil = $usuario->Perfil; 176 | 177 | if (isset($perfil)) { 178 | //$funcs = MenuConfig::FilterUserMenu($perfil->Roles, $GLOBALS['router']); 179 | $funcs = MenuConfig::FilterUserMenu($GLOBALS['router'], $idioma, $locale); 180 | $usuario->Funcionalidades = $funcs; 181 | 182 | Session::Instance()->usuario = $usuario; 183 | } 184 | } 185 | } 186 | 187 | public static function ObtenerIdiomas() { 188 | $listaIdiomas = SystemConfig::Instance()->Languages; 189 | $definicionesIdiomas = explode(',', $listaIdiomas); 190 | 191 | $idiomas = array(); 192 | 193 | foreach($definicionesIdiomas as $definicionIdioma) { 194 | $def = explode(':', $definicionIdioma); 195 | 196 | $idiomas[$def[0]] = $def[1]; 197 | } 198 | 199 | return $idiomas; 200 | } 201 | 202 | public static function ObtenerProductos() { 203 | $listaProductos = SystemConfig::Instance()->Producto; 204 | return explode(',', $listaProductos); 205 | } 206 | 207 | public static function ActualizarIdiomas() { 208 | 209 | $productos = self::ObtenerProductos(); 210 | $idiomas = self::ObtenerIdiomas(); 211 | 212 | // Crear los entries 213 | $entries = array(); 214 | foreach ($productos as $producto) { 215 | foreach ($idiomas as $codigo=>$nombre) { 216 | array_push($entries, $producto . '_' . $codigo); 217 | } 218 | } 219 | 220 | if (isset($GLOBALS['conn_mensajes'])) { 221 | $mensajes = $GLOBALS['conn_mensajes']; 222 | 223 | // Leer cada mensaje 224 | foreach($mensajes as $messageID => $mensaje) { 225 | // Para cada mensaje, se debe ver si existe cada producto_idioma 226 | $mensajes[$messageID]['PSTORE_es'] = $mensajes[$messageID][DEFAULT_PRODUCT . '_es']; 227 | $mensajes[$messageID]['PSTORE_en'] = $mensajes[$messageID][DEFAULT_PRODUCT . '_en']; 228 | 229 | // foreach ($entries as $entry) { 230 | // if (!isset($mensajes[$messageID][$entry])) { 231 | // $mensajes[$messageID][$entry] = ''; 232 | // } 233 | // } 234 | } 235 | 236 | $json = json_encode($mensajes); 237 | 238 | // Actualizar el archivo de mensajes 239 | $mensajesFilePath = __DIR__ . "/../../mensajes.config.json"; 240 | file_put_contents($mensajesFilePath, $json); 241 | 242 | // Volver a cargar la matriz de mensajes en memoria 243 | Loaders::CargarMensajes($mensajesFilePath); 244 | } 245 | else { 246 | return false; 247 | } 248 | } 249 | } -------------------------------------------------------------------------------- Total de líneas: 249 ================================================================================ ================================================================================ ARCHIVO #201: src/Mensajes/MensajeDto.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Mensajes/MensajeDto.php Tamaño: 356 bytes -------------------------------------------------------------------------------- 1 | Filename = $filename; 52 | $this->DtoName = $dtoName; 53 | $this->RowsIgnored = $rowsIgnored; 54 | $this->FieldRowExists = $fieldRowExists; 55 | $this->Delimiter = $delimiter; 56 | $this->Enclosure = $enclosure; 57 | $this->Escape = $escape; 58 | 59 | if (!file_exists($filename)) { 60 | throw new RuntimeException("El archivo no está disponible: " . $filename); 61 | } 62 | 63 | // Configurar UTF-8 si mbstring está disponible 64 | if (extension_loaded('mbstring')) { 65 | mb_internal_encoding("UTF-8"); 66 | } 67 | 68 | // Inicializar nombres de campo desde el DTO 69 | foreach(get_class_vars($dtoName) as $key => $value) { 70 | array_push($this->FieldNames, $key); 71 | } 72 | } 73 | 74 | /** 75 | * Método estático para crear una instancia de BigCsvSql. 76 | * 77 | * @param string $filename Ruta al archivo CSV. 78 | * @param string $dtoName Nombre completamente cualificado de la clase DTO. 79 | * @param int $rowsIgnored Número de filas a ignorar al inicio. 80 | * @param bool $fieldRowExists Indica si la primera fila contiene los nombres de los campos. 81 | * @param string $delimiter Delimitador del CSV. 82 | * @param string $enclosure Caracter de encierro. 83 | * @param string $escape Caracter de escape. 84 | * @return BigCsvSql 85 | * @throws \InvalidArgumentException Si el archivo no existe. 86 | */ 87 | public static function FromFile( 88 | string $filename, 89 | string $dtoName, 90 | int $rowsIgnored = 1, 91 | bool $fieldRowExists = true, 92 | string $delimiter = ',', 93 | string $enclosure = '"', 94 | string $escape = '\\' 95 | ): BigCsvSql { 96 | if (!file_exists($filename)) { 97 | throw new \InvalidArgumentException("El archivo CSV no existe en la ruta: " . $filename); 98 | } 99 | 100 | return new self($filename, $dtoName, $rowsIgnored, $fieldRowExists, $delimiter, $enclosure, $escape); 101 | } 102 | 103 | /** 104 | * Detecta automáticamente el delimitador del CSV analizando las primeras líneas. 105 | * 106 | * @param int $linesToCheck Número de líneas a analizar. 107 | * @return string El delimitador más probable. 108 | */ 109 | public function DetectDelimiter(int $linesToCheck = 5): string { 110 | $delimiters = [',', ';', '\t', '|']; 111 | $delimiterCounts = []; 112 | 113 | $handle = fopen($this->Filename, 'r'); 114 | if (!$handle) { 115 | throw new RuntimeException("No se pudo abrir el archivo CSV: " . $this->Filename); 116 | } 117 | 118 | $linesRead = 0; 119 | while (($line = fgets($handle)) !== false && $linesRead < $linesToCheck) { 120 | foreach ($delimiters as $delimiter) { 121 | $actualDelimiter = ($delimiter === '\t') ? "\t" : $delimiter; 122 | $count = substr_count($line, $actualDelimiter); 123 | $delimiterCounts[$delimiter] = ($delimiterCounts[$delimiter] ?? 0) + $count; 124 | } 125 | $linesRead++; 126 | } 127 | fclose($handle); 128 | 129 | // Retorna el delimitador con mayor frecuencia 130 | arsort($delimiterCounts); 131 | $bestDelimiter = array_key_first($delimiterCounts); 132 | 133 | return ($bestDelimiter === '\t') ? "\t" : $bestDelimiter; 134 | } 135 | 136 | /** 137 | * Procesa el archivo CSV fila por fila con callbacks. 138 | * 139 | * @param bool $breakOnEmptyRow Si es true, detiene el procesamiento al encontrar una fila vacía. 140 | * @param callable|null $saveRowCallback Callback para procesar cada objeto DTO. 141 | * @param mixed $payload Datos adicionales para los callbacks. 142 | * @param callable|null $errorRowCallback Callback para manejar errores. 143 | * @param callable|null $validateRowCallback Callback para validar filas. 144 | * @param int $bufferSize Tamaño del buffer de lectura en bytes (default 8KB). 145 | * @throws RuntimeException Para errores durante la lectura. 146 | */ 147 | public function ProcessRows( 148 | bool $breakOnEmptyRow = false, 149 | ?callable $saveRowCallback = null, 150 | $payload = null, 151 | ?callable $errorRowCallback = null, 152 | ?callable $validateRowCallback = null, 153 | int $bufferSize = 8192 154 | ): void { 155 | $handle = fopen($this->Filename, 'r'); 156 | if (!$handle) { 157 | throw new RuntimeException("No se pudo abrir el archivo CSV: " . $this->Filename); 158 | } 159 | 160 | // Optimización: aumentar buffer de lectura 161 | if (stream_set_read_buffer($handle, $bufferSize) !== 0) { 162 | error_log("Advertencia: No se pudo configurar el buffer de lectura"); 163 | } 164 | 165 | $rowIndex = 0; 166 | $totalRowsProcessed = 0; 167 | 168 | while (($csvRow = fgetcsv($handle, 0, $this->Delimiter, $this->Enclosure, $this->Escape)) !== false) { 169 | $rowIndex++; 170 | 171 | // Ignorar filas iniciales 172 | if ($rowIndex <= $this->RowsIgnored) { 173 | continue; 174 | } 175 | 176 | $totalRowsProcessed++; 177 | 178 | // Manejar filas vacías 179 | if ($breakOnEmptyRow && (empty($csvRow) || (count($csvRow) === 1 && empty($csvRow[0])))) { 180 | break; 181 | } 182 | 183 | try { 184 | // Si es la primera fila de datos y contiene nombres de campos 185 | if ($this->FieldRowExists && $totalRowsProcessed === 1) { 186 | // Actualizar nombres de campo desde el CSV si es necesario 187 | // Por simplicidad, mantenemos los nombres del DTO 188 | continue; 189 | } 190 | 191 | // Mapear valores CSV a propiedades del DTO 192 | $parsedRowData = []; 193 | foreach ($this->FieldNames as $colIndex => $fieldName) { 194 | $parsedRowData[$fieldName] = $csvRow[$colIndex] ?? null; 195 | } 196 | 197 | // Validación si está definida 198 | if ($validateRowCallback !== null) { 199 | if (!call_user_func($validateRowCallback, $parsedRowData, $rowIndex, $payload)) { 200 | continue; 201 | } 202 | } 203 | 204 | // Crear y poblar el objeto DTO 205 | $dto = new $this->DtoName(); 206 | foreach ($parsedRowData as $propertyName => $value) { 207 | if (property_exists($dto, $propertyName)) { 208 | try { 209 | // Convertir valores vacíos o manejo de tipos 210 | if ($value === '' || $value === null) { 211 | $dto->$propertyName = null; 212 | } elseif (is_numeric($dto->$propertyName) && !is_numeric($value)) { 213 | // No asignar valor no numérico a propiedad numérica 214 | } else { 215 | // Limpiar y asignar el valor 216 | $cleanValue = trim($value); 217 | $dto->$propertyName = $cleanValue; 218 | } 219 | } catch (\TypeError $ex) { 220 | // Manejar errores de tipo silenciosamente 221 | } catch (\Exception $ex) { 222 | // Log otros errores si es necesario 223 | } 224 | } 225 | } 226 | 227 | // Invocar callback para guardar/procesar la fila 228 | if ($saveRowCallback !== null) { 229 | call_user_func($saveRowCallback, $dto, $payload); 230 | } 231 | 232 | } catch (\Throwable $e) { 233 | if ($errorRowCallback !== null) { 234 | call_user_func($errorRowCallback, $e, $rowIndex, $parsedRowData ?? [], $payload); 235 | } else { 236 | throw new RuntimeException( 237 | "Error procesando fila {$rowIndex} del CSV: " . $e->getMessage(), 238 | $e->getCode(), 239 | $e 240 | ); 241 | } 242 | } 243 | } 244 | 245 | fclose($handle); 246 | } 247 | 248 | /** 249 | * Obtiene información básica del archivo CSV. 250 | * 251 | * @return array Array con información del archivo (filas totales, columnas, etc.). 252 | */ 253 | public function GetFileInfo(): array { 254 | $handle = fopen($this->Filename, 'r'); 255 | if (!$handle) { 256 | throw new RuntimeException("No se pudo abrir el archivo CSV: " . $this->Filename); 257 | } 258 | 259 | $totalRows = 0; 260 | $maxColumns = 0; 261 | $firstRow = null; 262 | 263 | while (($csvRow = fgetcsv($handle, 0, $this->Delimiter, $this->Enclosure, $this->Escape)) !== false) { 264 | $totalRows++; 265 | $columnCount = count($csvRow); 266 | 267 | if ($columnCount > $maxColumns) { 268 | $maxColumns = $columnCount; 269 | } 270 | 271 | if ($firstRow === null) { 272 | $firstRow = $csvRow; 273 | } 274 | } 275 | 276 | fclose($handle); 277 | 278 | return [ 279 | 'total_rows' => $totalRows, 280 | 'max_columns' => $maxColumns, 281 | 'first_row' => $firstRow, 282 | 'file_size' => filesize($this->Filename), 283 | 'delimiter' => $this->Delimiter 284 | ]; 285 | } 286 | 287 | /** 288 | * Valida que el archivo CSV tenga la estructura esperada. 289 | * 290 | * @param int $expectedColumns Número esperado de columnas. 291 | * @return bool True si es válido, false en caso contrario. 292 | */ 293 | public function ValidateStructure(int $expectedColumns = null): bool { 294 | $handle = fopen($this->Filename, 'r'); 295 | if (!$handle) { 296 | return false; 297 | } 298 | 299 | $isValid = true; 300 | $rowIndex = 0; 301 | 302 | while (($csvRow = fgetcsv($handle, 0, $this->Delimiter, $this->Enclosure, $this->Escape)) !== false) { 303 | $rowIndex++; 304 | 305 | if ($expectedColumns !== null && count($csvRow) !== $expectedColumns) { 306 | $isValid = false; 307 | break; 308 | } 309 | } 310 | 311 | fclose($handle); 312 | return $isValid; 313 | } 314 | } -------------------------------------------------------------------------------- Total de líneas: 314 ================================================================================ ================================================================================ ARCHIVO #204: src/OfficeHelper/BigExcel copy.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/OfficeHelper/BigExcel copy.php Tamaño: 35.26 KB -------------------------------------------------------------------------------- 1 | Filename = $filename; 49 | $this->DtoName = $dtoName; 50 | $this->Extension = $extension; 51 | $this->RowsIgnored = $rowsIgnored; 52 | $this->FieldRowExists = $fieldRowExists; 53 | 54 | // Procesamos el archivo para extraer las hojas en xml 55 | if (!file_exists($filename)) { 56 | throw new RuntimeException("El archivo no está disponible o no se ha cargado correctamente"); 57 | } 58 | 59 | $this->ConfigurarXlsx($filename); 60 | } 61 | 62 | private function ConfigurarXlsx($filename) { 63 | 64 | $excelInfo = $this->DescomprimirXlsx($filename); 65 | $excelInfo = $this->PrepararHojas($excelInfo); 66 | 67 | $stop = 1; 68 | 69 | } 70 | 71 | /** 72 | * Descomprime un archivo XLSX en una carpeta temporal única, 73 | * ubicada en el mismo directorio que el XLSX original, y devuelve 74 | * un objeto con información detallada de la descompresión. 75 | * 76 | * NOTA: Esta función crea una carpeta temporal. Eres responsable 77 | * de limpiar esta carpeta ($info->WorkingFolder) después de usarla. 78 | * Se recomienda usar un bloque try...finally en tu código principal 79 | * para asegurar la limpieza, llamando a FileHelper::removeDir(). 80 | * 81 | * @param string $filename La ruta completa al archivo XLSX. 82 | * @return ExcelUnzipInfo Un objeto que contiene la ruta de la carpeta de trabajo, 83 | * la ruta de la carpeta 'xl', y los nombres de archivo de cada hoja XML. 84 | * @throws RuntimeException Si el archivo XLSX no existe, la carpeta no se puede crear, o la descompresión falla. 85 | */ 86 | function DescomprimirXlsx(string $filename): ExcelUnzipInfo { 87 | 88 | // 1. Validar que el archivo XLSX exista. 89 | if (!file_exists($filename)) { 90 | throw new RuntimeException("Error: El archivo XLSX no existe en la ruta: " . $filename); 91 | } 92 | 93 | // 2. Determinar la ruta de la carpeta de trabajo temporal única. 94 | $path = (object)pathinfo($filename, PATHINFO_ALL); 95 | 96 | $excelDirectory = $path->dirname; // pathinfo($filename, PATHINFO_DIRNAME); 97 | $workingFolder = $excelDirectory . DIRECTORY_SEPARATOR . $path->filename . '_' . uniqid(); 98 | 99 | // 3. Crear la carpeta temporal. ¡Este paso es crucial! 100 | if (!mkdir($workingFolder, 0777, true)) { 101 | throw new RuntimeException("No se pudo crear la carpeta temporal: " . $workingFolder . ". Verifique los permisos."); 102 | } 103 | 104 | // 4. Escapar las rutas para el comando shell. 105 | $escapedFilename = escapeshellarg($filename); 106 | $escapedWorkingFolder = escapeshellarg($workingFolder); 107 | 108 | // 5. Construir y ejecutar el comando unzip. 109 | $command = "unzip -o {$escapedFilename} -d {$escapedWorkingFolder}"; 110 | 111 | $output = []; 112 | $return_var = 0; 113 | exec($command, $output, $return_var); 114 | 115 | // 6. Verificar el resultado de la descompresión. 116 | if ($return_var !== 0) { 117 | // Si falla la descompresión, intentar limpiar la carpeta que se creó. 118 | FileHelper::removeDir($workingFolder); // <--- ¡Llamada correcta a tu método estático! 119 | $errorMsg = "Error al descomprimir el archivo XLSX. Código de retorno: {$return_var}. Salida: " . implode("\n", $output); 120 | throw new RuntimeException($errorMsg); 121 | } 122 | 123 | // 7. Recopilar la información para el objeto ExcelUnzipInfo. 124 | $xlFolder = $workingFolder . DIRECTORY_SEPARATOR . 'xl'; 125 | $sharedStringsFilename = $xlFolder . "/sharedStrings.xml"; 126 | $sheetXmlsDir = $xlFolder . DIRECTORY_SEPARATOR . 'worksheets'; 127 | $sheetFilenames = []; 128 | 129 | // Encontrar los archivos XML que constituyen las hojas del excel 130 | // 131 | if (is_dir($sheetXmlsDir)) { 132 | $files = scandir($sheetXmlsDir); 133 | foreach ($files as $file) { 134 | 135 | $path = (object)pathinfo($file, PATHINFO_ALL); 136 | 137 | // Asegurarse de que sea un archivo XML y no un directorio o '.'/'..' 138 | if ($path->extension === 'xml' && is_file($sheetXmlsDir . DIRECTORY_SEPARATOR . $file)) { 139 | $fullSheetPath = $sheetXmlsDir . DIRECTORY_SEPARATOR . $file; 140 | // Intentar leer las primeras líneas o buscar la etiqueta 141 | // Para archivos grandes, es mejor no leer todo el contenido. 142 | // Usamos file_get_contents con un límite para verificar la cabecera. 143 | $fileContentPreview = file_get_contents($fullSheetPath, false, null, 0, 1024); // Leer los primeros 1KB 144 | 145 | if ($fileContentPreview !== false && str_contains($fileContentPreview, 'filename] = $fullSheetPath; 147 | $rowsFilename[$path->filename] = ''; 148 | } 149 | } 150 | } 151 | // Opcional: Ordenar los nombres de archivo si el orden es importante, 152 | // aunque con nombres arbitrarios el orden natural de `sheet1.xml` a `sheet2.xml` 153 | // ya no aplica. Podrías ordenarlos alfabéticamente si lo deseas. 154 | //sort($sheetFilenames, SORT_NATURAL); 155 | } 156 | 157 | // 8. Crear y devolver el objeto ExcelUnzipInfo. 158 | return new ExcelUnzipInfo( 159 | $filename, 160 | $workingFolder, 161 | $xlFolder, 162 | $sharedStringsFilename, 163 | $sheetFilenames, 164 | $rowsFilename 165 | ); 166 | } 167 | 168 | 169 | function CmdGetDimension($escapedSheetPath, $escapedFinalRowsPath) { 170 | 171 | // --- 1. Extraer los datos de --- 172 | // Buscamos la primera ocurrencia de en un solo paso --- 185 | $commandProcessRows = sprintf( 186 | 'sed "s||\\n|g" %s | grep \' %s', // Quité el -e 187 | $escapedSheetPath, 188 | $escapedFinalRowsPath 189 | ); 190 | 191 | $output = []; 192 | $return_var = 0; 193 | exec($commandProcessRows, $output, $return_var); 194 | 195 | if ($return_var !== 0) { 196 | $errorMsg = "Error al procesar/filtrar las etiquetas "; 197 | throw new RuntimeException($errorMsg); 198 | } 199 | 200 | return $return_var; 201 | } 202 | 203 | function CmdProcessRows($escapedSheetPath, $escapedFinalRowsPath, $tempSheetPath, $finalRowsPath) { 204 | 205 | $commandProcessRows = sprintf( 206 | 'sed "s||\\n|g" %s | grep \' %s', 207 | $escapedSheetPath, 208 | $escapedFinalRowsPath 209 | ); 210 | 211 | $output = []; 212 | $return_var = 0; 213 | exec($commandProcessRows, $output, $return_var); 214 | 215 | if ($return_var !== 0) { 216 | // Si el proceso falla, intentar limpiar el archivo temporal si se creó. 217 | if (file_exists($tempSheetPath)) { 218 | unlink($tempSheetPath); 219 | } 220 | if (file_exists($finalRowsPath)) { 221 | unlink($finalRowsPath); 222 | } 223 | $errorMsg = "Error al procesar/filtrar las etiquetas "; 224 | throw new RuntimeException($errorMsg); 225 | } 226 | } 227 | 228 | function CmdProcessFixedLen($excelUnzipInfo, $tempSheetPath, $finalRowsPath) { 229 | $sharedStringsFilename = $excelUnzipInfo->SharedStringsFilename; 230 | $finalStringsFilename = $sharedStringsFilename . ".vars"; 231 | $sharedStringsFixedLenFile = $sharedStringsFilename . ".vars_fixedlen"; 232 | 233 | // El comando BASH necesita que las rutas de los archivos sean pasadas como argumentos, 234 | // o que se usen directamente dentro de la cadena si ya están escapadas y seguras. 235 | // En este caso, usaremos los marcadores de posición %s para las rutas. 236 | $commandProcessStrings = sprintf( 237 | 'sed "s||\\n|g; s||\\n|g" %s | grep \'\' > %s', // Quité el -e de grep 238 | escapeshellarg($sharedStringsFilename), 239 | escapeshellarg($finalStringsFilename) 240 | ); 241 | 242 | $output = []; 243 | $return_var = 0; 244 | exec($commandProcessStrings, $output, $return_var); 245 | 246 | if ($return_var !== 0) { 247 | // Si el proceso falla, intentar limpiar el archivo temporal si se creó. 248 | if (file_exists($tempSheetPath)) { 249 | unlink($tempSheetPath); 250 | } 251 | if (file_exists($finalRowsPath)) { 252 | unlink($finalRowsPath); 253 | } 254 | $errorMsg = "Error al procesar/filtrar las etiquetas "; 255 | throw new RuntimeException($errorMsg); 256 | } 257 | 258 | // $commandProcessFixedLenStrings = sprintf( 259 | // '(MAX_LEN=$(awk \'{ len = length($0); if (len == 0) len = 1; if (len > max_len) max_len = len } END { print max_len }\' %s); ' . 260 | // 'awk -v max_len="$MAX_LEN" \'{ printf "%%-"max_len"s\\n", $0 }\' %s > %s; ' . 261 | // 'echo "MAX_LEN:$MAX_LEN")', // Imprimimos MAX_LEN para que PHP lo capture 262 | // escapeshellarg($finalStringsFilename), // Archivo de entrada para calcular MAX_LEN y procesar 263 | // escapeshellarg($finalStringsFilename), // Archivo de entrada para procesar 264 | // escapeshellarg($sharedStringsFixedLenFile) // Archivo de salida de largo fijo 265 | // ); 266 | 267 | $commandProcessFixedLenStrings = sprintf( 268 | 'export LC_ALL="C.UTF-8";(MAX_LEN=$(awk \'{ gsub(/\r/, ""); len = length($0); if (len == 0) len = 1; if (len > max_len) max_len = len } END { print max_len }\' %s); ' . 269 | 'MAX_LEN=$((MAX_LEN + 10));' . 270 | 'awk -v max_len="$MAX_LEN" \'{ printf "%%-"max_len"s\\n", $0 }\' %s > %s; ' . 271 | 'echo "MAX_LEN:$MAX_LEN")', 272 | escapeshellarg($finalStringsFilename), 273 | escapeshellarg($finalStringsFilename), 274 | escapeshellarg($sharedStringsFixedLenFile) 275 | ); 276 | 277 | $output = []; 278 | $return_var = 0; 279 | exec($commandProcessFixedLenStrings, $output, $return_var); 280 | 281 | $max_len = null; 282 | if ($return_var === 0) { 283 | // Buscar la longitud máxima en la salida del comando Bash 284 | foreach ($output as $line) { 285 | if (preg_match('/^MAX_LEN:(\d+)$/', $line, $matches)) { 286 | $max_len = (int)$matches[1]; 287 | break; 288 | } 289 | } 290 | 291 | if ($max_len !== null) { 292 | $this->MaxLen = $max_len; 293 | $this->SharedStringsFixedLenFile = $sharedStringsFixedLenFile; 294 | } else { 295 | throw new RuntimeException("Error: El archivo de shared strings de largo fijo pudo haber sido creado, pero no se pudo obtener MAX_LEN"); 296 | } 297 | } else { 298 | throw new RuntimeException("Error al ejecutar el comando Bash para shared strings de largo fijo"); 299 | } 300 | 301 | } 302 | 303 | /** 304 | * Prepara los archivos XML de las hojas de un XLSX descomprimido usando comandos de shell. 305 | * Esto es crucial para procesar archivos muy grandes sin cargar todo el contenido en memoria. 306 | * 307 | * Realiza las siguientes operaciones en cada archivo de hoja: 308 | * 1. Extrae el valor del atributo 'ref' de la etiqueta . 309 | * 2. Filtra el contenido para quedarse SÓLO con las líneas que contienen etiquetas . 310 | * 3. Asegura que cada etiqueta comience en una nueva línea, reescribiendo el archivo original. 311 | * 312 | * @param ExcelUnzipInfo $excelUnzipInfo Objeto con la información de la descompresión del XLSX. 313 | * @return bool True si todas las hojas fueron preparadas con éxito. 314 | * @throws RuntimeException Si ocurre algún error durante el procesamiento de las hojas. 315 | */ 316 | function PrepararHojas(ExcelUnzipInfo $excelUnzipInfo): ExcelUnzipInfo { 317 | if (empty($excelUnzipInfo->SheetFilenames)) { 318 | return $excelUnzipInfo; 319 | } 320 | 321 | foreach ($excelUnzipInfo->SheetFilenames as $sheetFilename => $sheetPath) { 322 | if (!file_exists($sheetPath) || !is_writable($sheetPath)) { 323 | throw new RuntimeException("Error: El archivo de hoja no existe o no tiene permisos de escritura: " . $sheetPath); 324 | } 325 | 326 | $escapedSheetPath = escapeshellarg($sheetPath); 327 | $tempSheetPath = $sheetPath . '.tmp'; 328 | $escapedTempSheetPath = escapeshellarg($tempSheetPath); 329 | $finalRowsPath = $sheetPath . ".rows"; 330 | $escapedFinalRowsPath = escapeshellarg($finalRowsPath); 331 | 332 | $this->FinalRowsFile = $finalRowsPath; 333 | 334 | // --- 1. Extraer los datos de --- 335 | $dimension = $this->CmdGetDimension($escapedSheetPath, $escapedFinalRowsPath); 336 | 337 | // --- 2. Filtrar y formatear las etiquetas en un solo paso --- 338 | $this->CmdProcessRows($escapedSheetPath, $escapedFinalRowsPath, $tempSheetPath, $finalRowsPath); 339 | $excelUnzipInfo->RowsFilenames[$sheetFilename] = $finalRowsPath; 340 | 341 | // --- 3. Ahora procedemos a formatear el archivo para los sharedStrings 342 | $this->CmdProcessFixedLen($excelUnzipInfo, $tempSheetPath, $finalRowsPath); 343 | 344 | } 345 | 346 | return $excelUnzipInfo; // Todas las hojas fueron procesadas con éxito 347 | } 348 | 349 | /** 350 | * Crea una instancia de la clase BigExcel, preparando el lector para el archivo. 351 | * 352 | * @param string $filename Ruta al archivo Excel. 353 | * @param string $dtoName Nombre completamente cualificado de la clase DTO a la que mapear cada fila. 354 | * @param string $extension Extensión del archivo (ej. 'Xlsx', 'Csv'). 355 | * @param int $rowsIgnored Número de filas a ignorar al inicio (ej. cabecera). 356 | * @return BigExcel 357 | * @throws \InvalidArgumentException Si el archivo no existe. 358 | * @throws \RuntimeException Si la funcionalidad de PhpSpreadsheet es incompatible (llamada al constructor). 359 | */ 360 | public static function FromFile(string $filename, string $dtoName, string $extension = 'Xlsx', int $rowsIgnored = 1, bool $fieldRowExists = true): BigExcel 361 | { 362 | if (!file_exists($filename)) { 363 | throw new \InvalidArgumentException("El archivo Excel no existe en la ruta: " . $filename); 364 | } 365 | 366 | return new self($filename, $dtoName, $extension, $rowsIgnored, $fieldRowExists); 367 | } 368 | 369 | /** 370 | * Obtiene una shared string específica del archivo de largo fijo. 371 | * Este es un método privado de la clase BigExcel. 372 | * 373 | * @param int $index El índice (base 0) de la shared string a recuperar. 374 | * @return string|null La shared string solicitada, o null si hay un error (por ejemplo, archivo no encontrado o índice fuera de rango). 375 | */ 376 | private function GetSharedString(int $index): ?string 377 | { 378 | // Cada registro ocupa $this->maxLen + 1 (por el salto de línea) bytes. 379 | $recordLength = $this->MaxLen + 1; 380 | $offset = $index * $recordLength; 381 | 382 | // Abrir el archivo en modo binario de lectura ('rb') para mejor compatibilidad 383 | $handle = fopen($this->SharedStringsFixedLenFile, 'rb'); 384 | if (!$handle) { 385 | throw new RuntimeException("Error: No se pudo abrir el archivo de shared strings de largo fijo: " . $this->SharedStringsFixedLenFile); 386 | } 387 | 388 | // Mover el puntero del archivo al inicio del registro deseado 389 | // fseek devuelve 0 en éxito, -1 en fallo. 390 | if (fseek($handle, $offset) === -1) { 391 | fclose($handle); 392 | throw new RuntimeException("Error: No se pudo buscar el offset $offset en el archivo " . $this->SharedStringsFixedLenFile); 393 | } 394 | 395 | // Leer la cantidad exacta de bytes del registro 396 | $line = fread($handle, $recordLength); 397 | fclose($handle); 398 | 399 | if ($line === false) { 400 | throw new RuntimeException("Error: No se pudo leer el registro en el offset $offset del archivo " . $this->SharedStringsFixedLenFile); 401 | } 402 | 403 | // 1. Eliminar el padding de espacios y el salto de línea al final 404 | $cleanLine = rtrim($line); 405 | 406 | // 2. ¡NUEVO PASO CRÍTICO! Extraer el texto puro de la cadena compartida. 407 | // Las shared strings pueden venir como: 408 | // Texto 409 | // O más complejo con formatos: 410 | // Parte1Parte2 411 | // Por simplicidad y eficacia, buscaremos el contenido de 412 | 413 | // Expresión regular para extraer el contenido de 414 | // Si hay múltiples (por formato enriquecido), las concatenamos. 415 | $extractedText = ''; 416 | if (preg_match_all('/(.*?)<\/t>/is', $cleanLine, $matches)) { 417 | $extractedText = implode('', $matches[1]); // Concatenar todos los contenidos de 418 | } else { 419 | // Si no se encuentra , puede ser un caso de ...... 420 | // O una string sin formato ... 421 | // O simplemente no tiene , lo cual es raro pero posible. 422 | // Para estos casos, podríamos intentar un SimpleXML para ser más robusto, 423 | // pero si tu sharedStrings.xml.vars siempre tiene , el de arriba es suficiente. 424 | // Si el texto está directamente en (muy raro), se podría manejar aquí. 425 | // Por ahora, si no hay , devolvemos la línea limpia (que estará mal, pero lo indica). 426 | error_log("Advertencia: No se encontró etiqueta en shared string: " . $cleanLine); 427 | 428 | // Opcional: una forma más robusta para el fallback usando SimpleXML solo para shared strings complejas 429 | // Si bien el enfoque es evitar SimpleXML en la celda principal, para un string compartido complejo, puede valer la pena. 430 | $libxmlState = libxml_use_internal_errors(true); 431 | $siElement = simplexml_load_string($cleanLine); // Parsear el fragmento ... 432 | libxml_use_internal_errors($libxmlState); 433 | if ($siElement !== false) { 434 | // Si la string está en ... (ya manejado por la regex), o ...... 435 | $tempText = ''; 436 | // Excel puede tener (rich text) dentro de , y cada tiene su propia 437 | if (isset($siElement->t)) { // Si tiene una directa 438 | $tempText = (string) $siElement->t; 439 | } elseif (isset($siElement->r)) { // Si tiene rich text 440 | foreach ($siElement->r as $rElement) { 441 | if (isset($rElement->t)) { 442 | $tempText .= (string) $rElement->t; 443 | } 444 | } 445 | } 446 | $extractedText = $tempText; 447 | } else { 448 | // Si SimpleXML también falla, o no hay nada parseable, devolvemos la línea cruda 449 | $extractedText = $cleanLine; 450 | } 451 | libxml_clear_errors(); // Limpiar errores de libxml 452 | } 453 | 454 | return $extractedText; 455 | } 456 | 457 | /** 458 | * Convierte un índice de columna basado en letras (A, B, AA) a un índice numérico (0, 1, 26). 459 | * Este es un método helper privado. 460 | * 461 | * @param string $colStr La cadena de la columna (ej. "A", "AB"). 462 | * @return int El índice numérico de la columna (base 0). 463 | */ 464 | private function ColCharToIndex(string $colStr): int 465 | { 466 | $colIndex = 0; 467 | $colLength = strlen($colStr); 468 | for ($i = 0; $i < $colLength; $i++) { 469 | $colIndex = $colIndex * 26 + (ord($colStr[$i]) - ord('A') + 1); 470 | } 471 | return $colIndex - 1; // Ajustar a base 0 472 | } 473 | 474 | 475 | /** 476 | * Procesa una única cadena XML de fila para extraer los datos de las celdas. 477 | * Este método reemplaza la lógica de preg_match_all. 478 | * 479 | * @param string $rowXmlString La cadena XML completa de una fila (ej. "..."). 480 | * @return array Un array asociativo de datos de celda mapeados por índice de columna numérica. 481 | * @throws \RuntimeException Si la cadena XML de la fila es inválida. 482 | */ 483 | private function ParseRowCells(string $rowXmlString): array 484 | { 485 | // Deshabilitar errores de entidades para SimpleXML, útil para XML de Excel 486 | // (Aunque para un ya filtrado, es menos crítico) 487 | $libxmlState = libxml_use_internal_errors(true); // Guarda el estado actual 488 | $rowElement = simplexml_load_string($rowXmlString); 489 | libxml_use_internal_errors($libxmlState); // Restaura el estado 490 | 491 | if ($rowElement === false) { 492 | // Manejar errores de XML. Puedes obtenerlos con libxml_get_errors() 493 | $errors = libxml_get_errors(); 494 | $errorMessage = "Error al parsear el XML de la fila. Errores: "; 495 | foreach ($errors as $error) { 496 | $errorMessage .= trim($error->message) . " en línea " . $error->line . "; "; 497 | } 498 | libxml_clear_errors(); // Limpiar errores 499 | throw new \RuntimeException($errorMessage); 500 | } 501 | 502 | $cellValuesByIndex = []; 503 | 504 | // Iterar sobre cada elemento (celda) dentro de la fila 505 | foreach ($rowElement->c as $cell) { 506 | $colRef = (string)$cell->attributes()->r; // Ej. "A2", "B2" 507 | 508 | if ($colRef == 'S688') { 509 | $stop = 1; 510 | } 511 | // Extraer la parte de la columna (ej. "A", "B") 512 | preg_match('/^([A-Z]+)/', $colRef, $colMatches); 513 | $colString = $colMatches[1]; 514 | $colIndex = $this->ColCharToIndex($colString); // Convertir "A" -> 0, "B" -> 1 515 | 516 | // Obtener el atributo 's' (estilo) si existe. Es crucial para fechas. 517 | $styleIndex = (string)$cell->attributes()->s; // "1", "2", etc. 518 | $cellType = (string)$cell->attributes()->t; // Tipo de celda (ej. "s", "n", o vacío si no está) 519 | $cellRawValue = (string)$cell->v; // El valor dentro de 520 | 521 | $actualCellValue = ''; 522 | 523 | 524 | 525 | switch ($cellType) { 526 | case 's': // Shared String 527 | $sharedStringIndex = (int)$cellRawValue; 528 | $actualCellValue = $this->GetSharedString($sharedStringIndex); 529 | break; 530 | case 'n': // Number (podría ser una fecha) 531 | case '': // Si no hay atributo 't', Excel a menudo asume numérico 532 | if (is_numeric($cellRawValue)) { 533 | $numericValue = (float)$cellRawValue; 534 | 535 | // *** Lógica para detectar y convertir fechas *** 536 | // Utilizamos la heurística de rango de la implementación anterior 537 | // para determinar si el número es un candidato probable para ser una fecha. 538 | // Si el valor está entre 1 y 65000 (aproximadamente hasta el año 2078) 539 | // se considera un posible número serial de fecha de Excel. 540 | if ($numericValue >= 1 && $numericValue < 65000) { 541 | // Asumo que tu lógica `$colString === 'C'` es para identificar las columnas de fecha. 542 | // Si tienes un array de columnas de fecha, sería mejor: `in_array($colString, $dateColumns)` 543 | // También puedes intentar la conversión para todos los números en este rango si no tienes información de columna/estilo. 544 | $convertedDate = Date::ConvertExcelDateTimeToYMDHIS($numericValue); 545 | 546 | if ($convertedDate !== false) { 547 | $actualCellValue = $convertedDate; 548 | } else { 549 | // La conversión falló, mantenemos el valor numérico original 550 | $actualCellValue = $numericValue; 551 | } 552 | } else { 553 | // No está dentro del rango de números seriales de fecha de Excel, 554 | // se trata como un número normal. 555 | $actualCellValue = $numericValue; 556 | } 557 | } else { 558 | $actualCellValue = $cellRawValue; // No es numérico o no es una fecha 559 | } 560 | break; 561 | case 'b': // Boolean (0 o 1) 562 | $actualCellValue = ($cellRawValue === '1' ? true : false); 563 | break; 564 | // Puedes añadir más tipos si tu Excel los usa (inlineStr, str para fórmulas, etc.) 565 | default: // Por defecto, se toma el valor crudo 566 | $actualCellValue = $cellRawValue; 567 | break; 568 | } 569 | $cellValuesByIndex[$colIndex] = $actualCellValue; 570 | } 571 | 572 | return $cellValuesByIndex; 573 | } 574 | 575 | 576 | /** 577 | * Procesa el archivo Excel fila por fila, aplicando callbacks para cada paso. 578 | * Esta función está optimizada para la RAM y requiere el método ListWorksheetInfo(). 579 | * 580 | * @param bool $breakOnEmptyRow Si es true, detiene el procesamiento al encontrar una fila vacía. 581 | * @param callable|null $saveRowCallback Callback para procesar/guardar cada objeto DTO de fila. Recibe (object $dto, mixed $payload). 582 | * @param mixed $payload Datos adicionales que se pasarán a los callbacks. 583 | * @param callable|null $errorRowCallback Callback para manejar errores en filas específicas. Recibe (\Exception $e, int $rowIndex, mixed $rowData, mixed $payload). 584 | * @param callable|null $validateRowCallback Callback para validar cada fila antes de procesar. Recibe (array $rowData, int $rowIndex, mixed $payload). Debe retornar true si es válida, false si no. 585 | * @throws \RuntimeException Para errores durante la lectura o procesamiento del archivo. 586 | */ 587 | public function ProcessRows( 588 | bool $breakOnEmptyRow = false, 589 | ?callable $saveRowCallback = null, 590 | $payload = null, 591 | ?callable $errorRowCallback = null, 592 | ?callable $validateRowCallback = null): void 593 | { 594 | // Recorrer las propiedades del DTO para generar el encabezado de la tabla 595 | // 596 | $dtoName = $this->DtoName; 597 | $idx = 0; 598 | foreach(get_class_vars($dtoName) as $key => $value){ 599 | 600 | // Agregar el nombre del campo en un arreglo temporal 601 | // para tener el orden en el siguiente bucle de llenado de filas 602 | array_push($this->FieldNames, $key); 603 | 604 | // Modificar el nombre de la propiedad, para cambiar los "_" por " " 605 | $propiedad = str_replace('_', ' ', $key); 606 | $idx++; 607 | } 608 | 609 | // Recorrer el archivo para generar los resultados 610 | // 611 | 612 | $totalRowsProcessed = 0; // Número de filas que se intentaron procesar (incluyendo las salteadas por validación) 613 | 614 | // Abrir el archivo de entrada (sheet1.xml.rows) 615 | $rowsHandle = fopen($this->FinalRowsFile, 'r'); 616 | if (!$rowsHandle) { 617 | throw new \RuntimeException("No se pudo abrir el archivo de filas procesadas: " . $this->FinalRowsFile); 618 | } 619 | 620 | // Abrir el archivo de salida (si se configuró) para escritura 621 | // $outputHandle = null; 622 | // if ($this->outputCombinedFile) { 623 | // $outputHandle = fopen($this->outputCombinedFile, 'w'); 624 | // if (!$outputHandle) { 625 | // fclose($rowsHandle); 626 | // throw new \RuntimeException("No se pudo crear el archivo de salida final: " . $this->outputCombinedFile); 627 | // } 628 | // } 629 | 630 | $rowIndexInFile = 0; // El índice de fila tal como aparece en el XML (r="X") 631 | 632 | // --- Bucle principal para leer el archivo de filas línea por línea --- 633 | $idx = 0; 634 | while (($rowLine = fgets($rowsHandle)) !== false) { 635 | 636 | $idx++; 637 | if ($idx <= $this->RowsIgnored) { 638 | $totalRowsProcessed++; 639 | continue; 640 | } 641 | 642 | $rowLine = trim($rowLine); 643 | $totalRowsProcessed++; // Incrementar el contador de filas procesadas 644 | 645 | // Manejar filas vacías 646 | if ($breakOnEmptyRow) { 647 | if (empty($rowLine)) { 648 | echo "Se encontró una fila vacía y 'breakOnEmptyRow' es true. Deteniendo procesamiento en la fila " . ($totalRowsProcessed - 1) . ".\n"; 649 | break; 650 | } 651 | continue; // Si no se debe romper, simplemente saltar líneas vacías 652 | } 653 | 654 | if ($totalRowsProcessed > 680) { 655 | $stop = 1; 656 | } 657 | 658 | try { 659 | // 1. Extraer el número de fila del XML (r="X") 660 | // Si no se encuentra 'r="X"', usamos $totalRowsProcessed como fallback 661 | preg_match('/ParseRowCells($rowLine); 666 | 667 | // Si es la fila de "campos", llenar la información para los futuros DTO 668 | if ($this->FieldRowExists && $totalRowsProcessed == $this->RowsIgnored + 1) { 669 | foreach($cellValuesByIndex as $idx => $field) { 670 | $this->FieldNames[$field] = $idx; 671 | } 672 | } 673 | else { 674 | // `$parsedRowData` será el array asociativo que se pasará a los callbacks 675 | $parsedRowData = []; 676 | // Mapear los valores de las celdas al formato del DTO (usando $this->FieldNames) 677 | foreach ($this->FieldNames as $dtoColIndex => $fieldName) { 678 | $parsedRowData[$fieldName] = $cellValuesByIndex[$dtoColIndex] ?? null; 679 | } 680 | 681 | // 4. Invocar el callback de validación (si está definido) 682 | if ($validateRowCallback !== null) { 683 | // Si el callback de validación retorna false, saltamos esta fila 684 | if (!call_user_func($validateRowCallback, $parsedRowData, $rowIndexInFile, $payload)) { 685 | echo "Fila {$rowIndexInFile} (desde el archivo) no pasó la validación. Saltando.\n"; 686 | continue; // Pasar a la siguiente fila en el bucle 687 | } 688 | } 689 | 690 | // 5. Crear la instancia del DTO y asignar los valores 691 | $dto = new $this->DtoName(); 692 | foreach ($parsedRowData as $propertyName => $value) { 693 | // Solo asignar si la propiedad realmente existe en el DTO para evitar errores 694 | if (property_exists($dto, $propertyName)) { 695 | try { 696 | $dto->$propertyName = $value; 697 | } 698 | catch (\TypeError $ex) { 699 | $stop = 1; 700 | } 701 | catch (\Exception $ex) { 702 | $stop = 1; 703 | } 704 | } else { 705 | // Opcional: loggear si una propiedad del DTO no coincide con un campo del Excel 706 | // error_log("Advertencia: Propiedad '{$propertyName}' no existe en DTO '{$this->DtoName}'."); 707 | } 708 | } 709 | 710 | // 6. Invocar el callback para guardar/procesar la fila (si está definido) 711 | if ($saveRowCallback !== null) { 712 | call_user_func($saveRowCallback, $dto, $payload); 713 | } 714 | } 715 | 716 | // 7. Opcional: Escribir la fila procesada al archivo de salida final 717 | // if ($outputHandle) { 718 | // $outputRowParts = [sprintf("r:%07d", $rowIndexInFile)]; 719 | // foreach ($parsedRowData as $value) { 720 | // // Asegurar que el valor sea string para str_replace 721 | // $escapedValue = str_replace('"', '""', (string)$value); 722 | // $outputRowParts[] = '"' . $escapedValue . '"'; 723 | // } 724 | // fwrite($outputHandle, implode(",", $outputRowParts) . "\n"); 725 | // } 726 | 727 | } catch (\Throwable $e) { // Capturar cualquier error que ocurra durante el procesamiento de ESTA fila 728 | // Si hay un callback de error, lo invocamos 729 | if ($errorRowCallback !== null) { 730 | // Pasar los datos de la fila que se intentaba procesar 731 | call_user_func($errorRowCallback, $e, $rowIndexInFile, $parsedRowData ?? [], $payload); 732 | } else { 733 | // Si no hay callback de error, lanzamos una RuntimeException 734 | // Esto detendrá el procesamiento si no se maneja más arriba 735 | throw new \RuntimeException( 736 | "Error inesperado procesando fila {$rowIndexInFile} del Excel: " . $e->getMessage(), 737 | $e->getCode(), 738 | $e 739 | ); 740 | } 741 | } 742 | } 743 | 744 | // Cierre de los manejadores de archivos 745 | fclose($rowsHandle); 746 | 747 | // if ($outputHandle) { 748 | // fclose($outputHandle); 749 | // } 750 | 751 | //echo "Proceso de filas completado. Total de filas procesadas (incluyendo vacías): {$totalRowsProcessed}.\n"; 752 | 753 | } 754 | 755 | } -------------------------------------------------------------------------------- Total de líneas: 755 ================================================================================ ================================================================================ ARCHIVO #205: src/OfficeHelper/BigExcel.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/OfficeHelper/BigExcel.php Tamaño: 65.56 KB -------------------------------------------------------------------------------- 1 | DefaultTemplate; 63 | 64 | $this->Filename = $filename; 65 | $this->DtoName = $dtoName; 66 | $this->Extension = $extension; 67 | $this->RowsIgnored = $rowsIgnored; 68 | $this->FieldRowExists = $fieldRowExists; 69 | $this->UseDefultTemplate = $useDefaultTemplate; 70 | 71 | // Procesamos el archivo para extraer las hojas en xml 72 | if (!file_exists($filename)) { 73 | throw new RuntimeException("El archivo no está disponible o no se ha cargado correctamente"); 74 | } 75 | 76 | // Establecer la codificación interna a UTF-8 para funciones multi-byte (si mbstring está habilitado) 77 | // Esto es crucial para que las operaciones de cadena manejen correctamente los caracteres UTF-8. 78 | if (extension_loaded('mbstring')) { 79 | mb_internal_encoding("UTF-8"); 80 | mb_regex_encoding("UTF-8"); 81 | } else { 82 | error_log("Advertencia: La extensión 'mbstring' no está habilitada. Podría haber problemas con caracteres multi-byte."); 83 | } 84 | 85 | if ($this->UseDefultTemplate) 86 | $this->ConfigurarXlsxTemplate(); 87 | else 88 | $this->ConfigurarXlsx($filename); 89 | } 90 | 91 | /** 92 | * Crea una instancia de la clase BigExcel, preparando el lector para el archivo. 93 | * 94 | * @param string $filename Ruta al archivo Excel. 95 | * @param string $dtoName Nombre completamente cualificado de la clase DTO a la que mapear cada fila. 96 | * @param string $extension Extensión del archivo (ej. 'Xlsx', 'Csv'). 97 | * @param int $rowsIgnored Número de filas a ignorar al inicio (ej. cabecera). 98 | * @param bool $fieldRowExists Indica si la primera fila contiene los nombres de los campos. 99 | * @return BigExcel 100 | * @throws \InvalidArgumentException Si el archivo no existe. 101 | * @throws \RuntimeException Si la funcionalidad de PhpSpreadsheet es incompatible (llamada al constructor). 102 | */ 103 | public static function FromFile(string $filename, string $dtoName, string $extension = 'Xlsx', int $rowsIgnored = 1, bool $fieldRowExists = true): BigExcel 104 | { 105 | if (!file_exists($filename)) { 106 | throw new \InvalidArgumentException("El archivo Excel no existe en la ruta: " . $filename); 107 | } 108 | 109 | return new self($filename, $dtoName, $extension, $rowsIgnored, $fieldRowExists); 110 | } 111 | 112 | /** 113 | * Crea una instancia de la clase BigExcel, preparando el escritor para el archivo. 114 | * 115 | * @return BigExcel 116 | * @throws \InvalidArgumentException Si el archivo no existe. 117 | * @throws \RuntimeException Si la funcionalidad de PhpSpreadsheet es incompatible (llamada al constructor). 118 | */ 119 | public static function FromDefaultTemplate(): BigExcel 120 | { 121 | return new self("", "", "Xlsx", 0, true, true); 122 | } 123 | 124 | 125 | private function ConfigurarXlsx($filename) 126 | { 127 | $excelInfo = $this->DescomprimirXlsx($filename); 128 | $this->workingFolder = $excelInfo->WorkingFolder; // Guardar la carpeta de trabajo para limpieza 129 | if (!$this->UseDefultTemplate) 130 | $excelInfo = $this->PrepararHojas($excelInfo); 131 | } 132 | 133 | private function ConfigurarXlsxTemplate() 134 | { 135 | $excelInfo = $this->CopyFolderTemplate(); 136 | $this->workingFolder = $excelInfo->WorkingFolder; // Guardar la carpeta de trabajo para limpieza 137 | } 138 | 139 | /** 140 | * Descomprime un archivo XLSX en una carpeta temporal única, 141 | * ubicada en el mismo directorio que el XLSX original, y devuelve 142 | * un objeto con información detallada de la descompresión. 143 | * 144 | * NOTA: Esta función crea una carpeta temporal. Eres responsable 145 | * de limpiar esta carpeta ($info->WorkingFolder) después de usarla. 146 | * Se recomienda usar un bloque try...finally en tu código principal 147 | * para asegurar la limpieza, llamando a FileHelper::removeDir(). 148 | * 149 | * @param string $filename La ruta completa al archivo XLSX. 150 | * @return ExcelUnzipInfo Un objeto que contiene la ruta de la carpeta de trabajo, 151 | * la ruta de la carpeta 'xl', y los nombres de archivo de cada hoja XML. 152 | * @throws RuntimeException Si el archivo XLSX no existe, la carpeta no se puede crear, o la descompresión falla. 153 | */ 154 | function DescomprimirXlsx(string $filename): ExcelUnzipInfo { 155 | 156 | // 1. Validar que el archivo XLSX exista. 157 | if (!file_exists($filename)) { 158 | throw new RuntimeException("Error: El archivo XLSX no existe en la ruta: " . $filename); 159 | } 160 | 161 | // 2. Determinar la ruta de la carpeta de trabajo temporal única. 162 | $path = (object)pathinfo($filename, PATHINFO_ALL); 163 | 164 | $excelDirectory = $path->dirname; // pathinfo($filename, PATHINFO_DIRNAME); 165 | $workingFolder = $excelDirectory . DIRECTORY_SEPARATOR . $path->filename . '_' . uniqid(); 166 | 167 | // 3. Crear la carpeta temporal. ¡Este paso es crucial! 168 | if (!mkdir($workingFolder, 0777, true)) { 169 | throw new RuntimeException("No se pudo crear la carpeta temporal: " . $workingFolder . ". Verifique los permisos."); 170 | } 171 | 172 | // 4. Escapar las rutas para el comando shell. 173 | $escapedFilename = escapeshellarg($filename); 174 | $escapedWorkingFolder = escapeshellarg($workingFolder); 175 | 176 | // 5. Construir y ejecutar el comando unzip. 177 | $command = "unzip -o {$escapedFilename} -d {$escapedWorkingFolder}"; 178 | 179 | $output = []; 180 | $return_var = 0; 181 | exec($command, $output, $return_var); 182 | 183 | // 6. Verificar el resultado de la descompresión. 184 | if ($return_var !== 0) { 185 | // Si falla la descompresión, intentar limpiar la carpeta que se creó. 186 | FileHelper::removeDir($workingFolder); // <--- ¡Llamada correcta a tu método estático! 187 | $errorMsg = "Error al descomprimir el archivo XLSX. Código de retorno: {$return_var}. Salida: " . implode("\n", $output); 188 | throw new RuntimeException($errorMsg); 189 | } 190 | 191 | // 7. Recopilar la información para el objeto ExcelUnzipInfo. 192 | $xlFolder = $workingFolder . DIRECTORY_SEPARATOR . 'xl'; 193 | $sharedStringsFilename = $xlFolder . "/sharedStrings.xml"; 194 | $sheetXmlsDir = $xlFolder . DIRECTORY_SEPARATOR . 'worksheets'; 195 | $sheetFilenames = []; 196 | $rowsFilename = []; // Inicializar para evitar errores si no hay hojas 197 | 198 | // Encontrar los archivos XML que constituyen las hojas del excel 199 | if (is_dir($sheetXmlsDir)) { 200 | $files = scandir($sheetXmlsDir); 201 | foreach ($files as $file) { 202 | 203 | $path = (object)pathinfo($file, PATHINFO_ALL); 204 | 205 | // Asegurarse de que sea un archivo XML y no un directorio o '.'/'..' 206 | if (isset($path->extension) && $path->extension === 'xml' && is_file($sheetXmlsDir . DIRECTORY_SEPARATOR . $file)) { 207 | $fullSheetPath = $sheetXmlsDir . DIRECTORY_SEPARATOR . $file; 208 | // Intentar leer las primeras líneas o buscar la etiqueta 209 | // Para archivos grandes, es mejor no leer todo el contenido. 210 | // Usamos file_get_contents con un límite para verificar la cabecera. 211 | $fileContentPreview = file_get_contents($fullSheetPath, false, null, 0, 1024); // Leer los primeros 1KB 212 | 213 | if ($fileContentPreview !== false && str_contains($fileContentPreview, 'filename] = $fullSheetPath; 215 | $rowsFilename[$path->filename] = ''; 216 | } 217 | } 218 | } 219 | } 220 | 221 | // 8. Crear y devolver el objeto ExcelUnzipInfo. 222 | return new ExcelUnzipInfo( 223 | $filename, 224 | $workingFolder, 225 | $xlFolder, 226 | $sharedStringsFilename, 227 | $sheetFilenames, 228 | $rowsFilename 229 | ); 230 | } 231 | 232 | 233 | function CmdGetDimension(string $escapedSheetPath, string $escapedFinalRowsPath): string { 234 | // --- 1. Extraer los datos de --- 235 | // Buscamos la primera ocurrencia de |\\n|g" %s | grep \' %s', 246 | $escapedSheetPath, 247 | $escapedFinalRowsPath 248 | ); 249 | 250 | $output = []; 251 | $return_var = 0; 252 | exec($commandProcessRows, $output, $return_var); 253 | 254 | if ($return_var !== 0) { 255 | // No limpiar $tempSheetPath aquí porque el proceso de filas no lo crea, 256 | // sino que es un archivo temporal dentro de PrepaprarHojas 257 | throw new RuntimeException("Error al procesar/filtrar las etiquetas para " . basename($escapedSheetPath) . ". Salida: " . implode("\n", $output)); 258 | } 259 | } 260 | 261 | function CmdProcessFixedLen(ExcelUnzipInfo $excelUnzipInfo): void { // Modificado para solo recibir ExcelUnzipInfo 262 | $sharedStringsFilename = $excelUnzipInfo->SharedStringsFilename; 263 | // El archivo .vars ya no es necesario, podemos procesar directamente 264 | $sharedStringsFixedLenFile = $sharedStringsFilename . ".vars_fixedlen"; 265 | 266 | // Paso 1: Extraer solo las etiquetas y su contenido. 267 | // Usamos xmllint para ser más robustos con XML, si está disponible. 268 | // Si xmllint no está disponible, se puede usar grep/sed como fallback. 269 | // Para asegurar que el "largo" sea solo el contenido significativo, no los tags. 270 | // Pero para el fixed-length, necesitamos el largo del XML completo de . 271 | // La depuración que mostraste "Comercializadora Lovac spa , no solo con . 273 | // Así que mantengamos la forma actual de extraer las líneas de . 274 | 275 | $commandExtractSi = sprintf( 276 | 'sed "s||\\n|g; s||\\n|g" %s | grep \'\'', 277 | escapeshellarg($sharedStringsFilename) 278 | ); 279 | 280 | // Paso 2: Calcular MAX_LEN y crear el archivo de largo fijo 281 | // Usamos un subshell para pasar MAX_LEN a awk de forma segura 282 | // Limpiamos los saltos de línea y CR/LF para un cálculo de longitud preciso. 283 | // El `tr -d '\n\r'` es crucial para que `length($0)` en awk calcule el largo *sin* el salto de línea. 284 | // Luego, awk añadirá *un* salto de línea al final. 285 | $commandProcessFixedLenStrings = sprintf( 286 | 'export LC_ALL="C.UTF-8"; %s | ' . // Pipe de la extracción de directamente a la subshell de awk 287 | '(TEMP_CONTENT=$(cat); ' . // Capturar la salida de la pipe en una variable temporal para doble pasada de awk 288 | 'MAX_LEN=$(echo "$TEMP_CONTENT" | tr -d "\n\r" | awk \'{len = length($0); if (len > max_len) max_len = len} END { print max_len }\'); ' . 289 | 'MAX_LEN=$((MAX_LEN + 10)); ' . // Margen de seguridad. 290 | 'echo "$TEMP_CONTENT" | tr -d "\n\r" | awk -v max_len="$MAX_LEN" \'{ printf "%%-"max_len"s\\n", $0 }\' > %s; ' . 291 | 'echo "MAX_LEN:$MAX_LEN")', 292 | $commandExtractSi, // La salida de este comando es la entrada para el subshell. 293 | escapeshellarg($sharedStringsFixedLenFile) 294 | ); 295 | 296 | $output = []; 297 | $return_var = 0; 298 | exec($commandProcessFixedLenStrings, $output, $return_var); 299 | 300 | $max_len = null; 301 | if ($return_var === 0) { 302 | foreach ($output as $line) { 303 | if (preg_match('/^MAX_LEN:(\d+)$/', $line, $matches)) { 304 | $max_len = (int)$matches[1]; 305 | break; 306 | } 307 | } 308 | 309 | if ($max_len !== null) { 310 | $this->MaxLen = $max_len; 311 | $this->SharedStringsFixedLenFile = $sharedStringsFixedLenFile; 312 | error_log("DEBUG: CmdProcessFixedLen - MAX_LEN calculado: {$this->MaxLen}. Archivo: {$this->SharedStringsFixedLenFile}"); 313 | } else { 314 | throw new RuntimeException("Error: El archivo de shared strings de largo fijo pudo haber sido creado, pero no se pudo obtener MAX_LEN del output."); 315 | } 316 | } else { 317 | if (file_exists($sharedStringsFixedLenFile)) { 318 | unlink($sharedStringsFixedLenFile); 319 | } 320 | throw new RuntimeException("Error al ejecutar el comando Bash para shared strings de largo fijo. Salida: " . implode("\n", $output)); 321 | } 322 | } 323 | 324 | /** 325 | * Prepara los archivos XML de las hojas de un XLSX descomprimido usando comandos de shell. 326 | * Esto es crucial para procesar archivos muy grandes sin cargar todo el contenido en memoria. 327 | * 328 | * @param ExcelUnzipInfo $excelUnzipInfo Objeto con la información de la descompresión del XLSX. 329 | * @return ExcelUnzipInfo El objeto ExcelUnzipInfo actualizado. 330 | * @throws RuntimeException Si ocurre algún error durante el procesamiento de las hojas. 331 | */ 332 | function PrepararHojas(ExcelUnzipInfo $excelUnzipInfo): ExcelUnzipInfo { 333 | if (empty($excelUnzipInfo->SheetFilenames)) { 334 | return $excelUnzipInfo; 335 | } 336 | 337 | // Procesar las shared strings una sola vez para todo el Excel 338 | $this->CmdProcessFixedLen($excelUnzipInfo); 339 | 340 | 341 | foreach ($excelUnzipInfo->SheetFilenames as $sheetFilename => $sheetPath) { 342 | if (!file_exists($sheetPath) || !is_writable($sheetPath)) { 343 | throw new RuntimeException("Error: El archivo de hoja no existe o no tiene permisos de escritura: " . $sheetPath); 344 | } 345 | 346 | $escapedSheetPath = escapeshellarg($sheetPath); 347 | $finalRowsPath = $sheetPath . ".rows"; 348 | $escapedFinalRowsPath = escapeshellarg($finalRowsPath); 349 | 350 | $this->FinalRowsFile = $finalRowsPath; // Asignamos el último processed file para que lo use ProcessRows 351 | 352 | $dimension = $this->CmdGetDimension($escapedSheetPath, $escapedFinalRowsPath); 353 | $this->CmdProcessRows($escapedSheetPath, $escapedFinalRowsPath); 354 | $excelUnzipInfo->RowsFilenames[$sheetFilename] = $finalRowsPath; 355 | } 356 | 357 | return $excelUnzipInfo; 358 | } 359 | 360 | /** 361 | * Obtiene una shared string específica del archivo de largo fijo. 362 | * Este es un método privado de la clase BigExcel. 363 | * 364 | * @param int $index El índice (base 0) de la shared string a recuperar. 365 | * @return string|null La shared string solicitada, o null si hay un error (por ejemplo, archivo no encontrado o índice fuera de rango). 366 | */ 367 | private function GetSharedString(int $index): ?string 368 | { 369 | // Cada registro ocupa $this->MaxLen + 1 (por el salto de línea) bytes. 370 | // Añadir un pequeño margen de lectura para capturar el posible byte extra. 371 | $readLength = (int)$this->MaxLen + 1 + 5; // Leer 5 bytes extras por seguridad. 372 | 373 | if ($index = 5435) { 374 | $stop = 1; 375 | } 376 | // Calcular el offset inicial 377 | $offset = $index * ((int)$this->MaxLen + 1); // El offset se basa en el tamaño exacto del registro 378 | 379 | $handle = fopen($this->SharedStringsFixedLenFile, 'rb'); 380 | if (!$handle) { 381 | throw new RuntimeException("Error: No se pudo abrir el archivo de shared strings de largo fijo: " . $this->SharedStringsFixedLenFile); 382 | } 383 | 384 | // Mover el puntero del archivo 385 | if (fseek($handle, $offset, SEEK_SET) === -1) { 386 | fclose($handle); 387 | // Esto es un error si el archivo no es lo suficientemente grande para el offset 388 | error_log("ERROR: fseek falló en offset $offset en " . $this->SharedStringsFixedLenFile); 389 | return null; 390 | } 391 | 392 | // Leer la línea con el margen extra 393 | $line = fread($handle, $readLength); 394 | fclose($handle); 395 | 396 | if ($line === false || empty($line)) { 397 | error_log("ERROR: fread falló o línea vacía para índice $index en " . $this->SharedStringsFixedLenFile); 398 | return null; 399 | } 400 | 401 | // Depuración: Mostrar la longitud real en bytes y el contenido de la línea leída 402 | error_log("DEBUG: GetSharedString - Indice: $index, Offset: $offset, Leído: " . strlen($line) . " bytes."); 403 | error_log("DEBUG: GetSharedString - Contenido RAW (primeros 50 bytes): " . substr(str_replace(["\n", "\r"], ['\n', '\r'], $line), 0, 50)); 404 | error_log("DEBUG: GetSharedString - Contenido RAW (últimos 50 bytes): " . substr(str_replace(["\n", "\r"], ['\n', '\r'], $line), -50)); 405 | 406 | 407 | // Eliminar el padding, saltos de línea y cualquier carácter invisible al principio/final. 408 | // trim() es multi-byte safe si mb_internal_encoding está configurado. 409 | // Podemos ser más agresivos con preg_replace para eliminar bytes no imprimibles. 410 | $cleanLine = trim($line); // Eliminar espacios y saltos de línea 411 | // Eliminar cualquier caracter no imprimible (ASCII 0-31 y 127) excepto salto de línea/tabulación 412 | // También puede intentar eliminar el BOM si lo encuentra (aunque raro a mitad de archivo) 413 | $cleanLine = preg_replace('/^[\x00-\x1F\x7F]+/', '', $cleanLine); // Eliminar caracteres de control al inicio 414 | $cleanLine = preg_replace('/[\x00-\x1F\x7F]+$/', '', $cleanLine); // Eliminar caracteres de control al final 415 | 416 | // Si la depuración muestra espacios al PRINCIPIO de la línea, 417 | // esto es porque la cadena original en el XML tenía esos espacios 418 | // y awk los incluyó, o el `printf` no se comportó como esperamos. 419 | // Si `awk` usó `printf "%%-"max_len"s\n", $0`, el relleno debería ser al FINAL. 420 | // Pero la depuración que mostraste " ..." 421 | // implica que los espacios están al principio. Esto es muy extraño. 422 | // Esto sugiere que el contenido de `$0` en `awk` ya tiene esos espacios, 423 | // o que `$0` en awk no es el XML que esperas. 424 | 425 | // Por ahora, asumamos que necesitamos quitar esos espacios iniciales si no forman parte del XML. 426 | // Esto es un parche, la causa raíz debería investigarse en la generación del archivo. 427 | $cleanLine = ltrim($cleanLine); 428 | 429 | 430 | // Extraer el texto puro de la cadena compartida. 431 | $extractedText = ''; 432 | if (preg_match_all('/(.*?)<\/t>/isu', $cleanLine, $matches)) { 433 | foreach ($matches[1] as $match) { 434 | $extractedText .= html_entity_decode($match, ENT_QUOTES | ENT_XML1, 'UTF-8'); 435 | } 436 | } else { 437 | // Fallback robusto usando SimpleXML. 438 | $tempSiXml = '' . $cleanLine . ''; // Envolver para hacer un XML válido 439 | $libxmlState = libxml_use_internal_errors(true); 440 | $siElement = simplexml_load_string($tempSiXml); 441 | libxml_use_internal_errors($libxmlState); 442 | 443 | if ($siElement !== false && isset($siElement->si)) { 444 | $tempText = ''; 445 | foreach ($siElement->si->xpath('.//t') as $tNode) { // Buscar todos los nodos dentro de 446 | $tempText .= (string)$tNode; 447 | } 448 | $extractedText = html_entity_decode($tempText, ENT_QUOTES | ENT_XML1, 'UTF-8'); 449 | } else { 450 | error_log("Advertencia: No se pudo extraer texto de shared string mediante regex o SimpleXML. Contenido RAW: " . substr($cleanLine, 0, 100)); 451 | // Si todo falla, intentamos una extracción más simple asumiendo que el texto está entre y 452 | if (preg_match('/(.*?)<\/t>/isu', $cleanLine, $simpleMatches)) { 453 | $extractedText = html_entity_decode($simpleMatches[1], ENT_QUOTES | ENT_XML1, 'UTF-8'); 454 | } else { 455 | $extractedText = $cleanLine; // Último recurso: devolver la línea limpia tal cual 456 | } 457 | } 458 | libxml_clear_errors(); 459 | } 460 | 461 | return $extractedText; 462 | } 463 | 464 | /** 465 | * Convierte un índice de columna basado en letras (A, B, AA) a un índice numérico (0, 1, 26). 466 | * Este es un método helper privado. 467 | * 468 | * @param string $colStr La cadena de la columna (ej. "A", "AB"). 469 | * @return int El índice numérico de la columna (base 0). 470 | */ 471 | private function ColCharToIndex(string $colStr): int 472 | { 473 | $colIndex = 0; 474 | $colLength = mb_strlen($colStr); // Usar mb_strlen 475 | for ($i = 0; $i < $colLength; $i++) { 476 | $colIndex = $colIndex * 26 + (ord(mb_substr($colStr, $i, 1)) - ord('A') + 1); // Usar mb_substr 477 | } 478 | return $colIndex - 1; // Ajustar a base 0 479 | } 480 | 481 | /** 482 | * Convierte un índice de columna numérico (0, 1, 26) a un índice basado en letras (A, B, AA). 483 | * Este es un método helper privado. 484 | * 485 | * @param int El índice numérico de la columna (base 0). 486 | * @return string $colStr La cadena de la columna (ej. "A", "AB"). 487 | */ 488 | function getExcelColumnLetter($index) 489 | { 490 | $letter = ''; 491 | while ($index >= 0) { 492 | $mod = $index % 26; 493 | $letter = chr(65 + $mod) . $letter; 494 | $index = intval($index / 26) - 1; 495 | } 496 | return strtoupper($letter); 497 | } 498 | 499 | /** 500 | * Procesa una única cadena XML de fila para extraer los datos de las celdas. 501 | * Este método reemplaza la lógica de preg_match_all. 502 | * 503 | * @param string $rowXmlString La cadena XML completa de una fila (ej. "..."). 504 | * @return array Un array asociativo de datos de celda mapeados por índice de columna numérica. 505 | * @throws \RuntimeException Si la cadena XML de la fila es inválida. 506 | */ 507 | private function ParseRowCells(string $rowXmlString): array 508 | { 509 | // Deshabilitar errores de entidades para SimpleXML, útil para XML de Excel 510 | $libxmlState = libxml_use_internal_errors(true); // Guarda el estado actual 511 | $rowElement = simplexml_load_string($rowXmlString); 512 | libxml_use_internal_errors($libxmlState); // Restaura el estado 513 | 514 | if ($rowElement === false) { 515 | $errors = libxml_get_errors(); 516 | $errorMessage = "Error al parsear el XML de la fila. Errores: "; 517 | foreach ($errors as $error) { 518 | $errorMessage .= trim($error->message) . " en línea " . $error->line . "; "; 519 | } 520 | libxml_clear_errors(); // Limpiar errores 521 | throw new \RuntimeException($errorMessage); 522 | } 523 | 524 | $cellValuesByIndex = []; 525 | 526 | // Iterar sobre cada elemento (celda) dentro de la fila 527 | foreach ($rowElement->c as $cell) { 528 | $colRef = (string)$cell->attributes()->r; 529 | 530 | if ($colRef == 'S688') { 531 | $stop = 1; 532 | } 533 | 534 | // Extraer la parte de la columna (ej. "A", "B") 535 | preg_match('/^([A-Z]+)/', $colRef, $colMatches); 536 | $colString = $colMatches[1]; 537 | $colIndex = $this->ColCharToIndex($colString); // Convertir "A" -> 0, "B" -> 1 538 | 539 | // Obtener el atributo 's' (estilo) si existe. Es crucial para fechas. 540 | $styleIndex = (string)$cell->attributes()->s; // "1", "2", etc. 541 | $cellType = (string)$cell->attributes()->t; // Tipo de celda (ej. "s", "n", o vacío si no está) 542 | $cellRawValue = (string)$cell->v; 543 | 544 | $actualCellValue = ''; 545 | 546 | switch ($cellType) { 547 | case 's': // Shared String 548 | $sharedStringIndex = (int)$cellRawValue; 549 | $actualCellValue = $this->GetSharedString($sharedStringIndex); 550 | break; 551 | case 'n': // Number (podría ser una fecha) 552 | case '': // Si no hay atributo 't', Excel a menudo asume numérico 553 | if (is_numeric($cellRawValue)) { 554 | $numericValue = (float)$cellRawValue; 555 | 556 | // *** Lógica para detectar y convertir fechas *** 557 | if ($numericValue >= 1 && $numericValue < 65000) { 558 | $convertedDate = Date::ConvertExcelDateTimeToYMDHIS($numericValue); 559 | 560 | if ($convertedDate !== false) { 561 | $actualCellValue = $convertedDate; 562 | } else { 563 | $actualCellValue = $numericValue; 564 | } 565 | } else { 566 | $actualCellValue = $numericValue; // No es numérico o no es una fecha 567 | } 568 | } else { 569 | $actualCellValue = $cellRawValue; // No es numérico o no es una fecha 570 | } 571 | break; 572 | case 'b': // Boolean (0 o 1) 573 | $actualCellValue = ($cellRawValue === '1' ? true : false); 574 | break; 575 | default: // Por defecto, se toma el valor crudo 576 | $actualCellValue = $cellRawValue; 577 | break; 578 | } 579 | $cellValuesByIndex[$colIndex] = $actualCellValue; 580 | } 581 | 582 | return $cellValuesByIndex; 583 | } 584 | 585 | 586 | /** 587 | * Procesa el archivo Excel fila por fila, aplicando callbacks para cada paso. 588 | * Esta función está optimizada para la RAM y requiere el método ListWorksheetInfo(). 589 | * 590 | * @param bool $breakOnEmptyRow Si es true, detiene el procesamiento al encontrar una fila vacía. 591 | * @param callable|null $saveRowCallback Callback para procesar/guardar cada objeto DTO de fila. Recibe (object $dto, mixed $payload). 592 | * @param mixed $payload Datos adicionales que se pasarán a los callbacks. 593 | * @param callable|null $errorRowCallback Callback para manejar errores en filas específicas. Recibe (\Exception $e, int $rowIndex, mixed $rowData, mixed $payload). 594 | * @param callable|null $validateRowCallback Callback para validar cada fila antes de procesar. Recibe (array $rowData, int $rowIndex, mixed $payload). Debe retornar true si es válida, false si no. 595 | * @throws \RuntimeException Para errores durante la lectura o procesamiento del archivo. 596 | */ 597 | public function ProcessRows( 598 | bool $breakOnEmptyRow = false, 599 | ?callable $saveRowCallback = null, 600 | $payload = null, 601 | ?callable $errorRowCallback = null, 602 | ?callable $validateRowCallback = null): void 603 | { 604 | // Recorrer las propiedades del DTO para generar el encabezado de la tabla 605 | $dtoName = $this->DtoName; 606 | $this->FieldNames = []; // Reiniciar a un array vacío para que se llene dinámicamente 607 | 608 | // Abrir el archivo de entrada (sheet1.xml.rows) 609 | $rowsHandle = fopen($this->FinalRowsFile, 'r'); 610 | if (!$rowsHandle) { 611 | throw new \RuntimeException("No se pudo abrir el archivo de filas procesadas: " . $this->FinalRowsFile); 612 | } 613 | 614 | $totalRowsProcessed = 0; // Número de filas que se intentaron procesar (incluyendo las salteadas por validación) 615 | $rowIndexInFile = 0; // El índice de fila tal como aparece en el XML (r="X") 616 | 617 | // --- Bucle principal para leer el archivo de filas línea por línea --- 618 | while (($rowLine = fgets($rowsHandle)) !== false) { 619 | $totalRowsProcessed++; 620 | 621 | // Ignorar filas de cabecera al inicio 622 | if (($totalRowsProcessed -1) < $this->RowsIgnored) { // Ajuste para que $totalRowsProcessed refleje el contador de líneas en el archivo 623 | continue; 624 | } 625 | 626 | $rowLine = trim($rowLine); 627 | 628 | // Manejar filas vacías 629 | if ($breakOnEmptyRow && empty($rowLine)) { 630 | //echo "Se encontró una fila vacía y 'breakOnEmptyRow' es true. Deteniendo procesamiento en la fila " . ($totalRowsProcessed - 1) . ".\n"; 631 | break; 632 | } elseif (empty($rowLine)) { 633 | continue; // Si la fila está vacía y no se debe romper, simplemente saltar 634 | } 635 | 636 | try { 637 | // 1. Extraer el número de fila del XML (r="X") 638 | // Si no se encuentra 'r="X"', usamos $totalRowsProcessed (ajustado) como fallback 639 | preg_match('/RowsIgnored)); 641 | 642 | // Usar la nueva función ParseRowCells para obtener los valores de las celdas 643 | $cellValuesByIndex = $this->ParseRowCells($rowLine); 644 | 645 | // Si es la fila de "campos", llenar la información para los futuros DTO 646 | // Esto se ejecuta una sola vez para la primera fila de datos (después de RowsIgnored) 647 | if ($this->FieldRowExists && ($totalRowsProcessed - $this->RowsIgnored) === 1) { 648 | $this->FieldNames = []; // Reiniciar FieldNames, ya que ahora los obtenemos del Excel 649 | foreach($cellValuesByIndex as $colIndex => $fieldValue) { 650 | // Limpiar y transformar el nombre del campo para que coincida con las propiedades del DTO 651 | // Eliminar caracteres no alfanuméricos y reemplazar espacios con guiones bajos 652 | $cleanFieldName = preg_replace('/[^a-zA-Z0-9_]/', '', str_replace(' ', '_', $fieldValue)); 653 | $this->FieldNames[$cleanFieldName] = $colIndex; 654 | } 655 | } else { 656 | // `$parsedRowData` será el array asociativo que se pasará a los callbacks 657 | $parsedRowData = []; 658 | // Mapear los valores de las celdas al formato del DTO (usando $this->FieldNames) 659 | foreach ($this->FieldNames as $propertyName => $colIndex) { // $propertyName es el nombre del DTO, $colIndex es el índice de la columna 660 | $parsedRowData[$propertyName] = $cellValuesByIndex[$colIndex] ?? null; 661 | } 662 | 663 | // 4. Invocar el callback de validación (si está definido) 664 | if ($validateRowCallback !== null) { 665 | if (!call_user_func($validateRowCallback, $parsedRowData, $rowIndexInFile, $payload)) { 666 | //echo "Fila {$rowIndexInFile} no pasó la validación. Saltando.\n"; 667 | continue; // Pasar a la siguiente fila en el bucle 668 | } 669 | } 670 | 671 | // 5. Crear la instancia del DTO y asignar los valores 672 | $dto = new $this->DtoName(); 673 | foreach ($parsedRowData as $propertyName => $value) { 674 | // Solo asignar si la propiedad realmente existe en el DTO para evitar errores 675 | if (property_exists($dto, $propertyName)) { 676 | try { 677 | $dto->$propertyName = $value; 678 | } 679 | catch (\TypeError $ex) { 680 | // Puedes loggear esto en lugar de solo asignar $stop = 1 681 | error_log("TypeError al asignar valor a la propiedad '{$propertyName}' en fila {$rowIndexInFile}: " . $ex->getMessage()); 682 | } 683 | catch (\Exception $ex) { 684 | // Puedes loggear esto 685 | error_log("Excepción al asignar valor a la propiedad '{$propertyName}' en fila {$rowIndexInFile}: " . $ex->getMessage()); 686 | } 687 | } else { 688 | // Opcional: loggear si una propiedad del DTO no coincide con un campo del Excel 689 | error_log("Advertencia: Propiedad '{$propertyName}' no existe en DTO '{$this->DtoName}' para la fila {$rowIndexInFile}."); 690 | } 691 | } 692 | 693 | // 6. Invocar el callback para guardar/procesar la fila (si está definido) 694 | if ($saveRowCallback !== null) { 695 | call_user_func($saveRowCallback, $dto, $payload); 696 | } 697 | } 698 | 699 | } catch (\Throwable $e) { // Capturar cualquier error que ocurra durante el procesamiento de ESTA fila 700 | // Si hay un callback de error, lo invocamos 701 | if ($errorRowCallback !== null) { 702 | // Pasar los datos de la fila que se intentaba procesar 703 | call_user_func($errorRowCallback, $e, $rowIndexInFile, $parsedRowData ?? [], $payload); 704 | } else { 705 | // Si no hay callback de error, lanzamos una RuntimeException 706 | // Esto detendrá el procesamiento si no se maneja más arriba 707 | throw new \RuntimeException( 708 | "Error inesperado procesando fila {$rowIndexInFile} del Excel: " . $e->getMessage(), 709 | $e->getCode(), 710 | $e 711 | ); 712 | } 713 | } 714 | } 715 | 716 | // Cierre de los manejadores de archivos 717 | fclose($rowsHandle); 718 | } 719 | 720 | /** 721 | * Inicializa la base de datos SQLite para SharedStrings 722 | */ 723 | private function initializeSharedStringsDB(): void 724 | { 725 | $this->sqliteDbFilename = $this->workingFolder . '/shared_strings.sqlite'; 726 | 727 | try { 728 | $this->sharedStringsDB = new PDO('sqlite:' . $this->sqliteDbFilename); 729 | $this->sharedStringsDB->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 730 | 731 | // Crear la tabla con índice único en el contenido para búsquedas rápidas 732 | $this->sharedStringsDB->exec("CREATE TABLE IF NOT EXISTS shared_strings ( 733 | id INTEGER PRIMARY KEY AUTOINCREMENT, 734 | content TEXT NOT NULL UNIQUE 735 | );"); 736 | 737 | // Crear índice para búsquedas más rápidas 738 | $this->sharedStringsDB->exec("CREATE INDEX IF NOT EXISTS idx_content ON shared_strings(content);"); 739 | 740 | // Preparar statements para reutilización 741 | $this->getSharedStringStmt = $this->sharedStringsDB->prepare( 742 | "SELECT id FROM shared_strings WHERE content = :content" 743 | ); 744 | 745 | $this->insertSharedStringStmt = $this->sharedStringsDB->prepare( 746 | "INSERT OR IGNORE INTO shared_strings (content) VALUES (:content)" 747 | ); 748 | 749 | $this->sharedStringsCount = 0; 750 | 751 | } catch (\PDOException $e) { 752 | throw new RuntimeException("Error al inicializar la base de datos SQLite para shared strings: " . $e->getMessage(), (int)$e->getCode(), $e); 753 | } 754 | } 755 | 756 | 757 | /** 758 | * Agrega un string al sistema SharedStrings si no existe y devuelve su índice 759 | * Usa SQLite para búsquedas e inserciones eficientes 760 | * 761 | * @param string $string La cadena a agregar 762 | * @return int El índice de la cadena (base 0) 763 | */ 764 | private function addToSharedStrings(string $string): int 765 | { 766 | if (!$this->sharedStringsDB instanceof PDO) { 767 | throw new RuntimeException("Error interno: La base de datos SQLite no está inicializada."); 768 | } 769 | 770 | try { 771 | // Buscar si ya existe 772 | $this->getSharedStringStmt->bindValue(':content', $string, PDO::PARAM_STR); 773 | $this->getSharedStringStmt->execute(); 774 | $result = $this->getSharedStringStmt->fetch(PDO::FETCH_ASSOC); 775 | 776 | if ($result) { 777 | // Ya existe, retornar el índice (id - 1 porque SQLite AUTOINCREMENT empieza en 1) 778 | return (int)$result['id'] - 1; 779 | } 780 | 781 | // No existe, insertar nuevo string 782 | $this->insertSharedStringStmt->bindValue(':content', $string, PDO::PARAM_STR); 783 | $this->insertSharedStringStmt->execute(); 784 | 785 | // Obtener el ID del último insert (base 1) y convertir a índice base 0 786 | $newIndex = (int)$this->sharedStringsDB->lastInsertId() - 1; 787 | 788 | // Actualizar contador 789 | $this->sharedStringsCount++; 790 | 791 | return $newIndex; 792 | 793 | } catch (\PDOException $e) { 794 | throw new RuntimeException("Error de SQLite al agregar shared string: " . $e->getMessage(), (int)$e->getCode(), $e); 795 | } 796 | } 797 | 798 | 799 | /** 800 | * Genera el archivo sharedStrings.xml final usando los datos de SQLite 801 | */ 802 | private function generateSharedStringsXml(): void 803 | { 804 | // Solo generar si tenemos strings 805 | if ($this->sharedStringsCount === 0) { 806 | return; 807 | } 808 | 809 | if (!$this->sharedStringsDB instanceof PDO) { 810 | throw new RuntimeException("Error interno: La base de datos SQLite no está inicializada."); 811 | } 812 | 813 | $sharedStringsPath = $this->workingFolder . '/xl/sharedStrings.xml'; 814 | 815 | try { 816 | // Abrir archivo para escritura 817 | $file = fopen($sharedStringsPath, 'w'); 818 | if (!$file) { 819 | throw new RuntimeException("No se pudo crear el archivo sharedStrings.xml: " . $sharedStringsPath); 820 | } 821 | 822 | // Escribir header XML 823 | fwrite($file, '' . "\n"); 824 | fwrite($file, '' . "\n"); 826 | 827 | // Leer todos los strings de la BD en orden de ID 828 | $stmt = $this->sharedStringsDB->query("SELECT content FROM shared_strings ORDER BY id ASC"); 829 | 830 | while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { 831 | $content = $row['content']; 832 | 833 | // Escapar caracteres XML especiales 834 | $escapedContent = htmlspecialchars($content, ENT_QUOTES | ENT_XML1, 'UTF-8'); 835 | 836 | fwrite($file, '' . $escapedContent . '' . "\n"); 837 | } 838 | 839 | // Escribir footer XML 840 | fwrite($file, ''); 841 | fclose($file); 842 | 843 | } catch (\PDOException $e) { 844 | throw new RuntimeException("Error de SQLite al generar sharedStrings.xml: " . $e->getMessage(), (int)$e->getCode(), $e); 845 | } 846 | } 847 | 848 | /** 849 | * Destructor que limpia automáticamente los archivos temporales. 850 | */ 851 | public function __destruct() 852 | { 853 | $this->cleanup(); 854 | } 855 | 856 | /** 857 | * Limpia los archivos temporales creados durante el procesamiento del Excel. 858 | * Se debe llamar después de que el procesamiento haya finalizado. 859 | */ 860 | public function cleanup(): void 861 | { 862 | // Cerrar la conexión a la base de datos SQLite 863 | $this->sharedStringsDB = null; 864 | $this->getSharedStringStmt = null; 865 | $this->insertSharedStringStmt = null; 866 | 867 | // Eliminar el archivo de la base de datos SQLite 868 | if (!empty($this->sqliteDbFilename) && file_exists($this->sqliteDbFilename)) { 869 | unlink($this->sqliteDbFilename); 870 | } 871 | 872 | // Limpiar la carpeta completa de trabajo 873 | if (!empty($this->workingFolder) && is_dir($this->workingFolder)) { 874 | FileHelper::removeDir($this->workingFolder); 875 | } 876 | } 877 | 878 | 879 | /** 880 | * Procesa el archivo fila por fila para crear guardar en Excel, aplicando callbacks para cada paso. 881 | * Esta función está optimizada para la RAM y requiere el método ListWorksheetInfo(). 882 | * 883 | * @param string $pathFileInputData ruta del archivo de donde obtener los datos de filas. 884 | * @param callable|null $saveRowCallback Callback para procesar/guardar cada objeto DTO de fila. Recibe (object $dto, mixed $payload). 885 | * @param mixed $payload Datos adicionales que se pasarán a los callbacks. 886 | * @param callable|null $errorRowCallback Callback para manejar errores en filas específicas. Recibe (\Exception $e, int $rowIndex, mixed $rowData, mixed $payload). 887 | * @param callable|null $validateRowCallback Callback para validar cada fila antes de procesar. Recibe (array $rowData, int $rowIndex, mixed $payload). Debe retornar true si es válida, false si no. 888 | * @throws \RuntimeException Para errores durante la lectura o procesamiento del archivo. 889 | */ 890 | public function WriteRows( 891 | BigExcelDefinition $excelDefinition, 892 | ?callable $saveRowCallback = null, 893 | $payload = null, 894 | ?callable $errorRowCallback = null, 895 | ?callable $validateRowCallback = null, 896 | $outputFilePath = '' 897 | ): void { 898 | // **PASADA 1**: Inicializar SQLite para SharedStrings (recolección durante procesamiento) 899 | $this->initializeSharedStringsDB(); 900 | 901 | /* 902 | * Variables para remplazar en los archivos 903 | * las etiquetas necesarias de definicion de 904 | * las hojas 905 | */ 906 | $workbookHojas = ''; 907 | $appHojas = ''; 908 | $typesHojas = ''; 909 | $relationships = ''; 910 | 911 | $count = 0; 912 | foreach ($excelDefinition->Hojas as $hoja) { 913 | 914 | try { 915 | $count++; 916 | $result = $this->AgregarHoja($hoja, $count); 917 | $workbookHojas = $workbookHojas . $result->WorkbookHoja; 918 | $appHojas = $appHojas . $result->AppHoja; 919 | $typesHojas = $typesHojas . $result->TypesHoja; 920 | $relationships = $relationships . $result->Relationship; 921 | } catch (\Throwable $e) { // Capturar cualquier error que ocurra durante el procesamiento de ESTA fila 922 | // Si hay un callback de error, lo invocamos 923 | if ($errorRowCallback !== null) { 924 | // Pasar los datos de la fila que se intentaba procesar 925 | call_user_func($errorRowCallback, $e, $payload); 926 | } else { 927 | // Si no hay callback de error, lanzamos una RuntimeException 928 | // Esto detendrá el procesamiento si no se maneja más arriba 929 | throw new \RuntimeException( 930 | "Error inesperado procesando la hoja {$hoja->Nomre} del Excel: " . $e->getMessage(), 931 | $e->getCode(), 932 | $e 933 | ); 934 | } 935 | } 936 | } 937 | 938 | // Remplazar archivos necesarios para las hojas 939 | $this->CmdReplaceTextInArchive($this->workingFolder . "/xl/workbook.xml", "\[sheets\]", $workbookHojas); 940 | $this->CmdReplaceTextInArchive($this->workingFolder . "/docProps/app.xml", "\[sheets\]", $appHojas); 941 | $this->CmdReplaceTextInArchive($this->workingFolder . "/docProps/app.xml", "\[countSheet\]", $count); 942 | $this->CmdReplaceTextInArchive($this->workingFolder . "/[Content_Types].xml", "\[sheets\]", $typesHojas); 943 | $this->CmdReplaceTextInArchive($this->workingFolder . "/xl/_rels/workbook.xml.rels", "\[relationships\]", $relationships); 944 | 945 | // Generar SharedStrings XML después del procesamiento 946 | $this->generateSharedStringsXml(); 947 | 948 | // Agregar referencias para SharedStrings 949 | $this->updateConfigFilesForSharedStrings(); 950 | 951 | // Limpiar archivos temporales antes de crear el ZIP 952 | $this->cleanupTemporaryFiles(); 953 | 954 | $rutaArchivo = $this->CrearArchivoXlsx(); 955 | $file = (object)pathinfo($excelDefinition->NombreArchivo, PATHINFO_ALL); 956 | 957 | // Se limpia directorio temporal del xlsx 958 | if (isset($outputFilePath) && $outputFilePath != '') { 959 | $destinoCompleto = $outputFilePath . '/' . $excelDefinition->NombreArchivo . ".xlsx"; 960 | 961 | // 2. Intentar copiar el archivo 962 | copy($rutaArchivo, $destinoCompleto); 963 | } 964 | else { 965 | $this->DownloadFile($rutaArchivo, $file->filename . (isset($file->extension) ? $file->extension : ".xlsx")); 966 | } 967 | 968 | FileHelper::removeDir($this->workingFolder); 969 | } 970 | 971 | /** 972 | * Agrega una nueva hoja y se asigna los valores correspondientes al xml 973 | * 974 | * @param BigExcelSheet $hoja Objeto que define las propiedades de la hoja. 975 | * @param int $contadorHoja Numero que define el contador asignado a la hoja (ejemplo sheet1, sheet2). 976 | * @return object Retorna un objecto con los valores asginados a la hoja para modificar en los archivos necesarios del xlsx. 977 | */ 978 | private function AgregarHoja(BigExcelSheet $hoja, $contadorHoja) 979 | { 980 | // Abrir el archivo de entrada 981 | $rowsHandle = fopen($hoja->RutaArchivoEntrada, 'r'); 982 | if (!$rowsHandle) { 983 | throw new \RuntimeException("No se pudo abrir el archivo de filas procesadas: " . $hoja->RutaArchivoEntrada); 984 | } 985 | 986 | $pathSheet = $this->PrepararHoja($contadorHoja); 987 | 988 | $hojaXml = fopen($pathSheet, "a+"); 989 | $totalRowsProcessed = 0; // Número de filas que se intentaron procesar (incluyendo las salteadas por validación) 990 | $rowIndexInFile = 1; // El índice de fila tal como aparece en el XML (r="X") 991 | $setHeader = true; 992 | 993 | $letraUltimaColumna = ""; 994 | 995 | // Iniciar transacción para mejorar el rendimiento de SQLite 996 | $batchSize = 1000; // Hacer commit cada 1000 filas 997 | $batchCounter = 0; 998 | if ($this->sharedStringsDB instanceof PDO) { 999 | $this->sharedStringsDB->beginTransaction(); 1000 | } 1001 | 1002 | // --- Bucle principal para leer el archivo de filas línea por línea --- 1003 | while (($rowLine = fgets($rowsHandle)) !== false) { 1004 | $totalRowsProcessed++; 1005 | $batchCounter++; 1006 | 1007 | $rowLine = trim($rowLine); 1008 | 1009 | // Manejar filas vacías 1010 | if (empty($rowLine)) 1011 | continue; // Si la fila está vacía y no se debe romper, simplemente saltar 1012 | 1013 | try { 1014 | $rowJon = json_decode($rowLine); 1015 | if (!isset($rowJon)) 1016 | continue; 1017 | 1018 | $rowArray = get_object_vars($rowJon); 1019 | 1020 | // Se agrega la primera fila como cabecera 1021 | if ($setHeader) { 1022 | // Se agrega fila. 1023 | $rowFile = ''; 1024 | fwrite($hojaXml, $rowFile); 1025 | 1026 | $count = 0; 1027 | foreach ($rowArray as $key => $value) { 1028 | $letraUltimaColumna = $this->getExcelColumnLetter($count); 1029 | /* 1030 | * Se valida que si viene definida las cabecera la columna debe 1031 | * estar siempre presente en los datos obtenidos del archivo para 1032 | * tomar el nombre definido en la cabera sino se salta 1033 | */ 1034 | if (isset($hoja->Cabeceras)) { 1035 | if (!isset($hoja->Cabeceras->{$key})) 1036 | continue; 1037 | $key = $hoja->Cabeceras->{$key}; 1038 | } 1039 | 1040 | // Para headers, usar SharedStrings para consistencia con el formato Excel 1041 | $sharedStringIndex = $this->addToSharedStrings($key); 1042 | $cel = '' . $sharedStringIndex . ''; 1043 | fwrite($hojaXml, $cel); 1044 | $count++; 1045 | } 1046 | fwrite($hojaXml, ''); 1047 | $setHeader = false; 1048 | $rowIndexInFile++; 1049 | } 1050 | 1051 | // Se agrega fila. 1052 | $rowFile = ''; 1053 | fwrite($hojaXml, $rowFile); 1054 | 1055 | $count = 0; 1056 | foreach ($rowArray as $key => $value) { 1057 | $letra = $this->getExcelColumnLetter($count); 1058 | 1059 | /* 1060 | * Se valida que si viene definida las cabecera la columna debe 1061 | * estar siempre presente en los datos obtenidos del archivo 1062 | * sino se salta 1063 | */ 1064 | if (isset($hoja->Cabeceras) && !isset($hoja->Cabeceras->{$key})) continue; 1065 | 1066 | if (isset($value) && $value !== '') { 1067 | // Determinar si es string o número con mejor lógica 1068 | if (is_string($value) && !is_numeric($value) && trim($value) !== '') { 1069 | // Es una cadena de texto - usar SharedStrings 1070 | $sharedStringIndex = $this->addToSharedStrings($value); 1071 | $cel = '' . $sharedStringIndex . ''; 1072 | } else { 1073 | // Es un número, fecha o valor que no necesita SharedStrings 1074 | $cleanValue = $this->ValidateAndReplaceChar($value); 1075 | $cel = '' . $cleanValue . ''; 1076 | } 1077 | } else { 1078 | // Celda vacía - formato correcto sin contenido 1079 | $cel = ''; 1080 | } 1081 | fwrite($hojaXml, $cel); 1082 | $count++; 1083 | } 1084 | fwrite($hojaXml, ''); 1085 | 1086 | $rowIndexInFile++; 1087 | 1088 | // Hacer commit cada $batchSize filas para optimizar rendimiento 1089 | if ($batchCounter >= $batchSize && $this->sharedStringsDB instanceof PDO && $this->sharedStringsDB->inTransaction()) { 1090 | $this->sharedStringsDB->commit(); 1091 | $this->sharedStringsDB->beginTransaction(); 1092 | $batchCounter = 0; 1093 | } 1094 | 1095 | } catch (\Throwable $e) { // Capturar cualquier error que ocurra durante el procesamiento de ESTA fila 1096 | 1097 | // Hacer rollback de la transacción SQLite en caso de error 1098 | if ($this->sharedStringsDB instanceof PDO && $this->sharedStringsDB->inTransaction()) { 1099 | $this->sharedStringsDB->rollBack(); 1100 | } 1101 | 1102 | // Si no hay callback de error, lanzamos una RuntimeException 1103 | // Esto detendrá el procesamiento si no se maneja más arriba 1104 | throw new \RuntimeException( 1105 | "Error inesperado procesando fila {$rowIndexInFile} del Excel: " . $e->getMessage(), 1106 | $e->getCode(), 1107 | $e 1108 | ); 1109 | } 1110 | } 1111 | 1112 | fwrite($hojaXml, ' 1113 | 1114 | 1115 | 1116 | '); 1117 | 1118 | // Hacer commit de la transacción SQLite 1119 | if ($this->sharedStringsDB instanceof PDO && $this->sharedStringsDB->inTransaction()) { 1120 | $this->sharedStringsDB->commit(); 1121 | } 1122 | 1123 | // Cierre de los manejadores de archivos 1124 | fclose($rowsHandle); 1125 | fclose($hojaXml); 1126 | 1127 | $this->CmdReplaceTextInArchive($pathSheet, "\[dimension\]", "A1:" . $letraUltimaColumna . ($rowIndexInFile - 1)); 1128 | 1129 | $result = new stdClass(); 1130 | $result->WorkbookHoja = 'Nombre . '\" sheetId=\"' . $contadorHoja . '\" r:id=\"rId' . $contadorHoja . '\"/>'; 1131 | $result->AppHoja = '' . $hoja->Nombre . ''; 1132 | $result->TypesHoja = ''; 1133 | $result->Relationship = ''; 1134 | 1135 | return $result; 1136 | } 1137 | 1138 | 1139 | 1140 | /** 1141 | * Copiar carpeta base del template para una nueva ruta con nuevo nombre. 1142 | * 1143 | * NOTA: Esta función crea una carpeta temporal. Eres responsable 1144 | * de limpiar esta carpeta ($info->WorkingFolder) después de usarla. 1145 | * Se recomienda usar un bloque try...finally en tu código principal 1146 | * para asegurar la limpieza, llamando a FileHelper::removeDir(). 1147 | * 1148 | * @param string $filename La ruta completa al archivo XLSX. 1149 | * @return ExcelUnzipInfo Un objeto que contiene la ruta de la carpeta de trabajo, 1150 | * la ruta de la carpeta 'xl', y los nombres de archivo de cada hoja XML. 1151 | * @throws RuntimeException Si el archivo XLSX no existe, la carpeta no se puede crear, o la descompresión falla. 1152 | */ 1153 | private function CopyFolderTemplate(): ExcelUnzipInfo 1154 | { 1155 | 1156 | // 1. Validar que la carpeta del XLSX exista. 1157 | if (!file_exists($this->DefaultTemplate)) { 1158 | throw new RuntimeException("Error: La carpeta del XLSX no existe en la ruta: " . $this->DefaultTemplate); 1159 | } 1160 | $filename = $this->DefaultTemplate; 1161 | 1162 | // 2. Determinar la ruta de la carpeta de trabajo temporal única. 1163 | $path = (object)pathinfo($filename, PATHINFO_ALL); 1164 | 1165 | $excelDirectory = $path->dirname . "/../../LocalData"; 1166 | $workingFolder = $excelDirectory . DIRECTORY_SEPARATOR . $path->filename . '_' . uniqid(); 1167 | 1168 | // 3. Crear la carpeta temporal. ¡Este paso es crucial! 1169 | if (!mkdir($workingFolder, 0777, true)) { 1170 | throw new RuntimeException("No se pudo crear la carpeta temporal: " . $workingFolder . ". Verifique los permisos."); 1171 | } 1172 | 1173 | // 4. Escapar las rutas para el comando shell. 1174 | $escapedFilename = escapeshellarg($filename); 1175 | $escapedWorkingFolder = escapeshellarg($workingFolder . DIRECTORY_SEPARATOR); 1176 | 1177 | // 5. Construir y ejecutar el comando cp. 1178 | $command = "cp -r {$escapedFilename}/* {$escapedWorkingFolder}"; 1179 | 1180 | $output = []; 1181 | $return_var = 0; 1182 | exec($command, $output, $return_var); 1183 | 1184 | // 6. Verificar el resultado de la copia. 1185 | if ($return_var !== 0) { 1186 | // Si falla la copia, se intentar limpiar la carpeta que se creó. 1187 | FileHelper::removeDir($workingFolder); // <--- ¡Llamada correcta a tu método estático! 1188 | $errorMsg = "Error al copiar el contendio de la carpeta de archivo XLSX. Código de retorno: {$return_var}. Salida: " . implode("\n", $output); 1189 | throw new RuntimeException($errorMsg); 1190 | } 1191 | 1192 | // 7. Recopilar la información para el objeto ExcelUnzipInfo. 1193 | $xlFolder = $workingFolder . DIRECTORY_SEPARATOR . 'xl'; 1194 | $sharedStringsFilename = $xlFolder . "/sharedStrings.xml"; 1195 | $sheetFilenames = []; 1196 | $rowsFilename = []; // Inicializar para evitar errores si no hay hojas 1197 | 1198 | // 8. Crear y devolver el objeto ExcelUnzipInfo. 1199 | return new ExcelUnzipInfo( 1200 | $filename, 1201 | $workingFolder, 1202 | $xlFolder, 1203 | $sharedStringsFilename, 1204 | $sheetFilenames, 1205 | $rowsFilename 1206 | ); 1207 | } 1208 | 1209 | /** 1210 | * Crear un archivo xml en base al template para cada hoja 1211 | * 1212 | * @param int $numeroHoja Numero asignado a la nueva hoja. 1213 | * @return string Ruta de la nueva hoja 1214 | */ 1215 | private function PrepararHoja($numeroHoja): string 1216 | { 1217 | 1218 | $rutaHojaTemp = $this->workingFolder . "/xl/worksheets/sheet_template.xml"; 1219 | 1220 | $rutaHoja = $this->workingFolder . "/xl/worksheets/sheet" . $numeroHoja . ".xml"; 1221 | 1222 | $escapedFilename = escapeshellarg($rutaHojaTemp); 1223 | $escapedWorkingFolder = escapeshellarg($rutaHoja); 1224 | 1225 | // 1. Construir y ejecutar el comando de copia. 1226 | $command = "cp {$escapedFilename} {$escapedWorkingFolder}"; 1227 | 1228 | $output = []; 1229 | $return_var = 0; 1230 | exec($command, $output, $return_var); 1231 | 1232 | // 2. Verificar el resultado de la copia. 1233 | if ($return_var !== 0) { 1234 | // Si falla la copia, se intentar limpiar la carpeta que se creó. 1235 | FileHelper::removeDir($this->workingFolder); // <--- ¡Llamada correcta a tu método estático! 1236 | $errorMsg = "Error al copiar el contendio de la carpeta de archivo XLSX. Código de retorno: {$return_var}. Salida: " . implode("\n", $output); 1237 | throw new RuntimeException($errorMsg); 1238 | } 1239 | 1240 | return $rutaHoja; 1241 | } 1242 | 1243 | /** 1244 | * Se crea el archivo xlsx en base a la carpeta base del template 1245 | * 1246 | * @return string Ruta de archivo xlsx creado. 1247 | */ 1248 | private function CrearArchivoXlsx(): string 1249 | { 1250 | $rutaHojaTemp = $this->workingFolder . "/xl/worksheets/sheet_template.xml"; 1251 | 1252 | $escapedFilename = escapeshellarg($rutaHojaTemp); 1253 | 1254 | // 1. Elimianar archivo template de la hoja. 1255 | $command = "rm -rf {$escapedFilename}"; 1256 | 1257 | $output = []; 1258 | $return_var = 0; 1259 | exec($command, $output, $return_var); 1260 | 1261 | // 2. Verificar el resultado de la eliminacion. 1262 | if ($return_var !== 0) { 1263 | // Si falla la eliminacion, se intentar limpiar la carpeta que se creó. 1264 | FileHelper::removeDir($this->workingFolder); // <--- ¡Llamada correcta a tu método estático! 1265 | $errorMsg = "Error al eliminar el archivo de template. Código de retorno: {$return_var}. Salida: " . implode("\n", $output); 1266 | throw new RuntimeException($errorMsg); 1267 | } 1268 | 1269 | 1270 | $path = (object)pathinfo(realpath($this->workingFolder), PATHINFO_ALL); 1271 | // 3. Crear archivo zip de la carpeta de trabajo y convertir en xlsx 1272 | $directory = $path->dirname . DIRECTORY_SEPARATOR . $path->filename; 1273 | 1274 | $command = "cd " . $directory . " && zip -r {$path->filename}.zip . && mv {$path->filename}.zip {$path->filename}.xlsx"; 1275 | 1276 | $output = []; 1277 | $return_var = 0; 1278 | exec($command, $output, $return_var); 1279 | 1280 | // 4. Verificar el resultado de la creacion del archivo. 1281 | if ($return_var !== 0) { 1282 | // Si falla la eliminacion, se intentar limpiar la carpeta que se creó. 1283 | FileHelper::removeDir($this->workingFolder); // <--- ¡Llamada correcta a tu método estático! 1284 | $errorMsg = "Error al crear el archivo desde el template. Código de retorno: {$return_var}. Salida: " . implode("\n", $output); 1285 | throw new RuntimeException($errorMsg); 1286 | } 1287 | 1288 | return $directory . DIRECTORY_SEPARATOR . $path->filename . ".xlsx"; 1289 | } 1290 | 1291 | /** 1292 | * Actualiza los archivos de configuración para incluir las referencias de SharedStrings 1293 | */ 1294 | private function updateConfigFilesForSharedStrings(): void 1295 | { 1296 | // Solo actualizar si se generó el archivo sharedStrings.xml 1297 | $sharedStringsPath = $this->workingFolder . '/xl/sharedStrings.xml'; 1298 | if (!file_exists($sharedStringsPath)) { 1299 | return; 1300 | } 1301 | 1302 | // 1. Actualizar Content_Types.xml usando PHP en lugar de sed 1303 | $contentTypesPath = $this->workingFolder . "/[Content_Types].xml"; 1304 | if (file_exists($contentTypesPath)) { 1305 | $content = file_get_contents($contentTypesPath); 1306 | $sharedStringsType = ' '; 1307 | 1308 | $content = str_replace('', $sharedStringsType . "\n", $content); 1309 | file_put_contents($contentTypesPath, $content); 1310 | } 1311 | 1312 | // 2. Actualizar workbook.xml.rels usando PHP en lugar de sed 1313 | $relsPath = $this->workingFolder . "/xl/_rels/workbook.xml.rels"; 1314 | if (file_exists($relsPath)) { 1315 | $content = file_get_contents($relsPath); 1316 | $nextRId = $this->getNextRelationshipId($relsPath); 1317 | 1318 | $sharedStringsRel = ' '; 1319 | 1320 | $content = str_replace('', $sharedStringsRel . "\n", $content); 1321 | file_put_contents($relsPath, $content); 1322 | } 1323 | } 1324 | 1325 | /** 1326 | * Limpia archivos temporales específicos antes de crear el ZIP 1327 | */ 1328 | private function cleanupTemporaryFiles(): void 1329 | { 1330 | // Cerrar la conexión SQLite antes de eliminar el archivo 1331 | $this->sharedStringsDB = null; 1332 | $this->getSharedStringStmt = null; 1333 | $this->insertSharedStringStmt = null; 1334 | 1335 | // Eliminar la base de datos SQLite 1336 | if (!empty($this->sqliteDbFilename) && file_exists($this->sqliteDbFilename)) { 1337 | unlink($this->sqliteDbFilename); 1338 | } 1339 | 1340 | // Limpiar archivos Zone.Identifier que pueden aparecer 1341 | $zoneFiles = glob($this->workingFolder . '/**/*.Zone.Identifier'); 1342 | if ($zoneFiles) { 1343 | foreach ($zoneFiles as $zoneFile) { 1344 | if (file_exists($zoneFile)) { 1345 | unlink($zoneFile); 1346 | } 1347 | } 1348 | } 1349 | } 1350 | 1351 | /** 1352 | * Obtiene el próximo ID de relación disponible del archivo workbook.xml.rels 1353 | */ 1354 | private function getNextRelationshipId(string $relsPath): int 1355 | { 1356 | $content = file_get_contents($relsPath); 1357 | 1358 | // Buscar todos los rId existentes 1359 | preg_match_all('/rId(\d+)/', $content, $matches); 1360 | 1361 | $maxId = 0; 1362 | if (!empty($matches[1])) { 1363 | $maxId = max(array_map('intval', $matches[1])); 1364 | } 1365 | 1366 | return $maxId + 1; 1367 | } 1368 | 1369 | /** 1370 | * Remplaza un texto dentro de un archivo 1371 | * 1372 | * @param string $archive Ruta de archivo donde cambiar txto. 1373 | * @param string $search Texto a buscar para el remplazo. 1374 | * @param string $replace Texto a cambiar. 1375 | */ 1376 | private function CmdReplaceTextInArchive($archive, $search, $replace): void 1377 | { 1378 | $escapedFilename = escapeshellarg($archive); 1379 | 1380 | // 1. Construir y ejecutar el comando para remplazar. 1381 | $command = 'sed -i "s|' . $search . '|' . $replace . '|g" ' . $escapedFilename; 1382 | 1383 | $output = []; 1384 | $return_var = 0; 1385 | exec($command, $output, $return_var); 1386 | 1387 | // 2. Verificar el resultado del remplazo. 1388 | if ($return_var !== 0) { 1389 | $errorMsg = "Error al remplazar el contendio pedido. Código de retorno: {$return_var}. Salida: " . implode("\n", $output); 1390 | throw new RuntimeException($errorMsg); 1391 | } 1392 | } 1393 | 1394 | 1395 | /** 1396 | * Replazar carecteres no permitidos en el archivo xml 1397 | * 1398 | * @param string $text texto a validar y replazar. 1399 | * @return string Un string luego de quitar caracteres invalidos. 1400 | */ 1401 | private function ValidateAndReplaceChar($text): string 1402 | { 1403 | /* 1404 | * Eliminar caracteres inválidos según XML 1.0 1405 | * Permitidos: \x09 (tab), \x0A (LF), \x0D (CR), y rango Unicode válido 1406 | */ 1407 | $result = preg_replace('/[^\x09\x0A\x0D\x20-\x{D7FF}\x{E000}-\x{FFFD}]/u', '', $text); 1408 | 1409 | /* 1410 | * Es null cuando no cumple con la condicion de replazo 1411 | * se asigna de nuevo el texto enviado para continuar con las validaciones 1412 | */ 1413 | if (!isset($result)) 1414 | $result = $text; 1415 | 1416 | /* 1417 | * Escapar caracteres reservados de XML (&, <, >, ", ') 1418 | */ 1419 | $result = htmlspecialchars($result, ENT_QUOTES | ENT_XML1, 'UTF-8'); 1420 | 1421 | return $result; 1422 | } 1423 | 1424 | /** 1425 | * Descargar archivo xlsx 1426 | * 1427 | * @param string $fileName Ruta completa del archivo a descargar. 1428 | * @param ?string $fileNameDownload Nombre del archivo que recibe el archivo descargado. 1429 | */ 1430 | private function DownloadFile($fileName, $fileNameDownload = null) 1431 | { 1432 | if (!isset($fileNameDownload)) { 1433 | $path = (object)pathinfo($fileName, PATHINFO_ALL); 1434 | $fileNameDownload = $path->basename; 1435 | } 1436 | 1437 | header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'); 1438 | header('Content-Disposition: attachment; filename="' . $fileNameDownload . '"'); 1439 | header('Content-Length: ' . filesize($fileName)); 1440 | header('Pragma: public'); 1441 | header('Cache-Control: must-revalidate'); 1442 | header('Expires: 0'); 1443 | 1444 | readfile($fileName); 1445 | } 1446 | 1447 | } -------------------------------------------------------------------------------- Total de líneas: 1447 ================================================================================ ================================================================================ ARCHIVO #206: src/OfficeHelper/BigExcelDefinition.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/OfficeHelper/BigExcelDefinition.php Tamaño: 549 bytes -------------------------------------------------------------------------------- 1 | NombreArchivo = $NombreArchivo; 22 | $this->Hojas = $Hojas; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- Total de líneas: 25 ================================================================================ ================================================================================ ARCHIVO #207: src/OfficeHelper/BigExcelSheet.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/OfficeHelper/BigExcelSheet.php Tamaño: 721 bytes -------------------------------------------------------------------------------- 1 | Nombre = $Nombre; 23 | $this->RutaArchivoEntrada = $RutaArchivoEntrada; 24 | $this->RutaArchivoEntrada = $RutaArchivoEntrada; 25 | $this->Cabeceras = $Cabeceras; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- Total de líneas: 28 ================================================================================ ================================================================================ ARCHIVO #208: src/OfficeHelper/BigExcelSql.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/OfficeHelper/BigExcelSql.php Tamaño: 39.05 KB -------------------------------------------------------------------------------- 1 | Filename = $filename; 62 | $this->DtoName = $dtoName; 63 | $this->Extension = $extension; 64 | $this->RowsIgnored = $rowsIgnored; 65 | $this->FieldRowExists = $fieldRowExists; 66 | $this->DeleteWorkFolderAfter = $deleteWorkFolderAfter; 67 | 68 | if (!file_exists($filename)) { 69 | throw new RuntimeException("El archivo no está disponible o no se ha cargado correctamente: " . $filename); 70 | } 71 | 72 | // Asegurarse de que mbstring esté cargado y configurado para UTF-8. 73 | if (extension_loaded('mbstring')) { 74 | mb_internal_encoding("UTF-8"); 75 | mb_regex_encoding("UTF-8"); 76 | } else { 77 | error_log("Advertencia: La extensión 'mbstring' no está habilitada. Podría haber problemas con caracteres multi-byte."); 78 | } 79 | 80 | // foreach(get_class_vars($dtoName) as $key => $value){ 81 | // // Agregar el nombre del campo en un arreglo temporal 82 | // // para tener el orden en el siguiente bucle de llenado de filas 83 | // array_push($this->FieldNames, $key); 84 | // } 85 | 86 | $this->ConfigurarXlsx($filename); 87 | } 88 | 89 | /** 90 | * Método estático para crear una instancia de BigExcelSql. 91 | * 92 | * @param string $filename Ruta al archivo Excel. 93 | * @param string $dtoName Nombre completamente cualificado de la clase DTO a la que mapear cada fila. 94 | * @param string $extension Extensión del archivo (ej. 'Xlsx', 'Csv'). 95 | * @param int $rowsIgnored Número de filas a ignorar al inicio (ej. cabecera). 96 | * @param bool $fieldRowExists Indica si la primera fila contiene los nombres de los campos. 97 | * @return BigExcelSql 98 | * @throws \InvalidArgumentException Si el archivo no existe. 99 | * @throws \RuntimeException Si hay problemas al configurar el archivo Excel. 100 | */ 101 | public static function FromFile(string $filename, string $dtoName, string $extension = 'Xlsx', int $rowsIgnored = 1, bool $fieldRowExists = true, bool $deleteWorkFolderAfter = false): BigExcelSql 102 | { 103 | if (!file_exists($filename)) { 104 | throw new \InvalidArgumentException("El archivo Excel no existe en la ruta: " . $filename); 105 | } 106 | 107 | return new self($filename, $dtoName, $extension, $rowsIgnored, $fieldRowExists, $deleteWorkFolderAfter); 108 | } 109 | 110 | /** 111 | * Configura el archivo XLSX: descomprime, procesa las hojas y carga las cadenas compartidas en SQLite. 112 | * 113 | * @param string $filename La ruta al archivo XLSX. 114 | * @throws RuntimeException Si hay errores en la descompresión o preparación. 115 | */ 116 | private function ConfigurarXlsx(string $filename): void { 117 | $excelInfo = $this->DescomprimirXlsx($filename); 118 | $this->workingFolder = $excelInfo->WorkingFolder; // Guardar la carpeta de trabajo para limpieza 119 | 120 | // Cargamos las shared strings a SQLite ANTES de procesar las hojas, una sola vez. 121 | $this->ConnectToSqliteAndLoadStrings($excelInfo->SharedStringsFilename, $excelInfo->WorkingFolder); 122 | 123 | 124 | // --- Cargar estilos desde styles.xml al arreglo en memoria --- 125 | $stylesXmlPath = $excelInfo->XlFolder . DIRECTORY_SEPARATOR . 'styles.xml'; 126 | if (file_exists($stylesXmlPath)) { 127 | $this->LoadStylesFromXml($stylesXmlPath); 128 | } else { 129 | // Manejar el caso donde styles.xml no existe (ej. Excel muy simple o corrupto) 130 | error_log("Advertencia: styles.xml no encontrado en " . $stylesXmlPath . ". La detección de fechas podría ser menos precisa."); 131 | } 132 | 133 | 134 | // Preparamos las hojas (esto aún usa comandos shell para extraer las filas) 135 | // La información de RowsFilenames en $excelInfo será relevante. 136 | $excelInfo = $this->PrepararHojas($excelInfo); 137 | } 138 | 139 | /** 140 | * Carga y parsea el archivo styles.xml en un arreglo en memoria para una rápida consulta. 141 | * Identifica los formatos de número y si corresponden a fechas. 142 | * 143 | * @param string $stylesXmlPath Ruta al archivo styles.xml. 144 | * @throws RuntimeException Si no se puede leer o parsear el archivo styles.xml. 145 | */ 146 | private function LoadStylesFromXml(string $stylesXmlPath): void 147 | { 148 | if (!file_exists($stylesXmlPath)) { 149 | throw new RuntimeException("El archivo styles.xml no se encontró: " . $stylesXmlPath); 150 | } 151 | 152 | libxml_use_internal_errors(true); 153 | $xml = simplexml_load_file($stylesXmlPath); 154 | if ($xml === false) { 155 | $errors = libxml_get_errors(); 156 | $errorMessage = "Error al parsear styles.xml. Errores: "; 157 | foreach ($errors as $error) { 158 | $errorMessage .= trim($error->message) . " en línea " . $error->line . "; "; 159 | } 160 | libxml_clear_errors(); 161 | throw new RuntimeException($errorMessage); 162 | } 163 | libxml_clear_errors(); 164 | 165 | $numFmts = []; 166 | if (isset($xml->numFmts) && $xml->numFmts->numFmt) { 167 | foreach ($xml->numFmts->numFmt as $numFmt) { 168 | $id = (int)$numFmt->attributes()->numFmtId; 169 | $code = (string)$numFmt->attributes()->formatCode; 170 | $numFmts[$id] = $code; 171 | } 172 | } 173 | 174 | $predefinedDateFmtIds = [ 175 | 14, 15, 16, 17, 18, 19, 20, 21, 22, 45, 46, 47, 176 | 30, 31, 32, 33, 34, 35, 36, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 177 | ]; 178 | 179 | if (isset($xml->cellXfs) && $xml->cellXfs->xf) { 180 | $styleIndex = 0; 181 | foreach ($xml->cellXfs->xf as $xf) { 182 | $numFmtId = (int)$xf->attributes()->numFmtId; 183 | $formatCode = $numFmts[$numFmtId] ?? null; 184 | 185 | $isDate = false; 186 | if (in_array($numFmtId, $predefinedDateFmtIds)) { 187 | $isDate = true; 188 | } else if ($formatCode !== null) { 189 | $datePatterns = ['y', 'm', 'd', 'h', 's']; 190 | foreach ($datePatterns as $pattern) { 191 | if (preg_match("/[\[\]]?" . $pattern . "[^a-zA-Z]/i", $formatCode) || 192 | str_contains($formatCode, $pattern . $pattern) 193 | ) { 194 | $isDate = true; 195 | break; 196 | } 197 | } 198 | } 199 | 200 | $this->Styles[$styleIndex] = [ 201 | 'numFmtId' => $numFmtId, 202 | 'formatCode' => $formatCode, 203 | 'isDate' => $isDate 204 | ]; 205 | $styleIndex++; 206 | } 207 | } 208 | } 209 | 210 | 211 | /** 212 | * Descomprime un archivo XLSX en una carpeta temporal única, 213 | * ubicada en el mismo directorio que el XLSX original. 214 | * 215 | * @param string $filename La ruta completa al archivo XLSX. 216 | * @return ExcelUnzipInfo Un objeto que contiene la ruta de la carpeta de trabajo, 217 | * la ruta de la carpeta 'xl', y los nombres de archivo de cada hoja XML. 218 | * @throws RuntimeException Si el archivo XLSX no existe, la carpeta no se puede crear, o la descompresión falla. 219 | */ 220 | private function DescomprimirXlsx(string $filename): ExcelUnzipInfo { 221 | if (!file_exists($filename)) { 222 | throw new RuntimeException("Error: El archivo XLSX no existe en la ruta: " . $filename); 223 | } 224 | 225 | $path = (object)pathinfo($filename, PATHINFO_ALL); 226 | $excelDirectory = $path->dirname; 227 | $workingFolder = $excelDirectory . DIRECTORY_SEPARATOR . $path->filename . '_' . uniqid(); 228 | 229 | if (!mkdir($workingFolder, 0777, true)) { 230 | throw new RuntimeException("No se pudo crear la carpeta temporal: " . $workingFolder . ". Verifique los permisos."); 231 | } 232 | 233 | $escapedFilename = escapeshellarg($filename); 234 | $escapedWorkingFolder = escapeshellarg($workingFolder); 235 | $command = "unzip -o {$escapedFilename} -d {$escapedWorkingFolder}"; 236 | 237 | $output = []; 238 | $return_var = 0; 239 | exec($command, $output, $return_var); 240 | 241 | if ($return_var !== 0) { 242 | FileHelper::removeDir($workingFolder); 243 | $errorMsg = "Error al descomprimir el archivo XLSX. Código de retorno: {$return_var}. Salida: " . implode("\n", $output); 244 | throw new RuntimeException($errorMsg); 245 | } 246 | 247 | $chmodCommand = "chmod -R 777 {$escapedWorkingFolder}"; 248 | 249 | // Ejecutar el comando chmod 250 | $chmodReturnVar = 0; 251 | exec($chmodCommand, $chmodOutput, $chmodReturnVar); 252 | if ($chmodReturnVar !== 0) { 253 | throw new RuntimeException("Error al cambiar permisos: " . implode("\n", $chmodOutput)); 254 | } 255 | 256 | $xlFolder = $workingFolder . DIRECTORY_SEPARATOR . 'xl'; 257 | $sharedStringsFilename = $xlFolder . "/sharedStrings.xml"; 258 | $sheetXmlsDir = $xlFolder . DIRECTORY_SEPARATOR . 'worksheets'; 259 | $sheetFilenames = []; 260 | $rowsFilename = []; // Inicializar para evitar errores si no hay sheets 261 | 262 | if (is_dir($sheetXmlsDir)) { 263 | $files = scandir($sheetXmlsDir); 264 | foreach ($files as $file) { 265 | $path = (object)pathinfo($file, PATHINFO_ALL); 266 | 267 | if (isset($path->extension) && $path->extension === 'xml' && is_file($sheetXmlsDir . DIRECTORY_SEPARATOR . $file)) { 268 | $fullSheetPath = $sheetXmlsDir . DIRECTORY_SEPARATOR . $file; 269 | $fileContentPreview = file_get_contents($fullSheetPath, false, null, 0, 1024); 270 | 271 | if ($fileContentPreview !== false && str_contains($fileContentPreview, 'filename] = $fullSheetPath; 273 | $rowsFilename[$path->filename] = ''; // Será llenado por PrepararHojas 274 | } 275 | } 276 | } 277 | } 278 | 279 | return new ExcelUnzipInfo( 280 | $filename, 281 | $workingFolder, 282 | $xlFolder, 283 | $sharedStringsFilename, 284 | $sheetFilenames, 285 | $rowsFilename 286 | ); 287 | } 288 | 289 | /** 290 | * Conecta a la base de datos SQLite y carga las cadenas compartidas si no existen. 291 | * 292 | * @param string $sharedStringsXmlPath Ruta al archivo sharedStrings.xml original. 293 | * @param string $tempDir Directorio temporal donde se almacenará la DB SQLite. 294 | * @throws RuntimeException Si hay errores de conexión o al cargar los datos. 295 | */ 296 | private function ConnectToSqliteAndLoadStrings(string $sharedStringsXmlPath, string $tempDir): void { 297 | $this->sqliteDbFilename = $tempDir . DIRECTORY_SEPARATOR . 'shared_strings.sqlite'; 298 | 299 | try { 300 | $this->db = new PDO('sqlite:' . $this->sqliteDbFilename); 301 | $this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 302 | 303 | // Crear la tabla si no existe 304 | $this->db->exec("CREATE TABLE IF NOT EXISTS shared_strings ( 305 | id INTEGER PRIMARY KEY, 306 | content TEXT NOT NULL 307 | );"); 308 | 309 | // Verificar si la tabla ya está poblada 310 | $count = $this->db->query("SELECT COUNT(*) FROM shared_strings")->fetchColumn(); 311 | 312 | if ($count == 0) { 313 | // Si la tabla está vacía, cargar las shared strings desde el XML 314 | $reader = new XMLReader(); 315 | if (!$reader->open($sharedStringsXmlPath)) { 316 | throw new RuntimeException("No se pudo abrir sharedStrings.xml para cargar en SQLite: " . $sharedStringsXmlPath); 317 | } 318 | 319 | $this->db->beginTransaction(); 320 | $stmtInsert = $this->db->prepare("INSERT INTO shared_strings (id, content) VALUES (:id, :content)"); 321 | 322 | $currentIndex = 0; 323 | while ($reader->read()) { 324 | // Buscar elementos 325 | if ($reader->nodeType === XMLReader::ELEMENT && $reader->name === 'si') { 326 | // Leer el contenido del nodo como DOM para manejar rich text 327 | $siNode = $reader->expand(); 328 | $dom = new DOMDocument(); 329 | $dom->appendChild($dom->importNode($siNode, true)); 330 | 331 | // textContent es la forma más sencilla de obtener el texto plano de un nodo XML, 332 | // incluyendo texto enriquecido o saltos de línea internos (representados como o directamente como \n) 333 | $content = $dom->documentElement->textContent; 334 | 335 | // Opcional: limpiar caracteres de control no deseados (excepto saltos de línea) 336 | // Para preservar los saltos de línea, usa una regex más específica. 337 | // Por ejemplo, para eliminar solo caracteres de control no imprimibles (Unicode category 'C'), 338 | // pero manteniendo \n, \r, \t. 339 | $content = preg_replace('/[^\P{C}\n\r\t]+/u', '', $content); // Elimina caracteres de control EXCEPTO \n, \r, \t 340 | 341 | $stmtInsert->bindValue(':id', $currentIndex, PDO::PARAM_INT); 342 | $stmtInsert->bindValue(':content', $content, PDO::PARAM_STR); 343 | $stmtInsert->execute(); 344 | 345 | $currentIndex++; 346 | } 347 | } 348 | $this->db->commit(); 349 | $reader->close(); 350 | } 351 | 352 | // Preparar el statement para futuras consultas de cadenas compartidas 353 | $this->getSharedStringStmt = $this->db->prepare("SELECT content FROM shared_strings WHERE id = :id"); 354 | 355 | } catch (\PDOException $e) { 356 | // Manejo de errores específicos de PDO 357 | throw new RuntimeException("Error SQLite al cargar shared strings: " . $e->getMessage(), (int)$e->getCode(), $e); 358 | } catch (RuntimeException $e) { 359 | // Re-lanzar si es un error de apertura de XMLReader 360 | throw $e; 361 | } 362 | } 363 | 364 | 365 | /** 366 | * Comando shell para obtener la dimensión de la hoja de cálculo. 367 | * 368 | * @param string $escapedSheetPath Ruta escapada del archivo XML de la hoja. 369 | * @param string $escapedFinalRowsPath Ruta escapada del archivo final de filas. 370 | * @return string La dimensión de la hoja. 371 | */ 372 | private function CmdGetDimension(string $escapedSheetPath, string $escapedFinalRowsPath): string { 373 | $commandDimension = "grep -oP '|\\n|g" %s | grep \' %s', 389 | // $escapedSheetPath, 390 | // $escapedFinalRowsPath 391 | // ); 392 | /* 393 | $intermediateFilePath = $escapedSheetPath . '.no_newlines_temp'; 394 | 395 | // --- Comando 1: Eliminar todos los saltos de línea y guardar en un archivo intermedio --- 396 | // Usamos 'tr' que es muy eficiente para este propósito. 397 | $commandRemoveNewlines = sprintf( 398 | 'tr -d "\\n" < %s > %s', 399 | $escapedSheetPath, 400 | $intermediateFilePath 401 | ); 402 | 403 | // --- Comando 2: Procesar el archivo intermedio y filtrar las filas --- 404 | // Este es tu comando 'sed' y 'grep' original, pero ahora leyendo del archivo intermedio. 405 | $commandProcessRowsFinal = sprintf( 406 | 'sed "s||\\n|g" %s | grep \'\' > %s', 407 | $intermediateFilePath, 408 | $escapedFinalRowsPath 409 | ); 410 | 411 | $output = []; 412 | $return_var = 0; 413 | 414 | exec($commandRemoveNewlines, $output1, $return_var1); 415 | if ($return_var1 !== 0) { 416 | // Manejar error del primer comando 417 | throw new RuntimeException("Error al procesar/filtrar las etiquetas para " . basename($escapedSheetPath) . ". Salida: " . implode("\n", $output)); 418 | //echo "Error en el comando 1. Código: " . $return_var1 . " Salida: " . implode("\n", $output1); 419 | } 420 | 421 | exec($commandProcessRowsFinal, $output2, $return_var2); 422 | if ($return_var2 !== 0) { 423 | // Manejar error del segundo comando 424 | throw new RuntimeException("Error al procesar/filtrar las etiquetas para " . basename($escapedSheetPath) . ". Salida: " . implode("\n", $output)); 425 | } 426 | */ 427 | 428 | $output = []; 429 | $return_var = 0; 430 | 431 | $commandProcessRows = sprintf( 432 | 'sed -E "s|(]*>)(.*)()|\\1\\2\\3|g; s||\\n|g" %s | tr -d "\\n" | sed "s|\' > %s', 433 | $escapedSheetPath, 434 | $escapedFinalRowsPath 435 | ); 436 | exec($commandProcessRows, $output, $return_var); 437 | 438 | if ($return_var !== 0) { 439 | throw new RuntimeException("Error al procesar/filtrar las etiquetas para " . basename($escapedSheetPath) . ". Salida: " . implode("\n", $output)); 440 | } 441 | } 442 | 443 | /** 444 | * Procesa un archivo XML grande, extrayendo cada etiqueta 445 | * y escribiéndola en una línea separada en un nuevo archivo de salida. 446 | * Está optimizado para eficiencia de memoria usando XMLReader. 447 | * 448 | * @param string $inputFilePath La ruta completa al archivo XML de entrada (ej: sheet1.xml). 449 | * @param string $outputFilePath La ruta completa donde se guardará el archivo de salida con las filas. 450 | * @return bool True si el procesamiento fue exitoso, false en caso de error. 451 | */ 452 | function ProcessXmlRowsToNewFile(string $inputFilePath, string $outputFilePath): bool 453 | { 454 | $reader = new XMLReader(); 455 | 456 | // Intentar abrir el archivo XML 457 | if (!$reader->open($inputFilePath)) { 458 | error_log("Error: No se pudo abrir el archivo XML de entrada: " . $inputFilePath); 459 | return false; 460 | } 461 | 462 | // Intentar abrir el archivo de salida para escritura 463 | $outputFile = fopen($outputFilePath, 'w'); 464 | if (!$outputFile) { 465 | error_log("Error: No se pudo crear o abrir el archivo de salida: " . $outputFilePath); 466 | $reader->close(); // Asegurarse de cerrar el lector si hay error aquí 467 | return false; 468 | } 469 | 470 | // Recorrer el documento XML nodo por nodo 471 | while ($reader->read()) { 472 | // Verificar si el nodo actual es un elemento y si su nombre es 'row' 473 | if ($reader->nodeType == XMLReader::ELEMENT && $reader->name == 'row') { 474 | // Obtener el XML completo del nodo , incluyendo sus hijos. 475 | // readOuterXML() es útil porque obtiene el tag de inicio, el contenido y el tag de cierre. 476 | $rowXml = $reader->readOuterXML(); 477 | 478 | // Eliminar cualquier salto de línea o retorno de carro dentro del XML de la fila. 479 | // Esto asegura que cada se escriba en una única línea en el archivo de salida. 480 | $rowXml = str_replace(["\n", "\r"], "", $rowXml); 481 | 482 | // Escribir la fila procesada en el archivo de salida, seguida de un salto de línea. 483 | fwrite($outputFile, $rowXml . "\n"); 484 | } 485 | } 486 | 487 | // Cerrar el lector XML y el archivo de salida 488 | $reader->close(); 489 | fclose($outputFile); 490 | 491 | return true; // Indicar éxito 492 | } 493 | 494 | /** 495 | * Prepara los archivos XML de las hojas de un XLSX descomprimido usando comandos de shell. 496 | * 497 | * @param ExcelUnzipInfo $excelUnzipInfo Objeto con la información de la descompresión del XLSX. 498 | * @return ExcelUnzipInfo El objeto ExcelUnzipInfo actualizado con las rutas de los archivos de filas procesadas. 499 | * @throws RuntimeException Si ocurre algún error durante el procesamiento de las hojas. 500 | */ 501 | private function PrepararHojas(ExcelUnzipInfo $excelUnzipInfo): ExcelUnzipInfo { 502 | if (empty($excelUnzipInfo->SheetFilenames)) { 503 | return $excelUnzipInfo; 504 | } 505 | 506 | foreach ($excelUnzipInfo->SheetFilenames as $sheetFilename => $sheetPath) { 507 | if (!file_exists($sheetPath) || !is_writable($sheetPath)) { 508 | throw new RuntimeException("Error: El archivo de hoja no existe o no tiene permisos de escritura: " . $sheetPath); 509 | } 510 | 511 | $escapedSheetPath = escapeshellarg($sheetPath); 512 | $finalRowsPath = $sheetPath . ".rows"; 513 | $escapedFinalRowsPath = escapeshellarg($finalRowsPath); 514 | 515 | $this->FinalRowsFile = $finalRowsPath; // Asignamos el último processed file para que lo use ProcessRows 516 | 517 | $dimension = $this->CmdGetDimension($escapedSheetPath, $escapedFinalRowsPath); // Puedes usar $dimension si es necesario 518 | 519 | //$this->CmdProcessRows($escapedSheetPath, $escapedFinalRowsPath); 520 | $this->ProcessXmlRowsToNewFile($sheetPath, $finalRowsPath); 521 | 522 | $excelUnzipInfo->RowsFilenames[$sheetFilename] = $finalRowsPath; 523 | } 524 | 525 | return $excelUnzipInfo; 526 | } 527 | 528 | /** 529 | * Obtiene una shared string específica de la base de datos SQLite. 530 | * 531 | * @param int $index El índice (base 0) de la shared string a recuperar. 532 | * @return string La shared string solicitada. 533 | * @throws RuntimeException Si la declaración SQL no está preparada o si la cadena no se encuentra. 534 | */ 535 | private function GetSharedStringFromDB(int $index): string 536 | { 537 | if (!$this->getSharedStringStmt instanceof PDOStatement) { 538 | throw new RuntimeException("Error interno: La declaración SQL para shared strings no está preparada."); 539 | } 540 | 541 | try { 542 | $this->getSharedStringStmt->bindValue(':id', $index, PDO::PARAM_INT); 543 | $this->getSharedStringStmt->execute(); 544 | $result = $this->getSharedStringStmt->fetch(PDO::FETCH_ASSOC); 545 | 546 | if ($result) { 547 | return $result['content']; 548 | } 549 | // Retornar cadena vacía o un valor por defecto si no se encuentra. 550 | // Considerar lanzar una excepción si no encontrar una shared string es un error crítico. 551 | return ""; 552 | } catch (\PDOException $e) { 553 | error_log("Error de DB al obtener shared string con índice $index: " . $e->getMessage()); 554 | throw new RuntimeException("Fallo de base de datos al obtener shared string.", (int)$e->getCode(), $e); 555 | } 556 | } 557 | 558 | /** 559 | * Convierte un índice de columna basado en letras (A, B, AA) a un índice numérico (0, 1, 26). 560 | * Este es un método helper privado. 561 | * 562 | * @param string $colStr La cadena de la columna (ej. "A", "AB"). 563 | * @return int El índice numérico de la columna (base 0). 564 | */ 565 | private function ColCharToIndex(string $colStr): int 566 | { 567 | $colIndex = 0; 568 | // Usamos mb_strlen y mb_substr para compatibilidad UTF-8, aunque para 'A'-'Z' no es estrictamente necesario, 569 | // es buena práctica cuando mb_internal_encoding está configurado. 570 | $colLength = mb_strlen($colStr); 571 | for ($i = 0; $i < $colLength; $i++) { 572 | $colIndex = $colIndex * 26 + (ord(mb_substr($colStr, $i, 1)) - ord('A') + 1); 573 | } 574 | return $colIndex - 1; // Ajustar a base 0 575 | } 576 | 577 | /** 578 | * Procesa una única cadena XML de fila para extraer los datos de las celdas. 579 | * 580 | * @param string $rowXmlString La cadena XML completa de una fila (ej. "..."). 581 | * @return array Un array asociativo de datos de celda mapeados por índice de columna numérica. 582 | * @throws \RuntimeException Si la cadena XML de la fila es inválida. 583 | */ 584 | private function ParseRowCells(string $rowXmlString): array 585 | { 586 | // Deshabilitar errores de entidades para SimpleXML, útil para XML de Excel 587 | $libxmlState = libxml_use_internal_errors(true); // Guarda el estado actual 588 | $rowElement = simplexml_load_string($rowXmlString); 589 | libxml_use_internal_errors($libxmlState); // Restaura el estado 590 | 591 | if ($rowElement === false) { 592 | $errors = libxml_get_errors(); 593 | $errorMessage = "Error al parsear el XML de la fila. Errores: "; 594 | foreach ($errors as $error) { 595 | $errorMessage .= trim($error->message) . " en línea " . $error->line . "; "; 596 | } 597 | libxml_clear_errors(); // Limpiar errores 598 | throw new \RuntimeException($errorMessage); 599 | } 600 | 601 | $cellValuesByIndex = []; 602 | 603 | // Iterar sobre cada elemento (celda) dentro de la fila 604 | foreach ($rowElement->c as $cell) { 605 | $colRef = (string)$cell->attributes()->r; 606 | 607 | if ($colRef == 'BE7') { 608 | $stop = 1; 609 | } 610 | 611 | // Extraer la parte de la columna (ej. "A", "B") 612 | preg_match('/^([A-Z]+)/', $colRef, $colMatches); 613 | $colString = $colMatches[1]; 614 | $colIndex = $this->ColCharToIndex($colString); // Convertir "A" -> 0, "B" -> 1 615 | 616 | // Obtener el atributo 's' (estilo) si existe. Es crucial para fechas. 617 | $styleIndex = (string)$cell->attributes()->s; // "1", "2", etc. 618 | $cellType = (string)$cell->attributes()->t; // Tipo de celda (ej. "s", "n", o vacío si no está) 619 | 620 | if ($cellType == 'inlineStr') { 621 | if (isset($cell->is) && isset($cell->is->t)) { 622 | $cellRawValue = (string)$cell->is->t; 623 | } else { 624 | // Manejar el caso donde o no existen dentro de inlineStr (aunque no debería pasar en un XML válido) 625 | $cellRawValue = ''; // O algún valor predeterminado o log de error 626 | } 627 | } 628 | else { 629 | $cellRawValue = (string)$cell->v; 630 | } 631 | 632 | $actualCellValue = ''; 633 | 634 | switch ($cellType) { 635 | case 's': // Shared String 636 | $sharedStringIndex = (int)$cellRawValue; 637 | $actualCellValue = $this->GetSharedStringFromDB($sharedStringIndex); // *** LLAMADA A LA NUEVA FUNCIÓN SQLite *** 638 | break; 639 | case 'n': // Number (podría ser una fecha) 640 | case '': // Si no hay atributo 't', Excel a menudo asume numérico 641 | if (is_numeric($cellRawValue)) { 642 | $numericValue = (float)$cellRawValue; 643 | $isDate = false; 644 | 645 | if (isset($this->Styles[$styleIndex])) { 646 | $isDate = $this->Styles[$styleIndex]['isDate']; 647 | } 648 | 649 | if ($isDate) { 650 | if ($numericValue >= 1 && $numericValue < 65000) { 651 | $convertedDate = Date::ConvertExcelDateTimeToYMDHIS($numericValue); 652 | if ($convertedDate !== false) { 653 | $actualCellValue = $convertedDate; 654 | } else { 655 | $actualCellValue = $numericValue; 656 | } 657 | } else { 658 | $actualCellValue = $numericValue; 659 | } 660 | } else { 661 | $actualCellValue = $numericValue; 662 | } 663 | } else { 664 | $actualCellValue = $cellRawValue; 665 | } 666 | break; 667 | case 'b': // Boolean (0 o 1) 668 | $actualCellValue = ($cellRawValue === '1' ? true : false); 669 | break; 670 | default: // Por defecto, se toma el valor crudo 671 | $actualCellValue = $cellRawValue; 672 | break; 673 | } 674 | $cellValuesByIndex[$colIndex] = $actualCellValue; 675 | } 676 | 677 | return $cellValuesByIndex; 678 | } 679 | 680 | /** 681 | * Procesa el archivo Excel fila por fila, aplicando callbacks para cada paso. 682 | * Esta función está optimizada para la RAM y lee las filas ya separadas en archivos .rows. 683 | * 684 | * @param bool $breakOnEmptyRow Si es true, detiene el procesamiento al encontrar una fila vacía. 685 | * @param callable|null $saveRowCallback Callback para procesar/guardar cada objeto DTO de fila. Recibe (object $dto, mixed $payload). 686 | * @param mixed $payload Datos adicionales que se pasarán a los callbacks. 687 | * @param callable|null $errorRowCallback Callback para manejar errores en filas específicas. Recibe (\Exception $e, int $rowIndex, mixed $rowData, mixed $payload). 688 | * @param callable|null $validateRowCallback Callback para validar cada fila antes de procesar. Recibe (array $rowData, int $rowIndex, mixed $payload). Debe retornar true si es válida, false si no. 689 | * @throws \RuntimeException Para errores durante la lectura o procesamiento del archivo. 690 | */ 691 | public function ProcessRows( 692 | bool $breakOnEmptyRow = false, 693 | ?callable $saveRowCallback = null, 694 | $payload = null, 695 | ?callable $errorRowCallback = null, 696 | ?callable $validateRowCallback = null): void 697 | { 698 | $dtoName = $this->DtoName; 699 | $idx = 0; 700 | //$this->FieldNames = []; // Reiniciar field names 701 | // Obtener nombres de propiedades del DTO para mapeo inicial. 702 | // Se sobrescribirá si FieldRowExists es true. 703 | foreach(get_class_vars($dtoName) as $key => $value){ 704 | // Aquí puedes decidir si quieres que el nombre de la propiedad sea la clave 705 | // o si solo te interesa el índice para el mapeo inicial. 706 | // Para el mapeo final, usaremos los nombres del Excel si FieldRowExists. 707 | //$this->FieldNames[$key] = null; // Inicializar sin índice de columna aún 708 | array_push($this->FieldNames, $key); 709 | 710 | // Modificar el nombre de la propiedad, para cambiar los "_" por " " 711 | $propiedad = str_replace('_', ' ', $key); 712 | $idx++; 713 | } 714 | 715 | $totalRowsProcessed = 0; 716 | 717 | // Abrir el archivo de entrada (ej. sheet1.xml.rows) 718 | $rowsHandle = fopen($this->FinalRowsFile, 'r'); 719 | if (!$rowsHandle) { 720 | throw new \RuntimeException("No se pudo abrir el archivo de filas procesadas: " . $this->FinalRowsFile); 721 | } 722 | 723 | //$totalRowsProcessed = 0; // Contador de líneas físicas leídas del archivo .rows 724 | //$isFirstDataRow = true; // Para identificar la fila de encabezado de datos si FieldRowExists es true 725 | 726 | $rowIndexInFile = 0; 727 | // --- Bucle principal para leer el archivo de filas línea por línea --- 728 | $idx = 0; 729 | while (($rowLine = fgets($rowsHandle)) !== false) { 730 | $idx++; 731 | if ($idx <= $this->RowsIgnored) { 732 | $totalRowsProcessed++; 733 | continue; 734 | } 735 | 736 | $rowLine = trim($rowLine); 737 | $totalRowsProcessed++; 738 | 739 | // Manejar filas vacías 740 | if ($breakOnEmptyRow && empty($rowLine)) { 741 | break; // Detener el procesamiento si se encuentra una fila vacía y se desea. 742 | } elseif (empty($rowLine)) { 743 | continue; // Saltar filas vacías si no se debe romper. 744 | } 745 | 746 | try { 747 | // Extraer el número de fila del XML (r="X") si está presente, o usar contador. 748 | preg_match('/RowsIgnored)); 751 | 752 | // Obtener los valores de las celdas de la fila. 753 | $cellValuesByIndex = $this->ParseRowCells($rowLine); 754 | 755 | // Si la primera fila contiene los nombres de los campos (encabezado dinámico). 756 | if ($this->FieldRowExists && $totalRowsProcessed == $this->RowsIgnored + 1) { 757 | // $this->FieldNames = []; // Limpiar los nombres de campo iniciales. 758 | // foreach($cellValuesByIndex as $colIndex => $fieldValue) { 759 | // // Limpiar el nombre del campo para que coincida con las propiedades del DTO 760 | // $cleanFieldName = preg_replace('/[^a-zA-Z0-9_]/', '', str_replace(' ', '_', $fieldValue)); 761 | // $this->FieldNames[$cleanFieldName] = $colIndex; // Mapear nombre limpio a índice de columna. 762 | // } 763 | // $isFirstDataRow = false; // Ya hemos procesado la primera fila de datos. 764 | } else { 765 | // Mapear los valores de las celdas a las propiedades del DTO. 766 | $parsedRowData = []; 767 | // Iterar sobre los nombres de campo definidos (ya sea por DTO predefinido o por encabezado Excel). 768 | foreach ($this->FieldNames as $dtoColIndex => $fieldName) { 769 | $parsedRowData[$fieldName] = $cellValuesByIndex[$dtoColIndex] ?? null; 770 | } 771 | 772 | // Invocar el callback de validación si está definido. 773 | if ($validateRowCallback !== null) { 774 | if (!call_user_func($validateRowCallback, $parsedRowData, $rowIndexInFile, $payload)) { 775 | continue; // Saltar a la siguiente fila si la validación falla. 776 | } 777 | } 778 | 779 | // Crear y poblar el objeto DTO. 780 | $dto = new $this->DtoName(); 781 | foreach ($parsedRowData as $propertyName => $value) { 782 | 783 | if ($propertyName == 'Ancho' && $value != "") { 784 | $stop = 1; 785 | } 786 | 787 | if (property_exists($dto, $propertyName)) { 788 | try { 789 | if (is_numeric($dto->$propertyName) && !is_numeric($value)) { 790 | // no asignamos valor en la propiedad 791 | } 792 | else { 793 | $dto->$propertyName = $value; 794 | } 795 | } catch (\TypeError $ex) { 796 | //error_log("TypeError asignando '$value' a '{$propertyName}' en DTO '{$this->DtoName}' (fila {$rowIndexInFile}): " . $ex->getMessage()); 797 | } catch (\Exception $ex) { 798 | //error_log("Excepción asignando '$value' a '{$propertyName}' en DTO '{$this->DtoName}' (fila {$rowIndexInFile}): " . $ex->getMessage()); 799 | } 800 | } else { 801 | error_log("Advertencia: Propiedad '{$propertyName}' no existe en DTO '{$this->DtoName}' para la fila {$rowIndexInFile}."); 802 | } 803 | } 804 | 805 | // Invocar el callback para guardar/procesar la fila. 806 | if ($saveRowCallback !== null) { 807 | call_user_func($saveRowCallback, $dto, $payload); 808 | } 809 | } 810 | 811 | } catch (\Throwable $e) { // Captura cualquier error durante el procesamiento de esta fila. 812 | if ($errorRowCallback !== null) { 813 | call_user_func($errorRowCallback, $e, $rowIndexInFile, $parsedRowData ?? [], $payload); 814 | } else { 815 | throw new \RuntimeException( 816 | "Error inesperado procesando fila {$rowIndexInFile} del Excel: " . $e->getMessage(), 817 | $e->getCode(), 818 | $e 819 | ); 820 | } 821 | } 822 | } 823 | 824 | fclose($rowsHandle); 825 | } 826 | 827 | /** 828 | * Destructor que limpia automáticamente los archivos temporales. 829 | */ 830 | public function __destruct() 831 | { 832 | $this->cleanup(); 833 | } 834 | 835 | /** 836 | * Limpia los archivos temporales creados durante el procesamiento del Excel. 837 | * Se debe llamar después de que el procesamiento haya finalizado. 838 | */ 839 | public function cleanup(): void 840 | { 841 | // Cerrar la conexión a la base de datos si está abierta 842 | $this->db = null; 843 | $this->getSharedStringStmt = null; 844 | 845 | // Eliminar el archivo de la base de datos SQLite 846 | if (file_exists($this->sqliteDbFilename)) { 847 | unlink($this->sqliteDbFilename); 848 | } 849 | 850 | // Eliminar la carpeta de trabajo y todo su contenido 851 | if (is_dir($this->workingFolder)) { 852 | FileHelper::removeDir($this->workingFolder); 853 | } 854 | } 855 | } -------------------------------------------------------------------------------- Total de líneas: 855 ================================================================================ ================================================================================ ARCHIVO #209: src/OfficeHelper/CeldaExcel.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/OfficeHelper/CeldaExcel.php Tamaño: 720 bytes -------------------------------------------------------------------------------- 1 | Nombre = $Nombre; 24 | $this->Valor = $Valor; 25 | $this->Color = $Color; 26 | $this->ColorLetra = $ColorLetra; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- Total de líneas: 29 ================================================================================ ================================================================================ ARCHIVO #210: src/OfficeHelper/Excel.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/OfficeHelper/Excel.php Tamaño: 22.93 KB -------------------------------------------------------------------------------- 1 | Cellbackup = [ 47 | 'A', 48 | 'B', 49 | 'C', 50 | 'D', 51 | 'E', 52 | 'F', 53 | 'G', 54 | 'H', 55 | 'I', 56 | 'J', 57 | 'K', 58 | 'L', 59 | 'M', 60 | 'N', 61 | 'O', 62 | 'P', 63 | 'Q', 64 | 'R', 65 | 'S', 66 | 'T', 67 | 'U', 68 | 'V', 69 | 'W', 70 | 'X', 71 | 'Y', 72 | 'Z', 73 | 'AA', 74 | 'AB', 75 | 'AC', 76 | 'AD', 77 | 'AE', 78 | 'AF', 79 | 'AG', 80 | 'AH', 81 | 'AI', 82 | 'AJ', 83 | 'AK', 84 | 'AL', 85 | 'AM', 86 | 'AN', 87 | 'AO', 88 | 'AP', 89 | 'AQ', 90 | 'AR', 91 | 'AS', 92 | 'AT', 93 | 'AU', 94 | 'AV', 95 | 'AW', 96 | 'AX', 97 | 'AY', 98 | 'AZ', 99 | 'BA', 100 | 'BB', 101 | 'BC', 102 | 'BD', 103 | 'BE', 104 | 'BF', 105 | 'BG', 106 | 'BH', 107 | 'BI', 108 | 'BJ', 109 | 'BK', 110 | 'BL', 111 | 'BM', 112 | 'BN', 113 | 'BO', 114 | 'BP', 115 | 'BQ', 116 | 'BR', 117 | 'BS', 118 | 'BT', 119 | 'BU', 120 | 'BV', 121 | 'BW', 122 | 'BX', 123 | 'BY', 124 | 'BZ', 125 | 'CA', 126 | 'CB', 127 | 'CC', 128 | 'CD', 129 | 'CE', 130 | 'CF', 131 | 'CG', 132 | 'CH', 133 | 'CI', 134 | 'CJ', 135 | 'CK', 136 | 'CL', 137 | 'CM', 138 | 'CN', 139 | 'CO', 140 | 'CP', 141 | 'CQ', 142 | 'CR', 143 | 'CS', 144 | 'CT', 145 | 'CU', 146 | 'CV', 147 | 'CW', 148 | 'CX', 149 | 'CY', 150 | 'CZ', 151 | 'DA', 152 | 'DB', 153 | 'DC', 154 | 'DD', 155 | 'DE', 156 | 'DF', 157 | 'DG', 158 | 'DH', 159 | 'DI', 160 | 'DJ', 161 | 'DK', 162 | 'DL', 163 | 'DM', 164 | 'DN', 165 | 'DO', 166 | 'DP', 167 | 'DQ', 168 | 'DR', 169 | 'DS', 170 | 'DT', 171 | 'DU', 172 | 'DV', 173 | 'DW', 174 | 'DX', 175 | 'DY', 176 | 'DZ', 177 | 'EA', 178 | 'EB', 179 | 'EC', 180 | 'ED', 181 | 'EE', 182 | 'EF', 183 | 'EG', 184 | 'EH', 185 | 'EI', 186 | 'EJ', 187 | 'EK', 188 | 'EL', 189 | 'EM', 190 | 'EN', 191 | 'EO', 192 | 'EP', 193 | 'EQ', 194 | 'ER', 195 | 'ES', 196 | 'ET', 197 | 'EU', 198 | 'EV', 199 | 'EW', 200 | 'EX', 201 | 'EY', 202 | 'EZ' 203 | ]; 204 | 205 | $o->CellNames = $o->Cellbackup; 206 | $o->temp_CellNames = $o->Cellbackup; 207 | 208 | 209 | if (isset($data) and !empty($data)) { 210 | /** 211 | * 212 | * SE RECORRE EL ARREGLO PARA GENERAR LAS PAGINAS 213 | * 214 | */ 215 | 216 | $c = 0; // pagination counter 217 | 218 | foreach ($data as $item) { 219 | 220 | //SI LOS VALORES SON UNA INSTANCIA DE UN GENERIC COLLECTION 221 | if ($item->Values instanceof GenericCollection) { 222 | 223 | //VERIFICO SI EXISTEN PAGINAS ADICIONALES O ES SOLO 1 224 | if ($c < 1) { 225 | $o->Sheet = $o->GenerateSheetFromMultiple($item); 226 | } else { 227 | /** 228 | * 229 | * GENERO UNA PAGINA TEMPORAL 230 | * 231 | */ 232 | $o->temporalSheet = $o->GenerateSheetFromMultiple($item, true); 233 | $o->temporalSheet->getActiveSheet()->setTitle($item->SheetName); 234 | 235 | /** 236 | * 237 | * COPIO LA PAGINA TEMPORAL A LA PAGINA PRINCIPAL 238 | * 239 | */ 240 | $clonedWorksheet = clone $o->temporalSheet->getSheetByName($item->SheetName); 241 | 242 | $o->Sheet->addExternalSheet($clonedWorksheet); 243 | // try { 244 | // $o->Sheet->addExternalSheet($clonedWorksheet); 245 | // } 246 | // catch (Exception $ex) {} 247 | 248 | //REINICIO EL VALOR DE LA PAGINA TEMPORAL A NULL 249 | $o->temporalSheet = null; 250 | $o->temp_CellNames = $o->Cellbackup; 251 | } 252 | 253 | $c++; //SUMO UNA PAGINA ADICIONAL 254 | } 255 | } 256 | } 257 | return $o; 258 | } 259 | 260 | 261 | public static function FromDataMultipleSheets(array $data = []): Excel 262 | { 263 | $o = new Excel(); 264 | $o->Sheet = new Spreadsheet(); // Inicializar el Spreadsheet principal AQUÍ. 265 | 266 | $o->Cellbackup = [ 267 | 'A', 268 | 'B', 269 | 'C', 270 | 'D', 271 | 'E', 272 | 'F', 273 | 'G', 274 | 'H', 275 | 'I', 276 | 'J', 277 | 'K', 278 | 'L', 279 | 'M', 280 | 'N', 281 | 'O', 282 | 'P', 283 | 'Q', 284 | 'R', 285 | 'S', 286 | 'T', 287 | 'U', 288 | 'V', 289 | 'W', 290 | 'X', 291 | 'Y', 292 | 'Z', 293 | 'AA', 294 | 'AB', 295 | 'AC', 296 | 'AD', 297 | 'AE', 298 | 'AF', 299 | 'AG', 300 | 'AH', 301 | 'AI', 302 | 'AJ', 303 | 'AK', 304 | 'AL', 305 | 'AM', 306 | 'AN', 307 | 'AO', 308 | 'AP', 309 | 'AQ', 310 | 'AR', 311 | 'AS', 312 | 'AT', 313 | 'AU', 314 | 'AV', 315 | 'AW', 316 | 'AX', 317 | 'AY', 318 | 'AZ', 319 | 'BA', 320 | 'BB', 321 | 'BC', 322 | 'BD', 323 | 'BE', 324 | 'BF', 325 | 'BG', 326 | 'BH', 327 | 'BI', 328 | 'BJ', 329 | 'BK', 330 | 'BL', 331 | 'BM', 332 | 'BN', 333 | 'BO', 334 | 'BP', 335 | 'BQ', 336 | 'BR', 337 | 'BS', 338 | 'BT', 339 | 'BU', 340 | 'BV', 341 | 'BW', 342 | 'BX', 343 | 'BY', 344 | 'BZ', 345 | 'CA', 346 | 'CB', 347 | 'CC', 348 | 'CD', 349 | 'CE', 350 | 'CF', 351 | 'CG', 352 | 'CH', 353 | 'CI', 354 | 'CJ', 355 | 'CK', 356 | 'CL', 357 | 'CM', 358 | 'CN', 359 | 'CO', 360 | 'CP', 361 | 'CQ', 362 | 'CR', 363 | 'CS', 364 | 'CT', 365 | 'CU', 366 | 'CV', 367 | 'CW', 368 | 'CX', 369 | 'CY', 370 | 'CZ', 371 | 'DA', 372 | 'DB', 373 | 'DC', 374 | 'DD', 375 | 'DE', 376 | 'DF', 377 | 'DG', 378 | 'DH', 379 | 'DI', 380 | 'DJ', 381 | 'DK', 382 | 'DL', 383 | 'DM', 384 | 'DN', 385 | 'DO', 386 | 'DP', 387 | 'DQ', 388 | 'DR', 389 | 'DS', 390 | 'DT', 391 | 'DU', 392 | 'DV', 393 | 'DW', 394 | 'DX', 395 | 'DY', 396 | 'DZ', 397 | 'EA', 398 | 'EB', 399 | 'EC', 400 | 'ED', 401 | 'EE', 402 | 'EF', 403 | 'EG', 404 | 'EH', 405 | 'EI', 406 | 'EJ', 407 | 'EK', 408 | 'EL', 409 | 'EM', 410 | 'EN', 411 | 'EO', 412 | 'EP', 413 | 'EQ', 414 | 'ER', 415 | 'ES', 416 | 'ET', 417 | 'EU', 418 | 'EV', 419 | 'EW', 420 | 'EX', 421 | 'EY', 422 | 'EZ' 423 | ]; 424 | 425 | $o->CellNames = $o->Cellbackup; 426 | $o->temp_CellNames = $o->Cellbackup; 427 | 428 | // Las propiedades Cellbackup, CellNames, temp_CellNames ya se inicializan en el constructor 429 | // de la clase Excel. 430 | 431 | if (isset($data) && !empty($data)) { 432 | $c = 0; // Contador de hojas 433 | 434 | foreach ($data as $item) { 435 | if ($item->Values instanceof GenericCollection) { 436 | 437 | // 1. Generar el Spreadsheet TEMPORAL 438 | // Esto devuelve un objeto Spreadsheet completo con una hoja activa y llena. 439 | $tempBook = $o->GenerateSheetFromMultiple($item); 440 | 441 | // 2. Obtener la Worksheet de ese Spreadsheet temporal 442 | $tempWorksheet = $tempBook->getActiveSheet(); 443 | 444 | // 3. Asegurarse de que el nombre de la hoja sea único en el Spreadsheet principal 445 | $sheetName = $item->SheetName; 446 | $originalSheetName = $sheetName; 447 | $counter = 1; 448 | while ($o->Sheet->sheetNameExists($sheetName)) { 449 | $sheetName = $originalSheetName . ' (' . $counter++ . ')'; 450 | } 451 | $tempWorksheet->setTitle($sheetName); // Asignar el nombre único a la hoja 452 | 453 | if ($c === 0) { 454 | // Para la primera hoja: 455 | // Eliminar la hoja por defecto ('Sheet1') del Spreadsheet principal 456 | $o->Sheet->removeSheetByIndex(0); 457 | 458 | // Añadir la hoja generada desde el temporal. 459 | // addExternalSheet "mueve" la hoja, eliminándola de su origen. 460 | $o->Sheet->addExternalSheet($tempWorksheet); 461 | } else { 462 | // Para las hojas subsiguientes: 463 | // addExternalSheet "mueve" la hoja del $tempBook al $o->Sheet. 464 | // No necesitas clonar explícitamente la hoja si usas addExternalSheet de esta forma, 465 | // ya que internamente PHPSpreadsheet maneja la referencia. 466 | $o->Sheet->addExternalSheet($tempWorksheet); 467 | } 468 | 469 | // Después de añadir la hoja con addExternalSheet, 470 | // el $tempBook probablemente estará vacío o con una hoja por defecto si se creó una nueva internamente. 471 | // No es necesario unset($tempWorksheet) porque addExternalSheet ya ha transferido la referencia. 472 | // Podemos liberar la referencia al $tempBook. 473 | unset($tempBook); 474 | } 475 | $c++; 476 | } 477 | } 478 | return $o; 479 | } 480 | 481 | 482 | public static function FromData(GenericCollection $data): Excel 483 | { 484 | 485 | $o = new Excel(); 486 | 487 | $o->CellNames = [ 488 | 'A', 489 | 'B', 490 | 'C', 491 | 'D', 492 | 'E', 493 | 'F', 494 | 'G', 495 | 'H', 496 | 'I', 497 | 'J', 498 | 'K', 499 | 'L', 500 | 'M', 501 | 'N', 502 | 'O', 503 | 'P', 504 | 'Q', 505 | 'R', 506 | 'S', 507 | 'T', 508 | 'U', 509 | 'V', 510 | 'W', 511 | 'X', 512 | 'Y', 513 | 'Z', 514 | 'AA', 515 | 'AB', 516 | 'AC', 517 | 'AD', 518 | 'AE', 519 | 'AF', 520 | 'AG', 521 | 'AH', 522 | 'AI', 523 | 'AJ', 524 | 'AK', 525 | 'AL', 526 | 'AM', 527 | 'AN', 528 | 'AO', 529 | 'AP', 530 | 'AQ', 531 | 'AR', 532 | 'AS', 533 | 'AT', 534 | 'AU', 535 | 'AV', 536 | 'AW', 537 | 'AX', 538 | 'AY', 539 | 'AZ', 540 | 'BA', 541 | 'BB', 542 | 'BC', 543 | 'BD', 544 | 'BE', 545 | 'BF', 546 | 'BG', 547 | 'BH', 548 | 'BI', 549 | 'BJ', 550 | 'BK', 551 | 'BL', 552 | 'BM', 553 | 'BN', 554 | 'BO', 555 | 'BP', 556 | 'BQ', 557 | 'BR', 558 | 'BS', 559 | 'BT', 560 | 'BU', 561 | 'BV', 562 | 'BW', 563 | 'BX', 564 | 'BY', 565 | 'BZ', 566 | 'CA', 567 | 'CB', 568 | 'CC', 569 | 'CD', 570 | 'CE', 571 | 'CF', 572 | 'CG', 573 | 'CH', 574 | 'CI', 575 | 'CJ', 576 | 'CK', 577 | 'CL', 578 | 'CM', 579 | 'CN', 580 | 'CO', 581 | 'CP', 582 | 'CQ', 583 | 'CR', 584 | 'CS', 585 | 'CT', 586 | 'CU', 587 | 'CV', 588 | 'CW', 589 | 'CX', 590 | 'CY', 591 | 'CZ', 592 | 'DA', 593 | 'DB', 594 | 'DC', 595 | 'DD', 596 | 'DE', 597 | 'DF', 598 | 'DG', 599 | 'DH', 600 | 'DI', 601 | 'DJ', 602 | 'DK', 603 | 'DL', 604 | 'DM', 605 | 'DN', 606 | 'DO', 607 | 'DP', 608 | 'DQ', 609 | 'DR', 610 | 'DS', 611 | 'DT', 612 | 'DU', 613 | 'DV', 614 | 'DW', 615 | 'DX', 616 | 'DY', 617 | 'DZ', 618 | 'EA', 619 | 'EB', 620 | 'EC', 621 | 'ED', 622 | 'EE', 623 | 'EF', 624 | 'EG', 625 | 'EH', 626 | 'EI', 627 | 'EJ', 628 | 'EK', 629 | 'EL', 630 | 'EM', 631 | 'EN', 632 | 'EO', 633 | 'EP', 634 | 'EQ', 635 | 'ER', 636 | 'ES', 637 | 'ET', 638 | 'EU', 639 | 'EV', 640 | 'EW', 641 | 'EX', 642 | 'EY', 643 | 'EZ' 644 | ]; 645 | 646 | $o->Sheet = $o->GenerateSheet($data); 647 | 648 | return $o; 649 | } 650 | 651 | public static function FromFile(string $filename, string $dtoName, string $extension = 'Xlsx', int $rowsIgnored = 1): Excel 652 | { 653 | 654 | $o = new Excel(); 655 | $o->DtoName = $dtoName; 656 | $o->RowsIgnored = $rowsIgnored; 657 | 658 | // Leer el archivo 659 | $reader = IOFactory::createReader($extension); 660 | $reader->setReadDataOnly(true); 661 | $reader->setReadEmptyCells(false); 662 | 663 | $spreadsheet = $reader->load($filename); 664 | 665 | $o->Sheet = $spreadsheet; 666 | 667 | return $o; 668 | } 669 | 670 | private function GenerateSheet(GenericCollection $data) 671 | { 672 | 673 | // Obtener el DTO que alimenta la hoja 674 | $dtoName = $data->GetDtoName(); 675 | $this->DtoName = $dtoName; 676 | 677 | $sheet = new Spreadsheet(); 678 | 679 | // Recorrer las propiedades del DTO para generar el encabezado de la tabla 680 | // 681 | $idx = 0; 682 | foreach (get_class_vars($dtoName) as $key => $value) { 683 | 684 | // Agregar el nombre del campo en un arreglo temporal 685 | // para tener el orden en el siguiente bucle de llenado de filas 686 | array_push($this->FieldNames, $key); 687 | 688 | // Modificar el nombre de la propiedad, para cambiar los "_" por " " 689 | $propiedad = str_replace('_', ' ', $key); 690 | 691 | // Asignar la propiedad a la celda correspondiente de la fila "1" de la tabla 692 | // que almacena los titulos de las columnas 693 | $sheet->setActiveSheetIndex(0) 694 | ->setCellValue($this->CellNames[$idx] . '1', $propiedad); 695 | 696 | $idx++; 697 | } 698 | 699 | // Recorrer el arreglo de resultados para generar las filas de la tabla 700 | // 701 | $idxFila = 2; 702 | foreach ($data as $fila) { 703 | 704 | // Por cada fila, recorrer las columnas y agregar el valor de la columna 705 | // en la celda correspondiente 706 | foreach ($this->FieldNames as $key => $field) { 707 | // Obtener el valor 708 | $valor = $fila->$field; 709 | // Asignar valor a celda 710 | $sheet->setActiveSheetIndex(0) 711 | ->setCellValue($this->CellNames[$key] . $idxFila, $valor); 712 | } 713 | 714 | $idxFila++; 715 | } 716 | 717 | return $sheet; 718 | } 719 | 720 | private function GenerateSheetFromMultiple(object $data, $temporal = false) 721 | { 722 | 723 | /** 724 | * 725 | * VERIFICO SI ES UNA GENERACIÓN TEMPORAL 726 | * 727 | */ 728 | 729 | if ($temporal) { 730 | $CellContainer = "temp_CellNames"; 731 | $FieldContainer = "temp_FieldNames"; 732 | $this->{$FieldContainer} = []; 733 | } else { 734 | $CellContainer = "CellNames"; 735 | $FieldContainer = "FieldNames"; 736 | $this->{$FieldContainer} = []; 737 | } 738 | 739 | // Obtener el DTO que alimenta la hoja 740 | 741 | $primerElemento = $data->Values->First(); 742 | $dtoName = $data->Values->GetDtoName(); 743 | $sheet = new Spreadsheet(); 744 | 745 | // Recorrer las propiedades del DTO para generar el encabezado de la tabla 746 | // 747 | $idx = 0; 748 | $properties = isset($primerElemento) ? get_object_vars($primerElemento) : get_class_vars($dtoName); 749 | foreach ($properties as $key => $value) { 750 | 751 | // Agregar el nombre del campo en un arreglo temporal 752 | // para tener el orden en el siguiente bucle de llenado de filas 753 | array_push($this->{$FieldContainer}, $key); 754 | 755 | if (isset($primerElemento->$key) && $primerElemento->$key instanceof CeldaExcel) { 756 | $propiedad = $primerElemento->$key->Nombre; 757 | $sheet->setActiveSheetIndex(0)->getCell($this->{$CellContainer}[$idx] . '1')->getStyle()->getFill()->setFillType(Fill::FILL_SOLID) 758 | ->getStartColor()->setRGB($primerElemento->$key->Color); 759 | 760 | $sheet->setActiveSheetIndex(0)->getCell($this->{$CellContainer}[$idx] . '1')->getStyle()->getFont()->getColor()->setRGB($primerElemento->$key->ColorLetra); 761 | } else 762 | // Modificar el nombre de la propiedad, para cambiar los "_" por " " 763 | $propiedad = str_replace('_', ' ', $key); 764 | 765 | // Asignar la propiedad a la celda correspondiente de la fila "1" de la tabla 766 | // que almacena los titulos de las columnas 767 | $sheet->setActiveSheetIndex(0) 768 | ->setCellValue($this->{$CellContainer}[$idx] . '1', $propiedad); 769 | 770 | 771 | $idx++; 772 | } 773 | 774 | // Recorrer el arreglo de resultados para generar las filas de la tabla 775 | // 776 | $idxFila = 2; 777 | foreach ($data->Values as $fila) { 778 | 779 | // Por cada fila, recorrer las columnas y agregar el valor de la columna 780 | // en la celda correspondiente 781 | foreach ($this->{$FieldContainer} as $key => $field) { 782 | // Obtener el valor 783 | $valor = isset($fila->$field) ? $fila->$field : null; 784 | if ($valor instanceof CeldaExcel) 785 | $valor = $valor->Valor; 786 | 787 | // Asignar valor a celda 788 | $sheet->setActiveSheetIndex(0) 789 | ->setCellValue($this->{$CellContainer}[$key] . $idxFila, $valor); 790 | } 791 | 792 | $idxFila++; 793 | } 794 | 795 | $sheet->getActiveSheet() 796 | ->setTitle($data->SheetName); 797 | 798 | // Se agrega automatizacion de tamaño en base al contenido de las columnas 799 | for ($i = 0; $i <= $idx; $i++) { 800 | $sheet->getActiveSheet()->getColumnDimensionByColumn($i)->setAutoSize(true); 801 | } 802 | 803 | return $sheet; 804 | } 805 | 806 | public function Write($fileName) 807 | { 808 | header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'); 809 | header('Content-Disposition: attachment;filename="' . $fileName . '.xlsx"'); 810 | header('Cache-Control: max-age=0'); 811 | // If you're serving to IE 9, then the following may be needed 812 | header('Cache-Control: max-age=1'); 813 | 814 | // If you're serving to IE over SSL, then the following may be needed 815 | header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); // Date in the past 816 | header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); // always modified 817 | header('Cache-Control: cache, must-revalidate'); // HTTP/1.1 818 | header('Pragma: public'); // HTTP/1.0 819 | 820 | $writer = IOFactory::createWriter($this->Sheet, 'Xlsx'); 821 | $writer->save('php://output'); 822 | } 823 | 824 | public function SaveTo($path, $fileName, $extension = 'Xlsx') 825 | { 826 | if (!is_dir($path)) { 827 | if (!mkdir($path, 0777, true)) 828 | throw new Exception(message: "No se pudo crear la carpeta : " . $path . ". Verifique los permisos."); 829 | } 830 | 831 | $writer = IOFactory::createWriter($this->Sheet, $extension); 832 | $writer->save($path . $fileName); 833 | } 834 | 835 | public function GetData($breakOnEmptyRow = false): GenericCollection 836 | { 837 | 838 | $worksheet = $this->Sheet->getSheet(0); 839 | $rowIterator = $worksheet->getRowIterator(); 840 | 841 | Cell::setValueBinder(new AdvancedValueBinder()); 842 | 843 | // Crear el arreglo de datos 844 | $result = []; 845 | 846 | // Crear la matriz de nombre de propiedades 847 | $props = get_class_vars($this->DtoName); 848 | $propNames = []; 849 | $propidx = 1; 850 | foreach ($props as $propname => $val) { 851 | $propNames[$propidx] = $propname; 852 | $propidx++; 853 | } 854 | 855 | foreach ($rowIterator as $idx => $row) { 856 | 857 | if ($row->isEmpty( 858 | CellIterator::TREAT_EMPTY_STRING_AS_EMPTY_CELL | 859 | CellIterator::TREAT_NULL_VALUE_AS_EMPTY_CELL 860 | )) { 861 | 862 | if ($breakOnEmptyRow) { 863 | break; 864 | } else { 865 | continue; 866 | } 867 | } 868 | 869 | if ($idx <= $this->RowsIgnored) { 870 | continue; 871 | } 872 | 873 | // Crear el objeto actual 874 | $dto = $this->DtoName; 875 | $o = new $dto(); 876 | 877 | $columnIterator = $row->getCellIterator(); 878 | $cellidx = 1; 879 | foreach ($columnIterator as $cellname => $cell) { 880 | 881 | $prop = $propNames[$cellidx]; 882 | 883 | if ($prop == "Fecha") { 884 | $value = \PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($cell->getValue()); 885 | } else { 886 | $value = $cell->getValue(); 887 | } 888 | 889 | try { 890 | $o->$prop = $value; 891 | } catch (\Exception $ex) { 892 | $ok = true; 893 | } 894 | 895 | $cellidx++; 896 | } 897 | 898 | $result[] = $o; 899 | } 900 | 901 | // devolver la coleccion 902 | $coleccion = new GenericCollection( 903 | Key: $propNames[1], 904 | DtoName: $this->DtoName, 905 | Values: $result 906 | ); 907 | 908 | return $coleccion; 909 | } 910 | } 911 | -------------------------------------------------------------------------------- Total de líneas: 911 ================================================================================ ================================================================================ ARCHIVO #211: src/OfficeHelper/ExcelTemplate/[Content_Types].xml ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/OfficeHelper/ExcelTemplate/[Content_Types].xml Tamaño: 1.01 KB -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 8 | [sheets] 10 | 13 | 16 | 19 | -------------------------------------------------------------------------------- Total de líneas: 19 ================================================================================ ================================================================================ ARCHIVO #212: src/OfficeHelper/ExcelTemplate/docProps/app.xml ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/OfficeHelper/ExcelTemplate/docProps/app.xml Tamaño: 988 bytes -------------------------------------------------------------------------------- 1 | 2 | 4 | Microsoft Excel 5 | 0 6 | false 7 | 8 | 9 | 10 | Worksheets 11 | 12 | 13 | [countSheet] 14 | 15 | 16 | 17 | 18 | 19 | [sheets] 20 | 21 | 22 | 23 | 24 | false 25 | false 26 | false 27 | 16.0300 28 | -------------------------------------------------------------------------------- Total de líneas: 28 ================================================================================ ================================================================================ ARCHIVO #213: src/OfficeHelper/ExcelTemplate/docProps/core.xml ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/OfficeHelper/ExcelTemplate/docProps/core.xml Tamaño: 651 bytes -------------------------------------------------------------------------------- 1 | 2 | 7 | Equipo 8 | Equipo 9 | 2015-06-05T18:19:34Z 10 | 2015-06-05T18:19:39Z 11 | -------------------------------------------------------------------------------- Total de líneas: 11 ================================================================================ ================================================================================ ARCHIVO #214: src/OfficeHelper/ExcelTemplate/xl/styles.xml ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/OfficeHelper/ExcelTemplate/xl/styles.xml Tamaño: 1.89 KB -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- Total de líneas: 48 ================================================================================ ================================================================================ ARCHIVO #215: src/OfficeHelper/ExcelTemplate/xl/theme/theme1.xml ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/OfficeHelper/ExcelTemplate/xl/theme/theme1.xml Tamaño: 11.59 KB -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | -------------------------------------------------------------------------------- Total de líneas: 259 ================================================================================ ================================================================================ ARCHIVO #216: src/OfficeHelper/ExcelTemplate/xl/workbook.xml ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/OfficeHelper/ExcelTemplate/xl/workbook.xml Tamaño: 942 bytes -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | [sheets] 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- Total de líneas: 17 ================================================================================ ================================================================================ ARCHIVO #217: src/OfficeHelper/ExcelTemplate/xl/worksheets/sheet_template.xml ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/OfficeHelper/ExcelTemplate/xl/worksheets/sheet_template.xml Tamaño: 580 bytes -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- Total de líneas: 11 ================================================================================ ================================================================================ ARCHIVO #218: src/OfficeHelper/ExcelUnzipInfo.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/OfficeHelper/ExcelUnzipInfo.php Tamaño: 585 bytes -------------------------------------------------------------------------------- 1 | startRow = $startRow; 23 | $this->endRow = $endRow; 24 | } 25 | 26 | public function readCell(string $column, int $row, string $worksheetName = ''): bool 27 | { 28 | // Solo leer las filas dentro del rango especificado 29 | return ($row >= $this->startRow && $row <= $this->endRow); 30 | } 31 | } -------------------------------------------------------------------------------- Total de líneas: 31 ================================================================================ ================================================================================ ARCHIVO #220: src/OfficeHelper/SheetDimensions.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/OfficeHelper/SheetDimensions.php Tamaño: 304 bytes -------------------------------------------------------------------------------- 1 | ParticipatingSchedules = array(); 41 | 42 | // Obtener el aporte de avance programado del turno 43 | $workShiftScheduleAcu = $this->GetScheduleProjectionAcu($workShift, $pendingSchedules); 44 | 45 | // Acumular el aporte 46 | $scheduleProjectionAcu += $workShiftScheduleAcu; 47 | 48 | // Registrar el avance programado neto aportado por el turno y el avance acumulado 49 | $workShift->ScheduleProjectionSum = $scheduleProjectionAcu; 50 | $workShift->ScheduleWorkShiftSum = $workShiftScheduleAcu; 51 | } 52 | } 53 | 54 | function BuildWorkCompletedProjection(GenericCollection $workShifts) { 55 | 56 | $workCompletedBag = new GenericCollection( 57 | Key : "TaskReferenceKey", 58 | DtoName : WorkShiftCompleted::class, 59 | Values : null 60 | ); 61 | 62 | // Variables de control 63 | // ******************************* 64 | // Valor acumulado de workcompleted de toda la proyección 65 | $workCompletedProjectionAcu = 0; 66 | 67 | // Recorremos los workshifts 68 | foreach($workShifts as $workShift) { 69 | 70 | $workShift->ParticipatingWorkCompleted = array(); 71 | 72 | // Obtener el aporte de workcompleted del turno 73 | $workShiftWorkCompletedAcu = $this->GetWorkCompletedProjectionAcu($workShift, $workCompletedBag); 74 | 75 | // Acumular el aporte 76 | $workCompletedProjectionAcu += $workShiftWorkCompletedAcu; 77 | 78 | // Registrar el workcompleted neto aportado por el turno y el workcompleted acumulado 79 | $workShift->WorkCompletedProjectionSum = $workCompletedProjectionAcu; 80 | $workShift->WorkCompletedWorkShiftSum = $workShiftWorkCompletedAcu; 81 | } 82 | 83 | $this->GlobalWorkCompleted = $workCompletedProjectionAcu; 84 | } 85 | 86 | function BuildForecastProjection(GenericCollection $workShifts, Projection $projection) { 87 | 88 | // Modificar los workshifts según reglas del negocio 89 | // En este caso, vamos a calcular la cantidad de avance 90 | // según la programacion corregida con offset y según registro que se va acumulando 91 | // por cada turno 92 | 93 | // Aqui iremos almacenando los schedules que inician en un turno, pero finalizan después 94 | $pendingSchedules = new GenericCollection( 95 | Key : "ScheduleId", 96 | DtoName : WorkShiftSchedule::class, 97 | Values : null 98 | ); 99 | 100 | // Variables de control 101 | // ******************************* 102 | // Valor acumulado de schedule de toda la proyección (inicia en el ultimo valor del registrado) 103 | $scheduleForecastAcu = ($this->GlobalWorkCompleted > 0) ? $this->GlobalWorkCompleted : 0; 104 | 105 | foreach($workShifts as $workShift) { 106 | 107 | // Monitoring 108 | $workShift->ParticipatingActualSchedules = array(); 109 | 110 | // Obtener el aporte de avance programado del turno 111 | $workShiftActualScheduleAcu = $this->GetForecastProjectionAcu($workShift, $pendingSchedules); 112 | 113 | if ($workShiftActualScheduleAcu > 0) { 114 | // Acumular el aporte 115 | $scheduleForecastAcu += $workShiftActualScheduleAcu; 116 | 117 | // Registrar el avance programado neto aportado por el turno y el avance acumulado 118 | $workShift->ForecastProjectionSum = $scheduleForecastAcu; 119 | $workShift->ForecastWorkShiftSum = $workShiftActualScheduleAcu; 120 | } 121 | } 122 | 123 | } 124 | 125 | /** 126 | * Calcula el aporte de avance programado de las tareas en el turno expecificado 127 | * 128 | * @param WorkShift @workShift El turno a analizar 129 | * @param GenericColletion $pendingSchedules Las tareas que iniciaron en turnos anteriores, pero que aún no finalizan según programación 130 | * 131 | * @return number Entrega el porcentaje de aporte de las tareas dentro del turno 132 | */ 133 | private function GetScheduleProjectionAcu(WorkShift $workShift, $pendingSchedules) { 134 | 135 | $workShiftScheduleAcu = 0; 136 | 137 | // Agregar los schedules pendientes 202004172000 / 202004171657 138 | if ($pendingSchedules->Count() > 0) { 139 | 140 | // Obtener los schedules pendientes de workshifts anteriores que aún no están programados para finalizar 141 | $pendientes = $pendingSchedules->Where("EndDateBlock > " . $workShift->WorkShiftStartDateBlock); 142 | 143 | foreach($pendientes as $pendingSchedule) { 144 | 145 | // Obtener el aporte neto del schedule al workshift actual (ya se aplica el "peso" del schedule respecto del conjunto total) 146 | $startDate = ($pendingSchedule->StartDate >= $workShift->WorkShiftStartDate) ? $pendingSchedule->StartDate : $workShift->WorkShiftStartDate; 147 | $endDate = ($pendingSchedule->EndDate <= $workShift->WorkShiftEndDate) ? $pendingSchedule->EndDate : $workShift->WorkShiftEndDate; 148 | 149 | $porcentajeNeto = $this->GetWorkShiftPercentageParticipation( 150 | $startDate, $endDate, $pendingSchedule->Duration, $pendingSchedule->Weight 151 | ); 152 | 153 | // Registrar el avance acumulado 154 | $workShiftScheduleAcu += $porcentajeNeto; 155 | 156 | array_push($workShift->ParticipatingSchedules, $pendingSchedule); 157 | } 158 | } 159 | 160 | // Analizar los schedules del workshift que inician dentro del workshift actual 161 | // 162 | foreach($workShift->WorkShiftSchedules as $schedule) { 163 | 164 | $startDate = ($schedule->StartDate >= $workShift->WorkShiftStartDate) ? $schedule->StartDate : $workShift->WorkShiftStartDate; 165 | $endDate = ($schedule->EndDate <= $workShift->WorkShiftEndDate) ? $schedule->EndDate : $workShift->WorkShiftEndDate; 166 | 167 | // Obtener el aporte neto del schedule al workshift actual (ya se aplica el "peso" del schedule respecto del conjunto total) 168 | $porcentajeNeto = $this->GetWorkShiftPercentageParticipation( 169 | $startDate, $endDate, $schedule->Duration, $schedule->Weight 170 | ); 171 | 172 | // Registrar el avance acumulado 173 | $workShiftScheduleAcu += $porcentajeNeto; 174 | 175 | // Si la tarea continua al siguiente turno, agregar a las tareas pendientes 176 | if ($schedule->EndDateBlock > $workShift->WorkShiftEndDateBlock) { 177 | // No necesitaremos indexar por ahora (false) 178 | $pendingSchedules->Add($schedule, false); 179 | } 180 | 181 | array_push($workShift->ParticipatingSchedules, $schedule); 182 | } 183 | 184 | 185 | return $workShiftScheduleAcu; 186 | } 187 | 188 | 189 | /** 190 | * Calcula el aporte de avance programado modificado con Offset 191 | * 192 | * @param WorkShift @workShift El turno a analizar 193 | * @param GenericColletion $pendingSchedules Las tareas que iniciaron en turnos anteriores, pero que aún no finalizan según programación 194 | * 195 | * @return number Entrega el porcentaje de aporte de las tareas dentro del turno 196 | */ 197 | private function GetForecastProjectionAcu(WorkShift $workShift, $pendingSchedules) { 198 | 199 | $workShiftForecastAcu = 0; 200 | 201 | // Agregar los schedules pendientes 202004172000 / 202004171657 202 | if ($pendingSchedules->Count() > 0) { 203 | 204 | // Obtener los schedules pendientes de workshifts anteriores que aún no están programados para finalizar 205 | $pendientes = $pendingSchedules->Where("ActualEndDateBlock > " . $workShift->WorkShiftStartDateBlock); 206 | 207 | foreach($pendientes as $pendingSchedule) { 208 | 209 | // Obtener el aporte neto del schedule al workshift actual (ya se aplica el "peso" del schedule respecto del conjunto total) 210 | $startDate = ($pendingSchedule->ActualStartDate >= $workShift->WorkShiftStartDate) ? $pendingSchedule->ActualStartDate : $workShift->WorkShiftStartDate; 211 | $endDate = ($pendingSchedule->ActualEndDate <= $workShift->WorkShiftEndDate) ? $pendingSchedule->ActualEndDate : $workShift->WorkShiftEndDate; 212 | 213 | $porcentajeNeto = $this->GetWorkShiftRemanentPercentage( 214 | $startDate, $endDate, $pendingSchedule->ActualDuration, $pendingSchedule->Duration, $pendingSchedule->Weight 215 | ); 216 | 217 | // Registrar el avance acumulado 218 | $workShiftForecastAcu += $porcentajeNeto; 219 | 220 | // Monitoring 221 | array_push($workShift->ParticipatingActualSchedules, $pendingSchedule); 222 | } 223 | } 224 | 225 | // Analizar los schedules del workshift que inician dentro del workshift actual 226 | // 227 | foreach($workShift->WorkShiftActualSchedules as $schedule) { 228 | 229 | $startDate = ($schedule->ActualStartDate >= $workShift->WorkShiftStartDate) ? $schedule->ActualStartDate : $workShift->WorkShiftStartDate; 230 | $endDate = ($schedule->ActualEndDate <= $workShift->WorkShiftEndDate) ? $schedule->ActualEndDate : $workShift->WorkShiftEndDate; 231 | 232 | // Obtener el aporte neto del schedule al workshift actual (ya se aplica el "peso" del schedule respecto del conjunto total) 233 | $porcentajeNeto = $this->GetWorkShiftRemanentPercentage( 234 | $startDate, $endDate, $schedule->ActualDuration, $schedule->Duration, $schedule->Weight 235 | ); 236 | 237 | // Registrar el avance acumulado 238 | $workShiftForecastAcu += $porcentajeNeto; 239 | 240 | // Si la tarea continua al siguiente turno, agregar a las tareas pendientes 241 | if ($schedule->ActualEndDateBlock > $workShift->WorkShiftEndDateBlock) { 242 | // No necesitaremos indexar por ahora (false) 243 | $pendingSchedules->Add($schedule, false); 244 | } 245 | 246 | // Monitoring 247 | array_push($workShift->ParticipatingActualSchedules, $schedule); 248 | } 249 | 250 | 251 | return $workShiftForecastAcu; 252 | } 253 | 254 | 255 | /** 256 | * Calcula el aporte de workcompleted (avance registrado) de las tareas en el turno expecificado 257 | * 258 | * @param WorkShift @workShift El turno a analizar 259 | * @param GenericColletion $workCompletedBag Los registros de avance asociados a tareas especificas, que se deben considerar al obtener el diferencial de avance 260 | * 261 | * @return number Entrega el porcentaje de aporte de los avances dentro del turno 262 | */ 263 | private function GetWorkCompletedProjectionAcu(WorkShift $workShift, $workCompletedBag) { 264 | 265 | $workShiftWorkCompletedAcu = 0; 266 | 267 | foreach($workShift->WorkShiftCompleted as $workCompleted) { 268 | 269 | // Primero necesitamos conocer el valor anterior reportado para esta tarea en algún turno previo 270 | // y que se va acumulando en el $workCompletedBag 271 | $taskBag = $workCompletedBag->Find($workCompleted->TaskReferenceKey); 272 | $lastWorkCompleted = 0; 273 | if (isset($taskBag)) { 274 | // Este valor, a diferencia de los valores en el WorkShiftCompleted del Projection, tienen aplicado 275 | // el "peso" de la tarea en el cálculo 276 | $lastWorkCompleted = $taskBag->WorkCompleted; 277 | } 278 | 279 | // Obtenemos el aporte actual del workCompleted 280 | $currentWorkCompleted = $workCompleted->WorkCompleted; 281 | 282 | // Debemos calcular la diferencia entre lo ultimo calculado y el valor actual informado 283 | // Se asume que siempre es incremental, pero cuando sea decremental se obtendrá un valor negativo 284 | // lo cual hará disminuir el total acumulado y retrasará la proyección 285 | $difference = $currentWorkCompleted - $lastWorkCompleted; 286 | 287 | $workCompleted->CurrentPercentageParticipation = $difference; 288 | 289 | // Actualizamos el bag 290 | if (isset($taskBag)) { 291 | $taskBag->WorkCompleted = $currentWorkCompleted; 292 | $workCompleted->PreviousExists = 1; 293 | } 294 | else { 295 | // Agregamos un bag 296 | $wcomp = new WorkShiftCompleted(); 297 | $wcomp->CompletedId = $workCompleted->CompletedId; 298 | $wcomp->TaskReferenceKey = $workCompleted->TaskReferenceKey; 299 | $wcomp->WorkCompleted = $currentWorkCompleted; 300 | 301 | $workCompletedBag->Add($wcomp); 302 | $workCompleted->PreviousExists = 0; 303 | } 304 | 305 | array_push($workShift->ParticipatingWorkCompleted, $workCompleted); 306 | 307 | // Acumulamos la diferencia 308 | $workShiftWorkCompletedAcu += $difference; 309 | } 310 | 311 | return $workShiftWorkCompletedAcu; 312 | } 313 | 314 | /** 315 | * Obtiene el porcentaje de avance de hora de esta tarea respecto del turno actual, sólo la parte que cae dentro 316 | * del rango de horas del turno. Aplica el "peso" de la tarea al resultado y entrega el porcentaje neto 317 | */ 318 | public function GetWorkShiftPercentageParticipation(\DateTime $startDate = null, \DateTime $endDate, $taskDuration, $weight) { 319 | 320 | // calcular el avance en horas (horas consumidas del schedule dentro de este workshift) 321 | // 322 | $avanceHoras = WorkShift::GetDateDifference($startDate, $endDate); // en horas 323 | 324 | // calcular el porcentaje de las horas consumidas, respecto del total de horas 325 | // de la tarea (el "porcentaje" de avance programado) 326 | // 327 | $porcentaje = ($avanceHoras*100) / $taskDuration; 328 | 329 | // aplicar el "peso" del schedule respecto del conjunto total al porcentaje calculado 330 | // 331 | $porcentajeNeto = $porcentaje * $weight; 332 | 333 | return $porcentajeNeto; 334 | } 335 | 336 | public function GetWorkShiftRemanentPercentage(\DateTime $startDate = null, \DateTime $endDate, $actualDuration, $duration, $weight) { 337 | // calcular el avance en horas (horas consumidas del schedule dentro de este workshift) 338 | // 339 | $avanceHoras = WorkShift::GetDateDifference($startDate, $endDate); // en horas 340 | 341 | // calcular el porcentaje de las horas consumidas, respecto del total de horas de la tarea 342 | // 343 | $porcentaje = ($avanceHoras*100) / $actualDuration; 344 | 345 | // calcular el porcentaje del ActualDuration respecto del total de horas de la tarea 346 | $porcentaje = $porcentaje * ($actualDuration / $duration); 347 | 348 | // aplicar el "peso" del schedule respecto del conjunto total al porcentaje calculado 349 | $porcentajeNeto = $porcentaje * $weight; 350 | 351 | if ($porcentajeNeto <= 0.05) { 352 | $revisar = true; 353 | } 354 | 355 | return $porcentajeNeto; 356 | } 357 | } 358 | -------------------------------------------------------------------------------- Total de líneas: 358 ================================================================================ ================================================================================ ARCHIVO #222: src/ProjectionEngine/IProjectionBuilder.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/ProjectionEngine/IProjectionBuilder.php Tamaño: 603 bytes -------------------------------------------------------------------------------- 1 | 8 horas (este intervalo debe ser divisor de 24) 28 | /** 29 | * required 30 | * validation = @prop != "" */ 31 | public $ProjectionName = ""; // etiqueta asociada a esta proyeccion 32 | /** 33 | * required 34 | * validation = @prop != "" */ 35 | public $IntervalLabelFormat = ""; // formato de fecha de salida de la etiqueta (ej: 'd-m-Y H:i') 36 | 37 | // Schedule related variables 38 | // ******************************************************************** 39 | /** 40 | * required 41 | * validation = @prop != "" */ 42 | public $TaskKeyField = ""; // nombre del campo que identifica a la tarea 43 | /** 44 | * required 45 | * validation = @prop != "" */ 46 | public $TaskDtoName = ""; // nombre de la entidad de la tarea 47 | /** 48 | * required 49 | * validation = @prop != "" */ 50 | public $StartDateField = ""; // nombre del campo de fecha de inicio programado 51 | /** 52 | * required 53 | * validation = @prop != "" */ 54 | public $EndDateField = ""; // nombre del campo de fin programado 55 | /** 56 | * required 57 | * validation = @prop != "" */ 58 | public $TaskStartDateField = ""; // nombre del campo de fecha de inicio real de la tarea 59 | /** 60 | * required 61 | * validation = @prop != "" */ 62 | public $TaskEndDateField = ""; // nombre del campo de fecha de fin real de la tarea 63 | /** 64 | * required 65 | * validation = @prop != "" */ 66 | public $TaskWorkField = ""; // Trabajo total de la tarea 67 | /** 68 | * required 69 | * validation = @prop != "" */ 70 | public $TaskWorkCompletedField = ""; // Trabajo total de la tarea 71 | /** 72 | * required 73 | * validation = @is_collection(@prop) */ 74 | public $ScheduleValues = null; // los valores de la programacion (en definitiva, las TAREAS) 75 | 76 | // Work related variables 77 | // ******************************************************************** 78 | /** 79 | * required 80 | * validation = @prop != "" */ 81 | public $WorkKeyField = ""; // nombre del campo que identifica al trabajo 82 | /** 83 | * required 84 | * validation = @prop != "" 85 | */ 86 | public $WorkDtoName = ""; // nombre de la entidad del trabajo 87 | /** 88 | * required 89 | * validation = @prop != "" */ 90 | public $TaskReferenceKeyField = ""; // nombre del campo que asocia el trabajo con la tarea 91 | /** 92 | * required 93 | * validation = @prop != "" */ 94 | public $WorkCompletedDateField = ""; // nombre del campo que contiene la fecha en que se registro un cambio en el estado de avance 95 | /** 96 | * required 97 | * validation = @prop != "" */ 98 | public $WorkCompletedField = ""; // nombre del campo que contiene el valor registrado de trabajo completado (avance) 99 | /** 100 | * required 101 | * validation = @is_collection(@prop) */ 102 | public $WorkCompletedValues = null; // los valores del trabajo completado (en definitiva, los AVANCES) 103 | 104 | /** 105 | * required 106 | * validation = isset(@prop) && (@prop instanceof Framework\ProjectionEngine\IProjectionBuilder) 107 | */ 108 | public $ProjectionBuilder; 109 | 110 | /** 111 | * required 112 | * validation = isset(@prop) && (@prop instanceof Framework\ProjectionEngine\IProjectionCalculator) 113 | */ 114 | public $ProjectionCalculator; 115 | 116 | /** 117 | * required 118 | * validation = isset(@prop) && (@prop instanceof Framework\ProjectionEngine\IProjectionResultWriter) 119 | */ 120 | public $ResultWriter; 121 | 122 | 123 | function __construct(array $definition = array()) { 124 | parent::__construct($definition, ProjectionValidator::class); 125 | 126 | // Clonar las colecciones 127 | // $this->ScheduleValues = new GenericCollection([ 128 | // "Key" => $this->TaskKeyField, 129 | // "DtoName" => $this->TaskDtoName, 130 | // "Values" => clone $this->ScheduleValues->Values 131 | // ]); 132 | 133 | $this->ScheduleValues = clone $this->ScheduleValues; 134 | $this->WorkCompletedValues = clone $this->WorkCompletedValues; 135 | 136 | // Convertir todas las fechas de texto en campos DateTime 137 | // 138 | 139 | // SCHEDULES 140 | // 141 | $startDateField = $this->StartDateField; 142 | $endDateField = $this->EndDateField; 143 | $taskStartDateField = $this->TaskStartDateField; 144 | $taskEndDateField = $this->TaskEndDateField; 145 | $workCompletedDateField = $this->WorkCompletedDateField; 146 | 147 | foreach($this->ScheduleValues as $schedule) { 148 | $schedule->$startDateField = new \DateTime($schedule->$startDateField); 149 | $schedule->$endDateField = new \DateTime($schedule->$endDateField); 150 | 151 | if (isset($schedule->$taskStartDateField) && ($schedule->$taskStartDateField != "")) 152 | $schedule->$taskStartDateField = new \DateTime($schedule->$taskStartDateField); 153 | 154 | if (isset($schedule->$taskEndDateField) && $schedule->$taskEndDateField != "") 155 | $schedule->$taskEndDateField = new \DateTime($schedule->$taskEndDateField); 156 | } 157 | 158 | // Ordenar 159 | $this->ScheduleValues->OrderBy($startDateField); 160 | 161 | // WORKCOMPLETED 162 | // 163 | foreach($this->WorkCompletedValues as $workCompleted) { 164 | $workCompleted->$workCompletedDateField = new \DateTime($workCompleted->$workCompletedDateField); 165 | } 166 | 167 | // Ordenar 168 | $this->WorkCompletedValues->OrderBy($workCompletedDateField); 169 | 170 | $stop =0; 171 | } 172 | 173 | } -------------------------------------------------------------------------------- Total de líneas: 173 ================================================================================ ================================================================================ ARCHIVO #228: src/ProjectionEngine/ProjectionValidator.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/ProjectionEngine/ProjectionValidator.php Tamaño: 1.54 KB -------------------------------------------------------------------------------- 1 | 23) return false; 38 | 39 | // Validar minutos 40 | if (!is_numeric($parts[1])) return false; 41 | if ($parts[1]*1 < 0 || $parts[1]*1 > 59) return false; 42 | 43 | // Retorna la fecha de hoy, a la hora especificada 44 | return new DateTime( (new \DateTime())->format('Y-m-d') . " " . $hora); 45 | } 46 | 47 | public function is_valid_interval($intervalo) { 48 | 49 | // Intervalo no puede cubrir más de media jornada 50 | if ($intervalo <= 0 || $intervalo > 12) return false; 51 | 52 | // Intervalo debe ser divisor de 24 53 | if ( 24 % $intervalo != 0) return false; 54 | 55 | return true; 56 | } 57 | } -------------------------------------------------------------------------------- Total de líneas: 57 ================================================================================ ================================================================================ ARCHIVO #229: src/ProjectionEngine/Projector.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/ProjectionEngine/Projector.php Tamaño: 18.51 KB -------------------------------------------------------------------------------- 1 | Projection = $projection; 35 | 36 | // Agregar el trabajo total para no buscarlo cada vez en la coleccion 37 | $this->TotalWork = $this->Projection->ScheduleValues->Sum($this->Projection->TaskWorkField); 38 | 39 | // Generar los WorkShifts 40 | $this->WorkShifts = new GenericCollection( 41 | Key : "WorkShiftId", 42 | DtoName : WorkShift::class, 43 | Values : array() 44 | ); 45 | 46 | // Generar las condiciones de intervalos, para no calcularlo cada vez que se agrega un WorkShift 47 | // Esta coleccion contiene los x intervalos formados por la configuración de turno actual y 48 | // tomando en cuenta la hora de inicio 49 | // 50 | // Ej: si el primer turno inica a las 08:00 y el intervalo es de 6 horas, se generaran los siguientes registros: 51 | // "08:00", "14:00", "20:00" y "02:00" 52 | // 53 | // Esta información es importante para la generación de WorkShifts para poder aproximar al INTERVALO cada fecha 54 | // informada, ya sea de programación o de cambio en avance. Ej: si es 01:15 del 05 de mayo, debe aproximarlo a las 20:00 del 04 de mayo 55 | // Esas aproximaciones se hacen en la generacion de WorkShifts (turnos) - GenerateWorkShifts(), la cual al final utiliza la funcion GetWorkShiftIdFromDate() 56 | // que es la que realiza la aproximaxión en sí. 57 | $this->Intervalos = $this->GetIntervalos($this->Projection->InitialHour, $this->Projection->Interval); 58 | 59 | // Generar los turnos, según SCHEDULE y según WORKCOMPLETED (programado y registrado en lenguaje de curva S) 60 | // También se obtendrá el listado de ActualSchedules para su procesamiento antes del Forecast 61 | $this->GenerateWorkShifts(); 62 | 63 | // Generar un workshift anterior al proyecto, cuya fecha de fin debe corresponder a la fecha/hora de inicio del 64 | // primer turno del proyecto 65 | $this->AddHeaderWorkshift(); 66 | 67 | // En caso de que los registro vengan desordenados, los ordenamos 68 | $this->WorkShifts->OrderBy("WorkShiftId"); 69 | 70 | // La generación de turnos no es lineal, por lo que debemos generar los registros intermedios que no hayan 71 | // venido con información y dejar el arreglo estictamente en intervalos de X horas (según sea el valor de horas del intervalo) 72 | $this->FillWorkShiftsGaps(); 73 | } 74 | 75 | private function AddHeaderWorkshift() { 76 | $primerWorkshift = $this->WorkShifts->First(); 77 | 78 | 79 | if (isset($primerWorkshift)) { 80 | // fecha de incio 81 | $fechaInicio = clone $primerWorkshift->WorkShiftStartDate; 82 | $fechaInicio = $fechaInicio->sub(new \DateInterval('PT1M')); 83 | 84 | $headerWorkshift = $this->GetWorkShift($fechaInicio); 85 | $plop = 1; 86 | } 87 | } 88 | 89 | function Run() { 90 | 91 | // Preparar el aporte acumulado de los schedules (Avance programado) 92 | $this->Projection->ProjectionBuilder->BuildScheduleProjection($this->WorkShifts); 93 | 94 | // Preparar el aporte acumulado de los workcompleted (Avance real) 95 | // Debe obtener también el último workshift para el cual existió registro de avance 96 | $this->Projection->ProjectionBuilder->BuildWorkCompletedProjection($this->WorkShifts); 97 | 98 | // Preparar la información de ActualSchedules, para poder ejecutar el proceso de Forecast 99 | $this->PrepareActualSchedules(); 100 | 101 | // Nuevamente, debemos llenar los WorkShifts que no hayan tenidos datos entremedio 102 | $this->FillWorkShiftsGaps(); 103 | 104 | // Preparar al forecast (Avance proyectado) 105 | $this->Projection->ProjectionBuilder->BuildForecastProjection($this->WorkShifts, $this->Projection); 106 | 107 | // Ejecutar reglas de negocio sobre los datos proyectados 108 | $this->Projection->ProjectionCalculator->RunProjection($this->WorkShifts, $this->Projection); 109 | 110 | // Extraer los resultados 111 | return $this->Projection->ResultWriter->WriteResults($this->WorkShifts, $this->Projection); 112 | } 113 | 114 | private function PrepareActualSchedules() { 115 | 116 | // Variables a utilizar 117 | // $this->ActualSchedules : contiene una copia de todos los schedules originales, y su fecha corregida de inicio programado (ActualStarDate) 118 | // $this->ActualSchedulesMinActualStartDate : contiene la menor fecha de inicio corregida, de la lista anterior. 119 | // $this->WorkCompletedLastDate : contiene la ultima fecha en la que se registró avance 120 | 121 | // Primero, calcular el startDateOffset utilizando el WorkCompletedLastDate y la ActualSchedulesMinActualStartDate 122 | $startDateOffset = 0; // minutos 123 | 124 | if (isset($this->WorkCompletedWorkShiftLastDate)) { 125 | // Este es el ultimo workshift que tiene avance registrado 126 | // La fecha del último avance registrado constituye la fecha de inicio 127 | // del forecast (avance proyectado) 128 | // Por lo tanto debemos calcular la diferencia que tiene con la fecha menor de 129 | // fecha de inicio programada de los workshifts totales 130 | if (isset($this->ActualSchedulesMinActualStartDate)) { 131 | // Calculamos el startDateOffset entre la menor fecha de inicio y la fecha del último registro 132 | if ($this->ActualSchedulesMinActualStartDate < $this->WorkCompletedWorkShiftLastDate) 133 | // Traer la fecha en "minutos" para poder redondear sin pérdida de precisión 134 | //$startDateOffset = round(WorkShift::GetDateDifference($this->ActualSchedulesMinActualStartDate, $this->WorkCompletedWorkShiftLastDate, WorkShiftDatePartEnum::MINUTE), 0); 135 | $startDateOffset = WorkShift::GetDateDifference($this->ActualSchedulesMinActualStartDate, $this->WorkCompletedWorkShiftLastDate, WorkShiftDatePartEnum::SECOND); 136 | } 137 | } 138 | else { 139 | // Si no hay registros, el startDateOffset será CERO y la proyección comenzará de inmediato 140 | $startDateOffset = 0; 141 | } 142 | 143 | // Si hay startDateOffset, debemos aplicarlo a todas las fechas del arreglo 144 | 145 | 146 | // Primero generamos los turnos según programación corregida 147 | // 148 | foreach($this->ActualSchedules as $schedule) { 149 | 150 | // Aplicar el startDateOffset al ActualStarDate y al ActualEndDate del schedule 151 | // 152 | if ($startDateOffset > 0) { 153 | $schedule->ActualStartDate = date_add($schedule->ActualStartDate, new \DateInterval("PT" . $startDateOffset . "S")); 154 | $schedule->ActualStartDateBlock = $schedule->ActualStartDate->format('YmdHis')*1; 155 | $schedule->ActualEndDate = date_add($schedule->ActualEndDate, new \DateInterval("PT" . $startDateOffset . "S")); 156 | $schedule->ActualEndDateBlock = $schedule->ActualEndDate->format('YmdHis')*1; 157 | } 158 | 159 | // Obtener el workshift 160 | // 161 | $workShift = $this->GetWorkShift($schedule->ActualStartDate); 162 | 163 | // Agregar la tarea al turno 164 | // 165 | $newSchedule = $workShift->AddWorkShiftActualSchedule($schedule); 166 | } 167 | 168 | // Reordenar los workshifts 169 | $this->WorkShifts->OrderBy("WorkShiftId"); 170 | } 171 | 172 | private function FillWorkShiftsGaps() { 173 | 174 | // Obtener el primer WorkShift 175 | $startWorkShift = $this->WorkShifts->Min("WorkShiftId"); 176 | // Obtener el ultimo WorkShift 177 | $endWorkShift = $this->WorkShifts->Max("WorkShiftId"); 178 | 179 | if (isset($startWorkShift) && isset($endWorkShift) && ($startWorkShift < $endWorkShift)) { 180 | // Realizar el bucle de busqueda 181 | $dateStart = WorkShift::GetDateFromWorkShiftId($startWorkShift); 182 | $dateEnd = WorkShift::GetDateFromWorkShiftId($endWorkShift); 183 | 184 | $date = $dateStart; 185 | // Ciclos de seguridad 186 | $maxCiclos = 1000; 187 | $ciclo = 1; 188 | // Verificar si se han agregado workshifts a la coleccion (sólo si se agregaron, la reindexamos) 189 | $added = false; 190 | 191 | while ($date < $dateEnd && $ciclo < $maxCiclos) { 192 | 193 | // Encontrar el turno correspondiente 194 | // Obs: 195 | // Dado que los WorkShifts ya están indexados por la fecha convertida, no se 196 | // realizará conversión por la función GetWorkShiftIdFromDate, sino que realizaremos 197 | // una conversión simple con format() 198 | $workshiftId = $date->format('YmdHi') * 1; 199 | 200 | // Buscamos si el WorkShift no existe, para crearlo 201 | $currentWorkShift = $this->WorkShifts->Find($workshiftId); 202 | 203 | if (!isset($currentWorkShift)) { 204 | // Creamos el workshift 205 | $currentWorkShift = new WorkShift($workshiftId, $this->TotalWork, $this->Projection->Interval, $this->Projection->IntervalLabelFormat); 206 | // Agregamos el workshift a la coleccion de la proyeccion 207 | $this->WorkShifts->Add($currentWorkShift, false); 208 | 209 | $added = true; 210 | } 211 | 212 | // Avanzar el turno en la cantidad de horas indicada por el intervalo de la proyección 213 | $date = $date->add(new \DateInterval("PT" . $this->Projection->Interval . "H")); 214 | $ciclo++; 215 | } 216 | 217 | // Si se agregaron workshifts, reindexamos el arreglo para que quede en orden de fecha 218 | if ($added) { 219 | $this->WorkShifts->OrderBy("WorkShiftId"); 220 | } 221 | } 222 | } 223 | 224 | /** 225 | * Recorre todos los valores de SCHEDULE y de WORKCOMPLETED y genera los workshifts necesarios 226 | * según las fechas de cada collección 227 | * 228 | * @return void 229 | */ 230 | private function GenerateWorkShifts() { 231 | $scheduleStartDateField = $this->Projection->StartDateField; 232 | $scheduleEndDateField = $this->Projection->EndDateField; 233 | $scheduleWorkField = $this->Projection->TaskWorkField; 234 | $workCompletedDateField = $this->Projection->WorkCompletedDateField; 235 | $workCompletedField = $this->Projection->WorkCompletedField; 236 | $taskWorkCompletedField = $this->Projection->TaskWorkCompletedField; 237 | $taskReferenceKeyField = $this->Projection->TaskReferenceKeyField; 238 | $taskWorkField = $this->Projection->TaskWorkField; 239 | 240 | // Este arreglo contiene todos los schedules, se utiliará para 241 | // aplicarles el startDateOffset con el ultimo avance registrado y poder 242 | // realizar el forecast 243 | $this->ActualSchedules = array(); 244 | 245 | // Primero generamos los turnos según programación 246 | // 247 | foreach($this->Projection->ScheduleValues as $schedule) { 248 | 249 | // Obtener el workshift 250 | // 251 | $workShift = $this->GetWorkShift($schedule->$scheduleStartDateField); 252 | 253 | // Calcular el duration del Schedule en horas 254 | // 255 | $duration = WorkShift::GetDateDifference($schedule->$scheduleStartDateField, $schedule->$scheduleEndDateField); 256 | 257 | // Agregar la tarea al turno 258 | // 259 | $newSchedule = $workShift->AddWorkShiftSchedule( 260 | $schedule->$scheduleStartDateField, 261 | $schedule->$scheduleEndDateField, 262 | $schedule->$scheduleWorkField, 263 | $schedule->$taskWorkCompletedField, 264 | $duration, 265 | $this->TotalWork, 266 | $schedule 267 | ); 268 | 269 | // Agregarlo al arreglo local si la tarea no se ha completado 270 | if ($schedule->$taskWorkCompletedField < 100) { 271 | array_push($this->ActualSchedules, clone $newSchedule); 272 | 273 | // Actualizar la menor fecha de inicio 274 | if (!isset($this->ActualSchedulesMinActualStartDate) || ($newSchedule->ActualStartDate < $this->ActualSchedulesMinActualStartDate)) { 275 | $this->ActualSchedulesMinActualStartDate = clone $newSchedule->ActualStartDate; 276 | } 277 | } 278 | } 279 | 280 | // Luego, generamos los turnos según workcompleted (avances) 281 | // 282 | $this->WorkCompletedWorkShiftLastDate = null; 283 | foreach($this->Projection->WorkCompletedValues as $work) { 284 | 285 | // Obtener el workshift 286 | $workShift = $this->GetWorkShift($work->$workCompletedDateField); 287 | 288 | // Obtener el esfuerzo de la tarea asociada 289 | $taskReferenceKey = $work->$taskReferenceKeyField; 290 | $task = $this->Projection->ScheduleValues->Find($taskReferenceKey); 291 | $taskWork = $task->$taskWorkField; 292 | 293 | $newWorkCompleted = $workShift->AddWorkShiftCompleted( 294 | $work->$workCompletedDateField, 295 | $work->$taskReferenceKeyField, 296 | $taskWork, 297 | $work->$workCompletedField, 298 | $this->TotalWork 299 | ); 300 | 301 | $newWorkCompleted->BusinessObject = $work; 302 | 303 | // Actualizar la ultima fecha de registro 304 | if (!isset($this->WorkCompletedWorkShiftLastDate)) { 305 | $this->WorkCompletedWorkShiftLastDate = $workShift->WorkShiftEndDate; // $work->$workCompletedDateField; 306 | } 307 | else { 308 | if ($workShift->WorkShiftEndDate > $this->WorkCompletedWorkShiftLastDate) 309 | $this->WorkCompletedWorkShiftLastDate = $workShift->WorkShiftEndDate; 310 | } 311 | } 312 | } 313 | 314 | /** 315 | * Entrega el WorkShift (turno) buscado según una fecha. Se aproximará la fecha al WorkShift que finaliza más tarde pero anterior a la fecha especificada 316 | * Si el WorkShift no existe, se agrega uno nuevo a la colección principal de la clase y se devuelve 317 | * 318 | * @param DateTime $date La fecha mediante la cual se buscará un WorkShift (turno) 319 | * 320 | * @return WorkShift El workshift buscado 321 | */ 322 | private function GetWorkShiftOld($date) { 323 | 324 | return $this->GetWorkShift(new \DateTime($date)); 325 | 326 | /* 327 | // Obtener el ID de turno asociado a esta tarea 328 | $workShiftId = WorkShift::GetWorkShiftIdFromDate( 329 | new \DateTime($date), 330 | $this->Intervalos, 331 | $this->Projection->Interval 332 | ); 333 | 334 | // Obtener el turno a modificar (si no existe, lo creamos) 335 | $workShift = $this->WorkShifts->Find($workShiftId); 336 | if (!isset($workShift)) { 337 | $workShift = new WorkShift( 338 | $workShiftId, 339 | $this->TotalWork, 340 | $this->Projection->Interval, 341 | $this->Projection->IntervalLabelFormat 342 | ); 343 | 344 | // Se debe agregar a la coleccion 345 | $this->WorkShifts->Add($workShift); 346 | } 347 | 348 | return $workShift; 349 | */ 350 | } 351 | 352 | private function GetWorkShift(\DateTime $date) { 353 | // Obtener el ID de turno asociado a esta tarea 354 | $workShiftId = WorkShift::GetWorkShiftIdFromDate( 355 | $date, 356 | $this->Intervalos, 357 | $this->Projection->Interval 358 | ); 359 | 360 | // Obtener el turno a modificar (si no existe, lo creamos) 361 | $workShift = $this->WorkShifts->Find($workShiftId); 362 | if (!isset($workShift)) { 363 | $workShift = new WorkShift( 364 | $workShiftId, 365 | $this->TotalWork, 366 | $this->Projection->Interval, 367 | $this->Projection->IntervalLabelFormat 368 | ); 369 | 370 | // Se debe agregar a la coleccion 371 | $this->WorkShifts->Add($workShift); 372 | } 373 | 374 | return $workShift; 375 | } 376 | 377 | /** 378 | * Genera una colección con las HORAS de INICIO de los WorkShifts según la hora de inicio primera de la proyección 379 | * y el valor de duración del intervalo en horas. 380 | * 381 | * Ej: si el primer turno inica a las 08:00 y el intervalo es de 6 horas, se generaran los siguientes registros: 382 | * "08:00", "14:00", "20:00" y "02:00" 383 | * 384 | * @param string $inicioTurno La hora de inicio de la programación. Ej: "08:30" 385 | * @param int $intervalo La duración del intervalo en horas. Debe ser mayor a cero, menor a 24 y ser divisor de 24 (1, 2, 3, 4, 6, 8, 12) 386 | * 387 | * @return GenericCollection Retorna la coleccion con los valores de horas de cada turno resultante. 388 | */ 389 | private function GetIntervalos($inicioTurno, $intervalo) { 390 | 391 | $valores = array(); 392 | 393 | $pivote = str_replace(":", "", $inicioTurno)*1; 394 | 395 | // Agregar el primer intervalo, el pivote 396 | $item = new Intervalo(); 397 | $item->Clave = $pivote; 398 | $item->Valor = $inicioTurno; 399 | array_push($valores, $item); 400 | 401 | $idx = $intervalo*100; 402 | $maxCiclos = 25; // seguridad para prevenir loop infinito 403 | $nuevoValor = $pivote; 404 | 405 | // hacia arriba 406 | $ciclo = 1; 407 | while ($ciclo < $maxCiclos) { 408 | //$idx += ($intervalo*100); 409 | $nuevoValor += $idx; 410 | 411 | if (($nuevoValor) >= 2400) break; 412 | 413 | $valor = str_pad($nuevoValor . "", 4, "0", STR_PAD_LEFT); 414 | $valor = substr($valor, 0, 2) . ":" . substr($valor, 2, 2); 415 | 416 | $item = new Intervalo(); 417 | $item->Clave = $nuevoValor; 418 | $item->Valor = $valor; 419 | 420 | array_push($valores, $item); 421 | 422 | $ciclo++; 423 | } 424 | 425 | // hacia abajo 426 | $ciclo = 1; 427 | $nuevoValor = $pivote; 428 | while ($ciclo < $maxCiclos) { 429 | //$idx += ($intervalo*100); 430 | $nuevoValor -= $idx; 431 | 432 | if (($nuevoValor) < 0) break; 433 | 434 | $valor = str_pad($nuevoValor . "", 4, "0", STR_PAD_LEFT); 435 | $valor = substr($valor, 0, 2) . ":" . substr($valor, 2, 2); 436 | 437 | $item = new Intervalo(); 438 | $item->Clave = $nuevoValor; 439 | $item->Valor = $valor; 440 | 441 | array_push($valores, $item); 442 | 443 | $ciclo++; 444 | } 445 | 446 | return new IntervaloCollection([ 447 | "Key" => "Clave", 448 | "DtoName" => Intervalo::class, 449 | "Values" => $valores 450 | ]); 451 | } 452 | 453 | } -------------------------------------------------------------------------------- Total de líneas: 453 ================================================================================ ================================================================================ ARCHIVO #230: src/ProjectionEngine/WorkShift.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/ProjectionEngine/WorkShift.php Tamaño: 10.18 KB -------------------------------------------------------------------------------- 1 | WorkShiftId = $workShiftId; 65 | $this->TotalWork = $totalWork; 66 | $this->WorkShiftDuration = $interval; 67 | $this->WorkShiftStartDate = self::GetDateFromWorkShiftId($workShiftId); 68 | $this->WorkShiftEndDate = (clone $this->WorkShiftStartDate)->add(new \DateInterval("PT" . $interval . "H")); 69 | $this->WorkShiftLabel = $this->WorkShiftStartDate->format($labelFormat); 70 | 71 | $this->WorkShiftStartDateBlock = $this->WorkShiftStartDate->format('YmdHis')*1; 72 | $this->WorkShiftEndDateBlock = $this->WorkShiftEndDate->format('YmdHis')*1; 73 | 74 | // Crear la coleccion de Schedules (tareas) 75 | $this->WorkShiftSchedules = new GenericCollection( 76 | Key : "ScheduleId", 77 | DtoName : WorkShiftSchedule::class, 78 | Values : array() 79 | ); 80 | 81 | // Crear la coleccion de WorkCompleted (avances) 82 | $this->WorkShiftCompleted = new GenericCollection( 83 | Key : "CompletedId", 84 | DtoName : WorkShiftCompleted::class, 85 | Values : array() 86 | ); 87 | 88 | // Crear la coleccion de Actual Schedules (tareas con fecha de inicio corregida con offset) 89 | $this->WorkShiftActualSchedules = new GenericCollection( 90 | Key : "ScheduleId", 91 | DtoName : WorkShiftSchedule::class, 92 | Values : array() 93 | ); 94 | 95 | } 96 | 97 | // Administracion de las colecciones 98 | // ************************************************************** 99 | 100 | /** 101 | * Agrega un schedule a este turno 102 | * 103 | * @param startDate La fecha de inicio programada 104 | * @param endDate La fecha de fin programada 105 | * @param work El esfuerzo declarado en la tarea 106 | * 107 | * @return WorkShiftSchedule El schedule agregado al turno 108 | */ 109 | public function AddWorkShiftSchedule(\DateTime $startDate, \DateTime $endDate, $work, $workCompleted, $duration, $totalWork, $businessObject = null) { 110 | 111 | $wss = WorkShiftSchedule::New($this->currentScheduleId, $startDate, $endDate, $work, $workCompleted, $duration, $totalWork, $businessObject); 112 | 113 | $this->WorkShiftSchedules->Add($wss); 114 | $this->currentScheduleId++; 115 | 116 | return $wss; 117 | } 118 | 119 | /** 120 | * Agrega un ActualSchedule a este turno, para el calculo de la proyeccion 121 | */ 122 | public function AddWorkShiftActualSchedule(WorkShiftSchedule $schedule) { 123 | $this->WorkShiftActualSchedules->Add($schedule); 124 | } 125 | 126 | /** 127 | * Agrega una marca de trabajo completado (no necesariamente al 100%) al turno 128 | * 129 | * @param completedDate La fecha en que se registró el avance o trabajo completado 130 | * @param workCompleted El porcentaje de completitud del trabajo (avance) 131 | * 132 | * @return void 133 | */ 134 | public function AddWorkShiftCompleted(\DateTime $completedDate, $taskReferenceKey, $taskWork, $workCompleted, $totalWork) { 135 | 136 | $wsc = WorkShiftCompleted::New($this->currentCompletedId, $completedDate, $taskReferenceKey, $taskWork, $workCompleted, $totalWork); 137 | 138 | $this->WorkShiftCompleted->Add($wsc); 139 | $this->currentCompletedId++; 140 | 141 | return $wsc; 142 | } 143 | 144 | // FUNCIONES Utilitarias 145 | // ************************************************************** 146 | 147 | /** 148 | * Obtiene un valor de turno en formato YmdHi respecto de la fecha 149 | * que se especifica. El valor de la fecha es llevado hacia atrás hasta 150 | * alcanzar el inicio del turno respectivo 151 | * 152 | * @param date La fecha que deseamos procesar 153 | * @param inicioTurno La hora en que se inicia el primer turno de la projeccion 154 | * @param intervalo El intervalo de horas que corresponde al turno 155 | * 156 | * @return integer La llave del turno correspondiente formateada como YYYYmmddHHii 157 | */ 158 | public static function GetWorkShiftIdFromDate(\DateTime $date, GenericCollection $intervalos, $intervalo) { 159 | return self::GetWorkShiftStartDateFromDate($date, $intervalos, $intervalo)->format('YmdHi') * 1; 160 | } 161 | 162 | /** 163 | * Obtiene la fecha de turno en formato DateTime respecto de la fecha 164 | * que se especifica. El valor de la fecha es llevado hacia atrás hasta 165 | * alcanzar el inicio del turno respectivo 166 | * 167 | * @param date La fecha que deseamos procesar 168 | * @param inicioTurno La hora en que se inicia el primer turno de la projeccion 169 | * @param intervalo El intervalo de horas que corresponde al turno 170 | * 171 | * @return DateTime La fecha de inicio del turno correspondiente 172 | */ 173 | public static function GetWorkShiftStartDateFromDate(\DateTime $date, GenericCollection $intervalos, $intervalo) { 174 | 175 | // Obtener el intervalo de hora de la fecha especificada 176 | $actual = $date->format("Hi") * 1; 177 | $intervaloEncontrado = null; 178 | $dayShift = 0; 179 | 180 | // Calcular el intervalo correcto 181 | // Caso 1, el intervalo de la fecha es mayor al máximo intervalo existente 182 | $maxClave = $intervalos->Max("Clave"); 183 | $minClave = $intervalos->Min("Clave"); 184 | 185 | if ($actual > $maxClave) { 186 | $intervaloEncontrado = $intervalos->ItemMax("Clave"); 187 | } 188 | else if ($actual < $minClave) { 189 | $intervaloEncontrado = $intervalos->ItemMin("Clave"); 190 | $dayShift = $intervalo; 191 | } 192 | else { 193 | // habrá que recorrerlos todos. La coleccion debe estar ordenado en forma Descendente 194 | $datos = $intervalos->OrderedBy("Clave DESC"); 195 | 196 | foreach($datos as $intervalo) { 197 | if ($actual >= $intervalo->Clave) { 198 | $intervaloEncontrado = $intervalo; 199 | break; 200 | } 201 | } 202 | } 203 | 204 | if (isset($intervaloEncontrado)) { 205 | // Ok, fabriquemos la fecha 206 | $fecha = new \DateTime( $date->format('Y-m-d') . " " . $intervaloEncontrado->Valor); 207 | 208 | if ($dayShift != 0) { 209 | $fecha = $fecha->sub(new \DateInterval("PT" . $dayShift . "H")); 210 | } 211 | 212 | return $fecha; 213 | } 214 | 215 | return null; 216 | 217 | // Ejemplos con: 218 | // inicio de turno: 08:00 219 | // 220 | // ej 1: 221 | // fecha: 01-05-2020 06:47 222 | // turno: 01-05-2020 08:00 223 | // esper: 30-04-2020 20:00 224 | 225 | // ej 2: 226 | // fecha: 01-05-2020 21:51 227 | // turno: 01-05-2020 08:00 228 | // esper: 01-05-2020 20:00 229 | 230 | // ej 3: 231 | // fecha: 01-05-2020 14:09 232 | // turno: 01-05-2020 08:00 233 | // esper: 01-05-2020 08:00 234 | } 235 | 236 | /** 237 | * Obtiene la fecha de turno en formato DateTime respecto de la llave del turno 238 | * que se almacena como entero. 239 | * 240 | * @param workShiftId La llave del turno 241 | * 242 | * @return DateTime La fecha de inicio del turno correspondiente 243 | */ 244 | public static function GetDateFromWorkShiftId($workShiftId) { 245 | $year = substr($workShiftId, 0, 4); 246 | $month = substr($workShiftId, 4, 2); 247 | $day = substr($workShiftId, 6, 2); 248 | 249 | $hour = substr($workShiftId, 8, 2); 250 | $minute = substr($workShiftId, 10, 2); 251 | 252 | $newdate = "$year-$month-$day $hour:$minute"; 253 | 254 | return new \DateTime($newdate); 255 | } 256 | 257 | /** 258 | * Entrega la diferencia TOTAL entre 2 fechas en minutos, horas (por defecto) o días. 259 | * 260 | * @param DateTime $start La fecha de inicio 261 | * @param DateTime $end La fecha de fin 262 | * @param int $intervalo El intervalo de tiempo de la respuestas (utilizar el enumerador: WorkShiftDatePartEnum) 263 | * 264 | * @return decimal La diferencia en horas si no se especifica otra cosa 265 | */ 266 | public static function GetDateDifference(\DateTime $start, \DateTime $end, int $intervalo = WorkShiftDatePartEnum::HOUR) { 267 | $diff = date_diff($start, $end); 268 | 269 | $segundos = ($diff->days * 24 * 60 * 60 270 | + $diff->h * 60 * 60 271 | + $diff->i * 60 272 | + $diff->s); 273 | 274 | switch ($intervalo) { 275 | case WorkShiftDatePartEnum::SECOND: 276 | return $segundos; 277 | case WorkShiftDatePartEnum::MINUTE: 278 | return $segundos / 60; 279 | case WorkShiftDatePartEnum::HOUR : 280 | return $segundos / (60 * 60); 281 | case WorkShiftDatePartEnum::DAY : 282 | return ($segundos / (60 * 60)) / 24; 283 | default: 284 | return $segundos / (60 * 60); 285 | } 286 | } 287 | } -------------------------------------------------------------------------------- Total de líneas: 287 ================================================================================ ================================================================================ ARCHIVO #231: src/ProjectionEngine/WorkShiftCompleted.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/ProjectionEngine/WorkShiftCompleted.php Tamaño: 1.24 KB -------------------------------------------------------------------------------- 1 | CompletedId = $completedId; 29 | $wsc->CompletedDate = $completedDate; 30 | $wsc->TaskReferenceKey = $taskReferenceKey; 31 | $wsc->TaskWork = $taskWork; 32 | 33 | // Calcular el porcentaje de esfuerzo de la tarea en base al avance actual 34 | // Ej: si la tarea es de 10 horas y el avance dice 20%, entonces el aporte es de 2 horas 35 | // Además debemos aplicar el "peso" de la tarea respecto del conjunto total 36 | $completedPercentage = $taskWork * $workCompleted; 37 | $wsc->WorkCompleted = $completedPercentage / $totalWork; 38 | 39 | return $wsc; 40 | } 41 | } -------------------------------------------------------------------------------- Total de líneas: 41 ================================================================================ ================================================================================ ARCHIVO #232: src/ProjectionEngine/WorkShiftDatePartEnum.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/ProjectionEngine/WorkShiftDatePartEnum.php Tamaño: 401 bytes -------------------------------------------------------------------------------- 1 | ScheduleId = $scheduleId; 42 | $wss->StartDate = $startDate; 43 | $wss->EndDate = $endDate; 44 | $wss->Work = $work; 45 | $wss->WorkCompleted = $workCompleted; 46 | $wss->Duration = $duration; 47 | $wss->StartDateBlock = $startDate->format('YmdHis')*1; 48 | $wss->EndDateBlock = $endDate->format('YmdHis')*1; 49 | $wss->Weight = $work / $totalWork; 50 | 51 | $wss->BusinessObject = $businessObject; 52 | 53 | // Según el avance que tenga esta tarea, calculo su fecha de inicio "actual" para utilizar 54 | // este dato en el cálculo de la proyección 55 | // 56 | $wss->ActualStartDate = clone $startDate; 57 | $wss->ActualEndDate = clone $endDate; 58 | 59 | if ($workCompleted < 100) { 60 | $offsetSeconds = round(($duration * ($workCompleted/100)) * 3600, 0); // en segundos 61 | 62 | // Aplico el Offset 63 | // 64 | $wss->ActualStartDate = date_add($wss->ActualStartDate, new \DateInterval("PT" . $offsetSeconds . "S")); 65 | $wss->ActualStartDateBlock = $wss->ActualStartDate->format('YmdHis')*1; 66 | 67 | $wss->ActualDuration = WorkShift::GetDateDifference($wss->ActualStartDate, $wss->ActualEndDate); 68 | } 69 | else { 70 | $wss->ActualDuration = $wss->Duration; 71 | } 72 | 73 | // Actualizar la menor fecha pendiente 74 | if (!isset(self::$FirstActualStartDate)) { 75 | self::$FirstActualStartDate = clone $wss->ActualStartDate; 76 | } 77 | else { 78 | if ($wss->ActualStartDate < self::$FirstActualStartDate) { 79 | self::$FirstActualStartDate = clone $wss->ActualStartDate; 80 | } 81 | } 82 | 83 | return $wss; 84 | } 85 | 86 | /** 87 | * Obtiene el porcentaje de avance de hora de esta tarea respecto del turno actual, sólo la parte que cae dentro 88 | * del rango de horas del turno. Aplica el "peso" de la tarea al resultado y entrega el porcentaje neto 89 | */ 90 | public function GetWorkShiftPercentageParticipation(WorkShift $workShift, \DateTime $start = null) { 91 | 92 | if (!isset($start)) { 93 | $startDate = ($this->StartDateBlock >= $workShift->WorkShiftStartDateBlock) ? $this->StartDate : $workShift->WorkShiftStartDate; 94 | } 95 | else { 96 | $startDate = $start; 97 | } 98 | 99 | $endDate = ($this->EndDateBlock <= $workShift->WorkShiftEndDateBlock) ? $this->EndDate : $workShift->WorkShiftEndDate; 100 | 101 | // calcular el avance en horas (horas consumidas del schedule dentro de este workshift) 102 | // 103 | $avanceHoras = WorkShift::GetDateDifference($startDate, $endDate); // en horas 104 | 105 | // calcular el porcentaje de las horas consumidas, respecto del total de horas 106 | // de la tarea (el "porcentaje" de avance programado) 107 | // 108 | $porcentaje = ($avanceHoras*100) / $this->Duration; 109 | 110 | // aplicar el "peso" del schedule respecto del conjunto total al porcentaje calculado 111 | // 112 | $porcentajeNeto = $porcentaje * $this->Weight; 113 | 114 | return $porcentajeNeto; 115 | } 116 | } -------------------------------------------------------------------------------- Total de líneas: 116 ================================================================================ ================================================================================ ARCHIVO #234: src/ReportEngine/Report.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/ReportEngine/Report.php Tamaño: 4.71 KB -------------------------------------------------------------------------------- 1 | IdCliente) || $reportDefinition->IdCliente <= 0) { 34 | throw new \Exception("No se ha especificado el ID de Cliente para este reporte. Este valor es mandatorio"); 35 | } 36 | else { 37 | $this->IdReporteDefinicion = $reportDefinition->IdReporteDefinicion; 38 | $this->ReporteDefinicion = $reportDefinition; 39 | } 40 | } 41 | } 42 | 43 | /** 44 | * Obtiene los datos para el reporte 45 | * 46 | * @param ReportFilter $filter 47 | * @param int $idCliente 48 | * 49 | * @return ReportDataset 50 | */ 51 | abstract function GetDataset(ReportFilter $filter, $idCliente); 52 | 53 | /** 54 | * Obtiene el reporte desde el servidor, según los parámetros especificados 55 | */ 56 | public function GetReport(ReportFilter $filter, ReportOutputDefinition $outputDefinition) { 57 | 58 | // SIEMPRE VERIFICAR QUE TENEMOS DEFINIDO EL ID_CLIENTE DE ESTE REPORTE!! 59 | // 60 | if (!isset($this->ReporteDefinicion) || !isset($this->ReporteDefinicion->IdCliente) || $this->ReporteDefinicion->IdCliente <= 0) { 61 | throw new \Exception("No se ha especificado el ID de Cliente para este reporte. Este valor es mandatorio"); 62 | } 63 | 64 | // Obtener el dataset para enviar al reporte 65 | // 66 | $sourceDataset = $this->GetDataset($filter, $this->ReporteDefinicion->IdCliente); 67 | 68 | // Validar el dataset 69 | if ( !($sourceDataset instanceof ReportDataset)) { 70 | throw new \Exception("El dataset obtenido no es una implementación de ReportDataset"); 71 | } 72 | 73 | // Obtener el reporte desde el servidor 74 | // 75 | $reportResult = $this->RunReport($this->ReporteDefinicion, $filter, $outputDefinition->OutputType, $sourceDataset); 76 | 77 | // Si se solicitó guardar el reporte, bajarlo a disco 78 | // if ($outputDefinition->SaveReport) 79 | // $this->SaveReport($outputDefinition->ReportFolder, $outputDefinition->ReportFilename); 80 | 81 | return $reportResult; 82 | } 83 | 84 | protected function RunReport(ReportDefinition $reportDefinition, ReportFilter $filter, $outputType, ReportDataset $sourceDataset) { 85 | 86 | // Creamos el cliente de ReportServer y realizamos login con el usuario 87 | $client = new Client($reportDefinition->ServerURI, $reportDefinition->ServerUsername, $reportDefinition->ServerPassword, $reportDefinition->ServerOrganization); 88 | 89 | $controls = array(); 90 | 91 | if (isset($sourceDataset->DataLocation) && $sourceDataset->DataLocation != '') { 92 | $controls['Location'] = $sourceDataset->DataLocation; 93 | } 94 | 95 | if (count($controls) <= 0) { 96 | $controls = null; 97 | } 98 | 99 | $report = $client->reportService()->runReport($reportDefinition->ReportURI, $outputType, null, null, $controls); 100 | 101 | return $report; 102 | } 103 | 104 | /** 105 | * Despliega el HTML necesario para capturar los parámetros del reporte en el sistema 106 | */ 107 | public function DisplayParameterView() { 108 | 109 | } 110 | 111 | /** 112 | * Mapea el objeto o arreglo de objetos DATASET en forma de arreglos 113 | */ 114 | protected function MapearDataset($dataset) { 115 | 116 | return json_encode($dataset, JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_PRESERVE_ZERO_FRACTION); 117 | 118 | /* 119 | $resultado = array(); 120 | 121 | if (is_array($dataset)) { 122 | foreach($dataset as $data) { 123 | if (is_array($data)) { 124 | array_push($resultado, $this->MapearDataset($data)); 125 | } 126 | else { 127 | array_push($resultado, $this->MapearObjeto($data)); 128 | } 129 | } 130 | 131 | return $resultado; 132 | } 133 | else { 134 | 135 | } 136 | */ 137 | } 138 | 139 | /** 140 | * Mapea un objeto en un arreglo asociativo 141 | */ 142 | protected function MapearObjeto($objeto) { 143 | // Mapear las propiedades del objeto 144 | $elemento = new \StdClass(); 145 | } 146 | } -------------------------------------------------------------------------------- Total de líneas: 146 ================================================================================ ================================================================================ ARCHIVO #235: src/ReportEngine/ReportDataset.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/ReportEngine/ReportDataset.php Tamaño: 716 bytes -------------------------------------------------------------------------------- 1 | 0 */ 20 | public $DataLocation = null; 21 | 22 | /** 23 | * required 24 | * validation = !isset(@prop) || (is_array(@prop)) */ 25 | public $Parameters = null; 26 | 27 | function __construct(array $definition = array()) { 28 | parent::__construct($definition); 29 | } 30 | } -------------------------------------------------------------------------------- Total de líneas: 30 ================================================================================ ================================================================================ ARCHIVO #236: src/ReportEngine/ReportDefinition.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/ReportEngine/ReportDefinition.php Tamaño: 1.98 KB -------------------------------------------------------------------------------- 1 | 0 */ 23 | public $IdCliente = null; 24 | 25 | /** 26 | * required 27 | * validation = isset(@prop) && @prop > 0 */ 28 | public $IdReporteDefinicion = 0; 29 | public $Nombre = ''; 30 | public $Descripcion = ''; 31 | 32 | /** 33 | * required 34 | * validation = isset(@prop) && @prop != "" */ 35 | public $ServerURI = null; 36 | 37 | /** 38 | * required 39 | * validation = isset(@prop) && @prop != "" */ 40 | public $ReportURI = null; 41 | 42 | /** 43 | * required 44 | * validation = isset(@prop) && @prop != "" */ 45 | public $ServerUsername = null; 46 | 47 | public $ServerOrganization = null; 48 | 49 | /** 50 | * required 51 | * validation = isset(@prop) && @prop != "" */ 52 | public $ServerPassword = null; 53 | 54 | 55 | // Parametros para reportes de gestión 56 | // 57 | public $ObtenerOperacion = false; 58 | public $ObtenerOperacionLabel = ''; 59 | public $ObtenerPlanta = false; 60 | public $ObtenerPlantaLabel = ''; 61 | public $ObtenerMaquina = false; 62 | public $ObtenerMaquinaLabel = false; 63 | 64 | // Parametros para reportes de operación 65 | // 66 | public $ObtenerDetencion = true; 67 | public $ObtenerDetencionLabel = ''; 68 | public $ObtenerMantencion = true; 69 | public $ObtenerMantencionLabel = ''; 70 | public $ObtenerTurno = true; 71 | public $ObtenerTurnoLabel = ''; 72 | public $ObtenerIntervaloTurno = false; 73 | public $ObtenerIntervaloTurnoLabel = ''; 74 | 75 | // Parametros generales 76 | // 77 | public $ObtenerFechaDesde = true; 78 | public $ObtenerFechaDesdeLabel = ''; 79 | public $ObtenerFechaHasta = true; 80 | public $ObtenerFechaHastaLabel = ''; 81 | 82 | } -------------------------------------------------------------------------------- Total de líneas: 82 ================================================================================ ================================================================================ ARCHIVO #237: src/ReportEngine/ReportFilter.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/ReportEngine/ReportFilter.php Tamaño: 739 bytes -------------------------------------------------------------------------------- 1 | 0 */ 20 | public $OutputType = null; 21 | 22 | /** 23 | * required 24 | * validation = isset(@prop) */ 25 | public $SaveReport = false; 26 | 27 | public $ReportFolder = null; 28 | 29 | public $ReportFilename = null; 30 | 31 | function __construct(array $definition = array()) { 32 | parent::__construct($definition); 33 | } 34 | } -------------------------------------------------------------------------------- Total de líneas: 34 ================================================================================ ================================================================================ ARCHIVO #239: src/ReportEngine/ReportOutputEnum.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/ReportEngine/ReportOutputEnum.php Tamaño: 403 bytes -------------------------------------------------------------------------------- 1 | __ControllerContainer; 50 | default: 51 | user_error("Invalid property: " . __CLASS__ . "->$name"); 52 | } 53 | } 54 | 55 | public function __construct() 56 | { 57 | 58 | // Obtenemos el contenedor de controladores. 59 | // El contenedor cargará automáticamente los controladores utilizando el RouteHelper 60 | // u obteniendo la clase completa desde caché en Redis. 61 | $this->__ControllerContainer = ControllerContainer::Instance(); 62 | } 63 | 64 | public static function GetLastResultForAudit() 65 | { 66 | 67 | $result = self::$LastResult; 68 | 69 | if (isset($result->ViewContent)) { 70 | $result->ViewContent = ''; 71 | } 72 | 73 | return $result; 74 | } 75 | 76 | public function DispatchRequest($preventEcho = false): Result | JsonResult | JsonPlainResult | JsonResultMovil | ErrorResult | ErrorJsonResult |ErrorJsonMovilResult 77 | { 78 | 79 | $result = null; 80 | 81 | $uri = Uri::Parse(); 82 | 83 | // Buscar un controlador asociado a esta ruta 84 | $route = $uri->FindMatch($this->ControllerContainer->controllers); 85 | 86 | try { 87 | 88 | if (!isset($route)) { 89 | // if ($uri->ServerRequestUri == '/favicon.ico') 90 | // return '/favicon.ico'; 91 | // else if ( BaseController::GetPathExtension($uri->ServerRequestUri) == 'map') 92 | // return ''; 93 | // else 94 | // //return ''; 95 | throw new BaseException(message: 'Recurso no encontrado', code: ExceptionCodesEnum::ERR_ROUTE_NOTFOUND, debugMessage: "Can't find a route for [$uri->ServerRequestUri] :" . __CLASS__); 96 | } else { 97 | // ¿Esta ruta requiere sesión iniciada? 98 | if ($route->RequireSession) { 99 | // Verificar la sesión 100 | if (!$this->IsSessionActive()) { 101 | user_error("Request [$route->Path] requires an active session :" . __CLASS__); 102 | throw new BaseException(message: 'Error inesperado', code: ExceptionCodesEnum::ERR_NO_SESSION, debugMessage: "Request [$route->Path] requires an active session :" . __CLASS__); 103 | } 104 | } 105 | 106 | // Revisar el RequestMethod 107 | if (!in_array($uri->ServerMethod, $route->Methods)) { 108 | user_error("Method [$uri->ServerMethod] not allowed by [$route->FullPath] :" . __CLASS__); 109 | throw new BaseException(message: 'Error inesperado', code: ExceptionCodesEnum::ERR_METHOD_NOTALLOWED, debugMessage: "Method [$uri->ServerMethod] not allowed by [$route->FullPath] :" . __CLASS__); 110 | //return $this->Error(new DispatchError(code: 403, message: "Method [$uri->ServerMethod] not allowed by [$route->FullPath]")); 111 | } 112 | 113 | // Revisar el acceso 114 | if ($route->Authorization != 'ALLOW_ALL' && $route->Authorization != 'APP_KEY') { 115 | if (!$this->IsAllowed($route->Roles)) { 116 | throw new BaseException(message: 'No autorizado', code: ExceptionCodesEnum::ERR_UNAUTHORIZED, debugMessage: "User not allowed to access this method [$route->FullPath] :" . __CLASS__); 117 | //return $this->Error(new DispatchError(code: 403, message: "User not allowed to access this method [$route->FullPath]")); 118 | } 119 | } 120 | 121 | // Instanciar el controlador 122 | $controller = new $route->Classname(); 123 | 124 | // Obtener el metodo con Reflection 125 | $reflectionMethod = new \ReflectionMethod($route->Classname, $route->MethodName); 126 | 127 | // Generar los argumentos de la llamada al metodo 128 | $args = $this->BuildArguments($uri, $route); 129 | 130 | // Invokar el metodo 131 | if (isset($args)) { 132 | try { 133 | $methodResult = $this->InvokeWithArgs($controller, $reflectionMethod, $args); 134 | } catch (\Exception $e) { 135 | throw $e; 136 | } 137 | } else { 138 | try { 139 | $methodResult = $this->Invoke($controller, $reflectionMethod); 140 | } catch (\Exception $e) { 141 | throw $e; 142 | } 143 | } 144 | 145 | // OBS: NO COMPARAR DIRECTAMENTE!!! utilizar variables de paso 146 | // Php, al momento de asignar: $MethodReturnType = ActionResult::class, le asigna el nombre completo con namespace 147 | // pero cuando vamos a comparar $MethodReturnType == ActionResult::class, esté último valor lo evalua sin el namespace 148 | // 149 | // Ej: 150 | // Asignamos 151 | // $MethodReturnType = ActionResult::class ( $MethodReturnType contendrá el valor "Framework\Controllers\ActionResult") 152 | // Cuando vamos a comprarar: 153 | // $MethodReturnType == ActionResult::class, nos devolverá "false" 154 | // porque "ActionResult::class" se evalúa en la comparación como "ActionResult" y no como "Framework\Controllers\ActionResult" 155 | $actionResultClass = ActionResult::class; 156 | $viewResultClass = ViewResult::class; 157 | $pdfInlineResultClass = PdfInlineResult::class; 158 | $actionViewResultClass = ActionViewResult::class; 159 | $redirectResultClass = RedirectResult::class; 160 | $jsonResultClass = JsonResult::class; 161 | $jsonPlainResultClass = JsonPlainResult::class; 162 | $jsonResultMovilClass = JsonResultMovil::class; 163 | 164 | // Retornar la salida según el tipo declarado en el metodo 165 | if ($route->MethodReturnType == $actionResultClass) { 166 | $result = new ActionResult( 167 | Result: $methodResult, 168 | UserUniqueID: $this->GetUserUniqueID(), 169 | IsSessionActive: $this->IsSessionActive(), 170 | Request: $route->FullPath 171 | ); 172 | } 173 | else if ($route->MethodReturnType == $pdfInlineResultClass) { 174 | $finalResult = new PdfInlineResult( 175 | ViewContent: $methodResult, 176 | UserUniqueID: $this->GetUserUniqueID(), 177 | IsSessionActive: $this->IsSessionActive(), 178 | Request: $route->FullPath 179 | ); 180 | } 181 | else if ($route->MethodReturnType == $viewResultClass) { 182 | $result = new ViewResult( 183 | ViewContent: $methodResult, 184 | UserUniqueID: $this->GetUserUniqueID(), 185 | IsSessionActive: $this->IsSessionActive(), 186 | Request: $route->FullPath 187 | ); 188 | } else if ($route->MethodReturnType == $actionViewResultClass) { 189 | $result = new ActionViewResult( 190 | ViewContent: $methodResult, 191 | UserUniqueID: $this->GetUserUniqueID(), 192 | IsSessionActive: $this->IsSessionActive(), 193 | Request: $route->FullPath 194 | ); 195 | } else if ($route->MethodReturnType == $redirectResultClass) { 196 | $result = new RedirectResult( 197 | RedirectUrl: $methodResult, 198 | UserUniqueID: $this->GetUserUniqueID(), 199 | IsSessionActive: $this->IsSessionActive(), 200 | Request: $route->FullPath 201 | ); 202 | } else if ($route->MethodReturnType == $jsonResultClass) { 203 | $finalResult = new JsonResult( 204 | idError: 0, 205 | msgError: '', 206 | msgFriendly: '', 207 | data: $methodResult 208 | ); 209 | } else if ($route->MethodReturnType == $jsonPlainResultClass) { 210 | $finalResult = new JsonPlainResult(Json: $methodResult); 211 | 212 | } else if ($route->MethodReturnType == $jsonResultMovilClass) { 213 | $finalResult = new JsonResultMovil( 214 | IdError: 0, 215 | MsgError: '', 216 | MsgFriendly: '', 217 | Data: $methodResult 218 | ); 219 | } 220 | 221 | // Solicitar a la aplicación cualquier modificación de última hora a la información 222 | if ($route->MethodReturnType != $jsonPlainResultClass && $route->MethodReturnType != $jsonResultMovilClass && $route->MethodReturnType != $pdfInlineResultClass && $route->MethodReturnType != $jsonResultClass) { 223 | 224 | $finalResult = $this->Success($result); 225 | 226 | } 227 | } 228 | } 229 | // Excepciones lanzadas por la aplicación por errores de negocio 230 | catch (BusinessException $ex) { 231 | Log::CreateTraceLog($ex, ExceptionTypeEnum::BUSINESS); 232 | if (isset($route) && $route->MethodReturnType == JsonResult::class) { 233 | return new ErrorJsonResult( 234 | idError: 1, 235 | msgError: 'Error en comunicación con el servidor', 236 | msgFriendly: 'Error en comunicación con el servidor', 237 | data: null 238 | ); 239 | } else if ($route->MethodReturnType == ViewResult::class || $route->MethodReturnType == ActionViewResult::class) { 240 | $viewContent = $this->GetErrorView(new BaseException(code: $ex->getCode(), message: $ex->getMessage(), debugMessage: $ex->getDebugMessage())); 241 | 242 | $result = new ErrorViewResult( 243 | ViewContent: $viewContent, 244 | UserUniqueID: $this->GetUserUniqueID(), 245 | IsSessionActive: $this->IsSessionActive(), 246 | Request: (isset($route)) ? $route->FullPath : $uri->ServerRequestUri, 247 | ErrorCode: ($ex->getCode() != 0) ? $ex->getCode() : 1, 248 | ErrorMessage: $ex->getMessage(), 249 | DebugMessage: $ex->getDebugMessage() 250 | ); 251 | 252 | $finalResult = $this->ErrorView($result); 253 | } else if (isset($route) && $route->MethodReturnType == JsonResultMovil::class) { 254 | return new ErrorJsonMovilResult( 255 | IdError: 1, 256 | MsgError: 'Error en comunicación con el servidor', 257 | MsgFriendly: 'Error en comunicación con el servidor', 258 | Data: null 259 | ); 260 | } else { 261 | $result = new ErrorResult( 262 | UserUniqueID: $this->GetUserUniqueID(), 263 | IsSessionActive: $this->IsSessionActive(), 264 | Request: (isset($route)) ? $route->FullPath : $uri->ServerRequestUri, 265 | ErrorCode: $ex->getCode(), 266 | ErrorMessage: $ex->getMessage(), 267 | DebugMessage: $ex->getDebugMessage() 268 | ); 269 | 270 | $finalResult = $this->Error($result); 271 | } 272 | } 273 | // Excepciones lanzadas por el dispatcher (en general, 400, 401, 402, 403, 500)... 274 | catch (BaseException $ex) { 275 | Log::CreateTraceLog($ex, ExceptionTypeEnum::BASE_EXCEPTION); 276 | if (!isset($route)) { 277 | $finalResult = new ErrorResult( 278 | UserUniqueID: $this->GetUserUniqueID(), 279 | IsSessionActive: $this->IsSessionActive(), 280 | Request: $uri->ServerRequestUri, 281 | ErrorCode: ($ex->getCode() != 0) ? $ex->getCode() : 1, 282 | ErrorMessage: $ex->getMessage(), 283 | DebugMessage: $ex->getDebugMessage() 284 | ); 285 | } else if ($route->MethodReturnType == ActionResult::class) { 286 | $finalResult = new ErrorResult( 287 | UserUniqueID: $this->GetUserUniqueID(), 288 | IsSessionActive: $this->IsSessionActive(), 289 | Request: (isset($route)) ? $route->FullPath : $uri->ServerRequestUri, 290 | ErrorCode: ($ex->getCode() != 0) ? $ex->getCode() : 1, 291 | ErrorMessage: $ex->getMessage(), 292 | DebugMessage: $ex->getDebugMessage() 293 | ); 294 | } else if ($route->MethodReturnType == ViewResult::class || $route->MethodReturnType == ActionViewResult::class) { 295 | $viewContent = $this->GetErrorView($ex); 296 | 297 | $result = new ErrorViewResult( 298 | ViewContent: $viewContent, 299 | UserUniqueID: $this->GetUserUniqueID(), 300 | IsSessionActive: $this->IsSessionActive(), 301 | Request: (isset($route)) ? $route->FullPath : $uri->ServerRequestUri, 302 | ErrorCode: ($ex->getCode() != 0) ? $ex->getCode() : 1, 303 | ErrorMessage: $ex->getMessage(), 304 | DebugMessage: $ex->getDebugMessage() 305 | ); 306 | 307 | $finalResult = $this->ErrorView($result); 308 | } else if ($route->MethodReturnType == JsonResult::class) { 309 | 310 | self::$LastResult = new ErrorJsonResult( 311 | idError: 1, 312 | msgError: 'Error en comunicación con el servidor', 313 | msgFriendly: 'Error en comunicación con el servidor', 314 | data: null 315 | ); 316 | 317 | return self::$LastResult; 318 | } else if ($route->MethodReturnType == JsonResultMovil::class) { 319 | 320 | self::$LastResult = new ErrorJsonMovilResult( 321 | IdError: 1, 322 | MsgError: 'Error en comunicación con el servidor', 323 | MsgFriendly: 'Error en comunicación con el servidor', 324 | Data: null 325 | ); 326 | 327 | return self::$LastResult; 328 | } 329 | 330 | // // Se le solicita a la aplicación que despliegue una vista personalizada 331 | // // para mostrar el error 332 | // $viewContent = $this->GetErrorView($ex); 333 | 334 | // $result = new ErrorViewResult( 335 | // ViewContent: $viewContent, 336 | // UserUniqueID: $this->GetUserUniqueID(), 337 | // IsSessionActive: $this->IsSessionActive(), 338 | // Request: (isset($route)) ? $route->FullPath : $uri->ServerRequestUri, 339 | // ErrorCode: ($ex->getCode() != 0) ? $ex->getCode() : 1, 340 | // ErrorMessage: $ex->getMessage(), 341 | // DebugMessage: $ex->getDebugMessage() 342 | // ); 343 | 344 | 345 | } catch (\Exception $ex) { 346 | Log::CreateTraceLog($ex, ExceptionTypeEnum::EXCEPTION); 347 | $result = new ErrorResult( 348 | UserUniqueID: $this->GetUserUniqueID(), 349 | IsSessionActive: $this->IsSessionActive(), 350 | Request: (isset($route)) ? $route->FullPath : $uri->ServerRequestUri, 351 | ErrorCode: ($ex->getCode() != 0) ? $ex->getCode() : 1, 352 | ErrorMessage: 'Error inesperado', 353 | DebugMessage: $ex->getMessage() 354 | ); 355 | 356 | $finalResult = $this->Error($result); 357 | } catch (\Throwable $ex) { 358 | Log::CreateTraceLog($ex, ExceptionTypeEnum::THROWABLE); 359 | $result = new ErrorResult( 360 | UserUniqueID: $this->GetUserUniqueID(), 361 | IsSessionActive: $this->IsSessionActive(), 362 | Request: (isset($route)) ? $route->FullPath : $uri->ServerRequestUri, 363 | ErrorCode: ($ex->getCode() != 0) ? $ex->getCode() : 1, 364 | ErrorMessage: 'Error inesperado', 365 | DebugMessage: $ex->getMessage() 366 | ); 367 | 368 | $finalResult = $this->Error($result); 369 | } 370 | 371 | // Codificar el resultado final según el tipo de salida 372 | if ($finalResult instanceof ViewResult || $finalResult instanceof ErrorViewResult) { 373 | if (!$preventEcho) 374 | header('Content-Type: text/html'); 375 | 376 | $output = $finalResult->ViewContent; 377 | } 378 | elseif ($finalResult instanceof PdfInlineResult) { 379 | 380 | header('Content-Type: application/pdf'); 381 | $preventEcho = false; 382 | $output = $finalResult->ViewContent; 383 | } 384 | elseif($finalResult instanceof ExcelResult || $finalResult instanceof ErrorViewResult){ 385 | if (!$preventEcho) 386 | header('Content-Type: text/html'); 387 | header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'); 388 | header('Cache-Control: max-age=0'); 389 | header('Cache-Control: max-age=1'); 390 | header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); // Date in the past 391 | header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); // always modified 392 | header('Cache-Control: cache, must-revalidate'); // HTTP/1.1 393 | header('Pragma: public'); // HTTP/1.0 394 | 395 | $output = $finalResult->ViewContent; 396 | } elseif ($finalResult instanceof RedirectResult) { 397 | header("Location: " . $finalResult->RedirectUrl); 398 | die(); 399 | } elseif ($finalResult instanceof JsonPlainResult) { 400 | header('Content-Type: application/json'); 401 | $preventEcho = false; 402 | 403 | $output = $finalResult->Json; 404 | } 405 | else { 406 | if (!$preventEcho) 407 | header('Content-Type: application/json'); 408 | 409 | $output = json_encode($finalResult, JSON_UNESCAPED_UNICODE); 410 | } 411 | 412 | if (!$preventEcho) { 413 | echo $output; 414 | } 415 | 416 | self::$LastResult = $finalResult; 417 | return $finalResult; 418 | } 419 | 420 | private function BuildArguments(Uri $uri, Route $route) 421 | { 422 | 423 | $args = array(); 424 | 425 | // Recorremos los argumentos del metodo según la especificación 426 | // y buscamos una variable coincidente en los argumentos del request 427 | // Prioridad 1 es el query string, luego el body, finalmente variables que vengan 428 | // declaradas por posicion 429 | 430 | // Bucle de recorrido de argumentos del metodo 431 | foreach ($route->MethodParameters as $parameter) { 432 | 433 | $found = false; 434 | 435 | // Buscar una variable en el query string 436 | foreach ($uri->Variables as $var => $value) { 437 | 438 | if (strtolower($parameter->name) == strtolower($var)) { 439 | $found = true; 440 | // agregar el argumento 441 | $args[$parameter->name] = $value; 442 | break; 443 | } 444 | } 445 | 446 | // Si no se encontró el argumento en las variables del query string, continuamos 447 | // la búsqueda en el body 448 | if (!$found && isset($uri->Body)) { 449 | 450 | // Si el body es un objeto anónimo, obtener las variables 451 | if (count($uri->Body) == 1 && isset($uri->Body[0])) { 452 | 453 | foreach ($uri->Body as $idx => $value) { 454 | if ($idx == '0') { 455 | // Es anonimo 456 | $bodyvars = get_object_vars($uri->Body[0]); 457 | } else { 458 | $bodyvars = $uri->Body; 459 | } 460 | 461 | break; 462 | } 463 | $bodyvars = get_object_vars($uri->Body[0]); 464 | } else { 465 | $bodyvars = $uri->Body; 466 | } 467 | //$bodyvars = get_object_vars($uri->Body); 468 | 469 | foreach ($bodyvars as $var => $value) { 470 | if (strtolower($parameter->name) == strtolower($var)) { 471 | $found = true; 472 | 473 | // agregar el argumento 474 | 475 | //if (is_object($value) && !($value instanceof stdClass)) { 476 | if (is_object($value) && isset($parameter->type) && $parameter->type != '') { 477 | $mapper = new BaseMapper($value); 478 | $args[$parameter->name] = $mapper->MapTo($parameter->type); 479 | } else { 480 | $args[$parameter->name] = $value; 481 | } 482 | 483 | break; 484 | } 485 | } 486 | } 487 | 488 | // Si no se encontró la variable en el querystring ni en el body, 489 | // la agregamos como NULL para verificar luego las variables por POSICION 490 | if (!$found) { 491 | $args[$parameter->name] = null; 492 | } 493 | 494 | /* 495 | Framework\Route\Uri 496 | Variables:array(2) 497 | idUsuario:"4" 498 | Fecha:"2020-12-21" 499 | 500 | name:"idUsuario" 501 | type:"int" 502 | allowsNull:false 503 | defaultValue:null 504 | position:0 505 | isOptional:false 506 | */ 507 | } 508 | 509 | // Recorrer las variables NULL e ir agregando las variables del request que vengan por "posicion" 510 | $idxPos = 0; // posicion de variable actual 511 | foreach ($args as $arg => $value) { 512 | if (!isset($value) || $value === null) { 513 | // ver si existe alguna variable por posicion 514 | if (isset($uri->PositionVariables)) { 515 | if (isset($uri->PositionVariables[$idxPos])) { 516 | $args[$arg] = $uri->PositionVariables[$idxPos]; 517 | // avanzar el puntero de variable por posición 518 | $idxPos++; 519 | } 520 | } 521 | } 522 | } 523 | 524 | if (count($args) > 0) { 525 | return $args; 526 | } else { 527 | return null; 528 | } 529 | } 530 | 531 | private function Invoke($object, \ReflectionMethod $method) 532 | { 533 | 534 | return $method->invoke($object); 535 | } 536 | 537 | /** 538 | * Pass method arguments by name 539 | * 540 | * @param \ReflectionMethod $method 541 | * @param array $args 542 | * @return mixed 543 | */ 544 | private function InvokeWithArgs($object, \ReflectionMethod $method, array $args = array()) 545 | { 546 | $pass = array(); 547 | 548 | foreach ($method->getParameters() as $param) { 549 | /* @var $param ReflectionParameter */ 550 | if (isset($args[$param->getName()])) { 551 | $pass[] = $args[$param->getName()]; 552 | } else { 553 | if ($param->isDefaultValueAvailable()) { 554 | $pass[] = $param->getDefaultValue(); 555 | } else if ($param->allowsNull()) { 556 | $pass[] = null; 557 | } else { 558 | user_error("Parameter not present, don't allows NULL and no default value specified [" . $method->getName() . ": $" . $param->getName() . "]: " . __CLASS__); 559 | } 560 | } 561 | } 562 | 563 | return $method->invokeArgs($object, $pass); 564 | } 565 | 566 | /** 567 | * Verifica si el usuario actual está autorizado con alguno de los 568 | * roles que se definen en la ruta actual 569 | * 570 | * @param array $roles Los roles permitidos por la ruta 571 | * 572 | * @return bool 573 | */ 574 | function IsAllowed(array $roles): bool 575 | { 576 | return $this->HasAnyRol($roles); 577 | } 578 | 579 | public function HasAnyRol(array $methodRoles): bool 580 | { 581 | $userRoles = $this->GetUserRoles(); 582 | 583 | if (count($methodRoles) == 0) 584 | return false; 585 | 586 | foreach ($methodRoles as $rol) { 587 | if ($this->HasRol($rol, $userRoles)) 588 | return true; 589 | } 590 | 591 | return false; 592 | } 593 | 594 | public function HasRol($rol, array $userRoles = null): bool 595 | { 596 | if (!isset($userRoles)) 597 | $userRoles = $this->GetUserRoles(); 598 | 599 | if ($rol == '') 600 | return false; 601 | 602 | foreach ($userRoles as $rolActual) { 603 | if ($rolActual->Codigo == $rol) { 604 | return true; 605 | } 606 | } 607 | 608 | return false; 609 | } 610 | } 611 | -------------------------------------------------------------------------------- Total de líneas: 611 ================================================================================ ================================================================================ ARCHIVO #241: src/Route/ControllerContainer.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Route/ControllerContainer.php Tamaño: 1.78 KB -------------------------------------------------------------------------------- 1 | GetControllers(); 38 | 39 | // Enumerar los métodos para búsquedas granulares 40 | $metodos = array(); 41 | 42 | foreach($controllers as $controller) { 43 | if (isset($controller->ControllerMethodRoutes)) { 44 | foreach ($controller->ControllerMethodRoutes as $route) { 45 | array_push($metodos, $route); 46 | } 47 | } 48 | } 49 | 50 | $controllerMethods = null; 51 | if (count($metodos) > 0) { 52 | $controllerMethods = new GenericCollection( 53 | DtoName : Route::class, 54 | Key : 'FullPath', 55 | Values : $metodos 56 | ); 57 | } 58 | 59 | return new ControllerContainer(controllers: $controllers, methods: $controllerMethods); 60 | } 61 | 62 | } -------------------------------------------------------------------------------- Total de líneas: 62 ================================================================================ ================================================================================ ARCHIVO #242: src/Route/IDispatchResponse.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Route/IDispatchResponse.php Tamaño: 1.67 KB -------------------------------------------------------------------------------- 1 | __Path; 45 | case "Rutas": return $this->__Rutas; 46 | default: 47 | user_error("Invalid property: " . __CLASS__ . "->$name"); 48 | } 49 | 50 | } 51 | 52 | public function __construct() { 53 | } 54 | 55 | function __set($name, $value) { 56 | user_error("Can't set property: " . __CLASS__ . "->$name"); 57 | } 58 | 59 | public function GetControllers() { 60 | 61 | $results = array(); 62 | 63 | $path = SITE_ROOT . '/Application/Controllers'; 64 | $frameworkPath = SITE_ROOT . '/Framework/Controllers/InternalControllers'; 65 | 66 | // Obtener todos los controladores definidos en el sistema 67 | $controladores = $this->ListControllers($frameworkPath); 68 | 69 | // Agregar los controladores de la framework 70 | $controladores = $this->ListControllers($path, $controladores); 71 | 72 | // Tengo los archivos, ahora se deben obtener los atributos por cada controlador y sus metodos 73 | if (isset($controladores) && is_array($controladores)) { 74 | 75 | foreach ($controladores as $controlador) { 76 | 77 | $annotations = AnnotationHelper::FromClass($controlador->ControllerClass); 78 | 79 | // Buscar atributo de ruta de la clase 80 | $ruta = $annotations->FindAttributeClass(Route::class); 81 | 82 | if (isset($ruta)) { 83 | 84 | // verificar si el programador definió la ruta 85 | if (!isset($ruta->attribute->Path) || $ruta->attribute->Path == '') { 86 | 87 | // Obtener el namespace 88 | $namespacePath = str_replace('\\', '/', strtolower(str_replace('Application\\Controllers\\', "", $controlador->ControllerNamespace)) ); 89 | 90 | $ruta->attribute->Path = '/' . $namespacePath . '/' . str_replace('controller', '', strtolower($controlador->ControllerClassname)); 91 | } 92 | 93 | $ruta->attribute->FullPath = $ruta->attribute->Path; 94 | 95 | // verificar si el programador definió métodos de request 96 | if (!isset($ruta->attribute->Methods) || count($ruta->attribute->Methods) == 0) { 97 | $ruta->attribute->Methods = ['GET']; 98 | } 99 | 100 | // verificar si el programador definió tipo de autorizacion 101 | if (!isset($ruta->attribute->Authorization) || $ruta->attribute->Authorization == '') { 102 | $ruta->attribute->Authorization = 'ENFORCE'; 103 | } 104 | 105 | $controlador->ControllerRoute = $ruta->attribute; 106 | } 107 | else { 108 | $route = new Route( 109 | Path: '/' . str_replace('controller', '', strtolower($controlador->ControllerClassname)), 110 | FullPath: '/' . str_replace('controller', '', strtolower($controlador->ControllerClassname)), 111 | Methods: ['GET'], 112 | Authorization: 'ENFORCE', 113 | Roles: [] 114 | ); 115 | 116 | $ruta = new ClassAttribute(className: $controlador->ControllerClassname, attribute: $route); 117 | } 118 | 119 | // Buscar atributo de ruta de los metodos 120 | $methodRoutes = $annotations->GetAttributeMethods(Route::class); 121 | 122 | if(isset($methodRoutes) && $methodRoutes->Count() > 0) { 123 | $controlador->ControllerMethodRoutes = array(); 124 | foreach($methodRoutes as $method) { 125 | 126 | if ($controlador->ControllerClassname == 'PulseController') { 127 | $stop = 1; 128 | } 129 | 130 | if (isset($method)) { 131 | 132 | $atributos = $annotations->GetMethodAttributes($method); 133 | 134 | // Verificar el tipo de retorno del metodo 135 | // 136 | if ($atributos->HasAttribute(ReturnActionResult::class)) { 137 | $method->attribute->MethodReturnType = (ActionResult::class); 138 | } 139 | else if ($atributos->HasAttribute(ReturnPdfInlineResult::class)) { 140 | $method->attribute->MethodReturnType = (PdfInlineResult::class); 141 | } 142 | else if ($atributos->HasAttribute(ReturnViewResult::class)) { 143 | $method->attribute->MethodReturnType = (ViewResult::class); 144 | } 145 | else if ($atributos->HasAttribute(ReturnActionViewResult::class)) { 146 | $method->attribute->MethodReturnType = (ActionViewResult::class); 147 | } 148 | else if ($atributos->HasAttribute(ReturnRedirectResult::class)) { 149 | $method->attribute->MethodReturnType = (RedirectResult::class); 150 | } 151 | else if ($atributos->HasAttribute(ReturnJsonResult::class)) { 152 | $method->attribute->MethodReturnType = (JsonResult::class); 153 | } 154 | else if ($atributos->HasAttribute(ReturnJsonPlainResult::class)) { 155 | $method->attribute->MethodReturnType = (JsonPlainResult::class); 156 | } 157 | else if ($atributos->HasAttribute(ReturnJsonResultMovil::class)) { 158 | $method->attribute->MethodReturnType = (JsonResultMovil::class); 159 | } 160 | else { 161 | user_error("Method [$method->methodName] doesn't define a return type attribute: " . __CLASS__); 162 | } 163 | 164 | // verificar si el programador definio la ruta 165 | if (!isset($method->attribute->Path) || $method->attribute->Path == '' || $method->attribute->Path == '/') { 166 | if ($method->methodName == 'Index') { 167 | $method->attribute->FullPath = $ruta->attribute->Path; 168 | } 169 | else { 170 | $method->attribute->Path = '/' . strtolower($method->methodName); 171 | $method->attribute->FullPath = str_replace('//', '/', $ruta->attribute->Path . '/' . $method->attribute->Path); 172 | } 173 | } 174 | else { 175 | $method->attribute->FullPath = str_replace('//', '/', $ruta->attribute->Path . '/' . $method->attribute->Path); 176 | } 177 | 178 | // verificar si el programador definió métodos de request 179 | if (!isset($method->attribute->Methods) || count($method->attribute->Methods) == 0) { 180 | // si no se definió, se toma por defecto la que se haya definido para la clase 181 | $method->attribute->Methods = $ruta->attribute->Methods; 182 | } 183 | 184 | // verificar si el programador definió tipo de autorizacion 185 | if (!isset($method->attribute->Authorization) || $method->attribute->Authorization == '') { 186 | // si no se definió, se toma por defecto la que se haya definido para la clase 187 | $method->attribute->Authorization = $ruta->attribute->Authorization; 188 | } 189 | 190 | // Nombre del metodo 191 | // 192 | $method->attribute->MethodName = $method->methodName; 193 | 194 | // Nombre de la clase que contiene al metodo (el controlador en este caso) 195 | // 196 | $method->attribute->Classname = $controlador->ControllerClass; 197 | 198 | // Parametros del metodo 199 | // 200 | $method->attribute->MethodParameters = $method->methodParameters; 201 | 202 | $tieneAutorizacion = isset($method->attribute->Authorization); 203 | $tieneRoles = is_array($method->attribute->Roles) && count($method->attribute->Roles) > 0; 204 | 205 | if (!$tieneAutorizacion) { 206 | $method->attribute->Authorization = $ruta->attribute->Authorization; 207 | $tieneAutorizacion = true; 208 | } 209 | 210 | if ($tieneAutorizacion && $method->attribute->Authorization == 'ENFORCE' && !$tieneRoles) { 211 | $method->attribute->Roles = $ruta->attribute->Roles; 212 | } 213 | 214 | // Agregar la ruta de este metodo a la coleccion de rutas del controlador 215 | $controlador->ControllerMethodRoutes[$method->attribute->FullPath] = $method->attribute; 216 | } 217 | } 218 | } 219 | 220 | if (isset($controlador->ControllerRoute) || (isset($controlador->ControllerMethodRoutes) && count($controlador->ControllerMethodRoutes) > 0)) { 221 | 222 | if (!isset($controlador->ControllerRoute)) { 223 | $controlador->ControllerRoute = $ruta->attribute; 224 | } 225 | 226 | array_push($results, $controlador); 227 | } 228 | 229 | } 230 | } 231 | 232 | return new GenericCollection( 233 | DtoName : ControllerDefinition::class, 234 | Key : 'ControllerClassname', 235 | Values : $results 236 | ); 237 | } 238 | 239 | private function ListControllers(string $path = '', array $controladoresActuales = null) { 240 | 241 | if (isset($controladoresActuales)) { 242 | $controladores = $controladoresActuales; 243 | } 244 | else { 245 | $controladores = array(); 246 | } 247 | 248 | if ($path == '') { 249 | $path = $this->Path; 250 | } 251 | 252 | $dirs = scandir($path); 253 | 254 | if ($dirs) { 255 | foreach($dirs as $dir) { 256 | if (!in_array($dir,array(".","..")) ) { 257 | 258 | $fulldir = $path . '/' . $dir; 259 | 260 | if (is_dir($fulldir)) { 261 | $controladores = $this->ListControllers($fulldir, $controladores); 262 | } 263 | else { 264 | // Revisar si el archivo contiene la nomenclatura xxxxController.php 265 | if (strlen($dir) > 14 && strtolower(substr($dir, -14)) == 'controller.php') { 266 | 267 | // Obtener Namespace 268 | $cleanDir = str_replacE(SITE_ROOT, '', $fulldir); 269 | 270 | if (substr($cleanDir, 0, 1) == '/') { 271 | $cleanDir = substr($cleanDir, 1); 272 | } 273 | 274 | $namespacePos = strrpos(strtolower($cleanDir), '/'); 275 | $namespace = str_replace('/', '\\', substr($cleanDir, 0, $namespacePos)); 276 | 277 | // Obtener el nombre de la clase 278 | $classname = substr($dir, 0, strlen($dir)-4); 279 | 280 | // Agregar el archivo a la lista si es un controlador 281 | if (strpos(strtolower($dir), 'controller')) 282 | array_push($controladores, 283 | new ControllerDefinition( 284 | ControllerClass : $namespace . '\\' . $classname, 285 | ControllerClassname : $classname, 286 | ControllerNamespace : $namespace, 287 | ControllerFilename : $fulldir 288 | ) 289 | ); 290 | } 291 | } 292 | } 293 | } 294 | } 295 | 296 | $max = 500; 297 | 298 | if (count($controladores) > $max) { 299 | throw new Exception('Demasiados controladores (+' . $max . ')'); 300 | } 301 | 302 | return $controladores; 303 | } 304 | 305 | } -------------------------------------------------------------------------------- Total de líneas: 305 ================================================================================ ================================================================================ ARCHIVO #244: src/Route/Uri.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Route/Uri.php Tamaño: 10.52 KB -------------------------------------------------------------------------------- 1 | CleanRequest = $request; 52 | } 53 | 54 | /** 55 | * Parse: obtiene toda la información de la petición HTTP actual y devuelve 56 | * un objeto que contiene el QueryString como un arreglo asociativo, el Body del 57 | * post como un objeto, y el nombre del controlador y de la accion respectiva 58 | * relativo al URI (no los nombre de clases ni los namespaces internos) 59 | * 60 | * @return null|Uri 61 | */ 62 | public static function Parse() : ?Uri { 63 | 64 | self::$LastInstance = null; 65 | 66 | // Obtener el URI original 67 | if (isset($_SERVER['REQUEST_URI'])) { 68 | 69 | // Scheme (http, https) 70 | $scheme = _nularr($_SERVER, 'REQUEST_SCHEME', ''); 71 | 72 | // Request 73 | $requestUri = _nularr($_SERVER, 'REQUEST_URI', ''); 74 | 75 | // Method 76 | $method = _nularr($_SERVER, 'REQUEST_METHOD', ''); 77 | 78 | // Content Type 79 | $contentType = _nularr($_SERVER, 'CONTENT_TYPE', ''); 80 | 81 | // Content Lenght 82 | $contentLength = _nularr($_SERVER, 'CONTENT_LENGTH', 0); 83 | 84 | // Querystring 85 | $queryString = _nularr($_SERVER, 'QUERY_STRING', ''); 86 | 87 | // Instanciar el resultado 88 | self::$LastInstance = new Uri( 89 | ServerScheme: $scheme, 90 | ServerRequestUri: $requestUri, 91 | ServerMethod: $method, 92 | ServerContentType: $contentType, 93 | ServerContentLength: $contentLength, 94 | ServerQueryString: $queryString 95 | ); 96 | 97 | // Obtener la información de controller, action y variables por posicion (controller/action/V1/V2/V3/.../Vn) 98 | // if ($requestUri != '') { 99 | // $uri->ParseRequestUri(); 100 | // } 101 | 102 | // Obtener las variables del query string 103 | if ($queryString != '') { 104 | self::$LastInstance->ParseQueryString(); 105 | } 106 | 107 | if (isset($contentType) && isset($contentLength) && $contentLength > 0) { 108 | self::$LastInstance->ParseBody(); 109 | } 110 | 111 | } 112 | 113 | return self::$LastInstance; 114 | } 115 | 116 | // protected function ParseRequestUri() { 117 | 118 | // $secciones = explode('?', $this->ServerRequestUri); 119 | 120 | // if (isset($secciones[0])) { 121 | // $request = $secciones[0]; 122 | 123 | // // eliminar el / inicial 124 | // if (substr($request, 0, 1) == '/') { 125 | // $request = substr($request, 1); 126 | // } 127 | 128 | // // Particionar la llamada 129 | // $parts = explode('/', $request); 130 | 131 | // // Ver si existe controlador 132 | // $this->Controller = _nularr($parts, 0, ''); 133 | 134 | // // Ver si existe action 135 | // $this->Action = _nularr($parts, 1, ''); 136 | 137 | // // Buscar variables por posicion 138 | // $count = count($parts); 139 | // if ($count > 2) { 140 | // $vars = array(); 141 | // for ($idx = 2; $idx < $count; $idx++) { 142 | // array_push($vars, $parts[$idx]); 143 | // } 144 | 145 | // $this->PositionVariables = $vars; 146 | // } 147 | // } 148 | // } 149 | 150 | protected function ParseQueryString() { 151 | $variables = explode('&', $this->ServerQueryString); 152 | 153 | $values = array(); 154 | foreach($variables as $value) { 155 | 156 | $par = explode('=', $value); 157 | 158 | if (isset($par) && is_array($par) && count($par) == 2) { 159 | $values[$par[0]] = $par[1]; 160 | } 161 | } 162 | 163 | $this->Variables = $values; 164 | } 165 | 166 | protected function ParseBody() { 167 | 168 | if (isset($_POST) && count($_POST) > 0) { 169 | 170 | $body = array(); 171 | 172 | foreach($_POST as $name => $post) { 173 | 174 | if (!is_array($post)) { 175 | try { 176 | //if (!is_array($post)) { 177 | $jsonAttempt = json_decode($post); 178 | //} 179 | } 180 | catch (\Exception $ex) { 181 | $stop = 1; 182 | } 183 | 184 | if (json_last_error() != JSON_ERROR_NONE) { 185 | $jsonAttempt = $post; 186 | } 187 | 188 | $body[$name] = $jsonAttempt; 189 | } 190 | else { 191 | $body[$name] = $post; 192 | } 193 | } 194 | $this->Body = $body; 195 | } 196 | else { 197 | // if (isset($_REQUEST) && count($_REQUEST) > 0) { 198 | // $body = new \stdClass; 199 | // foreach ($_REQUEST as $name => $request) { 200 | // $body->$name = json_decode($request); 201 | // } 202 | // $this->Body = $body; 203 | // } 204 | // else { 205 | $this->BodyContent = $this->file_get_contents_utf8('php://input'); 206 | $this->Body = [0 => json_decode($this->BodyContent)]; 207 | // } 208 | } 209 | 210 | } 211 | 212 | protected function file_get_contents_utf8($fn) { 213 | $content = file_get_contents($fn); 214 | return mb_convert_encoding($content, 'UTF-8', 215 | mb_detect_encoding($content, 'UTF-8, ISO-8859-1', true)); 216 | } 217 | 218 | /** 219 | * Encuentra la mejor ruta que haga match entre los controladores definidos 220 | * 221 | * @param array $route La definicion de ruta analizada 222 | * 223 | * @return null|Route 224 | */ 225 | public function FindMatch(GenericCollection $controllers) : null|Route { 226 | 227 | $matchs = array(); 228 | 229 | // Eliminar el query string del URI 230 | 231 | foreach($controllers as $controller) { 232 | if (isset($controller->ControllerMethodRoutes)) { 233 | foreach($controller->ControllerMethodRoutes as $path => $route) { 234 | if ($this->Match($this->CleanRequest, $route->FullPath)) { 235 | array_push($matchs,[$controller, $route]); 236 | } 237 | } 238 | } 239 | } 240 | 241 | if (count($matchs) > 1) { 242 | // Chequear si existe coincidencia exacta 243 | $coincidencia = null; 244 | foreach ($matchs as $item) { 245 | try { 246 | if ($item[1] instanceof Route) { 247 | if ($item[1]->FullPath == $this->CleanRequest) { 248 | return $item[1]; 249 | } 250 | } 251 | } 252 | catch (\Exception $e) { 253 | break; 254 | } 255 | } 256 | 257 | user_error("Se ha detectado mas de una ruta coincidente con el URI [$this->ServerRequestUri]: " . __CLASS__ . "->FindMatch"); 258 | return null; 259 | } 260 | else if (count($matchs) == 1) { 261 | 262 | $controller = $matchs[0][0]; 263 | $route = $matchs[0][1]; 264 | 265 | // Setear el controlador y el metodo 266 | $this->Controller = $controller; 267 | $this->Action = $route; 268 | 269 | // Setear variable por posicion 270 | // Ahora que se tiene identificado un controlador y método 271 | // se puede concluir cuáles son las variables por posicion 272 | // 273 | // Ej: /site/core/login/obtenerusuarios/4/18/?id=50&nombre=hola 274 | // | | 275 | // ^ éstas son 276 | $this->SetPositionVars($controller, $route); 277 | 278 | return $route; 279 | } 280 | else { 281 | return null; 282 | } 283 | 284 | } 285 | 286 | /** 287 | * Identifica si el path analizado coincide con el request 288 | * 289 | * @param string $request El URI enviado en el request 290 | * @param string $path La ruta encontrada a analizar 291 | * 292 | * @return bool 293 | */ 294 | private function Match(string $request, string $path) : bool { 295 | 296 | // Caso especial, request del sitio principal 297 | $pathR = strtolower(str_replace('/', '', str_replace('//', '', $path))); 298 | if ($request == '' && ($pathR == 'index' || $pathR == '')) { 299 | return true; 300 | } 301 | 302 | if ($request == '') 303 | return false; 304 | 305 | // quitar el querystring 306 | $parts = explode('?', $request); 307 | 308 | if (isset($parts[0])) { 309 | $requestOnly = $parts[0]; 310 | } 311 | else { 312 | $requestOnly = $request; 313 | } 314 | 315 | return str_starts_with( strtolower($request . '/'), strtolower($path . '/')); 316 | //return str_starts_with( strtolower($path), strtolower($requestOnly)); 317 | 318 | } 319 | 320 | private function SetPositionVars(ControllerDefinition $controller, Route $route) { 321 | 322 | $positionVars = array(); 323 | 324 | // Setear las variables por posicion 325 | $parts = explode('?', $this->ServerRequestUri); 326 | 327 | // Debemos ignorar todo el texto despues del "?" (el querystring) 328 | if (isset($parts[0])) { 329 | $request = $parts[0]; 330 | 331 | $variables = str_replace($route->FullPath, '', $request); 332 | 333 | if (isset($variables) && $variables != '') { 334 | $vars = explode('/', $variables); 335 | 336 | foreach($vars as $var) { 337 | if ($var != '') { 338 | array_push($positionVars, $var); 339 | } 340 | } 341 | } 342 | } 343 | 344 | if (isset($positionVars) && count($positionVars) > 0) { 345 | $this->PositionVariables = $positionVars; 346 | } 347 | 348 | } 349 | } -------------------------------------------------------------------------------- Total de líneas: 349 ================================================================================ ================================================================================ ARCHIVO #245: src/Security/Encoder.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Security/Encoder.php Tamaño: 3.98 KB -------------------------------------------------------------------------------- 1 | method = 'aes-256-cbc'; 29 | $this->skey = 'hxr48j96scXNYAMOSiRmtgR9JP3FDRuXGCUfhFhaGlI'; 30 | $this->salt = 'XbrkZI/bcS4d6v176acNSA'; 31 | // $this->skey = 'G1fM0aXhguJ5tVaqVMJOVHB+Jk6QFd99FgkfAcEgwjI'; 32 | // $this->salt = 'xIkaHuquZFjtP4SI4mIyOg'; 33 | } 34 | 35 | public static function Instance() { 36 | 37 | if (!isset(self::$_instance)) { 38 | self::$_instance = new Encoder(); 39 | } 40 | 41 | return self::$_instance; 42 | } 43 | 44 | //const OPEN_SSL_METHOD = 'aes-256-cbc'; 45 | // Generate a 256-bit encryption key 46 | //const BASE64_ENCRYPTION_KEY = 'G1fM0aXhguJ5tVaqVMJOVHB+Jk6QFd99FgkfAcEgwjI';//base64_encode(openssl_random_pseudo_bytes(32)); 47 | //const BASE64_IV = 'xIkaHuquZFjtP4SI4mIyOg';//base64_encode(openssl_random_pseudo_bytes(openssl_cipher_iv_length(AES_256_CBC))); 48 | 49 | private function base64_url_encode($input) { 50 | return strtr(base64_encode($input), '+/=', '-_,'); 51 | } 52 | 53 | private function base64_url_decode($input) { 54 | return base64_decode(strtr($input, '-_,', '+/=')); 55 | } 56 | 57 | function Encode($message) { 58 | 59 | // Encriptar con el metodo configurado 60 | // 61 | $encrypted = openssl_encrypt($message, $this->method, base64_decode(self::BASE64_ENCRYPTION_KEY), 0, base64_decode(self::BASE64_IV)); 62 | 63 | // Volver a encriptar con Base64 64 | // 65 | $base64_encrypted = $this->base64_url_encode($encrypted); 66 | 67 | return $base64_encrypted; 68 | } 69 | 70 | function Decode($encrypted) { 71 | 72 | // Decodificar el base64 73 | // 74 | $base64_decrypted = $this->base64_url_decode($encrypted); 75 | 76 | // Desencriptar con el metodo configurado 77 | // 78 | $decrypted = openssl_decrypt($base64_decrypted, $this->method, base64_decode(self::BASE64_ENCRYPTION_KEY), 0, base64_decode(self::BASE64_IV)); 79 | 80 | return $decrypted; 81 | } 82 | 83 | static function RandomString(int $length) { 84 | 85 | $keyspace = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; 86 | $keyspace = str_shuffle($keyspace ); 87 | 88 | if ($length < 1) { 89 | return null; 90 | } 91 | 92 | $pieces = []; 93 | $max = mb_strlen($keyspace, '8bit') - 1; 94 | for ($i = 0; $i < $length; ++$i) { 95 | $pieces []= $keyspace[random_int(0, $max)]; 96 | } 97 | 98 | return implode('', $pieces); 99 | } 100 | 101 | function SerializeEncode($object) { 102 | 103 | $serialized = serialize($object); 104 | $encoded = $this->Encode($serialized); 105 | 106 | return $encoded; 107 | } 108 | 109 | function DecodeUnserialize($object) { 110 | 111 | $decoded = $this->Decode($object); 112 | $unserialized = unserialize($decoded); 113 | 114 | return $unserialized; 115 | } 116 | 117 | // function Encode($message) { 118 | 119 | // // Encriptar con el metodo configurado 120 | // // 121 | // $encrypted = openssl_encrypt($message, $this->method, base64_decode($this->key), 0, base64_decode($this->salt)); 122 | 123 | // // Volver a encriptar con Base64 124 | // // 125 | // $base64_encrypted = $this->base64_url_encode($encrypted); 126 | 127 | // return $base64_encrypted; 128 | // } 129 | 130 | // function Decode($encrypted) { 131 | 132 | // // Decodificar el base64 133 | // // 134 | // $base64_decrypted = $this->base64_url_decode($encrypted); 135 | 136 | // // Desencriptar con el metodo configurado 137 | // // 138 | // $decrypted = openssl_decrypt($base64_decrypted, $this->method, base64_decode($this->skey), 0, base64_decode($this->salt)); 139 | 140 | // return $decrypted; 141 | // } 142 | } 143 | -------------------------------------------------------------------------------- Total de líneas: 143 ================================================================================ ================================================================================ ARCHIVO #246: src/String/Concat.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/String/Concat.php Tamaño: 1.31 KB -------------------------------------------------------------------------------- 1 | $item){ 65 | 66 | if(in_array($key,$Banned)){ 67 | continue; 68 | } 69 | 70 | $object->$key = $item; 71 | 72 | } 73 | 74 | 75 | return $object; 76 | 77 | } 78 | 79 | private function getVariavleName($var) { 80 | foreach($GLOBALS as $varName => $value) { 81 | if ($value === $var) { 82 | return $varName; 83 | } 84 | } 85 | return; 86 | } 87 | } -------------------------------------------------------------------------------- Total de líneas: 87 ================================================================================ ================================================================================ ARCHIVO #251: src/Styles/ThemeConfig.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Styles/ThemeConfig.php Tamaño: 4.58 KB -------------------------------------------------------------------------------- 1 | usuario == null){ 32 | $objectSTyle = self::identifyHostStyle(); 33 | self::setStyle($objectSTyle); 34 | }else{ 35 | $IdEstilo = Session::Instance()->usuario->Cliente->IdEstilo; 36 | 37 | if(is_numeric($IdEstilo) && $IdEstilo > 0){ 38 | self::updateByIdEstilo( $IdEstilo ); 39 | }else{ 40 | $objectSTyle = self::identifyHostStyle(); 41 | self::setStyle($objectSTyle); 42 | } 43 | } 44 | } 45 | 46 | static function identifyHostStyle() : StyleObject{ 47 | 48 | $host = self::getHost(); 49 | // buscamos dentro de la base de datos si existe el estilo para este host 50 | try{ 51 | 52 | $HostFinded = (new ValorEstilosSvc(ConnectionEnum::DEFAULT))->FindByHost($host); 53 | 54 | if(empty($HostFinded)){ 55 | return new StyleObject(); 56 | } 57 | 58 | return self::mapperStyle($HostFinded); 59 | 60 | }catch(Exception $e){ 61 | 62 | return new StyleObject(); 63 | 64 | } 65 | 66 | 67 | } 68 | 69 | static function setStyle(StyleObject $StyleName){ 70 | Session::Instance()->activeStyle = $StyleName; 71 | } 72 | 73 | static function exist_style() : bool { 74 | 75 | $theme = Session::Instance()->activeStyle; 76 | 77 | if($theme instanceof StyleObject){ 78 | return true; 79 | }else{ 80 | return false; 81 | } 82 | } 83 | static function getStyle() : StyleObject { 84 | return Session::Instance()->activeStyle; 85 | } 86 | 87 | static function ChangeColor($hex,$steps){ 88 | // Steps should be between -255 and 255. Negative = darker, positive = lighter 89 | $steps = max(-255, min(255, $steps)); 90 | 91 | // Normalize into a six character long hex string 92 | $hex = str_replace('#', '', $hex); 93 | if (strlen($hex) == 3) { 94 | $hex = str_repeat(substr($hex,0,1), 2). 95 | str_repeat(substr($hex,1,1), 2). 96 | str_repeat(substr($hex,2,1), 2); 97 | } 98 | 99 | // Split into three parts: R, G and B 100 | $color_parts = str_split($hex, 2); 101 | $return = '#'; 102 | 103 | foreach ($color_parts as $color) { 104 | $color = hexdec($color); // Convert to decimal 105 | $color = max(0,min(255,$color + $steps)); // Adjust color 106 | $return .= str_pad( 107 | dechex($color) 108 | , 2, '0', STR_PAD_LEFT); // Make two char hex code 109 | } 110 | 111 | return $return; 112 | } 113 | 114 | static function getHost(){ 115 | $host = $_SERVER['HTTP_HOST']; 116 | return $host; 117 | } 118 | 119 | static function mapperStyle(GenericCollection $data) : StyleObject{ 120 | $finalObject = new StyleObject(); 121 | foreach($data as $style ){ 122 | 123 | if(isset($style->Estilo ) && !empty($style->Estilo ) && $style->Estilo instanceof Estilo){ 124 | 125 | $finalObject->IdEstilo = $style->Estilo->IdEstilo; 126 | $finalObject->Descripcion = $style->Estilo->Descripcion; 127 | $finalObject->IndHost = $style->Estilo->IndHost; 128 | $finalObject->IdTipoLogin = $style->Estilo->IdTipoLogin; 129 | $finalObject->LogoAlternativo = $style->LogoAlternativo; 130 | 131 | } 132 | 133 | if($style instanceof ValorEstilosDto){ 134 | 135 | $property = $style->IdTipoEstilo; 136 | if( property_exists($finalObject,$property) ){ 137 | $finalObject->$property = $style->Color; 138 | } 139 | } 140 | } 141 | return $finalObject; 142 | } 143 | 144 | static function updateByIdEstilo(int $IdEstilo) : bool { 145 | 146 | $ByClient = (new ValorEstilosSvc(ConnectionEnum::DEFAULT))->FindByID($IdEstilo); 147 | 148 | if(!empty($ByClient)){ 149 | 150 | $mapping = self::mapperStyle($ByClient); 151 | 152 | self::setStyle($mapping); 153 | 154 | return true; 155 | 156 | }else{ 157 | // en caso de que no existan estilos retornamos falso y lo actualizamos nada 158 | self::setStyle(new StyleObject()); 159 | return false; 160 | } 161 | 162 | } 163 | } -------------------------------------------------------------------------------- Total de líneas: 163 ================================================================================ ================================================================================ ARCHIVO #252: src/Styles/TipoLoginEnum.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Styles/TipoLoginEnum.php Tamaño: 416 bytes -------------------------------------------------------------------------------- 1 | $entries) { 24 | 25 | if ($html != "") { 26 | $html .= ",\n"; 27 | } 28 | 29 | $languages = ""; 30 | 31 | foreach($entries as $language => $entry) { 32 | if ($languages != "") { 33 | $languages .= ","; 34 | } 35 | 36 | $languages .= "['$language', '$entry']"; 37 | } 38 | 39 | $html .= "['$messageID', [$languages]]"; 40 | } 41 | ?> 42 | 43 | -------------------------------------------------------------------------------- Total de líneas: 498 ================================================================================ ================================================================================ ARCHIVO #254: src/Utils.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Utils.php Tamaño: 4.10 KB -------------------------------------------------------------------------------- 1 | "; 22 | // echo "
";
   23 |         print_r($array);
   24 |         echo "
"; 25 | die(); 26 | } 27 | 28 | public static function formatRut($rut) 29 | { 30 | return number_format(substr($rut, 0, -1), 0, "", ".") . '-' . substr($rut, strlen($rut) - 1, 1); 31 | } 32 | 33 | public static function limpiarRut($rut) 34 | { 35 | $rut = str_replace('.', '', $rut); 36 | $rut = str_replace('-', '', $rut); 37 | return $rut; 38 | } 39 | 40 | public static function getTipoDocumento($dataApplicationStringBase64) 41 | { 42 | $array = explode('/', $dataApplicationStringBase64); 43 | $array = explode(';', $array[1]); 44 | return $array[0]; 45 | } 46 | 47 | public static function validateEmpty($key) 48 | { 49 | return isset($key) && empty($key) === false ? trim($key) : ''; 50 | } 51 | 52 | public static function validatePetitionGet($key) 53 | { 54 | return isset($_GET[$key]) && empty($_GET[$key]) === false ? strtolower(trim($_GET[$key])) : ''; 55 | } 56 | 57 | public static function validatePetitionPost($key) 58 | { 59 | return isset($_POST[$key]) && empty($_POST[$key]) === false ? strtolower(trim($_POST[$key])) : ''; 60 | } 61 | 62 | public static function formatDateTime($datetime) 63 | { 64 | $array = explode(" ", $datetime); 65 | return self::formatDate($array[0]); 66 | } 67 | 68 | public static function formatDate($date) 69 | { 70 | $array = explode("-", $date); 71 | $array = array_reverse($array); 72 | return join("-", $array); 73 | } 74 | 75 | public static function sanearVariables($var, $nosanear = false) 76 | { 77 | 78 | /* TIPOS DE VARIABLES DEVUELTOS POR gettype() 79 | "boolean" 80 | "integer" 81 | "double" 82 | "string" 83 | "array" 84 | "object" 85 | "resource" 86 | "NULL" 87 | "unknown type" 88 | */ 89 | switch (gettype($var)) { 90 | case "string": 91 | 92 | //$var = strtr($var, "<>(){}", " "); 93 | 94 | if (!$nosanear) { 95 | $var = str_replace('<', '', $var); 96 | $var = str_replace('>', '', $var); 97 | $var = str_replace('(', '', $var); 98 | $var = str_replace(')', '', $var); 99 | $var = str_replace('{', '', $var); 100 | $var = str_replace('}', '', $var); 101 | } 102 | break; 103 | case "NULL": 104 | case "unknown type": 105 | $var = null; 106 | break; 107 | } 108 | 109 | return $var; 110 | } 111 | 112 | public static function createDocument($base64) 113 | { 114 | $nombreArchivo = uniqid(); 115 | $base_to_php = explode(',', $base64); 116 | $data = base64_decode($base_to_php[1]); 117 | $path = "/public/documentos/" . $nombreArchivo . '.' . Utils::getTipoDocumento($base_to_php[0]); 118 | $filepath = ".." . $path; 119 | if (file_put_contents($filepath, $data)) { 120 | return $path; 121 | } 122 | 123 | return false; 124 | } 125 | 126 | public static function CortarTextoSinPartirPalabra($texto, $largo) 127 | { 128 | $result = new stdClass(); 129 | $result->SubTexto = ""; 130 | $result->Resto = ""; 131 | 132 | $result->SubTexto = trim(substr($texto, 0, $largo)); 133 | if (strlen($texto) < $largo) 134 | return $result; 135 | 136 | $result->Resto = substr($texto, $largo, strlen($texto)); 137 | 138 | if (substr($result->SubTexto, -1) == ' ' || substr($texto, $largo, 1) == ' ') 139 | return $result; 140 | 141 | if (preg_match_all('/\s/', $result->SubTexto, $matches, PREG_OFFSET_CAPTURE)) { 142 | $ultimoEspacio = (end($matches[0]))[1]; 143 | $result->Resto = substr($result->SubTexto, $ultimoEspacio, strlen($result->SubTexto)) . $result->Resto; 144 | $result->SubTexto = trim(substr($result->SubTexto, 0, $ultimoEspacio)); 145 | } 146 | 147 | return $result; 148 | } 149 | } 150 | -------------------------------------------------------------------------------- Total de líneas: 150 ================================================================================ ================================================================================ ARCHIVO #255: src/View/Display.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/View/Display.php Tamaño: 150.54 KB -------------------------------------------------------------------------------- 1 | "'Hoy': [moment(), moment()]", 111 | 2 => "'Ayer': [moment().subtract(1, 'days'), moment().subtract(1, 'days')]", 112 | 3 => "'Ultimos 7 Días': [moment().subtract(6, 'days'), moment()]", 113 | 4 => "'Ultimos 30 Días': [moment().subtract(29, 'days'), moment()]", 114 | 5 => "'Este Mes': [moment().startOf('month'), moment().endOf('month')]", 115 | 6 => "'Mes Anterior': [moment().subtract(1, 'month').startOf('month'), moment().subtract(1, 'month').endOf('month')]", 116 | 7 => "'Ultimos 6 Meses': [moment().subtract(6, 'months').startOf('month'), moment().subtract(1, 'month').endOf('month')]", 117 | 8 => "'Ultimos 12 Meses': [moment().subtract(12, 'months').startOf('month'), moment().subtract(1, 'month').endOf('month')]", 118 | 9 => "'Este Año': [moment().startOf('year'), moment().endOf('year')]", 119 | 10 => "'Año Anterior' : [ moment().subtract(1, 'year').startOf('year'), moment().subtract(1, 'year').endOf('year')]", 120 | ]; 121 | 122 | private $_RangeIntervalStartEnd = [ 123 | 1 => ["moment()", "moment()"], 124 | 2 => ["moment().subtract(1, 'days')", "moment().subtract(1, 'days')"], 125 | 3 => ["moment().subtract(6, 'days')", "moment()"], 126 | 4 => ["moment().subtract(29, 'days')", "moment()"], 127 | 5 => ["moment().startOf('month')", "moment().endOf('month')"], 128 | 6 => ["moment().subtract(1, 'month').startOf('month')", "moment().subtract(1, 'month').endOf('month')"], 129 | 7 => ["moment().subtract(6, 'months').startOf('month')", "moment().subtract(1, 'month').endOf('month')"], 130 | 8 => ["moment().subtract(12, 'months').startOf('month')", "moment().subtract(1, 'month').endOf('month')"], 131 | 9 => ["moment().startOf('year')", "moment().endOf('year')"], 132 | 10 => ["moment().subtract(1, 'year').startOf('year')", "moment().subtract(1, 'year').endOf('year')"], 133 | ]; 134 | 135 | public static function _($message) { 136 | return self::GetRenderer()->RenderMensaje($message); 137 | } 138 | 139 | public function Widgets() { 140 | return $this->_Widgets; 141 | } 142 | 143 | public function Scripts() { 144 | return $this->_Scripts; 145 | } 146 | 147 | // Imprime una fecha con formato dinámico para cambio de idioma en línea 148 | public static function DrawDateTime(\DateTime $fecha, $format, $classes = '') { 149 | 150 | $fmt = Mensaje::_($format); 151 | $fechaDisplay = $fecha->format($fmt); 152 | $Y = $fecha->format('Y'); 153 | $m = $fecha->format('m'); 154 | $d = $fecha->format('d'); 155 | $H = $fecha->format('H'); 156 | $i = $fecha->format('i'); 157 | $s = $fecha->format('s'); 158 | 159 | $html = "$fechaDisplay"; 160 | 161 | echo $html; 162 | } 163 | 164 | public static function GetRenderer($path = "", $forceNew = false): BaseController | null { 165 | 166 | if ($forceNew || self::$Renderer == null || $path != self::$Path) { 167 | self::$Renderer = new BaseController(assetManagerFactory: new AssetManagerFactory(), forcedController: $path); 168 | self::$Path = $path; 169 | } 170 | 171 | return self::$Renderer; 172 | } 173 | 174 | public static function DrawSection($title, $info, $classes = "") { 175 | echo " 176 |
177 |
178 |
179 |
180 | "; 181 | } 182 | 183 | public static function DrawInputSection($title, $id, $placeholder, $inputType, $inputAtributes = "", $classes = "") { 184 | echo " 185 |
186 |
187 |
188 | 189 |
190 |
191 | "; 192 | } 193 | 194 | public static function DrawInputTextAreaSection($title, $id, $placeholder, $inputType, $inputAtributes = "", $classes = "",$value="") { 195 | echo " 196 |
197 |
198 |
199 | 200 |
201 |
202 | "; 203 | } 204 | 205 | public static function DrawLabelSection($title, $info, $labelType, $classes = "") { 206 | 207 | echo " 208 |
209 |
" . $info . "
210 |
211 |
212 | "; 213 | } 214 | 215 | public static function DrawProgressSection($title, $percentage, $labelType, $classes = "") { 216 | 217 | $progressType = ""; 218 | 219 | if ($labelType == "") { 220 | $labelType = "default"; 221 | $progressType = "info"; 222 | } 223 | else { 224 | $progressType = $labelType; 225 | } 226 | 227 | echo " 228 |
229 |
230 |
231 | $title " . number_format($percentage, 0, '.', ',') . " % 232 |
233 |
234 |
235 |
236 |
240 |
241 |
242 |
243 |
244 | "; 245 | } 246 | 247 | public static function DrawProgressBar( 248 | $progressId, 249 | $containerStyle = "background-color: #f5f5f5; margin-top: 5px;", 250 | $progressStyle = "background-color: transparent;" 251 | ) { 252 | 253 | echo " 254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
262 |
263 | "; 264 | } 265 | 266 | public static function DrawPanelLabel($title, $size = 0) { 267 | 268 | if (isset($size) && $size > 0) { 269 | $font = "font-size: " . $size . "px;"; 270 | } 271 | else { 272 | $font = ""; 273 | } 274 | 275 | echo " 276 |
277 | "; 278 | } 279 | 280 | public static function DrawInfoLabel($title) { 281 | 282 | echo " 283 |
284 | "; 285 | } 286 | 287 | public static function DrawPageTile($title, $subtitle) { 288 | echo " 289 |
290 |

291 | " . $title ." 292 |

293 |
294 | " . $subtitle . " 295 | "; 296 | } 297 | 298 | public static function DrawInfoBox($content, $closable = false, $show = true) { 299 | 300 | echo " 301 |
302 | $content 303 |
304 | "; 305 | } 306 | 307 | public static function DrawInfoIcon($text, $placement = "top", $isHtml = false, $icon="fa-info-circle") { 308 | echo ""; 309 | } 310 | 311 | public static function DrawValueLabel($value, $style = 'default', $disableOnZero = true) { 312 | 313 | if ($disableOnZero && ($value == 0 || $value == '')) { 314 | echo "0"; 315 | } 316 | else { 317 | echo "$value"; 318 | } 319 | } 320 | 321 | public static function DrawTabTitle($title = "", $icon = "", $iconsize = 20) { 322 | 323 | if ($title=="") { 324 | echo " 325 |
326 | 327 |
328 | "; 329 | } 330 | else if ($icon=="") { 331 | echo " 332 |
333 | $title 334 |
335 | "; 336 | } 337 | else { 338 | echo " 339 |
340 | 341 | $title 342 |
343 | "; 344 | } 345 | } 346 | 347 | private function AddAnyButton(Button $button) { 348 | 349 | $formKey = ""; 350 | 351 | if ($button instanceof FormButton) { 352 | $type = 'FormButton'; 353 | $key = $button->Key; 354 | $formKey = $button->FormKey; 355 | } 356 | else { 357 | $type = 'Button'; 358 | $key = $button->Key; 359 | $formKey = ""; 360 | } 361 | 362 | $actionButton = new ActionButton( 363 | Key: $key, 364 | ButtonStyle: $button->ButtonStyle, 365 | Child: $button->Child, 366 | Classes: $button->Classes, 367 | Styles: $button->Styles, 368 | Attributes: $button->Attributes, 369 | Properties: $button->Properties 370 | ); 371 | 372 | $this->_Widgets[$button->Key] = $actionButton; 373 | 374 | // Get Scripts 375 | // 376 | // Scripts del evento actual 377 | // 378 | $eventScripts = []; 379 | foreach($button->Events as $event) { 380 | if ($event instanceof Event) { 381 | $eventScripts[ 382 | (new \ReflectionClass($event))->getShortName() 383 | ] = $event->GetScript(element: $button); 384 | } 385 | else if ($event instanceof FormEvent) { 386 | $eventScripts[ 387 | (new \ReflectionClass($event))->getShortName() 388 | ] = $event->GetScript(field: $button, formKey: $formKey); 389 | } 390 | } 391 | 392 | // GLOBAL Scripts 393 | // Scripts globales del campo, se definen fuera de cualquier evento, dentro del evento principal $(function(){}); 394 | // 395 | $globalScript = $button->GetGlobalScripts(); 396 | 397 | // Asociar los scripts con el boton 398 | $this->_Scripts[$button->Key] = [ 399 | 'Type' => $type, 400 | 'Scripts' => [ 401 | 'Key' => $button->Key, 402 | 'Events' => $eventScripts, 403 | 'Global' => $globalScript 404 | ] 405 | ]; 406 | 407 | } 408 | 409 | public function AddButton(Button $button) { 410 | 411 | $this->AddAnyButton($button); 412 | 413 | } 414 | 415 | public function AddSexyTabGroup(string $Key, array $Tabs = []) { 416 | 417 | $cantTabs = 0; 418 | foreach($Tabs as $tab) { 419 | if ($tab instanceof Tab) { 420 | $cantTabs++; 421 | } 422 | } 423 | 424 | if ($cantTabs <= 5) { 425 | $porcentaje = 20; 426 | $primero = 20; 427 | } 428 | else { 429 | // Calcular el porcentaje 430 | $porcentaje = round(98/$cantTabs, 0); 431 | $suma = $porcentaje * $cantTabs; 432 | 433 | $primero = $porcentaje; 434 | // if ($suma < 98) { 435 | // $primero = $primero + (98-$suma); 436 | // } 437 | } 438 | 439 | $sexyTabs = []; 440 | $sexyPages = []; 441 | $buttonScripts = []; 442 | $tabScripts = []; 443 | 444 | // Crear los WIDGETS 445 | // 446 | foreach($Tabs as $idx => $tab) { 447 | 448 | if ($tab instanceof Tab) { 449 | 450 | if ($idx == 0) { 451 | $width = $primero; 452 | } 453 | else { 454 | $width = $porcentaje; 455 | } 456 | 457 | array_push($sexyTabs, new SexyTab( 458 | Key: $tab->TabKey, 459 | Order: $idx+1, 460 | Icon: $tab->Icon, 461 | Title: $tab->Title, 462 | Styles: [ 463 | ['width', $width . '% !important'] 464 | ], 465 | Attributes: [ 466 | ['data-contentsourceurifunction', $tab->ContentSourceUriFunction] 467 | ] 468 | )); 469 | 470 | //array_push($tabScripts, $this->GenerateTabScript(Tab: $tab, Order: $idx+1)); 471 | 472 | $buttons = []; 473 | foreach($tab->PageButtons as $idxBtn => $button) { 474 | if ($button instanceof Button) { 475 | array_push($buttons, $button); 476 | } 477 | } 478 | 479 | $pageButtons = []; 480 | foreach($buttons as $idxBtn => $button) { 481 | 482 | // Sólo el primer botón ignora margen izquierdo 483 | if ($idxBtn > 0) { 484 | array_push($button->Styles, ['margin-left', '8px']); 485 | } 486 | 487 | // Crear el widget de este boton 488 | array_push($pageButtons, new ActionButton( 489 | Key: $button->Key, 490 | Child: $button->Child, 491 | ButtonStyle: $button->ButtonStyle, 492 | Classes: $button->Classes, 493 | Styles: $button->Styles, 494 | Attributes: $button->Attributes, 495 | Properties: $button->Properties, 496 | )); 497 | 498 | // Obtener el script de cada evento asociado al botón 499 | foreach($button->Events as $event) { 500 | if ($event instanceof Event) { 501 | $eventScript = $event->GetScript($button); 502 | array_push($buttonScripts, $eventScript); 503 | } 504 | } 505 | 506 | } 507 | 508 | // Agregar el botón REFRESCAR 509 | if ($tab->ContentSourceUriFunction != '') { 510 | $button = new Button( 511 | Key: 'BtnRefrescar' . $tab->TabKey, 512 | ButtonStyle: ButtonStyleEnum::BUTTON_DEFAULT, 513 | Child: new FaIconText('fa-sync-alt', 'Refrescar'), 514 | Styles: [ 515 | ['margin-left', '8px'] 516 | ], 517 | Events: [ 518 | new SexyPageButtonOnRefreshEvent( 519 | ContentSourceUriFunction: $tab->ContentSourceUriFunction, 520 | TabGroupKey: $Key) 521 | ] 522 | ); 523 | 524 | array_push($pageButtons, new ActionButton( 525 | Key: $button->Key, 526 | Child: $button->Child, 527 | ButtonStyle: $button->ButtonStyle, 528 | Classes: $button->Classes, 529 | Styles: $button->Styles, 530 | Attributes: $button->Attributes, 531 | Properties: $button->Properties, 532 | )); 533 | 534 | foreach($button->Events as $event) { 535 | if ($event instanceof Event) { 536 | $eventScript = $event->GetScript($button); 537 | array_push($buttonScripts, $eventScript); 538 | } 539 | } 540 | } 541 | 542 | $dataAttributes = []; 543 | foreach($tab->TabData as $key => $data) { 544 | $dataAttributes['data-' . $key] = $data; 545 | } 546 | 547 | array_push($sexyPages, new SexyTabPage( 548 | Key: $tab->TabKey, 549 | Order: $idx+1, 550 | Content: '', 551 | Attributes: $dataAttributes, 552 | ContentClasses: ['sexytab-page-content'], 553 | TopButtons: $pageButtons, 554 | )); 555 | } 556 | } 557 | 558 | // Crear el grupo 559 | $grupo = new SexyTabGroup( 560 | Key: $Key, 561 | Tabs: $sexyTabs, 562 | Pages: $sexyPages, 563 | ); 564 | 565 | // Agregar el grupoTab a la colección de widgets 566 | $this->_Widgets[$Key] = $grupo; 567 | 568 | // Agregar los scripts de este grupoTab a la colección de scripts 569 | $this->_Scripts[$Key] = [ 570 | 'Type' => 'SexyTabGroup', 571 | 'Scripts' => [ 572 | 'TabScripts' => $tabScripts, 573 | 'ButtonScripts' => $buttonScripts, 574 | 'GroupScripts' => [$this->GenerateSexyTabsOnLoadScript(Key: $Key)], 575 | ] 576 | ]; 577 | 578 | return true; 579 | } 580 | 581 | /** 582 | * ObjectToForm: genera un formulario para mostrar campos seleccionados desde un objeto 583 | * 584 | * @param Object: el objeto de origen 585 | * @param Rows: arreglo de campos del objeto origen que serán incluidos en el formulario. Cada elemento del arreglo constituirá una fila del formulario 586 | * y consiste a su vez en un arreglo con los campos que irán en dicha fila 587 | * 588 | */ 589 | public function AddFormFromObject( 590 | string $formKey, 591 | object $object, 592 | array $rowGroups, 593 | string $keyFieldName, 594 | bool $fillData = false 595 | ): bool { 596 | 597 | // Revisar si este formulario ya existe 598 | if (isset($this->_Widgets[$formKey])) { 599 | throw new \Exception('El elemento: ' . $formKey . ' ya ha sido definido previamente'); 600 | return false; 601 | } 602 | 603 | $rows = []; 604 | $groups = []; 605 | foreach($rowGroups as $rowGroup) { 606 | 607 | if ($rowGroup instanceof FormRowGroup) { 608 | 609 | $groups[$rowGroup->Key] = $rowGroup; 610 | 611 | foreach($rowGroup->Rows as $row) { 612 | array_push($rows, $row); 613 | } 614 | } 615 | } 616 | 617 | $keyFieldValue = (property_exists($object,$keyFieldName)) ? $object->$keyFieldName : null; 618 | 619 | $dataRows = []; 620 | $first = true; 621 | $firstGlobal = true; 622 | $fields = []; 623 | $formGroups = []; 624 | foreach($rowGroups as $rowGroup) { 625 | 626 | $formGroups[$rowGroup->Key] = new \stdClass(); 627 | $formGroups[$rowGroup->Key]->Group = $rowGroup; 628 | $formGroups[$rowGroup->Key]->Rows = []; 629 | 630 | if (isset($rowGroup->Title) && $rowGroup->Title != '') { 631 | 632 | $classes = []; 633 | if (!$firstGlobal) { 634 | $classes = ['separator']; 635 | } 636 | 637 | $dataRow = new FormGroupSeparator( 638 | Title: $rowGroup->Title, 639 | Classes: $classes 640 | ); 641 | array_push($dataRows, $dataRow); 642 | array_push($formGroups[$rowGroup->Key]->Rows, $dataRow); 643 | 644 | $firstGlobal = false; 645 | } 646 | 647 | foreach($rowGroup->Rows as $row) { 648 | 649 | $dataColumns = []; 650 | 651 | foreach($row as $field) { 652 | 653 | if (!isset($field)) 654 | continue; 655 | 656 | if (isset($field->PropertyName) && $field->PropertyName != '') { 657 | $field->Id = $formKey . '-' . $field->PropertyName; 658 | } 659 | else if (isset($field->Key) && $field->Key != '') { 660 | $field->Id = $formKey . '-' . $field->Key; 661 | } 662 | 663 | if ($field instanceof FormRowFieldLabel) { 664 | 665 | $column = $this->PropertyToLabel( 666 | field: $field, 667 | formKey: $formKey, 668 | object: $object, 669 | layout: $rowGroup->Layout 670 | ); 671 | } 672 | else if ($field instanceof FormRowFieldSubTitle) { 673 | $column = $this->PropertyToSubTitle( 674 | field: $field, 675 | formKey: $formKey, 676 | layout: $rowGroup->Layout 677 | ); 678 | } 679 | else if ($field instanceof FormRowFieldContent) { 680 | $column = $this->PropertyToContent( 681 | field: $field, 682 | layout: $rowGroup->Layout 683 | ); 684 | } 685 | else if ($field instanceof FormRowFieldEmpty) { 686 | $column = $this->PropertyToEmpty( 687 | field: $field, 688 | layout: $rowGroup->Layout 689 | ); 690 | } 691 | else if ($field instanceof FormRowFieldHidden) { 692 | $column = $this->PropertyToHidden( 693 | field: $field, 694 | formKey: $formKey, 695 | object: $object 696 | ); 697 | } 698 | else { 699 | 700 | if (!$this->ValidateObjectField($object, $field)) { 701 | throw new \Exception('El campo ' . $field->PropertyName . ' tiene problemas de validación'); 702 | return false; 703 | } 704 | 705 | $fields[$field->PropertyName] = $field; 706 | 707 | $propertyName = $field->PropertyName; 708 | 709 | if (isset($object->$propertyName)) { 710 | $propertyValue = $object->$propertyName; 711 | } 712 | else { 713 | $propertyValue = ''; 714 | } 715 | 716 | $field->Value = $propertyValue; 717 | 718 | $column = null; 719 | 720 | if ($field instanceof FormRowFieldCheck) { 721 | $column = $this->PropertyToCheck( 722 | field: $field, 723 | propertyValue: $propertyValue, 724 | keyFieldName: $keyFieldName, 725 | formKey: $formKey, 726 | fillData: $fillData, 727 | layout: $rowGroup->Layout 728 | ); 729 | } 730 | else if ($field instanceof FormRowFieldText && ( 731 | $field->FieldType == FormRowFieldTypeEnum::INPUT_TEXT || 732 | $field->FieldType == FormRowFieldTypeEnum::INPUT_PASSWORD || 733 | $field->FieldType == FormRowFieldTypeEnum::INPUT_EMAIL 734 | )) { 735 | $column = $this->PropertyToTextInput( 736 | field: $field, 737 | propertyValue: $propertyValue, 738 | keyFieldName: $keyFieldName, 739 | formKey: $formKey, 740 | fillData: $fillData, 741 | layout: $rowGroup->Layout 742 | ); 743 | } 744 | else if ($field instanceof FormRowFieldText && $field->FieldType == FormRowFieldTypeEnum::INPUT_COLOR ) 745 | { 746 | $column = $this->PropertytoColorInput( 747 | field: $field, 748 | propertyValue: $propertyValue, 749 | keyFieldName: $keyFieldName, 750 | formKey: $formKey, 751 | fillData: $fillData, 752 | layout: $rowGroup->Layout 753 | ); 754 | } 755 | else if ($field instanceof FormRowFieldText && ( 756 | $field->FieldType == FormRowFieldTypeEnum::INPUT_TEXTAREA 757 | )) { 758 | $column = $this->PropertyToTextArea( 759 | field: $field, 760 | propertyValue: $propertyValue, 761 | keyFieldName: $keyFieldName, 762 | formKey: $formKey, 763 | fillData: $fillData, 764 | layout: $rowGroup->Layout 765 | ); 766 | } 767 | else if ($field instanceof FormRowFieldText && ( 768 | $field->FieldType == FormRowFieldTypeEnum::INPUT_FILE || 769 | $field->FieldType == FormRowFieldTypeEnum::INPUT_ALL_FILES || 770 | $field->FieldType == FormRowFieldTypeEnum::INPUT_FILE_PROFILE_PICTURE 771 | )) { 772 | $column = $this->PropertyToFileInput( 773 | field: $field, 774 | propertyValue: $propertyValue, 775 | keyFieldName: $keyFieldName, 776 | formKey: $formKey, 777 | fillData: $fillData, 778 | layout: $rowGroup->Layout 779 | ); 780 | }else if ( $field instanceof FormRowFieldText && $field->FieldType == FormRowFieldTypeEnum::INPUT_FILE_EXCEL ) { 781 | $column = $this->PropertyToFileInputExcel( 782 | field: $field, 783 | propertyValue: $propertyValue, 784 | keyFieldName: $keyFieldName, 785 | formKey: $formKey, 786 | fillData: $fillData, 787 | layout: $rowGroup->Layout 788 | ); 789 | } 790 | else if ($field instanceof FormRowFieldDate && ( 791 | $field->FieldType == FormRowFieldTypeEnum::INPUT_DATE || 792 | $field->FieldType == FormRowFieldTypeEnum::INPUT_DATETIME || 793 | $field->FieldType == FormRowFieldTypeEnum::INPUT_TIME 794 | )) { 795 | 796 | $column = $this->PropertyToDateInput( 797 | field: $field, 798 | propertyValue: $propertyValue, 799 | keyFieldName: $keyFieldName, 800 | keyFieldValue: $keyFieldValue, 801 | formKey: $formKey, 802 | fillData: $fillData, 803 | layout: $rowGroup->Layout 804 | ); 805 | 806 | } 807 | else if ($field instanceof FormRowFieldDate && $field->FieldType == FormRowFieldTypeEnum::INPUT_DATERANGE) { 808 | 809 | $column = $this->PropertyToDateRangeInput( 810 | field: $field, 811 | propertyValue: $propertyValue, 812 | keyFieldName: $keyFieldName, 813 | keyFieldValue: $keyFieldValue, 814 | formKey: $formKey, 815 | fillData: $fillData, 816 | layout: $rowGroup->Layout 817 | ); 818 | 819 | } 820 | else if ($field instanceof FormRowFieldSelect) { 821 | 822 | $column = $this->PropertyToSelectInput( 823 | field: $field, 824 | propertyValue: $propertyValue, 825 | keyFieldName: $keyFieldName, 826 | keyFieldValue: $keyFieldValue, 827 | formKey: $formKey, 828 | fillData: $fillData, 829 | layout: $rowGroup->Layout 830 | ); 831 | 832 | } 833 | 834 | } 835 | 836 | if (isset($column)) { 837 | array_push($dataColumns, $column); 838 | } 839 | } 840 | 841 | if (count($dataColumns) > 0) { 842 | $dataRow = new FormGroupRow( 843 | Columns: $dataColumns, 844 | First: $first, 845 | Layout: $rowGroup->Layout 846 | ); 847 | 848 | array_push($dataRows, $dataRow); 849 | array_push($formGroups[$rowGroup->Key]->Rows, $dataRow); 850 | 851 | $first = false; 852 | $firstGlobal = false; 853 | } 854 | 855 | } 856 | } 857 | 858 | $scripts = []; 859 | 860 | foreach($rowGroups as $rowGroup) { 861 | foreach($rowGroup->Rows as $row) { 862 | foreach($row as $field) { 863 | 864 | if ($field instanceof FormRowField) { 865 | 866 | $eventScripts = []; 867 | foreach($field->Events as $event) { 868 | 869 | if ($event instanceof FormEvent) { 870 | $eventScripts[ 871 | (new \ReflectionClass($event))->getShortName() 872 | ] = $event->GetScript($field, $object, $fields, $groups, $rows, $formKey); 873 | } 874 | } 875 | 876 | // Scripts especiales de fields 877 | if ($field->FieldType == FormRowFieldTypeEnum::INPUT_FILE) { 878 | $eventScripts['FileInputInit'] = $this->GenerateFileInputScript($field); 879 | } 880 | // Scripts especiales de fields 881 | if ($field->FieldType == FormRowFieldTypeEnum::INPUT_FILE_PROFILE_PICTURE) { 882 | $eventScripts['FileInputInit'] = $this->GenerateOneFileInputScript($field); 883 | } 884 | 885 | // SCrips para FileInput para Excels 886 | if ($field->FieldType == FormRowFieldTypeEnum::INPUT_FILE_EXCEL) { 887 | $eventScripts['FileInputInit'] = $this->GenerateFileInputScriptExcel($field); 888 | } 889 | 890 | //GENERACION DEL DATERANGE 891 | if ($field->FieldType == FormRowFieldTypeEnum::INPUT_DATERANGE) { 892 | $eventScripts['DateRangeInit'] = $this->GenerateDateRangeOnKeyUpScript($field->PropertyName, $formKey); 893 | } 894 | 895 | // GLOBAL Scripts 896 | // Scripts globales del campo, se definen fuera de cualquier evento, dentro del evento principal $(function(){}); 897 | // 898 | $globalScript = $field->GetGlobalScripts(); 899 | 900 | // Asociar los scripts con el campo 901 | $scripts[$field->PropertyName] = [ 902 | 'Events' => $eventScripts, 903 | 'Global' => $globalScript 904 | ]; 905 | } 906 | } 907 | } 908 | } 909 | 910 | $form = null; 911 | if (count($dataRows) > 0) { 912 | 913 | $containerGroups = []; 914 | 915 | foreach($formGroups as $groupKey => $groupData) { 916 | 917 | $groupClasses = []; 918 | if (!$groupData->Group->Visible) { 919 | array_push($groupClasses, 'hide'); 920 | } 921 | 922 | if ($groupData->Group->Filled) { 923 | array_push($groupClasses, 'filled'); 924 | } 925 | 926 | $groupRows = $groupData->Rows; 927 | 928 | $containerGroups[$groupKey] = new FormGroup( 929 | Key: $groupKey, 930 | Rows: $groupRows, 931 | Classes: $groupClasses 932 | ); 933 | } 934 | 935 | $form = new Container( 936 | Children: $containerGroups 937 | ); 938 | } 939 | 940 | $this->_Widgets[$formKey] = $form; 941 | 942 | $this->_Scripts[$formKey] = [ 943 | 'Type' => 'Form', 944 | 'Scripts' => [ 945 | 'FieldScripts' => $scripts, 946 | 'FormScripts' => [$this->GenerateFormOnLoadScript($formKey)] 947 | ] 948 | ]; 949 | 950 | return true; 951 | } 952 | 953 | private function GetObjectMetadata(object $object) { 954 | 955 | $annotations = AnnotationHelper::FromObject($object); 956 | $meta = new \stdClass(); 957 | 958 | // Buscar la llave 959 | $llave = $annotations->FindAttributeProperty(ViewDisplayKey::class); 960 | $meta->KeyFieldName = (isset($llave) && isset($llave->propertyName)) ? $llave->propertyName : ''; 961 | 962 | $attributes = $annotations->GetAttributeProperties(ViewDisplay::class); 963 | 964 | $props = []; 965 | 966 | if (isset($attributes)) { 967 | foreach($attributes as $attr) { 968 | $prop = new \stdClass(); 969 | $prop->PropertyName = $attr->propertyName; 970 | $prop->FieldType = isset($attr->attribute->FieldType) ? $attr->attribute->FieldType : ''; 971 | $prop->Label = isset($attr->attribute->Label) ? $attr->attribute->Label : ''; 972 | $prop->Required = isset($attr->attribute->Required) ? $attr->attribute->Required : null; 973 | $prop->DisplayFunction = isset($attr->attribute->DisplayFunction) ? $attr->attribute->DisplayFunction : ''; 974 | 975 | $props[$attr->propertyName] = $prop; 976 | } 977 | } 978 | 979 | $meta->Properties = $props; 980 | 981 | return $meta; 982 | } 983 | 984 | // private function AutocompleteField(object $field, $metadata, string $formKey) { 985 | 986 | // if ( (isset($field->PropertyName) && $field->PropertyName != '') || ( isset($field->Key) && $field->Key != '') ) { 987 | // $id = (($formKey != '') ? $formKey . '-' : '') . ( (isset($field->PropertyName) && $field->PropertyName != '') ? $field->PropertyName : $field->Key ); 988 | // } 989 | // else { 990 | // $id = ''; 991 | // } 992 | 993 | // $field->Id = $id; 994 | 995 | // if (!isset($field->FieldType) || $field->FieldType == '') { 996 | 997 | // if (isset($field->PropertyName) && isset($metadata->Properties[$field->PropertyName])) { 998 | // $field->FieldType = $metadata->Properties[$field->PropertyName]->FieldType; 999 | // } 1000 | // } 1001 | 1002 | // if (!isset($field->Label) || $field->Label == '') { 1003 | // if (isset($field->PropertyName) && isset($metadata->Properties[$field->PropertyName])) { 1004 | // $field->Label = $metadata->Properties[$field->PropertyName]->Label; 1005 | // } 1006 | // } 1007 | 1008 | // if (!isset($field->Required)) { 1009 | // $field->Required = false; 1010 | // if (isset($field->PropertyName) && isset($metadata->Properties[$field->PropertyName])) { 1011 | // if (isset($metadata->Properties[$field->PropertyName]->Required)) 1012 | // $field->Required = $metadata->Properties[$field->PropertyName]->Required; 1013 | // } 1014 | // } 1015 | 1016 | // return $field; 1017 | // } 1018 | 1019 | private function GenerateFileInputScript(FormRowFieldText $field) { 1020 | 1021 | $extensiones = ""; 1022 | 1023 | foreach($field->Extensiones as $ext) { 1024 | 1025 | if ($extensiones != "") { 1026 | $extensiones .= ', '; 1027 | } 1028 | 1029 | $extensiones .= "'" . $ext . "'"; 1030 | } 1031 | 1032 | return " 1033 | $('#" . $field->Id . "').fileinput({ 1034 | language: 'es', 1035 | showUpload: false, 1036 | showCancel: false, 1037 | allowedFileExtensions: [" . $extensiones . "], 1038 | uploadExtraData : { 1039 | 'proceso' :'" . $field->Proceso . "', 1040 | 'tipo' : '" . $field->Tipo . "' 1041 | }, 1042 | uploadUrl : '/api/core/files', 1043 | uploadAsync: false 1044 | }).on('filebatchuploadsuccess', function (event, data) { 1045 | if (data) { 1046 | if (data.response) { 1047 | if (data.response.ErrorCode == 0) { 1048 | if (data.response.Result) { 1049 | 1050 | var evidenciaSvc = new EvidenciaSvc(); 1051 | evidenciaSvc.GuardarEvidencias(data.response.Result,$('#formSubirArchivos-Descripcion').val()); 1052 | 1053 | } 1054 | else { 1055 | 1056 | Toast.fire({ 1057 | icon: 'error', 1058 | html: 'Ocurrió un error al subir los archivos' 1059 | }); 1060 | } 1061 | } 1062 | else { 1063 | Toast.fire({ 1064 | icon: 'error', 1065 | html: data.response.ErrorMessage 1066 | }); 1067 | } 1068 | } 1069 | } 1070 | }).on('', function () { 1071 | 1072 | });"; 1073 | } 1074 | 1075 | private function GenerateOneFileInputScript(FormRowField $field) { 1076 | 1077 | 1078 | return " 1079 | console.log('generado'); 1080 | $('#" . $field->Id . "').fileinput({ 1081 | language: 'es', 1082 | showUpload: false, 1083 | showCancel: false, 1084 | maxFileCount: 1, 1085 | allowedFileExtensions: ['jpg', 'jpeg', 'png'], 1086 | uploadExtraData : { 1087 | 'proceso' :'PictureProfile', 1088 | 'tipo' : 'foto', 1089 | 'idUsuario' : $('#IdUsuario').val() 1090 | }, 1091 | uploadUrl : '/api/core/files', 1092 | uploadAsync: false 1093 | }).on('filebatchuploadsuccess', function (event, data) { 1094 | if (data) { 1095 | if (data.response) { 1096 | if (data.response.ErrorCode == 0) { 1097 | if (data.response.Result) { 1098 | 1099 | GuardarProfilePicture(data.response.Result); 1100 | 1101 | } 1102 | else { 1103 | 1104 | Toast.fire({ 1105 | icon: 'error', 1106 | html: 'Ocurrió un error al subir los archivos' 1107 | }); 1108 | } 1109 | } 1110 | else { 1111 | Toast.fire({ 1112 | icon: 'error', 1113 | html: data.response.ErrorMessage 1114 | }); 1115 | } 1116 | } 1117 | } 1118 | }).on('', function () { 1119 | 1120 | });"; 1121 | } 1122 | private function GenerateFileInputScriptExcel(FormRowField $field) { 1123 | 1124 | $ext = ""; 1125 | 1126 | if (isset($field->Extensiones) && is_array($field->Extensiones) && count($field->Extensiones) > 0) { 1127 | foreach($field->Extensiones as $idx => $ex) { 1128 | $field->Extensiones[$idx] = "'" . $ex . "'"; 1129 | } 1130 | $ext = implode(",", $field->Extensiones); 1131 | } 1132 | else { 1133 | $ext = "'xls', 'xlsx'"; 1134 | } 1135 | 1136 | return " 1137 | $('#" . $field->Id . "').fileinput({ 1138 | language: 'es', 1139 | showUpload: false, 1140 | showCancel: false, 1141 | allowedFileExtensions: [" . $ext . "], 1142 | uploadAsync: false 1143 | });"; 1144 | } 1145 | 1146 | private function GenerateGlobalPageScript() { 1147 | return " 1148 | // SCRIPT GLOBAL 1149 | // 1150 | if ( typeof Page_OnLoad === 'function') { 1151 | Page_OnLoad(); 1152 | } 1153 | "; 1154 | } 1155 | 1156 | private function GenerateGlobalScript() { 1157 | return " 1158 | 1159 | // SCRIPT GLOBAL GENERICO 1160 | // 1161 | 1162 | // Setear los formateadores 1163 | $('.money-format.new').each(function() { 1164 | 1165 | $(this).on(\"focusin\", function() { 1166 | $(this).UnFormat(); 1167 | $(this).select(); 1168 | }); 1169 | 1170 | $(this).on(\"focusout\", function() { 1171 | $(this).ApplyFormat( 1172 | 'es-CL', 1173 | { 1174 | style: 'currency', 1175 | currency: 'CLP' 1176 | } 1177 | ); 1178 | }); 1179 | 1180 | $(this).ApplyFormat( 1181 | 'es-CL', 1182 | { 1183 | style: 'currency', 1184 | currency: 'CLP' 1185 | } 1186 | ); 1187 | $(this).removeClass('new'); 1188 | }); 1189 | 1190 | $('.thousand-format.new').each(function() { 1191 | 1192 | $(this).on(\"focusin\", function() { 1193 | $(this).UnFormat(); 1194 | $(this).select(); 1195 | }); 1196 | 1197 | $(this).on(\"focusout\", function() { 1198 | $(this).ApplyFormat(); 1199 | }); 1200 | 1201 | $(this).ApplyFormat(); 1202 | $(this).removeClass('new'); 1203 | }); 1204 | 1205 | "; 1206 | } 1207 | 1208 | private function GenerateFormOnLoadScript($formKey) { 1209 | 1210 | return " 1211 | 1212 | // FORMULARIO: " . $formKey . " 1213 | // 1214 | // EVENTO: ONLOAD 1215 | // Llamar a la funcion de carga inicial del formulario actual 1216 | // 1217 | if ( typeof " . $formKey . "_OnLoad === 'function') { 1218 | var myForm = null; 1219 | var myElements = null; 1220 | 1221 | if (typeof ReadForm === 'function') { 1222 | myForm = ReadForm('" . $formKey . "'); 1223 | } 1224 | 1225 | if (typeof ReadFormElements === 'function') { 1226 | myElements = ReadFormElements('" . $formKey . "'); 1227 | } 1228 | 1229 | eventInfo = { 1230 | FormData : myForm, 1231 | FormElements : myElements 1232 | } 1233 | 1234 | if ( typeof " . $formKey . "_OnLoad === 'function' ) { 1235 | " . $formKey . "_OnLoad(eventInfo); 1236 | } 1237 | } 1238 | "; 1239 | 1240 | } 1241 | 1242 | /* 1243 | public function GenerateTabScript(Tab $Tab, $Order) { 1244 | 1245 | if ($Tab->ContentSourceUriFunction != '') { 1246 | 1247 | $number = '00' . $Order; 1248 | $number = substr($number, -3); 1249 | 1250 | $key = $number . '-' . $Tab->TabKey; 1251 | 1252 | return " 1253 | // TAB: " . $Tab->TabKey . " 1254 | // OnClick Event 1255 | $('ul.activas-ul > li).on('click', function () { 1256 | 1257 | if ( typeof " . $Tab->ContentSourceUriFunction . " === 'function') { 1258 | if (typeof RefreshContent === 'function') { 1259 | 1260 | // Obtener el SexyTabPage de este boton 1261 | var pageElement = $('div.ui-tabs-panel#" . $key . "'); 1262 | 1263 | // Obtener el contenedor para el contenido del page 1264 | var pageContentElement = $(pageElement).find('div.sexytab-page-content'); 1265 | 1266 | // Obtener los DATA asociados al page 1267 | var pageData = $(pageElement).data(); 1268 | 1269 | var uri = " . $Tab->ContentSourceUriFunction . "({ 1270 | PageElement: pageElement, 1271 | PageData: pageData, 1272 | PageContentElement: pageContentElement 1273 | }); 1274 | 1275 | // Refrescar el contenido 1276 | RefreshContent({ 1277 | ContentElement: pageContentElement, 1278 | ContentSourceUri: uri, 1279 | OnSuccessCallback: function() { 1280 | 1281 | if ( typeof " . $Tab->TabKey . "_OnRefresh === 'function') { 1282 | " . $Tab->TabKey . "_OnRefresh({ 1283 | PageElement: pageElement, 1284 | PageData: pageData, 1285 | PageContentElement: pageContentElement, 1286 | Result: true, 1287 | ErrorCode: 0, 1288 | ErrorMessage: '' 1289 | }); 1290 | } 1291 | }, 1292 | OnErrorCallback: function(errorCode, errorMessage) { 1293 | 1294 | if ( typeof " . $Tab->TabKey . "_OnRefresh === 'function') { 1295 | " . $Tab->TabKey . "_OnRefresh({ 1296 | PageElement: pageElement, 1297 | PageData: pageData, 1298 | PageContentElement: pageContentElement, 1299 | Result: false, 1300 | ErrorCode: errorCode, 1301 | ErrorMessage: errorMessage 1302 | }); 1303 | } 1304 | } 1305 | }); 1306 | } 1307 | } 1308 | }); 1309 | "; 1310 | } 1311 | else { 1312 | return ''; 1313 | } 1314 | } 1315 | */ 1316 | 1317 | public function GenerateDateRangeOnKeyUpScript($field, string $formKey) { 1318 | 1319 | $key = $field->PropertyName; 1320 | 1321 | $ranges = ""; 1322 | // Si no hay intervalos, dibujamos los intervalos estandar 1323 | // 1324 | $start = ""; 1325 | $end = ""; 1326 | 1327 | if (!isset($field->RangeIntervals) || !is_array($field->RangeIntervals) || count($field->RangeIntervals) == 0) { 1328 | $ranges .= " 1329 | 'Hoy': [moment(), moment()], 1330 | 'Ayer': [moment().subtract(1, 'days'), moment().subtract(1, 'days')], 1331 | 'Ultimos 7 Días': [moment().subtract(6, 'days'), moment()], 1332 | 'Ultimos 30 Días': [moment().subtract(29, 'days'), moment()], 1333 | 'Este Mes': [moment().startOf('month'), moment().endOf('month')], 1334 | 'Mes Anterior': [moment().subtract(1, 'month').startOf('month'), moment().subtract(1, 'month').endOf('month')], 1335 | 'Este Año': [moment().startOf('year'), moment().endOf('year')]\n"; 1336 | 1337 | $start = $this->_RangeIntervalStartEnd[1][0]; 1338 | $end = $this->_RangeIntervalStartEnd[1][1]; 1339 | } 1340 | else { 1341 | $intervals = ""; 1342 | 1343 | foreach($field->RangeIntervals as $id) { 1344 | if ($intervals != "") { 1345 | $intervals .= ",\n"; 1346 | } 1347 | else { 1348 | $start = $this->_RangeIntervalStartEnd[$id][0]; 1349 | $end = $this->_RangeIntervalStartEnd[$id][1]; 1350 | } 1351 | $intervals .= "\t\t" . $this->_RangeIntervals[$id]; 1352 | } 1353 | 1354 | $ranges .= $intervals; 1355 | } 1356 | 1357 | $script = " 1358 | 1359 | // Establecer los parametros iniciales del DateRange 1360 | // 1361 | var start = $start; 1362 | var end = $end; 1363 | 1364 | $('#$formKey-$key').daterangepicker({ 1365 | startDate: start, 1366 | endDate: end, 1367 | alwaysShowCalendars: true, 1368 | showCustomRangeLabel: false, 1369 | autoApply: true, 1370 | autoUpdateInput: false, 1371 | ranges: {\n"; 1372 | 1373 | $script .= $ranges; 1374 | 1375 | $script .= " 1376 | } 1377 | }, function (start, end, label) { 1378 | 1379 | if ( typeof " . $formKey . $key . "_OnChange === 'function' ) { 1380 | " . $formKey . $key . "_OnChange(start, end); 1381 | } 1382 | }); 1383 | 1384 | // Inicializar llamada 1385 | // 1386 | if ( typeof " . $formKey . $key . "_OnChange === 'function' ) { 1387 | " . $formKey . $key . "_OnChange(start, end); 1388 | } 1389 | "; 1390 | 1391 | return $script; 1392 | 1393 | } 1394 | 1395 | public function GenerateSexyTabsOnLoadScript(string $Key) { 1396 | 1397 | 1398 | return " 1399 | 1400 | // SEXYTABS: " . $Key . " 1401 | // 1402 | // EVENTO: ONLOAD 1403 | // Configurar el grupo de tabs 1404 | // 1405 | 1406 | // Obtener el SexyTab 1407 | var sexyTabGroup = $('#" . $Key . "'); 1408 | 1409 | // Obtener los DATA asociados al tabgroup 1410 | var sexyTabGroupData = $(sexyTabGroup).data(); 1411 | 1412 | if ( typeof " . $Key . "_OnLoad === 'function') { 1413 | " . $Key . "_OnLoad({ 1414 | TabGroupElement: sexyTabGroup, 1415 | TabGroupData: sexyTabGroupData 1416 | }); 1417 | } 1418 | 1419 | // Inicializar el grupo de tabs 1420 | $('#" . $Key . "').tabs({ 1421 | show: { effect: 'slide', direction: 'left', duration: 200, easing: 'easeOutBack' } , 1422 | hide: { effect: 'slide', direction: 'right', duration: 200, easing: 'easeInQuad' } 1423 | }); 1424 | 1425 | $('ul.activas-ul > li').on('click', function () { 1426 | 1427 | var tabId = $(this).attr('aria-controls'); 1428 | 1429 | // Obtener el SexyTabPage 1430 | var pageElement = $('.ui-tabs-panel[id=\"' + tabId + '\"]'); 1431 | 1432 | // Obtener el contenedor para el contenido del page 1433 | var pageContentElement = $(pageElement).find('div.sexytab-page-content'); 1434 | 1435 | // Si el contenido ya existe, no hacer nada 1436 | if ( $(pageContentElement).html() && $(pageContentElement).html().trim() != '') 1437 | return; 1438 | 1439 | // Obtener los DATA asociados al page 1440 | var pageData = $(pageElement).data(); 1441 | 1442 | // Obtener el URI para refrescar el contenido 1443 | var contentSourceUriFunction = $(this).data('contentsourceurifunction'); 1444 | var refreshFunction = $(this).data('refreshfunction'); 1445 | 1446 | if ( typeof window[contentSourceUriFunction] === 'function' ) { 1447 | 1448 | if (typeof RefreshContent === 'function') { 1449 | 1450 | var uri = window[contentSourceUriFunction]({ 1451 | PageElement: pageElement, 1452 | PageData: pageData, 1453 | PageContentElement: pageContentElement 1454 | }); 1455 | 1456 | // Refrescar el contenido 1457 | RefreshContent({ 1458 | ContentElement: pageContentElement, 1459 | ContentSourceUri: uri, 1460 | OnSuccessCallback: function() { 1461 | 1462 | if ( typeof window[refreshFunction] === 'function') { 1463 | window[refreshFunction]({ 1464 | PageElement: pageElement, 1465 | PageData: pageData, 1466 | PageContentElement: pageContentElement, 1467 | Result: true, 1468 | ErrorCode: 0, 1469 | ErrorMessage: '' 1470 | }); 1471 | } 1472 | }, 1473 | OnErrorCallback: function(errorCode, errorMessage) { 1474 | 1475 | if ( typeof window[refreshFunction] === 'function') { 1476 | window[refreshFunction]({ 1477 | PageElement: pageElement, 1478 | PageData: pageData, 1479 | PageContentElement: pageContentElement, 1480 | Result: false, 1481 | ErrorCode: errorCode, 1482 | ErrorMessage: errorMessage 1483 | }); 1484 | } 1485 | } 1486 | }); 1487 | } 1488 | } 1489 | }); 1490 | 1491 | // Activar el primer elemento del SexyTab 1492 | // 1493 | $('ul.activas-ul > li').first().click(); 1494 | "; 1495 | 1496 | } 1497 | 1498 | public function DrawScripts(bool $echo = true, bool $addLoadEvent = true) { 1499 | 1500 | // Agregar el script global 1501 | if ($addLoadEvent) { 1502 | $script = $this->GenerateGlobalPageScript(); 1503 | } 1504 | else { 1505 | $script = ""; 1506 | } 1507 | 1508 | $script .= $this->GenerateGlobalScript(); 1509 | 1510 | foreach($this->_Scripts as $key => $def) { 1511 | 1512 | switch($def['Type']) { 1513 | 1514 | case 'Form': 1515 | // FormScripts 1516 | $script .= $this->DrawFormScripts($def['Scripts']); 1517 | $script .= $this->DrawFormFieldScripts($def['Scripts']); 1518 | break; 1519 | 1520 | case 'Table': 1521 | $script .= $this->DrawTableButtonsScripts($def['Scripts'], $key); 1522 | $script .= $this->DrawTableScripts($def['Scripts']); 1523 | break; 1524 | 1525 | case 'Button': 1526 | case 'FormButton': 1527 | $script .= $this->DrawButtonScripts($def['Scripts']); 1528 | break; 1529 | 1530 | case 'SexyTabGroup': 1531 | $script .= $this->DrawSexyTabsScripts($def['Scripts']); 1532 | $script .= $this->DrawSexyTabGroupScripts($def['Scripts']); 1533 | $script .= $this->DrawSexyTabsButtonScripts($def['Scripts']); 1534 | break; 1535 | } 1536 | } 1537 | 1538 | if ($addLoadEvent) { 1539 | $scriptEvents = new Script( 1540 | [$script] 1541 | ); 1542 | } 1543 | else { 1544 | $scriptEvents = new ScriptDirect( 1545 | [$script] 1546 | ); 1547 | } 1548 | 1549 | return $scriptEvents->Draw($echo); 1550 | } 1551 | 1552 | private function DrawTableScripts($scripts) { 1553 | 1554 | $script = ''; 1555 | 1556 | foreach($scripts['TableScripts'] as $tableScript) { 1557 | $script .= $tableScript; 1558 | } 1559 | 1560 | return $script; 1561 | } 1562 | 1563 | private function DrawTableButtonsScripts($scripts, $tableKey) { 1564 | 1565 | 1566 | $script = " 1567 | // ENLAZAR EVENTOS DE BOTON DE LA TABLA: $tableKey 1568 | // 1569 | function " . $tableKey . "_BindButtons() { 1570 | 1571 | "; 1572 | 1573 | foreach($scripts['ButtonScripts'] as $buttonKey => $buttonScripts) { 1574 | 1575 | $eventScripts = $buttonScripts['Events']; 1576 | $globalScripts = $buttonScripts['Global']; 1577 | 1578 | if (count($eventScripts) > 0 || count($globalScripts) > 0) { 1579 | // Agregar comentarios del campo 1580 | $script = _att($script, " 1581 | // BOTON DE TABLA: " . $buttonKey . " 1582 | //", "\n"); 1583 | } 1584 | 1585 | if (count($eventScripts) > 0) { 1586 | $script = _att($script, " 1587 | // EVENTOS DEL BOTON 1588 | //", "\n"); 1589 | 1590 | foreach($eventScripts as $eventScript) { 1591 | $script = _att($script, $eventScript, "\n"); 1592 | } 1593 | } 1594 | 1595 | if (count($globalScripts) > 0) { 1596 | $script = _att($script, " 1597 | // SCRIPTS GLOBALES DEL BOTON 1598 | //", "\n"); 1599 | 1600 | foreach($globalScripts as $globalScript) { 1601 | $script = _att($script, $globalScript, "\n"); 1602 | } 1603 | } 1604 | 1605 | $script = _att($script, " 1606 | // DESASOCIAR EVENTOS EN REFRESCOS DE LA TABLA 1607 | $('." . $buttonScripts['OnClickClass'] . ".new').removeClass('new'); 1608 | ", "\n"); 1609 | 1610 | } 1611 | 1612 | $script .= "\n 1613 | }\n"; 1614 | 1615 | return $script; 1616 | 1617 | } 1618 | 1619 | private function DrawButtonScripts($scripts) { 1620 | 1621 | $script = ""; 1622 | 1623 | $eventScripts = $scripts['Events']; 1624 | $globalScripts = $scripts['Global']; 1625 | $buttonKey = $scripts['Key']; 1626 | 1627 | if (count($eventScripts) > 0 || count($globalScripts) > 0) { 1628 | // Agregar comentarios del campo 1629 | $script = _att($script, " 1630 | // BOTON : " . $buttonKey . " 1631 | //", "\n"); 1632 | } 1633 | 1634 | if (count($eventScripts) > 0) { 1635 | $script = _att($script, " 1636 | // EVENTOS DEL BOTON 1637 | //", "\n"); 1638 | 1639 | foreach($eventScripts as $eventScript) { 1640 | $script = _att($script, $eventScript, "\n"); 1641 | } 1642 | } 1643 | 1644 | if (count($globalScripts) > 0) { 1645 | $script = _att($script, " 1646 | // SCRIPTS GLOBALES DEL BOTON 1647 | //", "\n"); 1648 | 1649 | foreach($globalScripts as $globalScript) { 1650 | $script = _att($script, $globalScript, "\n"); 1651 | } 1652 | } 1653 | 1654 | return $script; 1655 | 1656 | } 1657 | 1658 | private function DrawFormFieldScripts($scripts) { 1659 | 1660 | /* 1661 | $scripts[$field->PropertyName] = [ 1662 | 'Events' => $eventScripts, 1663 | 'Global' => $globalScript 1664 | ]; 1665 | */ 1666 | $script = ''; 1667 | 1668 | foreach($scripts['FieldScripts'] as $propertyName => $fieldScripts) { 1669 | 1670 | $eventScripts = $fieldScripts['Events']; 1671 | $globalScripts = $fieldScripts['Global']; 1672 | 1673 | if (count($eventScripts) > 0 || count($globalScripts) > 0) { 1674 | // Agregar comentarios del campo 1675 | $script = _att($script, " 1676 | // CAMPO DE FORMULARIO: " . $propertyName . " 1677 | // 1678 | ", "\n"); 1679 | } 1680 | 1681 | if (count($eventScripts) > 0) { 1682 | $script = _att($script, " 1683 | // EVENTOS DEL CAMPO 1684 | //", "\n"); 1685 | 1686 | foreach($eventScripts as $eventScript) { 1687 | $script = _att($script, $eventScript, "\n"); 1688 | } 1689 | } 1690 | 1691 | if (count($globalScripts) > 0) { 1692 | $script = _att($script, " 1693 | // SCRIPTS GLOBALES DEL CAMPO 1694 | //", "\n"); 1695 | 1696 | foreach($globalScripts as $globalScript) { 1697 | $script = _att($script, $globalScript, "\n"); 1698 | } 1699 | } 1700 | } 1701 | 1702 | return $script; 1703 | } 1704 | 1705 | private function DrawFormScripts($scripts) { 1706 | /* 1707 | 'Scripts' => [ 1708 | 'FieldScripts' => $scripts, 1709 | 'FormScripts' => [$this->GenerateFormOnLoadScript($formKey)] 1710 | ] 1711 | */ 1712 | 1713 | $script = ""; 1714 | 1715 | foreach($scripts['FormScripts'] as $formScript) { 1716 | if ($script != "") $script .= "\n"; 1717 | 1718 | $script .= $formScript; 1719 | } 1720 | 1721 | return $script; 1722 | } 1723 | 1724 | private function DrawSexyTabsScripts($scripts) { 1725 | 1726 | $script = ""; 1727 | 1728 | foreach($scripts['TabScripts'] as $formScript) { 1729 | if ($script != "") $script .= "\n"; 1730 | 1731 | $script .= $formScript; 1732 | } 1733 | 1734 | return $script; 1735 | } 1736 | 1737 | private function DrawSexyTabGroupScripts($scripts) { 1738 | 1739 | $script = ""; 1740 | 1741 | foreach($scripts['GroupScripts'] as $formScript) { 1742 | if ($script != "") $script .= "\n"; 1743 | 1744 | $script .= $formScript; 1745 | } 1746 | 1747 | return $script; 1748 | } 1749 | 1750 | private function DrawSexyTabsButtonScripts($scripts) { 1751 | $script = ""; 1752 | 1753 | foreach($scripts['ButtonScripts'] as $formScript) { 1754 | if ($script != "") $script .= "\n"; 1755 | 1756 | $script .= $formScript; 1757 | } 1758 | 1759 | return $script; 1760 | } 1761 | 1762 | /** 1763 | * Genera el script principal de la pagina con todos los scripts generados 1764 | */ 1765 | public function GenerateScripts(array $scripts, array $globalScripts) { 1766 | 1767 | $scripts = array_merge($scripts, $globalScripts); 1768 | 1769 | $scriptEvents = new Script( 1770 | $scripts 1771 | ); 1772 | 1773 | return $scriptEvents->Draw(false); 1774 | } 1775 | 1776 | private function PropertyToContent(FormRowField $field, int $layout = TipoLayoutFilaEnum::BOOTSTRAP) { 1777 | 1778 | 1779 | $groupclasses = []; 1780 | if (isset($field->GroupClass)) { 1781 | array_push($groupclasses, $field->GroupClass); 1782 | } 1783 | 1784 | $result = new FormGroupColumnContent( 1785 | Key: (isset($field->GroupKey)) ? $field->GroupKey : '', 1786 | Classes: $groupclasses, 1787 | Child: $field->Content, 1788 | Layout: $layout, 1789 | Colspan: $field->Colspan 1790 | ); 1791 | 1792 | return $result; 1793 | 1794 | } 1795 | 1796 | private function PropertyToEmpty(FormRowField $field, 1797 | int $layout = TipoLayoutFilaEnum::BOOTSTRAP) { 1798 | 1799 | $result = new FormGroupColumnEmpty( 1800 | Layout: $layout, 1801 | Colspan: $field->Colspan 1802 | ); 1803 | 1804 | return $result; 1805 | 1806 | } 1807 | 1808 | private function PropertyToLabel(FormRowFieldLabel $field, $formKey, $object = null, int $layout = TipoLayoutFilaEnum::BOOTSTRAP) { 1809 | 1810 | $classes = []; 1811 | $styles = []; 1812 | if ($field->LabelStyle != '') { 1813 | $classes = ['label', $field->LabelStyle]; 1814 | $styles = [ 1815 | ['height', '33px'], 1816 | ['font-size', '110%'], 1817 | ['padding', '9px 0px 8px 0px'], 1818 | ['display', 'block'] 1819 | ]; 1820 | } 1821 | 1822 | if (isset($field->DisplayFunction)) { 1823 | $func = $field->DisplayFunction; 1824 | $content = $func($object); 1825 | 1826 | if ($content instanceof GenericWidget) { 1827 | $content = $content->Draw(false); 1828 | } 1829 | } 1830 | else { 1831 | $content = $field->Content; 1832 | } 1833 | 1834 | if (isset($field->Id) && $field->Id != '') { 1835 | $key = $field->Key; 1836 | $hiddenValue = isset($object->$key) ? $object->$key : ''; 1837 | $key = $field->Id; 1838 | } 1839 | else if (isset($field->Key) && $field->Key != '') { 1840 | $key = $field->Key; 1841 | $hiddenValue = isset($object->$key) ? $object->$key : ''; 1842 | } 1843 | else { 1844 | $hiddenValue = null; 1845 | } 1846 | 1847 | $groupclasses = []; 1848 | if (isset($field->GroupClass) && $field->GroupClass != "") { 1849 | array_push($groupclasses, $field->GroupClass); 1850 | } 1851 | 1852 | $result = new FormGroupColumnLabel( 1853 | Key: (isset($field->GroupKey) && $field->GroupKey != '') ? $field->GroupKey : $key, 1854 | HiddenValue: $hiddenValue, 1855 | Content: $content, 1856 | Label: $field->Label, 1857 | Layout: $layout, 1858 | Colspan: $field->Colspan, 1859 | Classes: $groupclasses, 1860 | ContentClasses: $classes, 1861 | ContentStyles: $styles, 1862 | HiddenAttributes: [ 1863 | ['data-form-id', $formKey], 1864 | ['data-pk', $field->Key], 1865 | ['data-property-name', $field->PropertyName] 1866 | ], 1867 | HiddenClasses: ['form-input'] 1868 | ); 1869 | 1870 | return $result; 1871 | 1872 | } 1873 | 1874 | private function PropertyToSubTitle(FormRowFieldSubTitle $field, $formKey, int $layout = TipoLayoutFilaEnum::BOOTSTRAP) { 1875 | 1876 | $classes = ['modal-group-subtitle-container']; 1877 | $styles = []; 1878 | $titleClasses = ['separator modal-group-subtitle']; 1879 | $titleStyles = []; 1880 | 1881 | if (isset($field->Classes) && count($field->Classes) > 0) { 1882 | foreach($field->Classes as $class) { 1883 | $classes[] = $class; 1884 | } 1885 | } 1886 | if (isset($field->Styles) && count($field->Styles) > 0) { 1887 | foreach($field->Styles as $style) { 1888 | $styles[] = $style; 1889 | } 1890 | } 1891 | 1892 | if (isset($field->TitleClasses) && count($field->TitleClasses) > 0) { 1893 | foreach($field->TitleClasses as $class) { 1894 | $titleClasses[] = $class; 1895 | } 1896 | } 1897 | if (isset($field->TitleStyles) && count($field->TitleStyles) > 0) { 1898 | foreach($field->TitleStyles as $style) { 1899 | $titleStyles[] = $style; 1900 | } 1901 | } 1902 | 1903 | $content = new Container( 1904 | Classes: $classes, 1905 | Styles : $styles, 1906 | Children: [ 1907 | new Text( 1908 | Content: $field->Title, 1909 | Classes: $titleClasses, 1910 | Styles: $titleStyles 1911 | ) 1912 | ] 1913 | ); 1914 | 1915 | $result = new FormGroupColumnContent( 1916 | Child: $content, 1917 | Layout: $layout, 1918 | Colspan: $field->Colspan 1919 | ); 1920 | 1921 | return $result; 1922 | 1923 | } 1924 | 1925 | private function PropertyToCheck( 1926 | FormRowField $field, $propertyValue, 1927 | string $keyFieldName, string $formKey, 1928 | $keyFieldValue = '', bool $fillData = false, 1929 | int $layout = TipoLayoutFilaEnum::BOOTSTRAP): FormGroupColumn | null { 1930 | 1931 | $checked = false; 1932 | if ($fillData && isset($field->Checked) && $field->Checked) { 1933 | $checked = true; 1934 | } 1935 | else if ($fillData && $propertyValue > 0) { 1936 | $checked = true; 1937 | } 1938 | 1939 | array_push($field->Attributes, ['data-form-id', $formKey]); 1940 | 1941 | $groupclasses = []; 1942 | if (isset($field->GroupClass)) { 1943 | array_push($groupclasses, $field->GroupClass); 1944 | } 1945 | 1946 | $labelClasses = []; 1947 | $checkStyles = []; 1948 | if (!isset($field->Label) || empty($field->Label)) { 1949 | $labelClasses[] = 'hide'; 1950 | } 1951 | else { 1952 | $checkStyles[] = ['padding-top', '4px']; 1953 | } 1954 | 1955 | $result = new FormGroupColumn( 1956 | Key: (isset($field->GroupKey)) ? $field->GroupKey : '', 1957 | Label: $field->Label, 1958 | Layout: $layout, 1959 | Colspan: $field->Colspan, 1960 | Required: $field->Required, 1961 | Classes: $groupclasses, 1962 | LabelClasses: $labelClasses, 1963 | Input: new InputCheck( 1964 | Key: $field->Id, 1965 | Label: $field->Title, 1966 | Checked: $checked, 1967 | Styles: $checkStyles, 1968 | Attributes: [ 1969 | ['data-' . $keyFieldName, $keyFieldValue], 1970 | ['data-pk', $keyFieldValue], 1971 | ['data-property-name', $field->PropertyName], 1972 | ['data-property-label', $field->Label] 1973 | ], 1974 | InputClasses: ['form-input'], 1975 | InputAttributes: $field->Attributes 1976 | ), 1977 | ); 1978 | 1979 | return $result; 1980 | } 1981 | 1982 | // private static function PropertyToSeparator(FormRowField $field) { 1983 | 1984 | // $result = new FormGroupSeparator( 1985 | // Title: $field->Label 1986 | // ); 1987 | 1988 | // return $result; 1989 | 1990 | // } 1991 | 1992 | private function PropertyToTextInput( 1993 | FormRowField $field, $propertyValue, 1994 | string $keyFieldName, string $formKey, 1995 | $keyFieldValue = '', bool $fillData = false, 1996 | int $layout = TipoLayoutFilaEnum::BOOTSTRAP): FormGroupColumn | null { 1997 | 1998 | $groupclasses = []; 1999 | if (isset($field->GroupClass)) { 2000 | array_push($groupclasses, $field->GroupClass); 2001 | } 2002 | 2003 | $attr = $field->Attributes; 2004 | $attr[] = ['data-' . $keyFieldName, $keyFieldValue]; 2005 | $attr[] = ['data-pk', $keyFieldValue]; 2006 | $attr[] = ['data-form-id', $formKey]; 2007 | $attr[] = ['data-property-name', $field->PropertyName]; 2008 | $attr[] = ['data-property-label', $field->Label]; 2009 | $attr[] = ['maxlength', $field->MaxLength]; 2010 | 2011 | $properties = []; 2012 | if (isset($field->ValidationRules) && $field->ValidationRules->Rules) { 2013 | foreach($field->ValidationRules->Rules as $rule) { 2014 | $properties[] = [$rule, true]; 2015 | } 2016 | } 2017 | 2018 | $classes = ['form-input']; 2019 | 2020 | if (isset($field->FieldClasses)) { 2021 | foreach($field->FieldClasses as $class) { 2022 | array_push($classes, $class); 2023 | } 2024 | } 2025 | 2026 | $result = new FormGroupColumn( 2027 | Key: (isset($field->GroupKey)) ? $field->GroupKey : '', 2028 | Label: $field->Label, 2029 | Layout: $layout, 2030 | Colspan: $field->Colspan, 2031 | Required: $field->Required, 2032 | Classes: $groupclasses, 2033 | Disabled: $field->Disabled, 2034 | Input: new InputText( 2035 | Key: $field->Id, 2036 | Type: $field->FieldType, 2037 | Value: ($fillData) ? $propertyValue : '', 2038 | Required: $field->Required, 2039 | Disabled: $field->Disabled, 2040 | Placeholder: $field->Placeholder, 2041 | Attributes: $attr, 2042 | Properties: $properties, 2043 | Classes: $classes, 2044 | ), 2045 | ); 2046 | 2047 | return $result; 2048 | } 2049 | 2050 | private function PropertyToHidden(FormRowFieldHidden $field, $formKey, $object = null) { 2051 | 2052 | if (isset($field->Value) && $field->Value != '') { 2053 | $hiddenValue = $field->Value; 2054 | } 2055 | else if (isset($field->PropertyName) && $field->PropertyName != '') { 2056 | $key = $field->PropertyName; 2057 | $hiddenValue = $object->$key; 2058 | } 2059 | else { 2060 | $hiddenValue = ''; 2061 | } 2062 | 2063 | $result = new InputText( 2064 | Key: $field->PropertyName, 2065 | Type: FormRowFieldTypeEnum::INPUT_HIDDEN, 2066 | Value: $hiddenValue, 2067 | Required: false, 2068 | Placeholder: '', 2069 | Attributes: [ 2070 | ['data-form-id', $formKey], 2071 | ['data-property-name', $field->PropertyName], 2072 | ['data-property-label', $field->Label] 2073 | ], 2074 | Classes: ['form-input'], 2075 | ); 2076 | 2077 | return $result; 2078 | 2079 | } 2080 | 2081 | private function PropertyToFileInput( 2082 | FormRowField $field, $propertyValue, 2083 | string $keyFieldName, string $formKey, 2084 | $keyFieldValue = '', bool $fillData = false, 2085 | ?int $layout = TipoLayoutFilaEnum::BOOTSTRAP): FormGroupColumn | null { 2086 | 2087 | $result = new FormGroupColumn( 2088 | Label: $field->Label, 2089 | Layout: $layout, 2090 | Colspan: $field->Colspan, 2091 | Required: $field->Required, 2092 | Input: new FileInput( 2093 | Key: $field->Id, 2094 | Multiple: $field->Multiple, 2095 | Attributes: [ 2096 | ['data-' . $keyFieldName, $keyFieldValue], 2097 | ['data-form-id', $formKey], 2098 | ['data-property-name', $field->PropertyName], 2099 | ['data-property-label', $field->Label] 2100 | ], 2101 | Classes: ['form-input'], 2102 | ), 2103 | ); 2104 | 2105 | return $result; 2106 | } 2107 | 2108 | private function PropertyToFileInputExcel( 2109 | FormRowField $field, $propertyValue, 2110 | string $keyFieldName, string $formKey, 2111 | $keyFieldValue = '', bool $fillData = false, 2112 | ?int $layout = TipoLayoutFilaEnum::BOOTSTRAP): FormGroupColumn | null { 2113 | 2114 | $result = new FormGroupColumn( 2115 | Label: $field->Label, 2116 | Layout: $layout, 2117 | Colspan: $field->Colspan, 2118 | Required: $field->Required, 2119 | Input: new ExcelInput( 2120 | Key: $field->Id, 2121 | Multiple: $field->Multiple, 2122 | Attributes: [ 2123 | ['data-' . $keyFieldName, $keyFieldValue], 2124 | ['data-form-id', $formKey], 2125 | ['data-property-name', $field->PropertyName], 2126 | ['data-property-label', $field->Label] 2127 | ], 2128 | Classes: ['form-input'], 2129 | ), 2130 | ); 2131 | 2132 | return $result; 2133 | } 2134 | 2135 | private function PropertytoColorInput( 2136 | FormRowField $field, $propertyValue, 2137 | string $keyFieldName, string $formKey, 2138 | $keyFieldValue = '', bool $fillData = false, 2139 | int $layout = TipoLayoutFilaEnum::BOOTSTRAP): FormGroupColumn | null 2140 | { 2141 | 2142 | $groupclasses = []; 2143 | if (isset($field->GroupClass)) { 2144 | array_push($groupclasses, $field->GroupClass); 2145 | } 2146 | 2147 | $result = new FormGroupColumn( 2148 | Key: (isset($field->GroupKey)) ? $field->GroupKey : '', 2149 | Label: $field->Label, 2150 | Layout: $layout, 2151 | Colspan: $field->Colspan, 2152 | Required: $field->Required, 2153 | Classes: $groupclasses, 2154 | Disabled: $field->Disabled, 2155 | Input: new InputColor( 2156 | Key: $field->Id, 2157 | Type: $field->FieldType, 2158 | Value: ($fillData) ? $propertyValue : '', 2159 | Required: $field->Required, 2160 | Disabled: $field->Disabled, 2161 | Placeholder: $field->Placeholder, 2162 | Attributes: [ 2163 | ['data-' . $keyFieldName, $keyFieldValue], 2164 | ['data-form-id', $formKey], 2165 | ['data-property-name', $field->PropertyName], 2166 | ['data-property-label', $field->Label] 2167 | ], 2168 | Classes: ['form-input'], 2169 | ), 2170 | ); 2171 | 2172 | return $result; 2173 | } 2174 | 2175 | private function PropertyToTextArea( 2176 | FormRowField $field, $propertyValue, 2177 | string $keyFieldName, string $formKey, 2178 | $keyFieldValue = '', bool $fillData = false, 2179 | int $layout = TipoLayoutFilaEnum::BOOTSTRAP): FormGroupColumn | null { 2180 | 2181 | $groupclasses = []; 2182 | if (isset($field->GroupClass)) { 2183 | array_push($groupclasses, $field->GroupClass); 2184 | } 2185 | 2186 | $attr = $field->Attributes; 2187 | $attr[] = ['data-' . $keyFieldName, $keyFieldValue]; 2188 | $attr[] = ['data-form-id', $formKey]; 2189 | $attr[] = ['data-property-name', $field->PropertyName]; 2190 | $attr[] = ['data-property-label', $field->Label]; 2191 | 2192 | $classes = ['form-input']; 2193 | 2194 | if (isset($field->FieldClasses)) { 2195 | foreach($field->FieldClasses as $class) { 2196 | array_push($classes, $class); 2197 | } 2198 | } 2199 | 2200 | $result = new FormGroupColumn( 2201 | Key: (isset($field->GroupKey)) ? $field->GroupKey : '', 2202 | Label: $field->Label, 2203 | Layout: $layout, 2204 | Colspan: $field->Colspan, 2205 | Required: $field->Required, 2206 | Disabled: $field->Disabled, 2207 | Classes: $groupclasses, 2208 | Input: new InputTextArea( 2209 | Key: $field->Id, 2210 | Type: $field->FieldType, 2211 | Value: ($fillData) ? $propertyValue : '', 2212 | Required: $field->Required, 2213 | Disabled: $field->Disabled, 2214 | Placeholder: $field->Placeholder, 2215 | Lines: $field->Lines, 2216 | Resize: $field->Resize, 2217 | Attributes: $attr, 2218 | Classes: $classes, 2219 | ), 2220 | ); 2221 | 2222 | return $result; 2223 | } 2224 | 2225 | private function PropertyToDateRangeInput( 2226 | FormRowField $field, $propertyValue, 2227 | string $keyFieldName, string $formKey, 2228 | $keyFieldValue = '', bool $fillData = false, 2229 | int $layout = TipoLayoutFilaEnum::BOOTSTRAP): FormGroupColumn | null { 2230 | 2231 | $value = ''; 2232 | 2233 | $groupclasses = []; 2234 | if (isset($field->GroupClass)) { 2235 | array_push($groupclasses, $field->GroupClass); 2236 | } 2237 | 2238 | $result = new FormGroupColumn( 2239 | Key: (isset($field->GroupKey)) ? $field->GroupKey : '', 2240 | Label: $field->Label, 2241 | Layout: $layout, 2242 | Colspan: $field->Colspan, 2243 | Required: $field->Required, 2244 | Classes: $groupclasses, 2245 | Input: new InputText( 2246 | Key: $field->Id, 2247 | Type: $field->FieldType, 2248 | Value: ($fillData) ? $value : '', 2249 | Required: $field->Required, 2250 | Placeholder: $field->Placeholder, 2251 | ), 2252 | ); 2253 | 2254 | return $result; 2255 | } 2256 | 2257 | private function PropertyToDateInput( 2258 | FormRowField $field, $propertyValue, 2259 | string $keyFieldName, string $formKey, 2260 | $keyFieldValue = '', bool $fillData = false, 2261 | int $layout = TipoLayoutFilaEnum::BOOTSTRAP): FormGroupColumn | null { 2262 | 2263 | // Select icon and value 2264 | $icon = null; 2265 | $value = ''; 2266 | switch($field->FieldType) { 2267 | case "date": 2268 | $icon = new FaIcon( 2269 | 'fa-calendar' 2270 | ); 2271 | $value = $propertyValue != "" || $field->Required? (new \Datetime($propertyValue))->format('d-m-Y'):null; 2272 | break; 2273 | case "datetime": 2274 | $icon = new FaIcon( 2275 | 'fa-calendar' 2276 | ); 2277 | $value = $propertyValue != "" || $field->Required? (new \Datetime($propertyValue))->format('d-m-Y H:i'):null; 2278 | break; 2279 | case "time": 2280 | $icon = new FaIcon( 2281 | 'fa-clock' 2282 | ); 2283 | $value = $propertyValue != "" || $field->Required? (new \Datetime($propertyValue))->format('H:i'):null; 2284 | break; 2285 | } 2286 | 2287 | $groupclasses = []; 2288 | if (isset($field->GroupClass)) { 2289 | array_push($groupclasses, $field->GroupClass); 2290 | } 2291 | 2292 | $result = new FormGroupColumn( 2293 | Key: (isset($field->GroupKey)) ? $field->GroupKey : '', 2294 | Label: $field->Label, 2295 | Layout: $layout, 2296 | Colspan: $field->Colspan, 2297 | Required: $field->Required, 2298 | Classes: $groupclasses, 2299 | Input: new InputDate( 2300 | Key: $field->Id, 2301 | Icon: $icon, 2302 | Type: $field->FieldType, 2303 | Value: ($fillData) ? $value : '', 2304 | Required: $field->Required, 2305 | Disabled: $field->Disabled, 2306 | Placeholder: $field->Placeholder, 2307 | DateAttributes: [ 2308 | ['data-' . $keyFieldName, $keyFieldValue], 2309 | ['data-form-id', $formKey], 2310 | ['data-property-name', $field->PropertyName], 2311 | ['data-property-label', $field->Label] 2312 | ], 2313 | DateClasses: ['form-input'] 2314 | ), 2315 | ); 2316 | 2317 | return $result; 2318 | } 2319 | 2320 | private function PropertyToSelectInput( 2321 | FormRowField $field, $propertyValue, 2322 | string $keyFieldName, string $formKey, 2323 | $keyFieldValue = '', 2324 | $fillData = false, 2325 | array $attributes = [], 2326 | int $layout = TipoLayoutFilaEnum::BOOTSTRAP): FormGroupColumn | null { 2327 | 2328 | // Search o sin search 2329 | $classes = ['form-input new']; 2330 | array_push($classes, ($field->SelectDefinition->DisplaySearch && $field->SelectDefinition->MultipleSelection == false) ? 'search-on' : 'search-off'); 2331 | 2332 | if($field->SelectDefinition->MultipleSelection == true){ 2333 | $classes = ['form-input new js-example-basic-multiple']; 2334 | } 2335 | 2336 | if (is_array($field->SelectDefinition->Values)) { 2337 | $values = $field->SelectDefinition->Values; 2338 | } 2339 | else if ($field->SelectDefinition->Values instanceof GenericCollection) { 2340 | $values = $field->SelectDefinition->Values->Values; 2341 | } 2342 | 2343 | $groupclasses = []; 2344 | if (isset($field->GroupClass)) { 2345 | array_push($groupclasses, $field->GroupClass); 2346 | } 2347 | 2348 | $valueDecoration = ($field->SelectDefinition->MultipleSelection == true) ? "[]" : ""; 2349 | 2350 | 2351 | 2352 | // Description 2353 | $result = new FormGroupColumn( 2354 | Key: (isset($field->GroupKey)) ? $field->GroupKey : '', 2355 | Label: $field->Label, 2356 | Layout: $layout, 2357 | Colspan: $field->Colspan, 2358 | Required: $field->Required, 2359 | Classes: $groupclasses, 2360 | Attributes: $attributes, 2361 | Input: new InputSelect( 2362 | Key: $field->Id, 2363 | ValueField: $field->SelectDefinition->Key . $valueDecoration, 2364 | DescriptionField: $field->SelectDefinition->Description, 2365 | DescriptionFunction: $field->SelectDefinition->DescriptionFunction, 2366 | Values: $values, 2367 | SelectedValue: ($fillData) ? $propertyValue : $field->SelectDefinition->SelectedValue, 2368 | SelectedValues: ($fillData) ? $field->SelectDefinition->SelectedValues : [], 2369 | Required: $field->Required, 2370 | Disabled: $field->Disabled, 2371 | Classes: $classes, 2372 | Attributes: [ 2373 | ['data-' . $keyFieldName, $keyFieldValue], 2374 | ['data-form-id', $formKey], 2375 | ['data-property-name', $field->PropertyName], 2376 | ['data-property-label', $field->Label] 2377 | ], 2378 | OptionAttributeNames: $field->SelectDefinition->OptionAttributeNames, 2379 | MultipleSelection: $field->SelectDefinition->MultipleSelection, 2380 | GroupCollectionName: $field->SelectDefinition->GroupCollectionName 2381 | ), 2382 | ); 2383 | 2384 | return $result; 2385 | } 2386 | 2387 | // Validacion del objeto y las propiedades solicitadas 2388 | private function ValidateObject(object $object, array $Rows, $keyFieldName): bool { 2389 | 2390 | // Validar la llave 2391 | if (!isset($object->$keyFieldName)) { 2392 | return false; 2393 | } 2394 | 2395 | $props = get_object_vars($object); 2396 | 2397 | // Verificar todas las propiedades solicitadas, que existan en el objeto de origen 2398 | foreach($Rows as $row) { 2399 | 2400 | if (is_array($row)) { 2401 | foreach($row as $field) { 2402 | 2403 | if ($field instanceof FormRowFieldLabel || $field instanceof FormRowFieldEmpty) { 2404 | return true; 2405 | } 2406 | 2407 | // Verificar que el objeto contenga la propiedad 2408 | if (!($field instanceof FormRowField || $field instanceof FormRowFieldLabel)) { 2409 | return false; 2410 | } 2411 | else if (!array_key_exists($field->PropertyName, $props) 2412 | && $field->FieldType != FormRowFieldTypeEnum::EMPTY) { 2413 | return false; 2414 | } 2415 | } 2416 | } 2417 | else if (!($row instanceof FormRowSection)) { 2418 | return false; 2419 | } 2420 | } 2421 | 2422 | return true; 2423 | } 2424 | 2425 | // Validacion del campo según tipo de campo 2426 | private function ValidateObjectField(object $Object, FormRowField | FormRowFieldSelect | null $field): bool { 2427 | 2428 | if (!isset($field->FieldType) || $field->FieldType == '') { 2429 | throw new \Exception('El campo ' . $field->PropertyName . ' no tiene definido el tipo'); 2430 | return false; 2431 | } 2432 | 2433 | // los SELECT, necesitan el campo 3, de extras (lista con la que se llena el select) 2434 | if (strtolower($field->FieldType) == FormRowFieldTypeEnum::INPUT_SELECT && $field instanceof FormRowFieldSelect) { 2435 | 2436 | if (!isset($field->SelectDefinition)) { 2437 | throw new \Exception('Falta la especificacion SelectDefinition'); 2438 | return false; 2439 | } 2440 | 2441 | if (!($field->SelectDefinition instanceof FormRowFieldSelectDefinition)) { 2442 | throw new \Exception('Falta la especificacion SelectDefinition'); 2443 | return false; 2444 | } 2445 | 2446 | $wrongType = true; 2447 | if (isset($field->SelectDefinition->Values)) { 2448 | if ($field->SelectDefinition->Values instanceof GenericCollection) { 2449 | $wrongType = false; 2450 | } 2451 | else if (is_array($field->SelectDefinition->Values)) { 2452 | $wrongType = false; 2453 | } 2454 | } 2455 | 2456 | if ($wrongType) { 2457 | throw new \Exception('La colección para el SELECT viene en null o es del tipo incorrecto'); 2458 | return false; 2459 | } 2460 | 2461 | //$values = $field->SelectDefinition->Values; 2462 | // La lista de valores debe ser un arreglo de objetos 2463 | // if (!is_array($values)) { 2464 | // throw new \Exception('La colección para el SELECT debe ser un arreglo de objetos'); 2465 | // return false; 2466 | // } 2467 | } 2468 | 2469 | return true; 2470 | } 2471 | 2472 | public function AddTableFromCollection( 2473 | string $tableKey, 2474 | string $RowIdFieldName, 2475 | array $CellDefinitions, 2476 | ?GenericCollection $Data = null, 2477 | array $RowAttributeNames = [], 2478 | array $Buttons = [], 2479 | bool $TablaSimple = false, 2480 | bool $CustomPdf = false, 2481 | bool $JSRenderTheTable = false, 2482 | ?DataTableSettingsFilterDto $CustomDataTable = null, 2483 | ?CustomExcelSettingsFilterDto $customExcel = null, 2484 | int $RecordsShown = 10, 2485 | array $TableClasses = [], 2486 | $Ordering = true 2487 | ): bool | null { 2488 | 2489 | $records = $RecordsShown; 2490 | 2491 | // Obtener la metadata 2492 | $metadata = []; 2493 | if (isset($Data) && $Data->Count() > 0) { 2494 | $pivot = $Data->First(); 2495 | $metadata = $this->GetObjectMetadata($pivot); 2496 | } 2497 | 2498 | // CREAR LOS WIDGETS 2499 | // 2500 | 2501 | // Crear el encabezado 2502 | $header = $this->ObjectToTableHeader( 2503 | CellDefinitions : $CellDefinitions, 2504 | Metadata : $metadata, 2505 | IncludeActionColumn : (count($Buttons) > 0), 2506 | btnNumber : count($Buttons) ?: 0, 2507 | JSTable : $JSRenderTheTable 2508 | ); 2509 | 2510 | // verificamos si es el servidor o el front quien debe renderizar la tabla 2511 | if($JSRenderTheTable == true) { 2512 | 2513 | // si es el front generamos la plantilla para el render 2514 | $body = $this->ObjectsToJSTableBody( 2515 | RowIdFieldName: $RowIdFieldName, 2516 | CellDefinitions: $CellDefinitions, 2517 | Values: isset($Data) ? $Data->Values : [], 2518 | RowAttributeNames: $RowAttributeNames, 2519 | Buttons: $Buttons, 2520 | tableKey: $tableKey, 2521 | CustomDataTable: $CustomDataTable, 2522 | 2523 | ); 2524 | 2525 | $tabla = new Table( 2526 | Header : $header, 2527 | Body : $body->Body, 2528 | Key : $tableKey, 2529 | JSRenderTheTable : $JSRenderTheTable, 2530 | Classes : $TableClasses 2531 | ); 2532 | 2533 | $this->_Widgets[$tableKey] = $tabla; 2534 | 2535 | // retornamos para asegurnarnos que no generemos ningun script demas 2536 | return true; 2537 | 2538 | }else{ 2539 | 2540 | // Crear el cuerpo de la tabla 2541 | $body = $this->ObjectsToTableBody( 2542 | RowIdFieldName: $RowIdFieldName, 2543 | CellDefinitions: $CellDefinitions, 2544 | Values: isset($Data) ? $Data->Values : [], 2545 | RowAttributeNames: $RowAttributeNames, 2546 | Buttons: $Buttons 2547 | ); 2548 | } 2549 | 2550 | 2551 | $tabla = new Table( 2552 | Header : $header, 2553 | Body : $body, 2554 | Key : $tableKey, 2555 | Classes : $TableClasses 2556 | ); 2557 | 2558 | $this->_Widgets[$tableKey] = $tabla; 2559 | 2560 | 2561 | // aca generamos una diferencia entre el flujo de la tabla normal y el nuevo flujos 2562 | 2563 | 2564 | 2565 | // CREAR LOS SCRIPTS 2566 | // 2567 | // Recorrer los botones para generar los scripts 2568 | $scripts = []; 2569 | foreach($Buttons as $button) { 2570 | 2571 | //Instancia de Botones Normales 2572 | if ($button instanceof TableButton) { 2573 | 2574 | // Scripts del boton actual 2575 | // 2576 | if ($button->OnClickClass != '') { 2577 | // Scripts del boton actual 2578 | $eventScripts = []; 2579 | foreach($button->Events as $event) { 2580 | if ($event instanceof TableEvent) { 2581 | $eventScripts[ 2582 | (new \ReflectionClass($event))->getShortName() 2583 | ] = $event->GetScript($button, null, $tableKey); 2584 | } 2585 | } 2586 | } 2587 | 2588 | // GLOBAL Scripts 2589 | $globalScripts = $button->GetGlobalScripts(); 2590 | 2591 | // Asociar los scripts con el boton 2592 | $scripts[$button->Key] = [ 2593 | 'OnClickClass' => $button->OnClickClass, 2594 | 'Events' => $eventScripts, 2595 | 'Global' => $globalScripts 2596 | ]; 2597 | }elseif($button instanceof TableDropDownButton){ 2598 | 2599 | foreach($button->Children as $item){ 2600 | // Scripts del boton actual 2601 | // 2602 | if ($item->OnClickClass != '') { 2603 | // Scripts del boton actual 2604 | $eventScripts = []; 2605 | foreach($item->Events as $event) { 2606 | if ($event instanceof TableEvent) { 2607 | $eventScripts[ 2608 | (new \ReflectionClass($event))->getShortName() 2609 | ] = $event->GetScript($item, null, $tableKey); 2610 | } 2611 | } 2612 | } 2613 | 2614 | // GLOBAL Scripts 2615 | $globalScripts = $item->GetGlobalScripts(); 2616 | 2617 | // Asociar los scripts con el boton 2618 | $scripts[$item->Key] = [ 2619 | 'OnClickClass' => $item->OnClickClass, 2620 | 'Events' => $eventScripts, 2621 | 'Global' => $globalScripts 2622 | ]; 2623 | } 2624 | 2625 | 2626 | } 2627 | 2628 | // Instancia Dropdown 2629 | } 2630 | 2631 | $tablaInit = ''; 2632 | if (!$TablaSimple) { 2633 | if(!empty($CustomDataTable) AND $CustomDataTable instanceof DataTableSettingsFilterDto){ 2634 | $z = 'null'; 2635 | if(!empty($customExcel) && $customExcel instanceof CustomExcelSettingsFilterDto ) { 2636 | $z = json_encode($customExcel); 2637 | } 2638 | 2639 | $x = json_encode($CustomDataTable); 2640 | $tablaInit = $tableKey . "DataTable = $('#" . $tableKey . "').TablaEstandar($x,null,$z, $records);"; 2641 | $x = null; 2642 | 2643 | 2644 | 2645 | unset($x); 2646 | }else{ 2647 | 2648 | $x = 'null'; 2649 | 2650 | if(!empty($customExcel) && $customExcel instanceof CustomExcelSettingsFilterDto ) { 2651 | 2652 | $x = json_encode($customExcel); 2653 | 2654 | } 2655 | 2656 | $CustomDataTable = (!empty($CustomDataTable)) ? $CustomDataTable : 'null'; 2657 | $CustomPdf = (!empty($CustomPdf)) ? $CustomPdf : 'null'; 2658 | 2659 | $order = ($Ordering) ? 'true' : 'false'; 2660 | 2661 | $tablaInit = $tableKey . "DataTable = $('#" . $tableKey . "').TablaEstandar($CustomPdf,null,$x, $records, $order);"; 2662 | 2663 | unset($x); 2664 | } 2665 | 2666 | } 2667 | else { 2668 | //$tablaInit = ""; 2669 | //$tablaInit = $tableKey . "DataTable = $('#" . $tableKey . "').DataTable();"; 2670 | } 2671 | 2672 | $this->_Tables[] = $tableKey . "DataTable"; 2673 | 2674 | $tableScript = " 2675 | // TABLA: " . $tableKey . " 2676 | // Init 2677 | try { 2678 | 2679 | " . $tablaInit . " 2680 | 2681 | // Llamada inicial 2682 | if ( typeof " . $tableKey . "_BindButtons === 'function' ) { 2683 | " . $tableKey . "_BindButtons(); 2684 | } 2685 | 2686 | // Enlazar botones al cambiar de página o realizar búsquedas 2687 | $('#" . $tableKey . "').on('draw.dt', function() { 2688 | " . $tableKey . "_BindButtons(); 2689 | }); 2690 | 2691 | } 2692 | catch (err) { 2693 | console.log('Error al inicializar la tabla: " . $tableKey . "'); 2694 | } 2695 | "; 2696 | 2697 | 2698 | $this->_Scripts[$tableKey] = [ 2699 | 'Type' => 'Table', 2700 | 'Scripts' => [ 2701 | 'TableScripts' => [$tableScript], 2702 | 'ButtonScripts' => $scripts 2703 | ] 2704 | ]; 2705 | 2706 | return true; 2707 | } 2708 | 2709 | 2710 | private function ObjectsToJSTableBody( 2711 | string $RowIdFieldName, 2712 | string $tableKey, 2713 | array $CellDefinitions, 2714 | array $Values, 2715 | array $RowAttributeNames = [], 2716 | array $Buttons = [], 2717 | ?DataTableSettingsFilterDto $CustomDataTable = null 2718 | ) { 2719 | 2720 | 2721 | 2722 | // Recorrer los campos del objeto 2723 | $rows = []; 2724 | $CellTemplateList = ""; 2725 | $TemplateRenderizado= false; 2726 | $ListaPropiedades = []; 2727 | $ToJson = []; 2728 | $rc = new ReflectionClass(get_class($this)); 2729 | $ruta = dirname($rc->getFileName()); 2730 | $switchFunction = ""; 2731 | $CellPropertiesList = []; 2732 | 2733 | if(is_array($RowAttributeNames) AND !empty($RowAttributeNames)){ 2734 | $ListaPropiedades = $RowAttributeNames; 2735 | } 2736 | //Llamamos al usuario que inicio sesión 2737 | $userdata = Session::Instance()->usuario; 2738 | 2739 | $residsname = $tableKey."_cell"; 2740 | Session::Instance()->${$residsname} = array(); 2741 | $Cell_Property_cache = []; 2742 | 2743 | $DtoName = null; 2744 | 2745 | $rolesList = []; 2746 | 2747 | if(!empty($userdata->Perfil->Roles)){ 2748 | 2749 | foreach($userdata->Perfil->Roles as $rolename => $roledata){ 2750 | 2751 | $rolesList[] = $rolename; 2752 | 2753 | } 2754 | 2755 | } 2756 | 2757 | foreach($Values as $index => $element) { 2758 | $columns = []; 2759 | 2760 | if($DtoName == null){ 2761 | $DtoName = get_class($element); 2762 | } 2763 | // -------------------------------------------------------------------------------------------------- 2764 | // generamos el template 2765 | // -------------------------------------------------------------------------------------------------- 2766 | if($TemplateRenderizado == false){ 2767 | foreach($CellDefinitions as $key => $cell) { 2768 | 2769 | if (!isset($cell) || !$cell instanceof JSTableCell ) { 2770 | continue; 2771 | } 2772 | $Cell_Property_cache[] = (object) [ 2773 | "property" => $cell->PropertyName, 2774 | "label" => $cell->Label 2775 | ]; 2776 | 2777 | 2778 | // ----------------------------------------------------------------------------------------------------------------- 2779 | // EN PRIMER LUGAR GENERAMOS LA LISTA DE PROPIEDADES A USAR DEL OBJETO 2780 | // ----------------------------------------------------------------------------------------------------------------- 2781 | 2782 | 2783 | if(isset($element->{$cell->PropertyName}) && !in_array($cell->PropertyName,$CellPropertiesList)){ 2784 | $CellPropertiesList[] = $cell->PropertyName; 2785 | } 2786 | // Validamos la propiedad principal de la celda 2787 | if(isset($element->{$cell->PropertyName}) && !in_array($cell->PropertyName,$ListaPropiedades)){ 2788 | $ListaPropiedades[] = $cell->PropertyName; 2789 | } 2790 | // validamos las propiedades secundarias 2791 | if(!empty($cell->PropertyList) && is_array($cell->PropertyList) ){ 2792 | foreach($cell->PropertyList as $PropertyItem) { 2793 | if( property_exists($element,$PropertyItem) && !in_array($PropertyItem,$ListaPropiedades)){ 2794 | $ListaPropiedades[] = $PropertyItem; 2795 | } 2796 | } 2797 | } 2798 | 2799 | // ----------------------------------------------------------------------------------------------------------------- 2800 | // GENERAMOS LA PLANTILLA DE RENDERIZADO DE ESTA CELDA 2801 | // ----------------------------------------------------------------------------------------------------------------- 2802 | 2803 | // -- Validamos si existe o no existe una definición del WidgetTemplate 2804 | $HtmlTemplate = ""; 2805 | $RenderScripts = ""; 2806 | if(isset($cell->WidgetFunction)){ 2807 | 2808 | // en caso de que existe el widgetFunction (Que Genera un WidgetTemplate) lo renderizamos 2809 | $func = $cell->WidgetFunction; 2810 | 2811 | // Generamos el template y enviamos información del elemento y los roles del usuario que inicio sesión 2812 | $HtmlTemplate = $func($element,$userdata->Roles); 2813 | 2814 | // verificamos que no se encuentre vacio 2815 | if(empty($HtmlTemplate)){ 2816 | $HtmlTemplate = "[[$cell->PropertyName]]"; 2817 | } 2818 | // verificamos si vuelve un widget 2819 | if($HtmlTemplate instanceof GenericWidget){ 2820 | 2821 | // antes de renderizar el widget busco dependencias al renderizado (atributos extras); 2822 | $JSTableContents = []; 2823 | if(!$HtmlTemplate instanceof JSTableContent){ 2824 | 2825 | if(isset( $HtmlTemplate->Children ) && !empty( $HtmlTemplate->Children )){ 2826 | 2827 | $JSTableContents = $this->JSWidgetChildSearch($HtmlTemplate); 2828 | 2829 | } 2830 | 2831 | }else{ 2832 | $JSTableContents[] = $HtmlTemplate; 2833 | } 2834 | 2835 | //--------------------------------------------------------------------------- 2836 | // GENERAMOS LOS SCRIPTS QUE VAN A REMPLAZAR LOS CONTENIDOS EN LA VISTA 2837 | //--------------------------------------------------------------------------- 2838 | // en caso de ser un widget lo renderizamos 2839 | 2840 | 2841 | 2842 | if(!empty($JSTableContents)){ 2843 | 2844 | foreach($JSTableContents as $JSTableItem){ 2845 | 2846 | if($JSTableItem instanceof JSTableContent){ 2847 | 2848 | // traemos el nombre de la propiedad 2849 | $Propiedad = $JSTableItem->PropertyName; 2850 | 2851 | // agregamos a la lista de propiedades que necesitamos 2852 | if(!in_array($Propiedad,$ListaPropiedades)){ 2853 | $ListaPropiedades[] = $Propiedad; 2854 | } 2855 | 2856 | // verificamos si existe una función en JS que deba filtrar esta información 2857 | if(!empty( $JSTableItem->JSFilterName)){ 2858 | 2859 | $JSFunct = trim($JSTableItem->JSFilterName)."_$key"; 2860 | 2861 | 2862 | $RenderScripts .= 2863 | " 2864 | // Obtenemos los valores 2865 | var val_$Propiedad = (element?.$Propiedad) ? element.$Propiedad : ''; 2866 | // si es una funcion la llamamos 2867 | if( filter_$JSFunct ) { 2868 | val_$Propiedad = filter_$JSFunct(element,roles); 2869 | } 2870 | 2871 | // renderizamos el contenido 2872 | htmltemplate = replaceAttribute( htmltemplate, '$Propiedad', val_$Propiedad ); 2873 | "; 2874 | 2875 | }else{ 2876 | $RenderScripts .= 2877 | " 2878 | // Obtenemos los valores 2879 | var val_$Propiedad = (element?.$Propiedad) ? element.$Propiedad : ''; 2880 | // si es una funcion la llamamos 2881 | 2882 | // renderizamos el contenido 2883 | htmltemplate = replaceAttribute( htmltemplate, '$Propiedad', val_$Propiedad ); 2884 | 2885 | "; 2886 | } 2887 | } 2888 | 2889 | } 2890 | 2891 | 2892 | } 2893 | //--------------------------------------------------------------------------- 2894 | // SE RENDERIZA EL TEMPLATE 2895 | //--------------------------------------------------------------------------- 2896 | $HtmlTemplate = $HtmlTemplate->Draw(false); 2897 | } 2898 | 2899 | 2900 | }else{ 2901 | 2902 | 2903 | $Propiedad = $cell->PropertyName; 2904 | 2905 | $HtmlTemplate = "[[$Propiedad]]"; 2906 | 2907 | if(!in_array($Propiedad,$ListaPropiedades)){ 2908 | $ListaPropiedades[] = $Propiedad; 2909 | } 2910 | 2911 | $RenderScripts .= 2912 | " 2913 | // Obtenemos los valores 2914 | var val_$Propiedad = (element?.$Propiedad) ? element.$Propiedad : ''; 2915 | // si es una funcion la llamamos 2916 | 2917 | // renderizamos el contenido 2918 | htmltemplate = replaceAttribute( htmltemplate, '$Propiedad', val_$Propiedad ); 2919 | "; 2920 | } 2921 | // ----------------------------------------------------------------------------------------------------------------- 2922 | // GENERAMOS LA LISTA DE SCRIPTS QUE NECESITA ESTA CELDA 2923 | // ----------------------------------------------------------------------------------------------------------------- 2924 | $scriptList = ""; 2925 | 2926 | if(!empty( $cell->JSDataFilter )){ 2927 | 2928 | foreach($cell->JSDataFilter as $scripts){ 2929 | 2930 | if($scripts instanceof JSTableScriptFilter){ 2931 | 2932 | $scriptname = trim($scripts->FunctionName)."_$key"; 2933 | 2934 | $func = $scripts->Script[0]; 2935 | 2936 | $scriptList .= 2937 | " 2938 | 2939 | // ----------------------------------------- 2940 | // FILTER NAME : $scriptname; 2941 | // ----------------------------------------- 2942 | var filter_$scriptname = (element,roles) => { 2943 | $func 2944 | } 2945 | // ----------------------------------------- 2946 | 2947 | "; 2948 | 2949 | 2950 | } 2951 | 2952 | } 2953 | 2954 | } 2955 | 2956 | // ----------------------------------------------------------------------------------------------------------------- 2957 | // Una vez generado el template... se agrega a la lista de plantillas 2958 | // ----------------------------------------------------------------------------------------------------------------- 2959 | $funcCellName = $tableKey."_cell_".$key; 2960 | 2961 | 2962 | $ScriptTemplate = file_get_contents($ruta.'/DisplayDefinitions/JSTable/Template/TableCellTemplate.js'); 2963 | $ScriptTemplate = str_replace('[[__function__name__]]' ,trim($funcCellName) ,$ScriptTemplate); 2964 | $ScriptTemplate = str_replace('[[PRIMARY_PROPERTY]]' ,$cell->PropertyName ,$ScriptTemplate); 2965 | $ScriptTemplate = str_replace('[[__PK__]]' ,$element->$RowIdFieldName ?: 0 ,$ScriptTemplate); 2966 | 2967 | 2968 | // ---- REMPLAZAMOS LAS PROPIEDADES FIJAS PARA CONSTRUIR EL JS 2969 | $ScriptTemplate = trim($ScriptTemplate); 2970 | $ScriptTemplate = str_replace('[[HTML_TEMPLATE]]' ,trim($HtmlTemplate) ,$ScriptTemplate); 2971 | $ScriptTemplate = str_replace('[[_TEMPLATE_REPLACES_]]' ,trim($RenderScripts) ,$ScriptTemplate); 2972 | $ScriptTemplate = str_replace('[[_SCRIPTS_FILTERS_]]' ,trim($scriptList) ,$ScriptTemplate); 2973 | 2974 | $claseses = ""; 2975 | if(!empty($cell->BodyClasses)){ 2976 | $claseses = $cell->BodyClasses[0]; 2977 | } 2978 | $ScriptTemplate = str_replace('"[[__CLASSESS__]]"' ,trim($claseses) ,$ScriptTemplate); 2979 | 2980 | $__styles = json_encode([]); 2981 | 2982 | if($cell->BodyStyles){ 2983 | $__styles = json_encode($cell->BodyStyles); 2984 | } 2985 | 2986 | $ScriptTemplate = str_replace('"[[JSON_STYLE]]"' ,$__styles ,$ScriptTemplate); 2987 | 2988 | 2989 | 2990 | 2991 | // ----------------------------------------------------------------------------------------------------------------- 2992 | // GENERAMOS EL ARREGLO 2993 | // ----------------------------------------------------------------------------------------------------------------- 2994 | 2995 | 2996 | 2997 | $switchFunction .= 2998 | "case $key : 2999 | template = window.".$tableKey."_controller.$funcCellName(element,roles); 3000 | break;"; 3001 | 3002 | $CellTemplateList .= $ScriptTemplate; 3003 | 3004 | } 3005 | 3006 | 3007 | } 3008 | 3009 | $TemplateRenderizado = true; 3010 | // -------------------------------------------------------------------------------------------------- 3011 | // UNA VEZ FINALIZADO EL CICLO DE GENERADO DEL TEMPLATE, SE VALIDA EL OBJETO JSON A ENVIAR A LA VISTA 3012 | // -------------------------------------------------------------------------------------------------- 3013 | foreach($element as $propertie => $__item){ 3014 | if(in_array($propertie,$ListaPropiedades)){ 3015 | $ToJson[$index][$propertie] = $__item; 3016 | } 3017 | } 3018 | } 3019 | 3020 | 3021 | Session::Instance()->$residsname = $Cell_Property_cache; 3022 | 3023 | 3024 | 3025 | 3026 | $body = new TableBody( 3027 | Rows: [] 3028 | ); 3029 | 3030 | $BaseScript = file_get_contents($ruta.'/DisplayDefinitions/JSTable/Template/TableBodyTemplate.js'); 3031 | 3032 | 3033 | Session::Instance()->$tableKey = new GenericCollection( 3034 | DtoName : $DtoName, 3035 | Values : $ToJson 3036 | ); 3037 | 3038 | $BaseScript = str_replace('"[[__JSON__DATA__]]"' ,json_encode($ToJson) ,$BaseScript); 3039 | $BaseScript = str_replace('"[[tabkey___]]"' ,$tableKey ,$BaseScript); 3040 | $BaseScript = str_replace('[[__switchFunction__]]' ,$switchFunction ,$BaseScript); 3041 | $BaseScript = str_replace('[[CELL_CONFIG_TEMPLATE]]' ,trim($CellTemplateList) ,$BaseScript); 3042 | $BaseScript = str_replace('[[TABLE_KEY]]' ,trim($tableKey) ,$BaseScript); 3043 | 3044 | $FileTitle = "Compromisos"; 3045 | $FileModule = "Compromisos"; 3046 | 3047 | $HideButton = 'false'; 3048 | $CustomButtons = [ 3049 | "{ 3050 | text: 'Excel', 3051 | className: 'btn-success', 3052 | action: function ( e, dt, node, config ) { 3053 | 3054 | new dataTablePDF( 3055 | { 3056 | Title : '[[FILE_TITLE]]', 3057 | Modulo : '[[FILE_MODULO]]', 3058 | Format : 'excel', 3059 | ajax : { 3060 | fromserver : true, 3061 | method : 'POST', 3062 | data : {} 3063 | }, 3064 | idDataTable : '[[TABLE_KEY]]' 3065 | } 3066 | ); 3067 | } 3068 | }", 3069 | "{ 3070 | text: 'PDF', 3071 | className: 'btn-danger', 3072 | action: function ( e, dt, node, config ) { 3073 | 3074 | new dataTablePDF( 3075 | { 3076 | Title : '[[FILE_TITLE]]', 3077 | Modulo : '[[FILE_MODULO]]', 3078 | Format : 'pdf', 3079 | ajax : { 3080 | fromserver : true, 3081 | method : 'POST', 3082 | data : {} 3083 | }, 3084 | idDataTable : '[[TABLE_KEY]]' 3085 | } 3086 | ); 3087 | } 3088 | }" 3089 | ] ; 3090 | 3091 | $xhrCustom = ""; 3092 | $groupButtons = 'true'; 3093 | if(!empty($CustomDataTable) and $CustomDataTable instanceof DataTableSettingsFilterDto){ 3094 | 3095 | if($CustomDataTable->HideDefaultButtons == true){ 3096 | $CustomButtons = []; 3097 | } 3098 | 3099 | if(!empty($CustomDataTable->TituloPdf)){ 3100 | $FileTitle = $CustomDataTable->TituloPdf; 3101 | } 3102 | if(!empty($CustomDataTable->Modulo)){ 3103 | $FileModule = $CustomDataTable->Modulo; 3104 | } 3105 | 3106 | $HideButton = "'".$CustomDataTable->HideAllButtons."'"; 3107 | 3108 | if(is_array($CustomDataTable->JSCustomButton) && !empty($CustomDataTable->JSCustomButton)){ 3109 | $CustomButtons = array_merge($CustomButtons,$CustomDataTable->JSCustomButton); 3110 | } 3111 | 3112 | if($CustomDataTable->DrawTableCallback != null && !empty($CustomDataTable->DrawTableCallback)) { 3113 | $xhrCustom = implode(' ', $CustomDataTable->DrawTableCallback); 3114 | } 3115 | 3116 | if($CustomDataTable->GroupedButtons == false){ 3117 | $groupButtons = 'false'; 3118 | } 3119 | 3120 | 3121 | 3122 | 3123 | } 3124 | 3125 | $CustomButtons = implode(',',$CustomButtons); 3126 | $BaseScript = str_replace('[[CUSTOMBUTTONS]]' ,trim($CustomButtons) ,$BaseScript); 3127 | $BaseScript = str_replace('[[XHRCALLBACK]]' ,trim($xhrCustom) ,$BaseScript); 3128 | $BaseScript = str_replace('[[__GROUPED__STATUS__]]' ,trim($groupButtons) ,$BaseScript); 3129 | 3130 | 3131 | $RowAttributeList = ""; 3132 | 3133 | foreach($RowAttributeNames as $atr){ 3134 | 3135 | $attributename = strtolower($atr); 3136 | $RowAttributeList .= " \n 3137 | if(rowTarget.data('". $attributename ."')){ 3138 | // existe el dato no se hace nada 3139 | }else{ 3140 | // en caso que no exista se genera la propiedad 3141 | rowTarget.data('". $attributename ."', target.data.".$atr."); \n 3142 | rowTarget.attr('". $attributename ."', target.data.".$atr."); \n 3143 | } "; 3144 | 3145 | 3146 | 3147 | } 3148 | 3149 | // -------------------------------------------------------------------------------------------------- 3150 | // SE GENERA EL TEMPLATE PARA EL RENDERIZADO DE LOS BOTONES 3151 | // -------------------------------------------------------------------------------------------------- 3152 | $BtnTemplateList = ""; 3153 | $BtnScriptList = ""; 3154 | $BtnBindList = ""; 3155 | $EventToTemplate = ""; 3156 | if(!empty($Buttons)){ 3157 | $globalScripts_btn = []; 3158 | $btnScriptList = []; 3159 | $BaseScript = str_replace('[[HASBUTTON]]','true',$BaseScript) ; 3160 | 3161 | 3162 | $BaseBtnTemplate = file_get_contents($ruta.'/DisplayDefinitions/JSTable/Template/TableButtonCellTemplate.js'); 3163 | foreach($Buttons as $btn){ 3164 | 3165 | $stop = 1; 3166 | // aca dependiendo de la instancia del btn se genera un nuevos script 3167 | $ActualBtnTemplate = $BaseBtnTemplate; 3168 | //generamos un script dependiendo del btn 3169 | 3170 | if($btn instanceof JSTableButton){ 3171 | $eventScripts = []; 3172 | 3173 | $ScriptList = ""; 3174 | if ($btn->OnClickClass != '') { 3175 | // Scripts del boton actual 3176 | 3177 | foreach($btn->Events as $event) { 3178 | if ($event instanceof TableEvent) { 3179 | $eventScripts[ 3180 | (new \ReflectionClass($event))->getShortName() 3181 | ] = $event->GetScript($btn, null, $tableKey); 3182 | } 3183 | } 3184 | // GLOBAL Scripts 3185 | $globalScripts_btn = $btn->GetGlobalScripts(); 3186 | $EventToTemplate .= " if($('.$btn->OnClickClass.new').length > 0 ) { "; 3187 | $EventToTemplate .= "\n"; 3188 | $EventToTemplate .= trim(implode("\n", $eventScripts) ?: ""); 3189 | $EventToTemplate .= '$(".'.$btn->OnClickClass.'.new").removeClass("new") '; 3190 | $EventToTemplate .= "\n"; 3191 | $EventToTemplate .= " } "; 3192 | $EventToTemplate .= "\n"; 3193 | // Asociar los scripts con el boton 3194 | $btnScriptList[$btn->Key] = [ 3195 | 'OnClickClass' => $btn->OnClickClass, 3196 | 'Events' => $eventScripts, 3197 | 'Global' => $globalScripts_btn 3198 | ]; 3199 | } 3200 | 3201 | 3202 | // ----------------------------------------------------------- 3203 | // GENERAMOS EL TEMPLATE DEL BOTON 3204 | // ----------------------------------------------------------- 3205 | $Toggle = ($btn->TogglePopUp == true) ? 'data-toggle="toggle" data-placement="top" data-content="'. $btn->ToggleText .'" ' : ""; 3206 | $child = (!empty($btn->Child) && $btn->Child instanceof GenericWidget) ? $btn->Child->Draw(false) : ""; 3207 | $buttonClasses_ = ($groupButtons == 'false') ? 'btn' : 'btn-sm btn-block'; 3208 | 3209 | $BaseButtonHTML = 3210 | trim(' 3211 | 3228 | '); 3229 | // ----------------------------------------------------------- 3230 | // GENERAMOS LOS SCRIPTS QUE CONDICIONAN EL BTN 3231 | // ----------------------------------------------------------- 3232 | 3233 | $DisplayFunction = "null"; 3234 | $EnabledFunction = "null"; 3235 | $BadgeFunction = "null"; 3236 | 3237 | // -- display 3238 | if($btn->DisplayFunction instanceof JSTableScriptFilter){ 3239 | $DisplayFunction = 3240 | trim(' 3241 | (element,roles) => { 3242 | '. trim($btn->DisplayFunction->Script[0]) .' 3243 | } 3244 | 3245 | '); 3246 | }else{ 3247 | $DisplayFunction = 3248 | trim(' 3249 | 3250 | (element,roles,template) => { 3251 | return true; 3252 | } 3253 | 3254 | '); 3255 | } 3256 | // -- enabledFunction 3257 | if($btn->EnabledFunction instanceof JSTableScriptFilter){ 3258 | $EnabledFunction = 3259 | trim(' 3260 | 3261 | (element,roles) => { 3262 | '. trim($btn->EnabledFunction->Script[0]) .' 3263 | } 3264 | 3265 | '); 3266 | }else{ 3267 | $EnabledFunction = 3268 | trim(' 3269 | 3270 | (element,roles,template) => { 3271 | return true; 3272 | } 3273 | 3274 | '); 3275 | } 3276 | // -- badgeFunction 3277 | 3278 | if($btn->TempalteFunction instanceof JSTableScriptFilter && !empty($btn->TempalteFunction)){ 3279 | $TEMPLTEFUNCTION = 3280 | trim(' 3281 | 3282 | (element,roles,template) => { 3283 | 3284 | '. trim($btn->TempalteFunction->Script[0]) .' 3285 | } 3286 | 3287 | '); 3288 | }else{ 3289 | $TEMPLTEFUNCTION = 3290 | trim(' 3291 | 3292 | (element,roles,template) => { 3293 | } 3294 | 3295 | '); 3296 | } 3297 | 3298 | if($btn->BadgeFunction instanceof JSTableScriptFilter){ 3299 | $BadgeFunction = 3300 | trim(' 3301 | 3302 | (element,roles) => { 3303 | 3304 | '. trim($btn->BadgeFunction->Script[0]) .' 3305 | } 3306 | 3307 | '); 3308 | }else{ 3309 | $BadgeFunction = 3310 | trim(' 3311 | 3312 | (element,roles,template) => { 3313 | return false; 3314 | } 3315 | 3316 | '); 3317 | } 3318 | 3319 | 3320 | // ----------------------------------------------------------- 3321 | // REMPLAZAMOS LOS VALORES EN EL TEMPLATE 3322 | // ----------------------------------------------------------- 3323 | 3324 | if($groupButtons == 'false'){ 3325 | $BaseButtonHTML = $BaseButtonHTML; 3326 | }else{ 3327 | $BaseButtonHTML = '
  • '.$BaseButtonHTML.'
  • '; 3328 | } 3329 | 3330 | 3331 | $ActualBtnTemplate = str_replace('[[__BTNKEY__]]' , $tableKey."_".$btn->Key ,$ActualBtnTemplate); 3332 | $ActualBtnTemplate = str_replace('[[TEMPLATE]]' ,$BaseButtonHTML ,$ActualBtnTemplate); 3333 | $ActualBtnTemplate = str_replace('[[DISPLAYFUNCTION]]' ,$DisplayFunction ,$ActualBtnTemplate); 3334 | $ActualBtnTemplate = str_replace('[[ENABLEDFUNCTION]]' ,$EnabledFunction ,$ActualBtnTemplate); 3335 | $ActualBtnTemplate = str_replace('[[BADGEFUNCTION]]' ,$BadgeFunction ,$ActualBtnTemplate); 3336 | $ActualBtnTemplate = str_replace('[[TEMPLTEFUNCTION]]' ,$TEMPLTEFUNCTION ,$ActualBtnTemplate); 3337 | 3338 | $BtnTemplateList .= $ActualBtnTemplate . " "; 3339 | $BtnScriptList .= " btntempalte += ".$tableKey."_".$btn->Key ."_CellButtonFn(element,". json_encode($rolesList) .") \n"; 3340 | 3341 | } 3342 | 3343 | 3344 | } 3345 | }else{ 3346 | $BaseScript = str_replace('[[HASBUTTON]]','false',$BaseScript) ; 3347 | } 3348 | $id = (new \DateTime())->format('YmdHis') . random_int(1,5000); 3349 | 3350 | $BaseScript = str_replace('[[BTN_CONFIG_TEMPLATE]]' ,trim($BtnTemplateList) ,$BaseScript); 3351 | $BaseScript = str_replace('[[BTN_LIST_FNC]]' ,trim($BtnScriptList) ,$BaseScript); 3352 | $BaseScript = str_replace('[[_BUTTON_EVENTS_TEMPLATE_]]',trim($EventToTemplate) ,$BaseScript); 3353 | $BaseScript = str_replace('[[TR_ATTRIBUTE_ADD]]' ,trim($RowAttributeList) ,$BaseScript); 3354 | $BaseScript = str_replace('[[FILE_TITLE]]' ,trim($FileTitle) ,$BaseScript); 3355 | $BaseScript = str_replace('[[FILE_MODULO]]' ,trim($FileModule) ,$BaseScript); 3356 | $BaseScript = str_replace('[[HIDEBUTTONS]]' ,trim($HideButton) ,$BaseScript); 3357 | $BaseScript = str_replace('[[TABLE_KEY]]' ,trim($tableKey) ,$BaseScript); 3358 | 3359 | 3360 | 3361 | 3362 | 3363 | 3364 | 3365 | $BaseScript = str_replace('[[__SCRIPT__ID__]]' ,trim($id) ,$BaseScript); 3366 | 3367 | 3368 | $this->_Scripts[$tableKey] = [ 3369 | 'Type' => 'Table', 3370 | 'Scripts' => [ 3371 | 'TableScripts' => [$BaseScript], 3372 | ] 3373 | ]; 3374 | 3375 | return (object) [ 3376 | "Body" => $body, 3377 | "JSTemplate" => $CellTemplateList 3378 | ]; 3379 | } 3380 | 3381 | 3382 | public function AddServerTableFromCollection( 3383 | string $tableKey, 3384 | string $RowIdFieldName, 3385 | array $CellDefinitions, 3386 | ?GenericCollection $Data = null, 3387 | array $RowAttributeNames = [], 3388 | array $Buttons = [], 3389 | int $RecordsShown = 10, 3390 | array $TableClasses = [], 3391 | bool $Ordering = true, 3392 | ): bool | null { 3393 | 3394 | $pageDef = Page::PutResults($Data); 3395 | 3396 | $records = $RecordsShown; 3397 | 3398 | // Obtener la metadata 3399 | $metadata = []; 3400 | if (isset($Data) && $Data->Count() > 0) { 3401 | $pivot = $Data->First(); 3402 | $metadata = $this->GetObjectMetadata($pivot); 3403 | } 3404 | 3405 | // CREAR LOS WIDGETS 3406 | // 3407 | 3408 | // Crear el encabezado 3409 | $header = $this->ObjectToTableHeader( 3410 | CellDefinitions : $CellDefinitions, 3411 | Metadata : $metadata, 3412 | IncludeActionColumn : (count($Buttons) > 0), 3413 | btnNumber : count($Buttons) ?: 0 3414 | ); 3415 | 3416 | // Almacenar la data para consulta 3417 | 3418 | 3419 | // Crear el cuerpo de la tabla 3420 | $body = $this->ObjectsToTableBody( 3421 | RowIdFieldName: $RowIdFieldName, 3422 | CellDefinitions: $CellDefinitions, 3423 | Values: [], 3424 | RowAttributeNames: $RowAttributeNames, 3425 | Buttons: $Buttons 3426 | ); 3427 | 3428 | 3429 | $tabla = new Table( 3430 | Header : $header, 3431 | Body : $body, 3432 | Key : $tableKey, 3433 | Classes : $TableClasses 3434 | ); 3435 | 3436 | $this->_Widgets[$tableKey] = $tabla; 3437 | 3438 | // CREAR LOS SCRIPTS 3439 | // 3440 | // Recorrer los botones para generar los scripts 3441 | $scripts = []; 3442 | foreach($Buttons as $button) { 3443 | 3444 | //Instancia de Botones Normales 3445 | if ($button instanceof TableButton) { 3446 | 3447 | // Scripts del boton actual 3448 | // 3449 | if ($button->OnClickClass != '') { 3450 | // Scripts del boton actual 3451 | $eventScripts = []; 3452 | foreach($button->Events as $event) { 3453 | if ($event instanceof TableEvent) { 3454 | $eventScripts[ 3455 | (new \ReflectionClass($event))->getShortName() 3456 | ] = $event->GetScript($button, null, $tableKey); 3457 | } 3458 | } 3459 | } 3460 | 3461 | // GLOBAL Scripts 3462 | $globalScripts = $button->GetGlobalScripts(); 3463 | 3464 | // Asociar los scripts con el boton 3465 | $scripts[$button->Key] = [ 3466 | 'OnClickClass' => $button->OnClickClass, 3467 | 'Events' => $eventScripts, 3468 | 'Global' => $globalScripts 3469 | ]; 3470 | } 3471 | elseif($button instanceof TableDropDownButton){ 3472 | 3473 | foreach($button->Children as $item){ 3474 | // Scripts del boton actual 3475 | // 3476 | if ($item->OnClickClass != '') { 3477 | // Scripts del boton actual 3478 | $eventScripts = []; 3479 | foreach($item->Events as $event) { 3480 | if ($event instanceof TableEvent) { 3481 | $eventScripts[ 3482 | (new \ReflectionClass($event))->getShortName() 3483 | ] = $event->GetScript($item, null, $tableKey); 3484 | } 3485 | } 3486 | } 3487 | 3488 | // GLOBAL Scripts 3489 | $globalScripts = $item->GetGlobalScripts(); 3490 | 3491 | // Asociar los scripts con el boton 3492 | $scripts[$item->Key] = [ 3493 | 'OnClickClass' => $item->OnClickClass, 3494 | 'Events' => $eventScripts, 3495 | 'Global' => $globalScripts 3496 | ]; 3497 | } 3498 | 3499 | 3500 | } 3501 | 3502 | // Instancia Dropdown 3503 | } 3504 | 3505 | $urlRefresh = '/core/api/framework/internal/page/getresults?ResultsId=' . $pageDef->ResultsId; 3506 | 3507 | $tablaInit = "\n\t\tvar " . $tableKey . "Cols = [\n"; 3508 | 3509 | // Aquí defino las columnas 3510 | // 3511 | $first = true; 3512 | foreach($CellDefinitions as $cell) { 3513 | 3514 | $property = $cell->PropertyName; 3515 | $label = (isset($cell->Label) && $cell->Label != '' ) ? $cell->Label : $cell->PropertyName; 3516 | $classes = (isset($cell->BodyClasses) && count($cell->BodyClasses) > 0 ) ? implode(' ', $cell->BodyClasses) : ""; 3517 | $function = ($cell instanceof TableJSCell && isset($cell->FormatJSFunction) && $cell->FormatJSFunction != "") ? $cell->FormatJSFunction : ""; 3518 | 3519 | $column = " 3520 | { 3521 | data: '" . $property . "', 3522 | defaultContent: '', 3523 | title: '" . $label . "'"; 3524 | 3525 | if ($classes != "") { 3526 | $column = $column . ", 3527 | className: '" . $classes . "'"; 3528 | } 3529 | 3530 | if ($function != "") { 3531 | $column = $column . ", 3532 | render: function (data, type, row) {" . 3533 | $function . " 3534 | }"; 3535 | } 3536 | 3537 | $column = $column . " 3538 | } 3539 | "; 3540 | 3541 | // if ($cell instanceof TableJSCell && isset($cell->FormatJSFunction) && $cell->FormatJSFunction != "") { 3542 | // $column = " 3543 | // { 3544 | // data : '" . $cell->PropertyName . "', 3545 | // title : '" . ( (isset($cell->Label) && $cell->Label != '' ) ? $cell->Label : $cell->PropertyName ) . "', 3546 | // render: function (data, type, row) {" . 3547 | // $cell->FormatJSFunction . 3548 | // "} 3549 | // }"; 3550 | // } 3551 | // else { 3552 | // $column = "{ data: '" . $cell->PropertyName . "', title: '" . ( (isset($cell->Label) && $cell->Label != '' ) ? $cell->Label : $cell->PropertyName ) . "' }"; 3553 | // } 3554 | 3555 | if (!$first) { 3556 | $tablaInit = $tablaInit . ",\n"; 3557 | } 3558 | 3559 | $tablaInit = $tablaInit . "\t\t\t" . $column; 3560 | $first = false; 3561 | } 3562 | $tablaInit = $tablaInit . "\n"; 3563 | $tablaInit = $tablaInit . "\t\t];\n\n"; 3564 | 3565 | $tablaInit = $tablaInit . "\t\t" . $tableKey . "DataTable = $('#" . $tableKey . "').TablaServer('$urlRefresh', $records, " . $tableKey . "Cols);"; 3566 | 3567 | unset($x); 3568 | 3569 | 3570 | 3571 | 3572 | $this->_Tables[] = $tableKey . "DataTable"; 3573 | 3574 | $tableScript = " 3575 | // TABLA: " . $tableKey . " 3576 | // Init 3577 | try { 3578 | 3579 | " . $tablaInit . " 3580 | 3581 | // Llamada inicial 3582 | if ( typeof " . $tableKey . "_BindButtons === 'function' ) { 3583 | " . $tableKey . "_BindButtons(); 3584 | } 3585 | 3586 | // Enlazar botones al cambiar de página o realizar búsquedas 3587 | $('#" . $tableKey . "').on('draw.dt', function() { 3588 | " . $tableKey . "_BindButtons(); 3589 | }); 3590 | 3591 | } 3592 | catch (err) { 3593 | console.log('Error al inicializar la tabla: " . $tableKey . "'); 3594 | } 3595 | "; 3596 | 3597 | 3598 | $this->_Scripts[$tableKey] = [ 3599 | 'Type' => 'Table', 3600 | 'Scripts' => [ 3601 | 'TableScripts' => [$tableScript], 3602 | 'ButtonScripts' => $scripts 3603 | ] 3604 | ]; 3605 | 3606 | return true; 3607 | } 3608 | 3609 | 3610 | 3611 | private function ObjectsToTableBody( 3612 | string $RowIdFieldName, 3613 | array $CellDefinitions, 3614 | array $Values, 3615 | array $RowAttributeNames = [], 3616 | array $Buttons = []) : TableBody | null { 3617 | 3618 | 3619 | 3620 | // Recorrer los campos del objeto 3621 | $rows = []; 3622 | 3623 | // Aumentar la RAM 3624 | Ini::Instance()->Change(IniEnum::MEMORY_LIMIT, '2048M'); 3625 | 3626 | foreach($Values as $element) { 3627 | 3628 | $columns = []; 3629 | 3630 | // Revisar estados de los botones para esta fila 3631 | foreach($Buttons as $idxButton => $action) { 3632 | 3633 | if($action instanceof TableDropDownButton){ 3634 | foreach($action->Children as $idxChildButton => $item){ 3635 | $showButton = true; 3636 | if (isset($item->DisplayFunction) && is_callable($item->DisplayFunction)) { 3637 | $func = $item->DisplayFunction; 3638 | 3639 | if (is_callable($func)) 3640 | $showButton = $func($item, Session::Instance()->usuario, Session::Instance()->usuario->Perfil, Session::Instance()->usuario->Perfil->Roles, $element); 3641 | } 3642 | 3643 | $enableButton = true; 3644 | if ($showButton === true) { 3645 | if (isset($item->EnabledFunction) && is_callable($item->EnabledFunction)) { 3646 | $func = $item->EnabledFunction; 3647 | 3648 | if (is_callable($func)) 3649 | $enableButton = $func($item, Session::Instance()->usuario, Session::Instance()->usuario->Perfil, Session::Instance()->usuario->Perfil->Roles, $element); 3650 | } 3651 | } 3652 | 3653 | $badge = null; 3654 | if (isset($item->BadgeFunction) && is_callable($item->BadgeFunction)) { 3655 | $func = $item->BadgeFunction; 3656 | 3657 | if (is_callable($func)) 3658 | $badge = $func($item, Session::Instance()->usuario, Session::Instance()->usuario->Perfil, Session::Instance()->usuario->Perfil->Roles, $element); 3659 | } 3660 | 3661 | $Buttons[$idxButton]->Children[$idxChildButton]->Show = $showButton; 3662 | $Buttons[$idxButton]->Children[$idxChildButton]->Enabled = $enableButton; 3663 | $Buttons[$idxButton]->Children[$idxChildButton]->Badge = $badge; 3664 | } 3665 | } 3666 | 3667 | $showButton = true; 3668 | if (isset($action->DisplayFunction) && is_callable($action->DisplayFunction)) { 3669 | $func = $action->DisplayFunction; 3670 | 3671 | if (is_callable($func)) 3672 | $showButton = $func($action, Session::Instance()->usuario, Session::Instance()->usuario->Perfil, Session::Instance()->usuario->Perfil->Roles, $element); 3673 | } 3674 | 3675 | $enableButton = true; 3676 | if ($showButton === true) { 3677 | if (isset($action->EnabledFunction) && is_callable($action->EnabledFunction)) { 3678 | $func = $action->EnabledFunction; 3679 | 3680 | if (is_callable($func)) 3681 | $enableButton = $func($action, Session::Instance()->usuario, Session::Instance()->usuario->Perfil, Session::Instance()->usuario->Perfil->Roles, $element); 3682 | } 3683 | } 3684 | 3685 | $badge = null; 3686 | if (isset($action->BadgeFunction) && is_callable($action->BadgeFunction)) { 3687 | $func = $action->BadgeFunction; 3688 | 3689 | if (is_callable($func)) 3690 | $badge = $func($action, Session::Instance()->usuario, Session::Instance()->usuario->Perfil, Session::Instance()->usuario->Perfil->Roles, $element); 3691 | } 3692 | 3693 | $Buttons[$idxButton]->Show = $showButton; 3694 | $Buttons[$idxButton]->Enabled = $enableButton; 3695 | $Buttons[$idxButton]->Badge = $badge; 3696 | } 3697 | 3698 | foreach($CellDefinitions as $cell) { 3699 | 3700 | if (!isset($cell)) 3701 | continue; 3702 | 3703 | // Agregar el ID que define a esta fila 3704 | array_push($cell->BodyAttributes, ['data-pk', $element->$RowIdFieldName]); 3705 | 3706 | // Verificar si se debe obtener el contenido desde la función de formato 3707 | if ($cell instanceof TableCell && isset($cell->FormatFunction)) { 3708 | $func = $cell->FormatFunction; 3709 | $result = $func($element,$cell); 3710 | 3711 | // Revisar el tipo de valor obtenido 3712 | if ($result instanceof GenericWidget) { 3713 | $value = $result->Draw(false); 3714 | } 3715 | else { 3716 | $value = $result; 3717 | } 3718 | 3719 | } 3720 | else if ($cell instanceof TableJSCell && isset($cell->FormatJSFunction)) { 3721 | // Buscar el valor en el objeto 3722 | $prop = $cell->PropertyName; 3723 | $value = $element->$prop; 3724 | } 3725 | else { 3726 | // Buscar el valor en el objeto 3727 | $prop = $cell->PropertyName; 3728 | $value = $element->$prop; 3729 | } 3730 | 3731 | if (!isset($value)) { 3732 | $value = ' '; 3733 | } 3734 | 3735 | array_push($cell->BodyAttributes, ['data-property-name', str_replace(' ', '', $cell->PropertyName)]); 3736 | 3737 | $col = new TableColumn( 3738 | PropertyName: $cell->PropertyName, 3739 | Content: $value, 3740 | Classes: $cell->BodyClasses, 3741 | Styles: $cell->BodyStyles, 3742 | Attributes: $cell->BodyAttributes, 3743 | Properties: $cell->BodyProperties 3744 | ); 3745 | 3746 | array_push($columns, $col); 3747 | } 3748 | 3749 | // Agregar botones 3750 | $buttons = []; 3751 | $DropDown = false; 3752 | foreach($Buttons as $buttonIndex => $action) { 3753 | // settings de los botones 3754 | if ($action->Show === true || ($action->Show == false && $action->DisplayFunctionMode == DisplayFunctionModeEnum::HIDE_MODE )) { 3755 | 3756 | $buttonClasses = $action->Classes; 3757 | 3758 | if ($action->Enabled === false) { 3759 | $buttonProperties = [ 3760 | ['disabled', 'true'] 3761 | ]; 3762 | $buttonClasses[] = 'btn-disabled'; 3763 | } 3764 | else { 3765 | $buttonProperties = []; 3766 | } 3767 | 3768 | $buttonAtttributes = []; 3769 | 3770 | if ($action instanceof TableButton && $action->OnClickClass != '') { 3771 | array_push($buttonClasses, $action->OnClickClass); 3772 | array_push($buttonClasses, 'new'); 3773 | } 3774 | 3775 | if ($action->Show == false && $action->DisplayFunctionMode == DisplayFunctionModeEnum::HIDE_MODE) { 3776 | array_push($buttonClasses, 'hide'); 3777 | } 3778 | 3779 | if ($action instanceof Button && $action->TogglePopUp) { 3780 | array_push($buttonAtttributes, 3781 | ['data-toggle', 'toggle'], 3782 | ['data-placement', $action->TogglePlacement], 3783 | ['data-content', $action->ToggleText] 3784 | ); 3785 | } 3786 | 3787 | // Agregar pk que define esta fila 3788 | array_push($buttonAtttributes, ['data-pk', $element->$RowIdFieldName]); 3789 | 3790 | 3791 | // EN CASO DE QUE EL BUTTON SEA DE TIPO DROPDOWN 3792 | if($action instanceof TableDropDownButton){ 3793 | $DropDown = true; 3794 | //SE VERIFICA QUE TENGA BOTONES HIJOS 3795 | if(!empty($action->Children) || count($action->Children) > 0){ 3796 | //SI LOS BOTONES HIJOS EXISTEN SE FORMATEAN Y SE GUARDAN 3797 | 3798 | //CONTENEDOR TEMPORAL DE LOS HIJOS 3799 | $DropButtonChild = []; 3800 | 3801 | foreach($action->Children as $item){ 3802 | 3803 | if ($item->Show === true) { 3804 | if ($item->Enabled === false) { 3805 | $buttonProperties = [ 3806 | ['disabled', 'true'] 3807 | ]; 3808 | } 3809 | else { 3810 | $buttonProperties = []; 3811 | } 3812 | 3813 | $buttonClasses = $item->Classes; 3814 | $buttonAtttributes = []; 3815 | 3816 | // Agregar pk que define esta fila 3817 | array_push($buttonAtttributes, ['data-pk', $element->$RowIdFieldName]); 3818 | if ($item instanceof TableButton && $item->OnClickClass != '') { 3819 | array_push($buttonClasses, $item->OnClickClass); 3820 | array_push($buttonClasses, 'new'); 3821 | } 3822 | if ($item instanceof Button && $item->TogglePopUp) { 3823 | array_push($buttonAtttributes, 3824 | ['data-toggle', 'toggle'], 3825 | ['data-placement', $item->TogglePlacement], 3826 | ['data-content', $item->ToggleText] 3827 | ); 3828 | } 3829 | 3830 | 3831 | $DropButtonChild[] = new ActionButtonDropDownChild( 3832 | Key: $item->Key, 3833 | ButtonStyle: $item->ButtonStyle, 3834 | Badge: $item->Badge, 3835 | BadgeStyle: $item->BadgeStyle, 3836 | Child: $item->Child, 3837 | Properties: $buttonProperties, 3838 | Classes: $buttonClasses, 3839 | Attributes: $buttonAtttributes 3840 | ) ; 3841 | } 3842 | } 3843 | } 3844 | 3845 | 3846 | //SE GUARDA EL BOTÓN DE TIPO DROPDOWN 3847 | array_push($buttons, new ActionButtonDropDown( 3848 | Key : $action->Key, 3849 | ButtonStyle : $action->ButtonStyle, 3850 | Badge : $action->Badge, 3851 | BadgeStyle : $action->BadgeStyle, 3852 | Content : $action->Content, 3853 | Children : $DropButtonChild, 3854 | Properties : $action->Properties, 3855 | Classes : $action->Classes, 3856 | Attributes : $action->Attributes 3857 | )); 3858 | 3859 | 3860 | }else{ 3861 | array_push($buttons, new ActionButton( 3862 | Key: $action->Key, 3863 | ButtonStyle: $action->ButtonStyle, 3864 | Badge: $action->Badge, 3865 | BadgeStyle: $action->BadgeStyle, 3866 | Child: $action->Child, 3867 | Properties: $buttonProperties, 3868 | Classes: $buttonClasses, 3869 | Attributes: $buttonAtttributes 3870 | )); 3871 | } 3872 | 3873 | 3874 | } 3875 | 3876 | 3877 | } 3878 | 3879 | if (count($Buttons) > 0) { 3880 | if($DropDown){ 3881 | $botonera = new Container( 3882 | Classes: [''], 3883 | Children: $buttons 3884 | ); 3885 | }else{ 3886 | $botonera = new Container( 3887 | Classes: ['text-right', 'one-line-text'], 3888 | Children: $buttons 3889 | ); 3890 | } 3891 | 3892 | array_push( 3893 | $columns, 3894 | new TableColumn( 3895 | Content: $botonera->Draw(false) 3896 | ) 3897 | ); 3898 | } 3899 | 3900 | // Preparar Atributos 3901 | // 3902 | $rowAttributes = []; 3903 | 3904 | // Agregar el ID que define a esta fila 3905 | array_push($rowAttributes, ['data-pk', $element->$RowIdFieldName]); 3906 | 3907 | // Agregar los atributos especificados por el sistema 3908 | foreach($RowAttributeNames as $rowAttribute) { 3909 | // Obtener el valor 3910 | $valor = $element->$rowAttribute; 3911 | 3912 | if (!isset($valor)) { 3913 | $valor = ''; 3914 | } 3915 | 3916 | array_push($rowAttributes, ['data-' . $rowAttribute, $valor]); 3917 | } 3918 | // 3919 | 3920 | $row = new TableRow( 3921 | Columns: $columns, 3922 | Attributes: $rowAttributes 3923 | ); 3924 | 3925 | array_push($rows, $row); 3926 | } 3927 | 3928 | $body = new TableBody( 3929 | Rows: $rows 3930 | ); 3931 | 3932 | // Bajar la RAM 3933 | Ini::Instance()->Rollback(IniEnum::MEMORY_LIMIT); 3934 | 3935 | return $body; 3936 | } 3937 | 3938 | 3939 | 3940 | private function ObjectToTableHeader(array $CellDefinitions, $Metadata, bool $IncludeActionColumn = false, int $btnNumber = 0, bool $JSTable = false) : TableHeader | null { 3941 | 3942 | // Recorrer los campos del objeto 3943 | $columns = []; 3944 | foreach($CellDefinitions as $cell) { 3945 | 3946 | if (!isset($cell)) 3947 | continue; 3948 | 3949 | // Preferencia, la etiqueta de la definicion, sino, la etiqueta de la metadata 3950 | // y si no existen, usar el nombre de la propiedad 3951 | if (isset($cell->Label) && $cell->Label != '') { 3952 | $label = $cell->Label; 3953 | } 3954 | else if ( 3955 | isset($Metadata->Properties[$cell->PropertyName]) 3956 | && isset($Metadata->Properties[$cell->PropertyName]->Label) 3957 | && $Metadata->Properties[$cell->PropertyName]->Label != '' 3958 | ) { 3959 | $label = $Metadata->Properties[$cell->PropertyName]->Label; 3960 | } 3961 | else { 3962 | $label = $cell->PropertyName; 3963 | } 3964 | 3965 | $col = new TableHeaderColumn( 3966 | Title: $label, 3967 | Classes: $cell->HeaderClasses, 3968 | Styles: $cell->HeaderStyles, 3969 | Attributes: $cell->HeaderAttributes, 3970 | Properties: $cell->HeaderProperties 3971 | ); 3972 | 3973 | array_push($columns, $col); 3974 | } 3975 | 3976 | if ($IncludeActionColumn) { 3977 | 3978 | 3979 | if($JSTable == true){ 3980 | 3981 | $width = $btnNumber * 30; 3982 | array_push( 3983 | $columns, 3984 | new TableHeaderColumn( 3985 | Title : '::', 3986 | Classes : ['text-center','btnAccion'], //Clase btnAccion para ocultar en la exportacion de PDF o Excel 3987 | Styles :[ 3988 | ["width",$width."px"] 3989 | ] 3990 | ) 3991 | ); 3992 | 3993 | }else{ 3994 | array_push( 3995 | $columns, 3996 | new TableHeaderColumn( 3997 | Title: '::', 3998 | Classes: ['text-center','btnAccion'] //Clase btnAccion para ocultar en la exportacion de PDF o Excel 3999 | ) 4000 | ); 4001 | } 4002 | 4003 | } 4004 | 4005 | $row = new TableHeaderRow( 4006 | Columns: $columns 4007 | ); 4008 | 4009 | return new TableHeader( 4010 | Rows: [$row] 4011 | ); 4012 | } 4013 | 4014 | 4015 | 4016 | private function GenerateTableScripts(array $scripts, array $globalScripts, $tableKey) { 4017 | 4018 | // Scripts globales 4019 | $scriptGlobal = " 4020 | // Configuración inicial de la tabla 4021 | $('#" . $tableKey . "').TablaEstandar(); 4022 | 4023 | // Llamar a la funcion de carga inicial de la tabla 4024 | if ( typeof " . $tableKey . "_OnLoad === 'function') { 4025 | " . $tableKey . "_OnLoad(eventInfo); 4026 | } 4027 | "; 4028 | 4029 | array_push($scripts, $scriptGlobal); 4030 | $scripts = array_merge($scripts, $globalScripts); 4031 | 4032 | $scriptEvents = new Script( 4033 | $scripts 4034 | ); 4035 | 4036 | return $scriptEvents->Draw(false); 4037 | 4038 | } 4039 | 4040 | private function JSWidgetChildSearch($Widget,$founded = []){ 4041 | 4042 | 4043 | 4044 | if($Widget instanceof GenericWidget){ 4045 | 4046 | if($Widget instanceof JSTableContent){ 4047 | 4048 | if(is_array($founded)){ 4049 | array_push($founded,$Widget); 4050 | }else{ 4051 | $founded = [ $Widget ]; 4052 | } 4053 | return $founded; 4054 | } 4055 | 4056 | 4057 | if(isset($Widget->Children)){ 4058 | 4059 | $founded = $this->JSWidgetChildSearch($Widget->Children,$founded); 4060 | return $founded; 4061 | 4062 | }elseif($Widget->Child){ 4063 | 4064 | $founded = $this->JSWidgetChildSearch($Widget->Child,$founded); 4065 | return $founded; 4066 | 4067 | }elseif($Widget->Content){ 4068 | 4069 | $founded = $this->JSWidgetChildSearch($Widget->Content,$founded); 4070 | return $founded; 4071 | 4072 | }else{ 4073 | 4074 | return $founded; 4075 | 4076 | } 4077 | 4078 | 4079 | }elseif(is_array($Widget)){ 4080 | 4081 | $response = null; 4082 | 4083 | foreach($Widget as $item){ 4084 | 4085 | $founded = $this->JSWidgetChildSearch($item,$founded); 4086 | 4087 | } 4088 | return $founded; 4089 | 4090 | } 4091 | 4092 | return $founded; 4093 | 4094 | } 4095 | 4096 | } -------------------------------------------------------------------------------- Total de líneas: 4096 ================================================================================ ================================================================================ ARCHIVO #256: src/View/DisplayDefinitions/Button.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/View/DisplayDefinitions/Button.php Tamaño: 1.68 KB -------------------------------------------------------------------------------- 1 | EvaluateOnLoad) { 52 | return [" 53 | // CHECK EvaluateOnLoad=true 54 | $('#" . $this->Id . "').trigger('change'); 55 | "]; 56 | } 57 | 58 | return []; 59 | 60 | } 61 | 62 | } -------------------------------------------------------------------------------- Total de líneas: 62 ================================================================================ ================================================================================ ARCHIVO #262: src/View/DisplayDefinitions/FormRowFieldContent.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/View/DisplayDefinitions/FormRowFieldContent.php Tamaño: 743 bytes -------------------------------------------------------------------------------- 1 | Rows[0][$FieldName])) { 36 | $this->Rows[0][$FieldName]->Attributes = $attr; 37 | } 38 | } 39 | 40 | } -------------------------------------------------------------------------------- Total de líneas: 40 ================================================================================ ================================================================================ ARCHIVO #274: src/View/DisplayDefinitions/FormRowSection.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/View/DisplayDefinitions/FormRowSection.php Tamaño: 400 bytes -------------------------------------------------------------------------------- 1 | ' + row.Estado + ''; } return data;" 31 | * @param array $HeaderClasses Array de clases CSS a aplicar al elemento
    del encabezado de la columna. 32 | * @param array $HeaderStyles Array asociativo de estilos CSS inline (propiedad => valor) para el elemento del encabezado. 33 | * @param array $HeaderAttributes Array asociativo de atributos HTML adicionales (atributo => valor) para el elemento del encabezado. 34 | * @param array $HeaderProperties Array asociativo de propiedades JS adicionales para el encabezado (uso avanzado de DataTables). 35 | * @param array $BodyClasses Array de clases CSS a aplicar a todos los elementos de esta columna. 36 | * @param array $BodyStyles Array asociativo de estilos CSS inline (propiedad => valor) para todos los elementos de esta columna. 37 | * @param array $BodyAttributes Array asociativo de atributos HTML adicionales (atributo => valor) para los elementos del cuerpo. 38 | * @param array $BodyProperties Array asociativo de propiedades JS adicionales para las celdas del cuerpo (uso avanzado de DataTables). 39 | */ 40 | public function __construct( 41 | public string $PropertyName, 42 | public string $Label = '', 43 | public int $Colspan = 1, 44 | public ?string $FormatJSFunction = null, 45 | public array $HeaderClasses = [], 46 | public array $HeaderStyles = [], 47 | public array $HeaderAttributes = [], 48 | public array $HeaderProperties = [], 49 | public array $BodyClasses = [], 50 | public array $BodyStyles = [], 51 | public array $BodyAttributes = [], 52 | public array $BodyProperties = [], 53 | ) 54 | { 55 | // Constructor vacío, las propiedades se inicializan directamente. 56 | } 57 | 58 | } -------------------------------------------------------------------------------- Total de líneas: 58 ================================================================================ ================================================================================ ARCHIVO #286: src/View/DisplayDefinitions/TableJSCellFunctions.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/View/DisplayDefinitions/TableJSCellFunctions.php Tamaño: 8.81 KB -------------------------------------------------------------------------------- 1 | ' + _Cdateauto(row." . $valueProperty . ", '', 'd-m-Y', '') + ''; 33 | } 34 | 35 | // para otros casos (como cuando datatables necesita el dato para ordenar, no para pintarlo), 36 | // debemos devolver el dato 37 | return data; 38 | 39 | "; 40 | 41 | return $func; 42 | } 43 | 44 | public static function HourDateLabelFunc(string $valueProperty, string $labelStyle, bool $checkEmpty = false) { 45 | 46 | $func = ""; 47 | 48 | if ($checkEmpty) { 49 | $func .= " 50 | if (!row." . $valueProperty . " || row." . $valueProperty . " == '' || row." . $valueProperty . ".substring(0,4) == '1900') { 51 | return ''; 52 | } 53 | "; 54 | } 55 | 56 | $func .= " 57 | if (type=='display') { 58 | return '' + _Cdateauto(row." . $valueProperty . ", '', 'd-m-Y H:i', '') + ' hrs'; 59 | } 60 | 61 | // para otros casos (como cuando datatables necesita el dato para ordenar, no para pintarlo), 62 | // debemos devolver el dato 63 | return data; 64 | "; 65 | 66 | return $func; 67 | } 68 | 69 | public static function HourDateTwoLinesFunc(string $valueProperty, bool $checkEmpty = false) { 70 | 71 | $func = ""; 72 | 73 | if ($checkEmpty) { 74 | $func .= " 75 | if (!row." . $valueProperty . " || row." . $valueProperty . " == '' || row." . $valueProperty . ".substring(0,4) == '1900') { 76 | return ''; 77 | } 78 | "; 79 | } 80 | 81 | $func .= " 82 | if (type=='display') { 83 | return '
    ' + _Cdateauto(row." . $valueProperty . ", '', 'd-m-Y', '') + '
    ' + _Cdateauto(row." . $valueProperty . ", '', 'H:i', '') + ' hrs.
    '; 84 | } 85 | "; 86 | 87 | return $func; 88 | } 89 | 90 | public static function SimpleLabelFunc(string $valueProperty, string $labelStyle, bool $checkEmpty = false) { 91 | 92 | $func = ""; 93 | 94 | if ($checkEmpty) { 95 | $func .= " 96 | if (!row." . $valueProperty . " || row." . $valueProperty . " == '') { 97 | return ''; 98 | } 99 | "; 100 | } 101 | 102 | $func .= " 103 | if (type=='display') { 104 | return '' + row." . $valueProperty . " + ''; 105 | } 106 | 107 | // para otros casos (como cuando datatables necesita el dato para ordenar, no para pintarlo), 108 | // debemos devolver el dato 109 | return data; 110 | "; 111 | 112 | return $func; 113 | } 114 | 115 | public static function LabelFunc(string $queryProperty, string $valueProperty, array $choices) { 116 | 117 | $func = " 118 | if (type=='display') { 119 | "; 120 | 121 | $cond = ""; 122 | 123 | foreach ($choices as $item) { 124 | if ($item instanceof LabelSpec) { 125 | $cond .= " 126 | if (row." . $queryProperty . " == " . $item->Option . " ) { 127 | return 'LabelStyle . "\">' + row." . $valueProperty . " + ''; 128 | } 129 | "; 130 | } 131 | } 132 | 133 | if ($cond != "") { 134 | $cond .= " 135 | else { 136 | return ' '; 137 | } 138 | "; 139 | } 140 | else { 141 | $cond .= " 142 | return ' '; 143 | "; 144 | } 145 | 146 | $func .= $cond; 147 | 148 | $func .= " 149 | } 150 | 151 | // para otros casos (como cuando datatables necesita el dato para ordenar, no para pintarlo), 152 | // debemos devolver el dato 153 | return data; 154 | "; 155 | 156 | return $func; 157 | } 158 | 159 | 160 | 161 | public static function LinkFuncChoice(string $queryProperty, string $valueProperty, array $linkHrefChoices, string $linkTarget = '_blank') { 162 | 163 | $func = " 164 | if (!row." . $valueProperty . " || row." . $valueProperty . " == '') { 165 | return ''; 166 | } 167 | "; 168 | 169 | $func .= " 170 | if (type=='display') { 171 | "; 172 | 173 | $cond = ""; 174 | 175 | foreach ($linkHrefChoices as $hrefItem) { 176 | 177 | if ($hrefItem instanceof HrefSpec) { 178 | 179 | // $hrefItem contiene la href de base: $hrefItem->Href 180 | $cond .= " 181 | if (row." . $queryProperty . " == " . $hrefItem->Option . " ) { 182 | 183 | var files = row." . $valueProperty . " ? row." . $valueProperty . ".split('|') : []; 184 | if (files.length === 0) return ''; 185 | 186 | var links = files.map(function(file) { 187 | var trimmedFile = file.trim(); 188 | if (!trimmedFile) return ''; 189 | return 'Href . "' + trimmedFile + '\" target=\"" . $linkTarget . "\">' + trimmedFile + ''; 190 | }).filter(function(link) { 191 | return link !== ''; 192 | }); 193 | 194 | return links.join('
    '); 195 | } 196 | "; 197 | } 198 | } 199 | 200 | if ($cond != "") { 201 | $cond .= " 202 | else { 203 | return ' '; 204 | } 205 | "; 206 | } 207 | else { 208 | $cond .= " 209 | return ' '; 210 | "; 211 | } 212 | 213 | $func .= $cond; 214 | 215 | $func .= " 216 | } 217 | 218 | // para otros casos (como cuando datatables necesita el dato para ordenar, no para pintarlo), 219 | // debemos devolver el dato 220 | return data; 221 | "; 222 | 223 | return $func; 224 | } 225 | 226 | public static function LinkFunc(string $valueProperty, string $linkHref, string $linkTarget = '_blank') { 227 | 228 | $func = " 229 | if (!row." . $valueProperty . " || row." . $valueProperty . " == '') { 230 | return ''; 231 | } 232 | "; 233 | 234 | $func .= " 235 | if (type=='display') { 236 | var files = row." . $valueProperty . " ? row." . $valueProperty . ".split('|') : []; 237 | if (files.length === 0) return ''; 238 | 239 | var links = files.map(function(file) { 240 | var trimmedFile = file.trim(); 241 | if (!trimmedFile) return ''; 242 | return '' + trimmedFile + ''; 243 | }).filter(function(link) { 244 | return link !== ''; 245 | }); 246 | 247 | return links.join('
    '); 248 | } 249 | "; 250 | 251 | 252 | return $func; 253 | } 254 | 255 | public static function DateDiff(string $desdeProperty, string $hastaProperty, bool $checkEmpty = true) { 256 | $func = ""; 257 | 258 | if ($checkEmpty) { 259 | $func .= " 260 | if (!row." . $desdeProperty . " || row." . $desdeProperty . " == '' || row." . $desdeProperty . ".substring(0,4) == '1900') { 261 | return ' '; 262 | } 263 | if (!row." . $hastaProperty . " || row." . $hastaProperty . " == '' || row." . $hastaProperty . ".substring(0,4) == '1900') { 264 | return ' '; 265 | } 266 | "; 267 | } 268 | 269 | $func .= " 270 | if (type=='display') { 271 | return obtenerDiferenciaTiempo(row." . $desdeProperty . ", row." . $hastaProperty . "); 272 | } 273 | "; 274 | 275 | return $func; 276 | } 277 | 278 | } 279 | 280 | -------------------------------------------------------------------------------- Total de líneas: 280 ================================================================================ ================================================================================ ARCHIVO #287: src/View/DisplayDefinitions/TogglePlacementEnum.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/View/DisplayDefinitions/TogglePlacementEnum.php Tamaño: 454 bytes -------------------------------------------------------------------------------- 1 | GetScriptContent($field, $object, $fields, $formGroups, $rows, $formKey); 25 | 26 | // Agregar código general de todas las acciones 27 | // 28 | // to-do... 29 | 30 | 31 | return $script; 32 | } 33 | 34 | protected function GetJquerySelector(string $id) { 35 | return "$('#" . $id . "')"; 36 | } 37 | } -------------------------------------------------------------------------------- Total de líneas: 37 ================================================================================ ================================================================================ ARCHIVO #292: src/View/DisplayEventActions/CallFunctionAction.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/View/DisplayEventActions/CallFunctionAction.php Tamaño: 1.14 KB -------------------------------------------------------------------------------- 1 | FunctionName . "({ 26 | Element : me, 27 | FormKey :'" . $formKey . "', 28 | FormData : myForm, 29 | FormElements : myElements 30 | })"; 31 | 32 | if ($this->Timeout > 0) { 33 | return " 34 | setTimeout( function() {" . $function . "}, " . $this->Timeout . "); 35 | "; 36 | } 37 | else { 38 | return " 39 | " . $function . "; 40 | "; 41 | } 42 | 43 | } 44 | } -------------------------------------------------------------------------------- Total de líneas: 44 ================================================================================ ================================================================================ ARCHIVO #293: src/View/DisplayEventActions/ChangeVisibilityAction.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/View/DisplayEventActions/ChangeVisibilityAction.php Tamaño: 2.34 KB -------------------------------------------------------------------------------- 1 | TargetElementKey])) { 37 | $target = $fields[$this->TargetElementKey]; 38 | $targetId = $target->Id; 39 | // return " 40 | // " . $this->GetJquerySelector($target->Id) . "." . ( $mostrar ? 'remove' : 'add' ) . "Class('hide');\n 41 | // \n"; 42 | } 43 | else if (isset($formGroups) && isset($formGroups[$this->TargetElementKey])) { 44 | $target = $formGroups[$this->TargetElementKey]; 45 | $targetId = $target->Key; 46 | // return "\n 47 | // " . $this->GetJquerySelector($target->Key) . "." . ( $mostrar ? 'remove' : 'add' ) . "Class('hide');\n 48 | // \n"; 49 | } 50 | 51 | if ($targetId != '') { 52 | 53 | if ($this->ActionType == VisibilityActionEnum::SHOW_ONCHECKED) { 54 | $script .= " 55 | 56 | if (isChecked) { 57 | " . $this->GetJquerySelector($targetId) . ".removeClass('hide'); 58 | } 59 | else { 60 | " . $this->GetJquerySelector($targetId) . ".addClass('hide'); 61 | } 62 | "; 63 | } 64 | else { 65 | $script .= " 66 | 67 | if (!isChecked) { 68 | " . $this->GetJquerySelector($targetId) . ".removeClass('hide'); 69 | } 70 | else { 71 | " . $this->GetJquerySelector($targetId) . ".addClass('hide'); 72 | } 73 | "; 74 | } 75 | 76 | } 77 | 78 | return $script; 79 | 80 | } 81 | 82 | } -------------------------------------------------------------------------------- Total de líneas: 82 ================================================================================ ================================================================================ ARCHIVO #294: src/View/DisplayEventActions/RefreshListAction.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/View/DisplayEventActions/RefreshListAction.php Tamaño: 3.22 KB -------------------------------------------------------------------------------- 1 | TargetElementKeys as $key) { 37 | 38 | if (isset($fields) && isset($fields[$key])) { 39 | 40 | // Obtener el campo dependiente 41 | $field = $fields[$key]; 42 | 43 | // El campo debe ser de tipo SELECT 44 | if ($field instanceof FormRowFieldSelect) { 45 | 46 | // Tiene funcion de despliegue de la descripción?? 47 | $descFunc = null; 48 | if (isset($field->SelectDefinition->JSDescriptionFunction)) { 49 | if ($field->SelectDefinition->JSDescriptionFunction == '') { 50 | $descFunc = str_replace('-', '_', $field->Id) . '_GetDescription'; 51 | } 52 | else { 53 | $descFunc = $field->SelectDefinition->JSDescriptionFunction; 54 | } 55 | } 56 | 57 | // Agregar el código de refresco de la framework 58 | // 59 | $refreshService = ''; 60 | $refreshAction = ''; 61 | if (isset($field->SelectDefinition->JSRefreshService) && is_array($field->SelectDefinition->JSRefreshService) and count($field->SelectDefinition->JSRefreshService) >= 2) { 62 | $refreshService = $field->SelectDefinition->JSRefreshService[0]; 63 | $refreshAction = $field->SelectDefinition->JSRefreshService[1]; 64 | } 65 | 66 | $actions .= " 67 | // Actualizar el SELECT con id=" . $field->Id . " 68 | // 69 | ActualizarListaDependiente({ 70 | DependantList: " . $this->GetJquerySelector($field->Id) . ", 71 | Controller: '" . $field->SelectDefinition->RefreshController . "', 72 | RefreshService: '" . $refreshService . "', 73 | RefreshAction: '" . $refreshAction . "', 74 | Identifier: identifier, 75 | KeyField: '" . $field->SelectDefinition->Key . "', 76 | DescriptionField: '" . $field->SelectDefinition->Description . "', 77 | DescriptionFunction: '" . ((isset($descFunc) && $descFunc != '') ? $descFunc : '') . "' 78 | }); 79 | "; 80 | } 81 | } 82 | } 83 | 84 | return $actions; 85 | 86 | } 87 | } -------------------------------------------------------------------------------- Total de líneas: 87 ================================================================================ ================================================================================ ARCHIVO #295: src/View/DisplayEventActions/VisibilityActionEnum.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/View/DisplayEventActions/VisibilityActionEnum.php Tamaño: 470 bytes -------------------------------------------------------------------------------- 1 | Key . "_OnClick === 'function') { 30 | " . $element->Key . "_OnClick({Element: this}); 31 | } 32 | "; 33 | 34 | } 35 | 36 | } -------------------------------------------------------------------------------- Total de líneas: 36 ================================================================================ ================================================================================ ARCHIVO #297: src/View/DisplayEvents/Event.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/View/DisplayEvents/Event.php Tamaño: 1.56 KB -------------------------------------------------------------------------------- 1 | Actions as $action) { 26 | 27 | if ($scriptContent != "") { 28 | $scriptContent .= "\n\n"; 29 | } 30 | 31 | $scriptContent .= $action->GetActionScript($element); 32 | } 33 | 34 | return $this->BuildScript($element, $scriptContent); 35 | } 36 | 37 | public function __construct( 38 | public string $jsEvent, 39 | public array $Actions = [] 40 | ) 41 | { 42 | } 43 | 44 | private function BuildScript(?object $element = null, string $scriptContent = '') { 45 | 46 | // Agregar llamado estandar de funcion de evento 47 | // 48 | $callScript = $this->GetStandardCall($element); 49 | 50 | if (!isset($callScript)) { 51 | $callScript = ""; 52 | } 53 | 54 | // Aquí se debe construir el código javascript 55 | // 56 | $script = " 57 | $('#" . $element->Key . "').on('" . strtolower($this->jsEvent) . "', function(event) { 58 | " . $callScript . " 59 | " . $scriptContent . " 60 | }); 61 | "; 62 | 63 | return $script; 64 | } 65 | 66 | } -------------------------------------------------------------------------------- Total de líneas: 66 ================================================================================ ================================================================================ ARCHIVO #298: src/View/DisplayEvents/FormButtonOnClickEvent.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/View/DisplayEvents/FormButtonOnClickEvent.php Tamaño: 686 bytes -------------------------------------------------------------------------------- 1 | Id . "_OnClick === 'function' ) { 23 | * " . $field->Id . "_OnClick(); 24 | * } 25 | */ 26 | abstract function GetStandardCall(?object $field = null, string $formKey = ''); 27 | 28 | 29 | public function GetScript(?object $field = null, ?object $object = null, array $fields = [], array $formGroupRows = [], array $rows = [], string $formKey = '') { 30 | 31 | // Recorrer acciones 32 | // 33 | $scriptContent = ""; 34 | foreach($this->Actions as $action) { 35 | 36 | if ($scriptContent != "") { 37 | $scriptContent .= "\n\n"; 38 | } 39 | 40 | $scriptContent .= $action->GetActionScript($field, $object, $fields, $formGroupRows, $rows, $formKey); 41 | } 42 | 43 | return $this->BuildScript($field, $scriptContent, $formKey); 44 | } 45 | 46 | public function __construct( 47 | public string $jsEvent, 48 | public array $Actions = [] 49 | ) 50 | { 51 | } 52 | 53 | private function BuildScript(?object $field = null, string $scriptContent = '', string $formKey = '') { 54 | 55 | if (isset($field) && isset($field->Id)) { 56 | $key = $field->Id; 57 | } 58 | else if (isset($field) && isset($field->Key)) { 59 | $key = $field->Key; 60 | } 61 | else { 62 | $key = 'unkownId_' . _guid(); 63 | } 64 | 65 | // Agregar llamado estandar de funcion de evento 66 | // 67 | $callScript = $this->GetStandardCall($field, $formKey); 68 | 69 | if (!isset($callScript)) { 70 | $callScript = " 71 | // Llamar evento estandar 72 | if (typeof " . str_replace('-', '_', $key) . "_On" . $this->jsEvent . " === 'function') { 73 | " . str_replace('-', '_', $key) . "_On" . $this->jsEvent . " ({ 74 | Element : me, 75 | FormKey : '" . $formKey . "', 76 | FormData : myForm, 77 | FormElements : myElements, 78 | Event : event 79 | }); 80 | } 81 | "; 82 | } 83 | 84 | // Aquí se debe construir el código javascript 85 | // 86 | $script = " 87 | $('#" . $key . "').on('" . strtolower($this->jsEvent) . "', function(event) { 88 | 89 | var me = $(this)[0]; 90 | var myForm = null; 91 | var myElements = null; 92 | 93 | if (typeof ReadForm === 'function') { 94 | myForm = ReadForm('" . $formKey . "'); 95 | } 96 | 97 | if (typeof ReadFormElements === 'function') { 98 | myElements = ReadFormElements('" . $formKey . "'); 99 | } 100 | 101 | " . $callScript . " 102 | " . $scriptContent . " 103 | }); 104 | "; 105 | 106 | if ($field instanceof FormRowFieldSelect && isset($field->SelectDefinition) && $field->SelectDefinition->TriggerChangeOnload) { 107 | $script .= " 108 | $('#" . $key . "').trigger('change'); 109 | "; 110 | } 111 | 112 | 113 | 114 | 115 | return $script; 116 | } 117 | 118 | } -------------------------------------------------------------------------------- Total de líneas: 118 ================================================================================ ================================================================================ ARCHIVO #300: src/View/DisplayEvents/FormOnBlurEvent.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/View/DisplayEvents/FormOnBlurEvent.php Tamaño: 670 bytes -------------------------------------------------------------------------------- 1 | Id . "_OnChange === 'function' ) { 31 | // " . $field->Id . "_OnChange(); 32 | // } 33 | // "; 34 | } 35 | 36 | } -------------------------------------------------------------------------------- Total de líneas: 36 ================================================================================ ================================================================================ ARCHIVO #302: src/View/DisplayEvents/FormOnClickEvent.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/View/DisplayEvents/FormOnClickEvent.php Tamaño: 750 bytes -------------------------------------------------------------------------------- 1 | Id . "_OnClick === 'function' ) { 29 | " . $field->Id . "_OnClick(); 30 | } 31 | "; 32 | } 33 | 34 | } -------------------------------------------------------------------------------- Total de líneas: 34 ================================================================================ ================================================================================ ARCHIVO #303: src/View/DisplayEvents/FormOnKeyPressEvent.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/View/DisplayEvents/FormOnKeyPressEvent.php Tamaño: 1.73 KB -------------------------------------------------------------------------------- 1 | AllowedCharsRegex != '') { 34 | $inputValidation = " 35 | // Validar input 36 | // 37 | var regex = new RegExp('" . $this->AllowedCharsRegex . "'); 38 | var key = String.fromCharCode( 39 | event.charCode == event.which ? event.which : event.charCode 40 | ); 41 | 42 | // Si el input no es valido, desactivamos la tecla 43 | if (!regex.test(key)) { 44 | event.preventDefault(); 45 | return false; 46 | } 47 | "; 48 | } 49 | 50 | return $inputValidation . " 51 | if (typeof " . str_replace('-', '_', $field->Id) . "_On" . $this->jsEvent . " === 'function') { 52 | " . str_replace('-', '_', $field->Id) . "_On" . $this->jsEvent . " ({ 53 | Element : me, 54 | FormKey : '" . $formKey . "', 55 | FormData : myForm, 56 | FormElements : myElements, 57 | Event : event 58 | }, event.keyCode); 59 | } 60 | "; 61 | } 62 | 63 | } -------------------------------------------------------------------------------- Total de líneas: 63 ================================================================================ ================================================================================ ARCHIVO #304: src/View/DisplayEvents/FormOnKeyUpEvent.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/View/DisplayEvents/FormOnKeyUpEvent.php Tamaño: 1.17 KB -------------------------------------------------------------------------------- 1 | Id) . "_On" . $this->jsEvent . " === 'function') { 33 | " . str_replace('-', '_', $field->Id) . "_On" . $this->jsEvent . " ({ 34 | Element : me, 35 | FormKey : '" . $formKey . "', 36 | FormData : myForm, 37 | FormElements : myElements, 38 | Event : event 39 | }, event.keyCode); 40 | } 41 | "; 42 | } 43 | 44 | } -------------------------------------------------------------------------------- Total de líneas: 44 ================================================================================ ================================================================================ ARCHIVO #305: src/View/DisplayEvents/JsEventEnum.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/View/DisplayEvents/JsEventEnum.php Tamaño: 570 bytes -------------------------------------------------------------------------------- 1 | Key . "_OnClick === 'function') { 38 | " . $element->Key . "_OnClick({ 39 | PageElement: pageElement, 40 | PageData: pageData, 41 | PageContentElement: pageContentElement 42 | }); 43 | } 44 | "; 45 | 46 | } 47 | 48 | } -------------------------------------------------------------------------------- Total de líneas: 48 ================================================================================ ================================================================================ ARCHIVO #308: src/View/DisplayEvents/SexyPageButtonOnRefreshEvent.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/View/DisplayEvents/SexyPageButtonOnRefreshEvent.php Tamaño: 2.85 KB -------------------------------------------------------------------------------- 1 | ContentSourceUriFunction . " === 'function') { 40 | var uri = " . $this->ContentSourceUriFunction . "({ 41 | PageElement: pageElement, 42 | PageData: pageData, 43 | PageContentElement: pageContentElement 44 | }); 45 | 46 | // Refrescar el contenido 47 | // 48 | if (typeof RefreshContent === 'function') { 49 | RefreshContent({ 50 | ContentElement: pageContentElement, 51 | ContentSourceUri: uri, 52 | OnSuccessCallback: function() { 53 | 54 | if ( typeof " . $this->TabGroupKey . "_OnRefresh === 'function') { 55 | " . $this->TabGroupKey . "_OnRefresh({ 56 | PageElement: pageElement, 57 | PageData: pageData, 58 | PageContentElement: pageContentElement, 59 | Result: true, 60 | ErrorCode: 0, 61 | ErrorMessage: '' 62 | }); 63 | } 64 | }, 65 | OnErrorCallback: function(errorCode, errorMessage) { 66 | 67 | if ( typeof " . $this->TabGroupKey . "_OnRefresh === 'function') { 68 | " . $this->TabGroupKey . "_OnRefresh({ 69 | PageElement: pageElement, 70 | PageData: pageData, 71 | PageContentElement: pageContentElement, 72 | Result: false, 73 | ErrorCode: errorCode, 74 | ErrorMessage: errorMessage 75 | }); 76 | } 77 | } 78 | }); 79 | } 80 | } 81 | "; 82 | 83 | } 84 | 85 | } -------------------------------------------------------------------------------- Total de líneas: 85 ================================================================================ ================================================================================ ARCHIVO #309: src/View/DisplayEvents/TableButtonOnClickEvent.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/View/DisplayEvents/TableButtonOnClickEvent.php Tamaño: 993 bytes -------------------------------------------------------------------------------- 1 | Key . "_OnClick === 'function') { 33 | " . $element->Key . "_OnClick({ 34 | Element: me, 35 | RowData: myRowData 36 | }); 37 | } 38 | "; 39 | 40 | } 41 | 42 | } -------------------------------------------------------------------------------- Total de líneas: 42 ================================================================================ ================================================================================ ARCHIVO #310: src/View/DisplayEvents/TableEvent.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/View/DisplayEvents/TableEvent.php Tamaño: 2.72 KB -------------------------------------------------------------------------------- 1 | Actions as $action) { 27 | 28 | if ($scriptContent != "") { 29 | $scriptContent .= "\n\n"; 30 | } 31 | 32 | $scriptContent .= $action->GetActionScript($element, $object, $tableKey); 33 | } 34 | 35 | return $this->BuildScript($element, $scriptContent, $tableKey); 36 | } 37 | 38 | public function __construct( 39 | public string $jsEvent, 40 | public array $Actions = [] 41 | ) 42 | { 43 | } 44 | 45 | private function BuildScript(TableCell | TableButton $element, string $scriptContent, string $tableKey) { 46 | 47 | // Agregar llamado estandar de funcion de evento 48 | // 49 | $callScript = $this->GetStandardCall($element, $tableKey); 50 | 51 | if ($element instanceof TableCell) { 52 | $jKey = '#' . $element->PropertyName; 53 | $key = $element->PropertyName; 54 | } 55 | else if ($element instanceof TableButton) { 56 | 57 | $key = $element->Key; 58 | 59 | if ($element->OnClickClass != '') { 60 | $jKey = '.' . $element->OnClickClass . '.new'; 61 | } 62 | else { 63 | $jKey = '#' . $element->Key; 64 | } 65 | } 66 | 67 | if (!isset($callScript)) { 68 | $callScript = " 69 | // Llamar evento estandar 70 | if (typeof " . str_replace('-', '_', $key) . "_On" . $this->jsEvent . " === 'function') { 71 | " . str_replace('-', '_', $key) . "_On" . $this->jsEvent . " (myRowData); 72 | } 73 | "; 74 | } 75 | 76 | // Aquí se debe construir el código javascript 77 | // 78 | $script = " 79 | $('" . $jKey . "').on('" . strtolower($this->jsEvent) . "', function(event) { 80 | 81 | var me = $(this)[0]; 82 | var row = $(this).closest('tr'); 83 | 84 | if (typeof ReadData === 'function') { 85 | myRowData = ReadData($(row)); 86 | } 87 | 88 | " . $callScript . " 89 | " . $scriptContent . " 90 | }); 91 | "; 92 | 93 | return $script; 94 | } 95 | 96 | } -------------------------------------------------------------------------------- Total de líneas: 96 ================================================================================ ================================================================================ ARCHIVO #311: src/View/DisplayValidations/Validation.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/View/DisplayValidations/Validation.php Tamaño: 398 bytes -------------------------------------------------------------------------------- 1 | AddClasses($Classes); 31 | 32 | // Styles 33 | $this->AddStyles($Styles); 34 | $this->AddStyle('cursor', 'pointer'); 35 | 36 | // Attributes 37 | $this->AddAttributes([ 38 | ['id', $this->Key], 39 | ['href', $this->Action], 40 | ['target', $this->ActionTarget], 41 | ['name', $this->Key] 42 | ]); 43 | 44 | 45 | parent::__construct(Replace: [ 46 | 'ATTRIBUTES' => $this->DrawAttributes(), 47 | 'PROPERTIES' => $this->DrawProperties(), 48 | 'CLASSES' => $this->DrawClasses(), 49 | 'STYLES' => $this->DrawStyles(), 50 | 'CONTENT' => $this->Child->Draw(false) 51 | ]); 52 | } 53 | } -------------------------------------------------------------------------------- Total de líneas: 53 ================================================================================ ================================================================================ ARCHIVO #313: src/Widget/ActionButton.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/ActionButton.php Tamaño: 4.00 KB -------------------------------------------------------------------------------- 1 | AddClasses($Classes); 40 | $this->AddClass('btn'); 41 | $this->AddClass($ButtonStyle); 42 | 43 | // Styles 44 | $this->AddStyles($Styles); 45 | $this->AddStyle('position', 'relative'); 46 | $this->AddStyle('cursor', 'pointer'); 47 | 48 | // Attributes 49 | $this->AddAttributes([ 50 | ['id', $this->Key], 51 | ['name', $this->Key] 52 | ]); 53 | $this->AddAttributes($Attributes); 54 | 55 | // Properties 56 | $this->AddProperties($Properties); 57 | 58 | $badgeVisible = isset($Badge); 59 | $badgeClasses = ($badgeVisible) ? [] : ['hide']; 60 | array_push($badgeClasses, 'badge-element'); 61 | 62 | $badgeStyles = []; 63 | $badgeStyles[] = ['cursor', 'pointer']; 64 | 65 | if (isset($BadgePosition)) { 66 | if (isset($BadgePosition->Right)) $badgeStyles[] = ['right', $BadgePosition->Right . 'px']; 67 | if (isset($BadgePosition->Left)) $badgeStyles[] = ['left', $BadgePosition->Left . 'px']; 68 | if (isset($BadgePosition->Top)) $badgeStyles[] = ['top', $BadgePosition->Top . 'px']; 69 | if (isset($BadgePosition->Bottom)) $badgeStyles[] = ['bottom', $BadgePosition->Bottom . 'px']; 70 | if (isset($BadgePosition->Type)) $badgeStyles[] = ['position', $BadgePosition->Type]; 71 | } 72 | else { 73 | $badgeStyles[] = ['position', 'absolute']; 74 | $badgeStyles[] = ['right', '2px']; 75 | $badgeStyles[] = ['top', '0px']; 76 | } 77 | 78 | $badge = (new Container( 79 | Key: $Key . 'Badge', 80 | Classes: $badgeClasses, 81 | Styles: $badgeStyles, 82 | Children: [ 83 | new Label( 84 | Key: $Key . 'BadgeContent', 85 | LabelStyle: $BadgeStyle, 86 | LabelSize: LabelSizeEnum::LABEL_SMALL, 87 | Content: isset($Badge) ? $Badge : '', 88 | Classes: ['badge-text-element'], 89 | Styles: [ 90 | ['border', '1px solid #ffffff'], 91 | ['padding', '0px 4px 1px 4px'], 92 | ['font-size', '10px'], 93 | ['cursor', 'pointer'], 94 | ] 95 | ) 96 | ] 97 | ))->Draw(false); 98 | 99 | 100 | 101 | parent::__construct(Replace: [ 102 | 'ATTRIBUTES' => $this->DrawAttributes(), 103 | 'PROPERTIES' => $this->DrawProperties(), 104 | 'CLASSES' => $this->DrawClasses(), 105 | 'STYLES' => $this->DrawStyles(), 106 | 'CONTENT' => $this->Child->Draw(false), 107 | 'BADGE' => $badge 108 | ]); 109 | } 110 | } -------------------------------------------------------------------------------- Total de líneas: 110 ================================================================================ ================================================================================ ARCHIVO #314: src/Widget/ActionButtonDropDown.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/ActionButtonDropDown.php Tamaño: 3.81 KB -------------------------------------------------------------------------------- 1 | AddClasses($Classes); 40 | $this->AddClass('btn'); 41 | $this->AddClass($ButtonStyle); 42 | 43 | // Styles 44 | $this->AddStyles($Styles); 45 | $this->AddStyle('position', 'relative'); 46 | $this->AddStyle('cursor', 'pointer'); 47 | $this->AddStyle('white-space', 'nowrap'); 48 | 49 | // Attributes 50 | $this->AddAttributes([ 51 | ['id', $this->Key], 52 | ['name', $this->Key] 53 | ]); 54 | $this->AddAttributes($Attributes); 55 | 56 | // Properties 57 | $this->AddProperties($Properties); 58 | 59 | $badgeVisible = isset($Badge); 60 | $badgeClasses = ($badgeVisible) ? [] : ['hide']; 61 | array_push($badgeClasses, 'badge-element'); 62 | 63 | $badge = (new Container( 64 | Key: $Key . 'Badge', 65 | Classes: $badgeClasses, 66 | Styles: [ 67 | ['position', 'absolute'], 68 | ['right', '2px'], 69 | ['top', '0px'], 70 | ['cursor', 'pointer'], 71 | ], 72 | Children: [ 73 | new Label( 74 | Key: $Key . 'BadgeContent', 75 | LabelStyle: $BadgeStyle, 76 | LabelSize: LabelSizeEnum::LABEL_SMALL, 77 | Content: isset($Badge) ? $Badge : '', 78 | Classes: ['badge-text-element'], 79 | Styles: [ 80 | ['border', '1px solid #ffffff'], 81 | ['padding', '0px 4px 1px 4px'], 82 | ['font-size', '10px'], 83 | ['cursor', 'pointer'], 84 | ] 85 | ) 86 | ] 87 | ))->Draw(false); 88 | 89 | $items = ''; 90 | foreach($Children as $child) { 91 | if ($child instanceof ActionButton || $child instanceof ActionButtonDropDownChild) { 92 | if ($items != '') { 93 | $items .= "\n"; 94 | } 95 | $items .= $child->Draw(false); 96 | } 97 | } 98 | 99 | 100 | if($Content instanceof GenericWidget){ 101 | $Content = $Content->Draw(false); 102 | } 103 | 104 | 105 | 106 | parent::__construct(Replace: [ 107 | 'ATTRIBUTES' => $this->DrawAttributes(), 108 | 'PROPERTIES' => $this->DrawProperties(), 109 | 'CLASSES' => $this->DrawClasses(), 110 | 'STYLES' => $this->DrawStyles(), 111 | 'ICON' => $Content, 112 | 'CONTENT' => $items, 113 | 'BADGE' => $badge 114 | ]); 115 | } 116 | } -------------------------------------------------------------------------------- Total de líneas: 116 ================================================================================ ================================================================================ ARCHIVO #315: src/Widget/ActionButtonDropDownChild.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/ActionButtonDropDownChild.php Tamaño: 3.41 KB -------------------------------------------------------------------------------- 1 | AddClasses($Classes); 38 | $this->AddClass('btn-block text-left btn-default'); 39 | $this->AddClass($ButtonStyle); 40 | 41 | // Styles 42 | $this->AddStyles($Styles); 43 | $this->AddStyle('position', 'relative'); 44 | 45 | $this->AddStyle('border', 'none'); 46 | $this->AddStyle('padding','5px 15px 5px 15px'); 47 | $this->AddStyle('cursor', 'pointer'); 48 | $this->AddStyle('white-space', 'nowrap'); 49 | 50 | // Attributes 51 | $this->AddAttributes([ 52 | ['id', $this->Key], 53 | ['name', $this->Key] 54 | ]); 55 | $this->AddAttributes($Attributes); 56 | 57 | // Properties 58 | $this->AddProperties($Properties); 59 | 60 | $badgeVisible = isset($Badge); 61 | $badgeClasses = ($badgeVisible) ? [] : ['hide']; 62 | array_push($badgeClasses, 'badge-element'); 63 | 64 | $badge = (new Container( 65 | Key: $Key . 'Badge', 66 | Classes: $badgeClasses, 67 | Styles: [ 68 | ['position', 'absolute'], 69 | ['right', '2px'], 70 | ['top', '0px'], 71 | ['cursor', 'pointer'], 72 | ], 73 | Children: [ 74 | new Label( 75 | Key: $Key . 'BadgeContent', 76 | LabelStyle: $BadgeStyle, 77 | LabelSize: LabelSizeEnum::LABEL_SMALL, 78 | Content: isset($Badge) ? $Badge : '', 79 | Classes: ['badge-text-element'], 80 | Styles: [ 81 | ['border', '1px solid #ffffff'], 82 | ['padding', '0px 4px 1px 4px'], 83 | ['font-size', '10px'], 84 | ['cursor', 'pointer'], 85 | ] 86 | ) 87 | ] 88 | ))->Draw(false); 89 | 90 | 91 | 92 | parent::__construct(Replace: [ 93 | 'ATTRIBUTES' => $this->DrawAttributes(), 94 | 'PROPERTIES' => $this->DrawProperties(), 95 | 'CLASSES' => $this->DrawClasses(), 96 | 'STYLES' => $this->DrawStyles(), 97 | 'CONTENT' => $this->Child->Draw(false), 98 | 'BADGE' => $badge 99 | ]); 100 | } 101 | } -------------------------------------------------------------------------------- Total de líneas: 101 ================================================================================ ================================================================================ ARCHIVO #316: src/Widget/ActionMenu.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/ActionMenu.php Tamaño: 2.36 KB -------------------------------------------------------------------------------- 1 | AddClasses($Classes); 38 | $this->AddClasses($TitleClasses, 'title'); 39 | $this->AddClass('dropdown'); 40 | $this->AddClass('action-menu-title', 'title'); 41 | 42 | // Styles 43 | $this->AddStyles($Styles); 44 | $this->AddStyle('display', 'block'); 45 | $this->AddStyle('cursor', 'pointer'); 46 | 47 | // Attributes 48 | $this->AddAttributes($Attributes); 49 | 50 | if ($Active) { 51 | $this->AddClass('active'); 52 | } 53 | 54 | if (isset($Items)) { 55 | $menuTree = (new ActionMenuTree( 56 | Animated: $Animated, 57 | AnimationType: $AnimationType, 58 | Items: $Items, 59 | Classes: $MenuTreeClasses, 60 | Attributes: $MenuTreeAttributes 61 | ))->Draw(false); 62 | } 63 | 64 | $faicon = ''; 65 | if (isset($Icon)) { 66 | $faicon = $Icon->Draw(false); 67 | } 68 | 69 | parent::__construct(Replace: [ 70 | 'MENUTITLE' => $Title, 71 | 'MENUTREE' => $menuTree, 72 | 'ICON' => $faicon, 73 | 'CLASSES' => $this->DrawClasses(), 74 | 'TITLECLASSES' => $this->DrawClasses('title'), 75 | 'STYLES' => $this->DrawStyles(), 76 | 'ATTRIBUTES' => $this->DrawAttributes() 77 | ]); 78 | } 79 | } -------------------------------------------------------------------------------- Total de líneas: 79 ================================================================================ ================================================================================ ARCHIVO #317: src/Widget/ActionMenuItem.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/ActionMenuItem.php Tamaño: 1.48 KB -------------------------------------------------------------------------------- 1 | AddClasses($Classes); 30 | 31 | // Styles 32 | $this->AddStyle('display', 'block'); 33 | $this->AddStyles($Styles); 34 | 35 | // Attributes 36 | $this->AddAttributes($Attributes); 37 | 38 | if ($Active) { 39 | $this->AddClass('active'); 40 | } 41 | 42 | $faicon = ''; 43 | if (isset($Icon)) { 44 | //$Icon->AddClass('pull-left'); 45 | $faicon = $Icon->Draw(false); 46 | } 47 | 48 | parent::__construct(Replace: [ 49 | 'CONTENT' => $Content, 50 | 'ACTION' => $Action, 51 | 'ICON' => $faicon, 52 | 'CLASSES' => $this->DrawClasses(), 53 | 'STYLES' => $this->DrawStyles(), 54 | 'ATTRIBUTES' => $this->DrawAttributes() 55 | ]); 56 | } 57 | } -------------------------------------------------------------------------------- Total de líneas: 57 ================================================================================ ================================================================================ ARCHIVO #318: src/Widget/ActionMenuMiniSeparator.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/ActionMenuMiniSeparator.php Tamaño: 894 bytes -------------------------------------------------------------------------------- 1 | AddClass('divider'); 25 | $this->AddClasses($Classes); 26 | 27 | // Styles 28 | $this->AddStyle('display', 'block'); 29 | $this->AddStyles($Styles); 30 | 31 | parent::__construct(Replace: [ 32 | 'CLASSES' => $this->DrawClasses(), 33 | 'STYLES' => $this->DrawStyles() 34 | ]); 35 | } 36 | } -------------------------------------------------------------------------------- Total de líneas: 36 ================================================================================ ================================================================================ ARCHIVO #319: src/Widget/ActionMenuSeparator.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/ActionMenuSeparator.php Tamaño: 886 bytes -------------------------------------------------------------------------------- 1 | AddClass('divider'); 25 | $this->AddClasses($Classes); 26 | 27 | // Styles 28 | $this->AddStyle('display', 'block'); 29 | $this->AddStyles($Styles); 30 | 31 | parent::__construct(Replace: [ 32 | 'CLASSES' => $this->DrawClasses(), 33 | 'STYLES' => $this->DrawStyles() 34 | ]); 35 | } 36 | } -------------------------------------------------------------------------------- Total de líneas: 36 ================================================================================ ================================================================================ ARCHIVO #320: src/Widget/ActionMenuTitle.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/ActionMenuTitle.php Tamaño: 963 bytes -------------------------------------------------------------------------------- 1 | AddClasses($Classes); 26 | $this->AddClass('menu-separator-title'); 27 | 28 | // Styles 29 | $this->AddStyles($Styles); 30 | $this->AddStyle('display', 'block'); 31 | 32 | parent::__construct(Replace: [ 33 | 'CONTENT' => $Content, 34 | 'CLASSES' => $this->DrawClasses(), 35 | 'STYLES' => $this->DrawStyles() 36 | ]); 37 | } 38 | } -------------------------------------------------------------------------------- Total de líneas: 38 ================================================================================ ================================================================================ ARCHIVO #321: src/Widget/ActionMenuTitleSubtitle.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/ActionMenuTitleSubtitle.php Tamaño: 2.55 KB -------------------------------------------------------------------------------- 1 | AddClasses($Classes); 39 | $this->AddClasses($TitleClasses, 'title'); 40 | $this->AddClass('dropdown'); 41 | $this->AddClass('action-menu-title', 'title'); 42 | 43 | // Styles 44 | $this->AddStyles($Styles); 45 | $this->AddStyle('display', 'block'); 46 | $this->AddStyle('cursor', 'pointer'); 47 | 48 | // Attributes 49 | $this->AddAttributes($Attributes); 50 | 51 | if ($Active) { 52 | $this->AddClass('active'); 53 | } 54 | 55 | if (isset($Items)) { 56 | $menuTree = (new ActionMenuTree( 57 | Animated: $Animated, 58 | AnimationType: $AnimationType, 59 | Items: $Items, 60 | Classes: $MenuTreeClasses, 61 | Attributes: $MenuTreeAttributes 62 | ))->Draw(false); 63 | } 64 | 65 | $faicon = ''; 66 | if (isset($Icon)) { 67 | $faicon = $Icon->Draw(false); 68 | } 69 | if ($Key != '') { 70 | $this->AddAttribute('id', $this->Key); 71 | } 72 | 73 | parent::__construct(Replace: [ 74 | 'TITLE' => $Title, 75 | 'SUBTITLE' => $Subtitle, 76 | 'MENUTREE' => $menuTree, 77 | 'ICON' => $faicon, 78 | 'CLASSES' => $this->DrawClasses(), 79 | 'TITLECLASSES' => $this->DrawClasses('title'), 80 | 'STYLES' => $this->DrawStyles(), 81 | 'ATTRIBUTES' => $this->DrawAttributes() 82 | ]); 83 | } 84 | } -------------------------------------------------------------------------------- Total de líneas: 84 ================================================================================ ================================================================================ ARCHIVO #322: src/Widget/ActionMenuTree.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/ActionMenuTree.php Tamaño: 1.76 KB -------------------------------------------------------------------------------- 1 | AddClasses($Classes); 30 | $this->AddClass('dropdown-menu'); 31 | $this->AddClass('m-t-xs'); 32 | 33 | if ($Animated) { 34 | $this->AddClass('animated'); 35 | $this->AddClass($AnimationType); 36 | } 37 | 38 | // Styles 39 | $this->AddStyles($Styles); 40 | 41 | // Attributes 42 | $this->AddAttributes($Attributes); 43 | 44 | $menuItems = ''; 45 | 46 | foreach($Items as $item) { 47 | if ($item instanceof ActionMenuItem || $item instanceof ActionMenuSeparator || $item instanceof ActionMenuMiniSeparator || $item instanceof ActionMenuTitle) { 48 | if ($menuItems != '') { 49 | $menuItems .= "\n"; 50 | } 51 | 52 | $menuItems .= $item->Draw(false); 53 | } 54 | } 55 | 56 | parent::__construct(Replace: [ 57 | 'CLASSES' => $this->DrawClasses(), 58 | 'STYLES' => $this->DrawStyles(), 59 | 'MENUITEMS' => $menuItems, 60 | 'ATTRIBUTES'=> $this->DrawAttributes() 61 | ]); 62 | } 63 | } -------------------------------------------------------------------------------- Total de líneas: 63 ================================================================================ ================================================================================ ARCHIVO #323: src/Widget/Am5Chart.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/Am5Chart.php Tamaño: 1.69 KB -------------------------------------------------------------------------------- 1 | AddClasses($Classes); 29 | $this->AddStyles($Styles); 30 | $this->AddAttributes($Attributes); 31 | $this->AddAttribute('id', $RootElement->DivContainer); 32 | $this->AddProperties($Properties); 33 | 34 | $script = new ScriptDirectSimple( 35 | Key: 'chart_' . str_replace('-', '_', $RootElement->DivContainer), 36 | Scripts: [ 37 | $RootElement->Draw(false), 38 | ] 39 | ); 40 | 41 | $scriptContent = $script->Draw(false); 42 | $scriptContent = str_replace('[[DIVCONTAINER]]', $RootElement->DivContainer, $scriptContent); 43 | 44 | parent::__construct(Replace: [ 45 | 'ATTRIBUTES' => $this->DrawAttributes(), 46 | 'PROPERTIES' => $this->DrawProperties(), 47 | 'CLASSES' => $this->DrawClasses(), 48 | 'STYLES' => $this->DrawStyles(), 49 | 'SCRIPT' => $scriptContent, 50 | ] 51 | ); 52 | } 53 | } -------------------------------------------------------------------------------- Total de líneas: 53 ================================================================================ ================================================================================ ARCHIVO #324: src/Widget/AmChartGeneric.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/AmChartGeneric.php Tamaño: 3.38 KB -------------------------------------------------------------------------------- 1 | AddClasses($Classes); 34 | $this->AddStyles($Styles); 35 | $this->AddAttributes($Attributes); 36 | $this->AddAttribute('id', $Key); 37 | $this->AddProperties($Properties); 38 | 39 | parent::__construct(Replace: [ 40 | 'ATTRIBUTES' => $this->DrawAttributes(), 41 | 'PROPERTIES' => $this->DrawProperties(), 42 | 'CLASSES' => $this->DrawClasses(), 43 | 'STYLES' => $this->DrawStyles(), 44 | 'SCRIPT' => $script->Draw(false), 45 | ]); 46 | } 47 | 48 | 49 | //GENERA EL FORMAT DE LA DATA 50 | public function format_simple_data($data,$settings){ 51 | $object = []; 52 | 53 | $LabelName = $settings->LabelName; 54 | $LabelValue = $settings->ValueName; 55 | $n = 0; 56 | foreach($data as $key => $item){ 57 | 58 | if(is_null($item->{$LabelValue})): 59 | continue; 60 | endif; 61 | 62 | if(is_null($LabelName) OR empty($LabelName)): 63 | 64 | $object[$n] = array( 65 | 'Label' => $key, 66 | $LabelValue => (int) $item->{$LabelValue} 67 | ); 68 | 69 | else: 70 | 71 | $object[$n] = array( 72 | $LabelName => $item->{$LabelName}, 73 | $LabelValue => (int) $item->{$LabelValue}, 74 | ); 75 | 76 | endif; 77 | if($settings->ColorName): 78 | $object[$n][$settings->ColorName] = $item->{$settings->ColorName}; 79 | endif; 80 | $n++; 81 | 82 | 83 | } 84 | return $object; 85 | } 86 | 87 | public function ChartHeader($ChartType,$key){ 88 | 89 | return " 90 | am4core.useTheme(am4themes_animated); 91 | var chart_$key = am4core.create('$key', $ChartType); 92 | chart_$key.hiddenState.properties.radius = am4core.percent(0); 93 | 94 | "; 95 | } 96 | 97 | public function ColorInObject($settings,$key){ 98 | if(!is_null($settings->ColorName) AND !empty($settings->ColorName)): 99 | return "pieSeries_$key.slices.template.propertyFields.fill = '".$settings->ColorName."';"; 100 | else: 101 | return "//Colores por defecto"; 102 | endif; 103 | } 104 | 105 | public function SetLegend($settings,$key){ 106 | 107 | if($settings->Legend == true): 108 | return " 109 | chart_$key.legend = new am4charts.Legend(); 110 | 111 | chart_$key.legend.scrollable = false;" 112 | ; 113 | else: 114 | return "//Sin Legenda"; 115 | endif; 116 | 117 | } 118 | 119 | public function ChartFooter(){ 120 | return "$(`g[shape-rendering='auto']`).remove(); "; 121 | } 122 | 123 | 124 | 125 | } 126 | 127 | -------------------------------------------------------------------------------- Total de líneas: 127 ================================================================================ ================================================================================ ARCHIVO #325: src/Widget/AmChartGraph.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/AmChartGraph.php Tamaño: 31.28 KB -------------------------------------------------------------------------------- 1 | _Key = $Key; 62 | $this->_Type = $Type; 63 | $this->_Series = $Series; 64 | $this->_Data = $Data; 65 | $this->_Label = $Label; 66 | $this->_LEGEND = $Legend; 67 | $this->_Title = $Title; 68 | $this->_NoDataMessage = $NoDataMessage; 69 | $this->_IsHiddeable = $IsHiddeable; 70 | $this->_Controls = $Controls; 71 | 72 | 73 | $this->AddClasses($Classes); 74 | if($this->CheckDataIncome() OR $this->_IsHiddeable != true): 75 | $this->AddStyles($Styles); 76 | endif; 77 | $this->AddAttributes($Attributes); 78 | $this->AddAttribute('id', $Key); 79 | $this->AddProperties($Properties); 80 | 81 | //INIT DEL GRAPH 82 | $this->Init_graph(); 83 | } 84 | 85 | //Función que inicializa el Graph 86 | private function Init_graph(){ 87 | 88 | if($this->CheckDataIncome() OR $this->_IsHiddeable != true): 89 | 90 | //SE CONFIGURAN LAS SERIES 91 | $this->_Series = $this->BuildSeries(); 92 | 93 | //SE FORMATEA LA DATA 94 | $this->_Data = $this->BuildData(); 95 | 96 | //SE CONSTRUYE EL HEADER 97 | $this->_Header = $this->BuildHeader(); 98 | 99 | //SE CONSTRUYE EL LABEL 100 | $this->_Label = $this->BuildLabel(); 101 | 102 | //SE CONSTRUYE EL FOOTER 103 | $this->_FOOTER = $this->BuildFooter(); 104 | 105 | //SE CONSTURYE EL LABEL 106 | $legend = ''; 107 | if($this->_LEGEND instanceof AmChartLegend): 108 | $this->_LEGEND->Build_Legend($this->_Key); 109 | 110 | $legend = $this->_LEGEND->_SCRIPT; 111 | 112 | endif; 113 | 114 | $TimeOutStart = ($this->AddLoadEvent) ? 115 | " 116 | document.addEventListener(\"DOMContentLoaded\", function(event){ 117 | 118 | // setTimeout(function(){ 119 | " : ""; 120 | $TimeOutEnd = ($this->AddLoadEvent) ? 121 | " 122 | // }, 1500); 123 | }); 124 | " : ''; 125 | 126 | $this->_SCRIPT_ = (new ScriptDirect( 127 | Scripts: [ 128 | $TimeOutStart , 129 | 130 | $this->_Header, 131 | $this->_Data , 132 | //$this->_Label, 133 | $this->_Series, 134 | $legend, 135 | $this->_FOOTER, 136 | $TimeOutEnd, 137 | 138 | 139 | ], Key: 'chart' 140 | )); 141 | else: 142 | 143 | if(is_string($this->_NoDataMessage) AND !empty($this->_NoDataMessage)): 144 | $Message = $this->_NoDataMessage; 145 | $this->_SCRIPT_ = new Label( 146 | LabelStyle: LabelStyleEnum::LABEL_INFO, 147 | Content: $this->_NoDataMessage 148 | ); 149 | else: 150 | $this->_SCRIPT_ = new Text(''); 151 | endif; 152 | 153 | endif; 154 | parent::__construct(Replace: [ 155 | 'ATTRIBUTES' => $this->DrawAttributes(), 156 | 'PROPERTIES' => $this->DrawProperties(), 157 | 'CLASSES' => $this->DrawClasses(), 158 | 'STYLES' => $this->DrawStyles(), 159 | 'SCRIPT' => $this->_SCRIPT_->Draw(false), 160 | ]); 161 | 162 | 163 | 164 | 165 | 166 | } 167 | 168 | // ############################ 169 | // FUNCIONES PROPIAS DEL OBJETO 170 | // ############################ 171 | 172 | private function BuildSeries(){ 173 | $TemporalSeries = ""; 174 | 175 | 176 | $SeriesType = $this->_Type; 177 | 178 | if(!empty($this->_Series)): 179 | switch($this->Type){ 180 | case AmChartTypeEnum::DONUTH_CHART: 181 | case AmChartTypeEnum::PIE_CHART: 182 | $TemporalSeries = $this->PIE_TEMPORAL_SERIES($SeriesType); 183 | break; 184 | case AmChartTypeEnum::PIE_DRILLDOWN: 185 | $TemporalSeries = $this->PIE_STACKED_TEMPORAL_SERIES($SeriesType); 186 | break; 187 | case AmChartTypeEnum::BAR_CHART: 188 | $TemporalSeries = $this->BAR_TEMPORAL_SERIES($SeriesType); 189 | break; 190 | case AmChartTypeEnum::BAR_CHART_HORIZONTAL: 191 | $TemporalSeries = $this->BAR_TEMPORAL_SERIES($SeriesType,true); 192 | break; 193 | case AmChartTypeEnum::LINE_CHART: 194 | $TemporalSeries = $this->LINE_TEMPORAL_SERIES($SeriesType); 195 | break; 196 | } 197 | 198 | endif; 199 | return $TemporalSeries; 200 | 201 | } 202 | 203 | private function BuildData(){ 204 | 205 | $TemporalData = ''; 206 | if(empty(!$this->Data->_DATA)): 207 | 208 | 209 | 210 | if($this->_Type == AmChartTypeEnum::LINE_CHART){ 211 | $TemporalData = "chart_$this->_Key.data =["; 212 | foreach($this->Data->_DATA as $item){ 213 | 214 | $TemporalData .= "{"; 215 | 216 | $total = count($item); 217 | $counter = 1; 218 | foreach($item as $key => $value){ 219 | 220 | 221 | if($key != "date"){ 222 | if($counter >= $total){ 223 | if(is_int($value)){ 224 | $TemporalData .= ' "'.$key.'" : '.$value.' '; 225 | } else{ 226 | $TemporalData .= ' "'.$key.'" : "'.$value.'" '; 227 | } 228 | 229 | }else{ 230 | $TemporalData .= ' "'.$key.'" : "'.$value.'", '; 231 | } 232 | }else{ 233 | if($counter >= $total){ 234 | $TemporalData .= ' "'.$key.'" : '.$value.' '; 235 | }else{ 236 | $TemporalData .= ' "'.$key.'" : '.$value.', '; 237 | } 238 | } 239 | 240 | $counter++; 241 | } 242 | $TemporalData .= "},"; 243 | 244 | } 245 | $TemporalData .= "]"; 246 | 247 | }else{ 248 | $TemporalData = 249 | " 250 | chart_$this->_Key.data = ". json_encode($this->Data->_DATA); 251 | } 252 | 253 | 254 | 255 | 256 | 257 | /* 258 | $TemporalData = 259 | ' 260 | chart_'.$this->_Key.'.data = [{ 261 | "country": "USA", 262 | "visits": 2025 263 | }, { 264 | "country": "China", 265 | "visits": 1882 266 | }, { 267 | "country": "Japan", 268 | "visits": 1809 269 | }, { 270 | "country": "Germany", 271 | "visits": 1322 272 | }, { 273 | "country": "UK", 274 | "visits": 1122 275 | }, { 276 | "country": "France", 277 | "visits": 1114 278 | }, { 279 | "country": "India", 280 | "visits": 984 281 | }, { 282 | "country": "Spain", 283 | "visits": 711 284 | }, { 285 | "country": "Netherlands", 286 | "visits": 665 287 | }, { 288 | "country": "Russia", 289 | "visits": 580 290 | }, { 291 | "country": "South Korea", 292 | "visits": 443 293 | }, { 294 | "country": "Canada", 295 | "visits": 441 296 | }, { 297 | "country": "Brazil", 298 | "visits": 395 299 | }]; 300 | '; 301 | */ 302 | 303 | endif; 304 | 305 | return $TemporalData; 306 | 307 | } 308 | 309 | private function BuildHeader(){ 310 | 311 | 312 | $_HEADER = 313 | " 314 | // Themes begin 315 | am4core.useTheme(am4themes_animated); 316 | 317 | var chart_$this->_Key = am4core.create('$this->_Key', $this->_Type); 318 | 319 | chart_$this->_Key.padding(20, 20, 20, 20); 320 | chart_$this->_Key.radius = am4core.percent(98); 321 | 322 | //chart_$this->_Key.cursor = new am4charts.XYCursor(); 323 | 324 | "; 325 | 326 | 327 | if(!empty($this->_Title) AND is_string($this->_Title)): 328 | 329 | $_HEADER .= " var title_$this->_Key = chart_$this->_Key.titles.create(); 330 | title_$this->_Key.text = '$this->_Title'; 331 | title_$this->_Key.fontSize = 20; 332 | title_$this->_Key.marginBottom = 30; 333 | title_$this->_Key.align = 'center'; 334 | "; 335 | endif; 336 | 337 | return $_HEADER; 338 | } 339 | 340 | private function BuildFooter(){ 341 | 342 | $script = ""; 343 | 344 | //SE AGREGAN LOS CONTROLADORES ADICIONALES 345 | 346 | if($this->_Controls instanceof AmChartControls): 347 | $script .= $this->_Controls->BuildAmChartControls("chart_$this->_Key",$this->_Type); 348 | endif; 349 | 350 | $script .= " $(`g[shape-rendering='auto']`).remove();"; 351 | 352 | return $script; 353 | 354 | } 355 | 356 | private function BuildLabel(){ 357 | 358 | return 359 | " 360 | 361 | 362 | "; 363 | 364 | } 365 | 366 | 367 | private function PIE_STACKED_TEMPORAL_SERIES($SeriesType){ 368 | $enum = 1; 369 | $SeriesType = $this->_Type; 370 | $TemporalSeries = ""; 371 | foreach($this->_Series as $item){ 372 | 373 | $varname = $enum.$this->_Key; 374 | if($item instanceof AmChartSeries): 375 | 376 | $TemporalSeries .= ""; 377 | if( 378 | empty($this->_Data->_DATAGROUP) AND 379 | empty($this->_Data->_GROUPVALUE) 380 | ): 381 | $TemporalSeries .= 382 | " 383 | //GENERACION SERIES N° $enum 384 | 385 | let ChartSeries_$varname = chart_$this->_Key.series.push(new $SeriesType); 386 | ChartSeries_$varname.dataFields.value = '$item->DataValue'; 387 | ChartSeries_$varname.dataFields.category = '$item->DataLabel'; 388 | 389 | ChartSeries_$varname.slices.template.stroke = am4core.color('$item->Color'); 390 | ChartSeries_$varname.slices.template.strokeOpacity = $item->Opacity; 391 | 392 | ChartSeries_$varname.slices.template.propertyFields.fill = 'Color'; 393 | 394 | "; 395 | 396 | if(!empty($item->HiddenState)): 397 | 398 | $HiddenObject = (object) $item->HiddenState; 399 | 400 | $TemporalSeries .= 401 | " 402 | //SETTINGS DE ANIMACIÓN DE LA SERIE 403 | ChartSeries_$varname.hiddenState.properties.opacity = 1; 404 | ChartSeries_$varname.hiddenState.properties.endAngle = -90; 405 | ChartSeries_$varname.hiddenState.properties.startAngle = -90; 406 | 407 | "; 408 | 409 | endif; 410 | else: 411 | $TemporalSeries = 412 | " 413 | chart_$this->_Key.colors.step = 2; 414 | chart_$this->_Key.fontSize = 11; 415 | chart_$this->_Key.innerRadius = am4core.percent(20); 416 | 417 | chart_$this->_Key.dataFields.value = '$item->DataValue'; 418 | chart_$this->_Key.dataFields.name = '$item->DataLabel'; 419 | chart_$this->_Key.dataFields.children = 'children'; 420 | 421 | chart_$this->_Key.dataFields.color = 'Color'; 422 | 423 | 424 | //DEFINICION DEL ZOOM BUTTON 425 | var zoomOutButton = chart_$this->_Key.seriesContainer.createChild(am4core.ZoomOutButton); 426 | 427 | zoomOutButton.visible = false; 428 | zoomOutButton.horizontalCenter = 'middle'; 429 | zoomOutButton.verticalCenter = 'middle'; 430 | zoomOutButton.events.on('hit', function() { 431 | drillUp(currentlySelected) 432 | }) 433 | 434 | function drillUp(slice) { 435 | collapse(slice); 436 | var series = slice.dataItem.component; 437 | series.tooltip.disabled = false; 438 | series.dummyData = false; 439 | series.setState('default'); 440 | 441 | series.slices.each(function(slice) { 442 | if (slice != event.target) { 443 | slice.dataItem.show(); 444 | } 445 | }) 446 | 447 | if (series.parentDataItem.seriesDataItem) { 448 | currentlySelected = series.parentDataItem.seriesDataItem.slice; 449 | } 450 | else { 451 | zoomOutButton.hide(); 452 | } 453 | } 454 | 455 | 456 | function collapse(slice) { 457 | 458 | slice.dataItem.label.bent = false; 459 | slice.dataItem.label.radius = 10; 460 | 461 | 462 | if (slice.dataItem.sunburstDataItem.children) { 463 | slice.dataItem.sunburstDataItem.children.each(function(child) { 464 | child.seriesDataItem.component.setState('hidden'); 465 | collapse(child.seriesDataItem.slice); 466 | }) 467 | } 468 | } 469 | 470 | 471 | var ChartSeries_$varname = new am4plugins_sunburst.SunburstSeries(); 472 | 473 | chart_$this->_Key.seriesTemplates.setKey('0', ChartSeries_$varname); 474 | 475 | ChartSeries_$varname.labels.template.truncate = true; 476 | ChartSeries_$varname.labels.template.hideOversized = true; 477 | ChartSeries_$varname.showOnInit = false; 478 | ChartSeries_$varname.usePercentHack = false; 479 | ChartSeries_$varname.radius = am4core.percent(100); 480 | ChartSeries_$varname.innerRadius = am4core.percent(0); 481 | 482 | ChartSeries_$varname.slices.template.propertyFields.fill = 'Color'; 483 | 484 | let selectedState = ChartSeries_$varname.states.create('selected'); 485 | selectedState.properties.opacity = 0.7; 486 | 487 | ChartSeries_$varname.defaultState.properties.radius = am4core.percent(100); 488 | 489 | var currentlySelected; 490 | 491 | ChartSeries_$varname.slices.template.events.on('over', function(event) { 492 | if(event.target.dataItem.sunburstDataItem.children){ 493 | event.target.cursorOverStyle = am4core.MouseCursorStyle.pointer; 494 | } 495 | }); 496 | 497 | ChartSeries_$varname.slices.template.events.on('hit', function(event) { 498 | 499 | zoomOutButton.show(); 500 | var hitSlice = event.target; 501 | 502 | if (hitSlice.dataItem.sunburstDataItem.children) { 503 | 504 | var series = event.target.dataItem.component; 505 | 506 | if (!series.dummyData) { 507 | series.tooltip.disabled = true; 508 | hitSlice.dataItem.label.radius = (hitSlice.radius - hitSlice.pixelInnerRadius) - 7; 509 | hitSlice.dataItem.label.bent = true; 510 | hitSlice.dataItem.label.rotation = -180; 511 | 512 | currentlySelected = hitSlice; 513 | series.dummyData = true; 514 | series.setState('selected'); 515 | hitSlice.dataItem.sunburstDataItem.series.show(); 516 | series.slices.each(function(slice) { 517 | if (slice != event.target) { 518 | slice.dataItem.hide(); 519 | } 520 | }) 521 | } 522 | else { 523 | drillUp(hitSlice); 524 | } 525 | } 526 | }) 527 | 528 | ChartSeries_$varname.labels.template.adapter.add('rotation', function(rotation, target) { 529 | target.maxWidth = target.dataItem.slice.radius - target.dataItem.slice.innerRadius - 10; 530 | target.maxHeight = Math.abs(target.dataItem.slice.arc * (target.dataItem.slice.innerRadius + target.dataItem.slice.radius) / 2 * am4core.math.RADIANS); 531 | return rotation; 532 | }) 533 | 534 | var level1SeriesTemplate_$varname = ChartSeries_$varname.clone(); 535 | level1SeriesTemplate_$varname.hidden = true; 536 | level1SeriesTemplate_$varname.innerRadius = am4core.percent(10); 537 | level1SeriesTemplate_$varname.hiddenInLegend = true; 538 | 539 | chart_$this->_Key.seriesTemplates.setKey('1', level1SeriesTemplate_$varname) 540 | 541 | level1SeriesTemplate_$varname.fillOpacity = 0.75; 542 | 543 | var level2SeriesTemplate_$varname = level0SeriesTemplate.clone(); 544 | level2SeriesTemplate_$varname.hidden = true; 545 | level2SeriesTemplate_$varname.innerRadius = am4core.percent(20); 546 | level2SeriesTemplate_$varname.hiddenInLegend = true; 547 | 548 | chart_$this->_Key.seriesTemplates.setKey('2', level2SeriesTemplate_$varname); 549 | 550 | 551 | 552 | 553 | "; 554 | endif; 555 | 556 | endif; 557 | 558 | $enum++; 559 | } 560 | 561 | 562 | return $TemporalSeries; 563 | } 564 | 565 | private function BAR_TEMPORAL_SERIES($SeriesType, $inverted = false){ 566 | $enum = 1; 567 | $SeriesType = $this->_Type; 568 | $TemporalSeries = ""; 569 | $KeyCount = 0; 570 | 571 | foreach($this->_Series as $item){ 572 | if($item instanceof AmChartSeries): 573 | $varname = $enum.$this->_Key; 574 | $enum++; 575 | 576 | $LabelName = $item->DataLabel; 577 | $ValueName = $item->DataValue; 578 | $GrouName = $item->DataLabeGroupName ?: $LabelName; 579 | $GrouKey = $item->DataLabeKeyName ?: $LabelName; 580 | 581 | $_value = "Y"; 582 | $_Category = "X"; 583 | $_valueAxes = "y"; 584 | $_CategoryAxes = "x"; 585 | if($inverted == true): 586 | $_value = "X"; 587 | $_Category = "Y"; 588 | $_valueAxes = "x"; 589 | $_CategoryAxes = "y"; 590 | endif; 591 | 592 | //DEFINICION DE LOS COLORES 593 | $color_definition = "'Color'"; 594 | if(!empty($item->DataColor) AND $item->DataColor != 'Color'){ 595 | $color_definition = "am4core.color('$item->DataColor')"; 596 | }elseif(!empty($item->DataColor)){ 597 | $color_definition = "'Color'"; 598 | }else{ 599 | $color_definition = "am4core.color('blue')"; 600 | } 601 | 602 | /////////////////////////////////////////////////// 603 | // DEFINICION DEL AXIS (SOLO DEBE DEFINIRCE UNA VEZ EN TODO LE CHART CONFIG) 604 | 605 | //SE DEFINIE EL GRUPO 606 | $GroupedAxis = "categoryAxis_$varname.dataFields.category = '$LabelName';"; 607 | 608 | $stacked = ""; 609 | if($this->_Data->SimpleStackedData == true): 610 | $GroupedAxis = "categoryAxis_$varname.dataFields.category = '$GrouKey';"; 611 | if($KeyCount > 0): 612 | $stacked = "series_$varname.stacked = true;"; 613 | endif; 614 | 615 | endif; 616 | 617 | if($KeyCount < 1): 618 | $TemporalSeries .= 619 | " 620 | var categoryAxis_$varname = chart_$this->_Key.".$_CategoryAxes."Axes.push(new am4charts.CategoryAxis()); 621 | $GroupedAxis 622 | categoryAxis_$varname.renderer.grid.template.location = 0; 623 | categoryAxis_$varname.renderer.minGridDistance = 30; 624 | 625 | categoryAxis_$varname.renderer.startLocation = 0; 626 | categoryAxis_$varname.renderer.cellStartLocation = 0.2; 627 | categoryAxis_$varname.renderer.cellEndLocation = 0.8; 628 | 629 | 630 | 631 | 632 | 633 | "; 634 | 635 | $TemporalSeries .= 636 | " 637 | 638 | let label_$varname = categoryAxis_$varname.renderer.labels.template; 639 | label_$varname.wrap = true; 640 | label_$varname.maxWidth = 150; 641 | label_$varname.tooltipText = '{category}';"; 642 | 643 | 644 | if($this->_Type == AmChartTypeEnum::BAR_CHART): 645 | $TemporalSeries .= 646 | " 647 | categoryAxis_$varname.events.on('sizechanged', function(ev) { 648 | let axis = ev.target; 649 | var cellWidth = axis.pixelWidth / (axis.endIndex - axis.startIndex); 650 | if (cellWidth < axis.renderer.labels.template.maxWidth) { 651 | axis.renderer.labels.template.rotation = -45; 652 | axis.renderer.labels.template.horizontalCenter = 'right'; 653 | axis.renderer.labels.template.verticalCenter = 'middle'; 654 | } 655 | else { 656 | axis.renderer.labels.template.rotation = 0; 657 | axis.renderer.labels.template.horizontalCenter = 'middle'; 658 | axis.renderer.labels.template.verticalCenter = 'top'; 659 | } 660 | }); 661 | "; 662 | endif; 663 | endif; 664 | $KeyCount++; 665 | 666 | 667 | $TemporalSeries .= " 668 | 669 | var valueAxis = chart_$this->_Key.".$_valueAxes."Axes.push(new am4charts.ValueAxis()); 670 | 671 | // SE CREEA LA SERIE 672 | var series_$varname = chart_$this->_Key.series.push(new am4charts.ColumnSeries()); 673 | series_$varname.dataFields.value$_value = '$ValueName'; 674 | series_$varname.dataFields.category$_Category = '$LabelName'; 675 | series_$varname.name = '$GrouName'; 676 | series_$varname.columns.template.tooltipText = '{name}: [bold]{value$_value}[/]'; 677 | series_$varname.columns.template.fillOpacity = .8; 678 | series_$varname.columns.template.propertyFields.fill = $color_definition; 679 | 680 | series_$varname.columns.template.fill = $color_definition; 681 | 682 | let valueLabel_$varname = series_$varname.bullets.push(new am4charts.LabelBullet()); 683 | valueLabel_$varname.label.text = '{value$_value}'; 684 | valueLabel_$varname.label.fontSize = 12; 685 | valueLabel_$varname.label.truncate = true; 686 | valueLabel_$varname.label.hideOversized = true; 687 | 688 | $stacked 689 | 690 | 691 | 692 | 693 | 694 | 695 | "; 696 | 697 | 698 | 699 | 700 | 701 | 702 | endif; 703 | } 704 | return $TemporalSeries; 705 | } 706 | 707 | private function PIE_TEMPORAL_SERIES($SeriesType){ 708 | $enum = 1; 709 | $SeriesType = $this->_Type; 710 | $TemporalSeries = ""; 711 | foreach($this->_Series as $item){ 712 | 713 | if($enum > 1): 714 | break; 715 | endif; 716 | $enum++; 717 | 718 | $total_data = 0; 719 | if($item instanceof AmChartSeries): 720 | $varname = $enum.$this->_Key; 721 | 722 | $LabelName = $item->DataLabel; 723 | $ValueName = $item->DataValue; 724 | 725 | foreach($this->_Data->Datos as $item){ 726 | $subtotal = $item->{$ValueName}; 727 | 728 | if(is_numeric($subtotal)): 729 | $total_data += $subtotal; 730 | endif; 731 | } 732 | 733 | if($this->Type == AmChartTypeEnum::DONUTH_CHART): 734 | 735 | $TemporalSeries .= 736 | " 737 | chart_$this->_Key.innerRadius = am4core.percent(60); 738 | "; 739 | 740 | endif; 741 | 742 | $TemporalSeries .= 743 | " 744 | // CONFIGURACION DE LA SERIE 745 | var ChartSeries_$varname = chart_$this->_Key.series.push(new am4charts.PieSeries()); 746 | 747 | 748 | 749 | ChartSeries_$varname.dataFields.value = '$ValueName'; 750 | ChartSeries_$varname.dataFields.category = '$LabelName'; 751 | ChartSeries_$varname.slices.template.stroke = am4core.color('#fff'); 752 | ChartSeries_$varname.slices.template.strokeOpacity = 1; 753 | 754 | ChartSeries_$varname.slices.template.propertyFields.fill = 'Color'; 755 | 756 | ChartSeries_$varname.ticks.template.disabled = true; 757 | ChartSeries_$varname.alignLabels = false; 758 | ChartSeries_$varname.labels.template.text = '{value}'; 759 | ChartSeries_$varname.labels.template.radius = am4core.percent(-20); 760 | ChartSeries_$varname.labels.template.fill = am4core.color('white'); 761 | 762 | ChartSeries_$varname.labels.template.adapter.add('radius', function(radius, target) { 763 | if (target.dataItem && (target.dataItem.values.value.percent < 10)) { 764 | return 0; 765 | } 766 | return radius; 767 | }); 768 | 769 | ChartSeries_$varname.labels.template.adapter.add('fill', function(color, target) { 770 | if (target.dataItem && (target.dataItem.values.value.percent < 10)) { 771 | return am4core.color('#000'); 772 | } 773 | return color; 774 | }); 775 | 776 | 777 | 778 | "; 779 | if($this->Type == AmChartTypeEnum::DONUTH_CHART): 780 | $TemporalSeries .= 781 | " 782 | let label_$varname = ChartSeries_$varname.createChild(am4core.Label); 783 | label_$varname .text = '". number_format($total_data,0,',','.') ."'; 784 | label_$varname .horizontalCenter = 'middle'; 785 | label_$varname .verticalCenter = 'middle'; 786 | label_$varname .fontSize = 40; 787 | "; 788 | endif; 789 | 790 | if(!empty($item->HiddenState)): 791 | 792 | $HiddenObject = (object) $item->HiddenState; 793 | 794 | $TemporalSeries .= 795 | " 796 | //SETTINGS DE ANIMACIÓN DE LA SERIE 797 | ChartSeries_$varname.hiddenState.properties.opacity = 1; 798 | ChartSeries_$varname.hiddenState.properties.endAngle = -90; 799 | ChartSeries_$varname.hiddenState.properties.startAngle = -90; 800 | 801 | "; 802 | 803 | endif; 804 | 805 | endif; 806 | } 807 | return $TemporalSeries; 808 | } 809 | 810 | 811 | private function LINE_TEMPORAL_SERIES($SeriesType,$inverted = false){ 812 | $enum = 1; 813 | $SeriesType = $this->_Type; 814 | $TemporalSeries = ""; 815 | $KeyCount = 0; 816 | foreach($this->_Series as $item){ 817 | if($item instanceof AmChartSeries): 818 | $varname = $enum.trim($this->_Key); 819 | $enum++; 820 | 821 | $LabelName = $item->DataLabel; 822 | $ValueName = $item->DataValue; 823 | $GrouName = $item->DataLabeGroupName ?: $LabelName; 824 | $GrouKey = $item->DataLabeKeyName ?: $LabelName; 825 | 826 | // ------------------------------------------------------------------------------------------------------- 827 | // SI EL KEY COUNT ES MENOR A 1 SE INGRESAN TODAS LAS FUNCIONES DEL GRAFICO (QUE TENGA QUE VER CON SERIES) 828 | // ------------------------------------------------------------------------------------------------------- 829 | if($KeyCount < 1){ 830 | 831 | $TemporalSeries .= 832 | ' 833 | 834 | var dateAxis = chart_'.$this->_Key.'.xAxes.push(new am4charts.DateAxis()); 835 | dateAxis.baseInterval = { timeUnit: "hour", count: 1 }; 836 | dateAxis.dateFormats.setKey("hour", "dd/MM/yyyy HH:mm:ss"); 837 | ; 838 | 839 | var valueAxis = chart_'.$this->_Key.'.yAxes.push(new am4charts.ValueAxis()); 840 | 841 | 842 | 843 | 844 | function createSeries(field, name) { 845 | var series = chart_'.$this->_Key.'.series.push(new am4charts.LineSeries()); 846 | series.dataFields.valueY = field; 847 | series.dataFields.dateX = "date"; 848 | series.name = name; 849 | series.tooltipText = "Accesos {valueY}: [b]{name}[/]"; 850 | series.strokeWidth = 1; 851 | series.tensionX = 0.99; 852 | series.tooltip.label.adapter.add("text", function(text, target) { 853 | if (target.dataItem && target.dataItem.valueY == 0) { 854 | return ""; 855 | } 856 | else { 857 | return text; 858 | } 859 | }); 860 | 861 | 862 | var bullet = series.bullets.push(new am4charts.CircleBullet()); 863 | 864 | bullet.circle.strokeWidth = 1; 865 | 866 | return series; 867 | } 868 | '; 869 | 870 | } 871 | 872 | 873 | // ------------------------------------------------- 874 | // SE GENERA LA SERIA DEL GRAFICO DE LINEA 875 | // ------------------------------------------------- 876 | $TemporalSeries .= " var series_$varname = createSeries('$ValueName', '$GrouName'); "; 877 | 878 | 879 | // --------------------------------------------- 880 | 881 | 882 | 883 | $KeyCount++; 884 | 885 | 886 | endif; 887 | } 888 | return $TemporalSeries; 889 | } 890 | 891 | 892 | 893 | 894 | private function CheckDataIncome(){ 895 | $status = false; 896 | 897 | $ValueName = $this->_Series[0]->DataValue; 898 | 899 | if (!isset($this->_Data) || !isset($this->_Data->Datos)) 900 | return false; 901 | 902 | foreach($this->_Data->Datos as $item){ 903 | 904 | $Value = $item->{$ValueName}; 905 | 906 | if(is_numeric($Value)): 907 | 908 | if($Value > 0): 909 | 910 | $status = true; 911 | 912 | endif; 913 | 914 | endif; 915 | 916 | if(is_string($Value)): 917 | 918 | if(!empty($Value)): 919 | 920 | $status = true; 921 | 922 | endif; 923 | 924 | endif; 925 | } 926 | 927 | return $status; 928 | } 929 | 930 | } -------------------------------------------------------------------------------- Total de líneas: 930 ================================================================================ ================================================================================ ARCHIVO #326: src/Widget/AmchartPie.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/AmchartPie.php Tamaño: 5.39 KB -------------------------------------------------------------------------------- 1 | "", 38 | "ValueName" => "", 39 | "DonutMode" => false, 40 | "ColorName" => null, 41 | "Legend" => true 42 | ] 43 | 44 | ) 45 | { 46 | //Seteo el key 47 | $this->_Key = trim($Key); 48 | //ME ASEGURO QUE LA VARIABLE PieConfig SEA UN OBJETO 49 | $this->_Settings = json_decode(json_encode($PieConfig)); 50 | 51 | $this->_Data = $this->format_simple_data($Datos,$this->_Settings); 52 | 53 | //Se construye el pie 54 | $this->_Script_ = $this->BuildPie(); 55 | 56 | //SE MANDA TODA LA INFORMACIÓN AL CONSTRUCTOR PADRE 57 | parent::__construct( 58 | $Key, 59 | $Classes, 60 | $Styles, 61 | $Attributes, 62 | $Properties, 63 | $Titulo, 64 | $this->_Script_ 65 | ); 66 | } 67 | 68 | private function BuildPie(){ 69 | //Converción de los datos del PIE a formato JSON 70 | $datos = str_replace('"',"'", json_encode($this->_Data)); 71 | 72 | //Generación del script 73 | $Script = 74 | " 75 | document.addEventListener(\"DOMContentLoaded\", function(event){ 76 | //setTimeout(function(){ 77 | 78 | ". $this->ChartHeader(AmChartTypeEnum::PIE_CHART,$this->_Key) ." 79 | ". $this->PieHeader() ." 80 | ". $this->DonutMode() ." 81 | ". $this->ColorInObject($this->_Settings,$this->_Key) ." 82 | ". $this->SetLegend($this->_Settings,$this->_Key) ." 83 | 84 | chart_$this->_Key.data = $datos; 85 | 86 | ". $this->ChartFooter() ." 87 | 88 | //}, 1000); 89 | }); 90 | "; 91 | 92 | //Se genera el ScriptDirect 93 | $ScriptReturn = (new ScriptDirect( 94 | Scripts: [ (string)$Script] 95 | )); 96 | return $ScriptReturn; 97 | 98 | } 99 | 100 | private function PieHeader(){ 101 | 102 | $labelname = $this->_Settings->LabelName; 103 | if(empty($labelname) OR is_null($labelname)): 104 | $labelname = "Label"; 105 | endif; 106 | 107 | $Valuename = $this->_Settings->ValueName; 108 | 109 | return 110 | " 111 | var pieSeries_$this->_Key = chart_$this->_Key.series.push(new am4charts.PieSeries()); 112 | pieSeries_$this->_Key.dataFields.value = '$Valuename'; 113 | pieSeries_$this->_Key.dataFields.category = '$labelname'; 114 | 115 | pieSeries_$this->_Key.slices.template.stroke = am4core.color('#fff'); 116 | pieSeries_$this->_Key.slices.template.strokeWidth = 2; 117 | pieSeries_$this->_Key.slices.template.strokeOpacity = 1; 118 | 119 | pieSeries_$this->_Key.labels.template.adapter.add('radius', function(radius, target) { 120 | if (target.dataItem && (target.dataItem.values.value.percent < 10)) { 121 | return 0; 122 | } 123 | return radius; 124 | }); 125 | 126 | pieSeries_$this->_Key.labels.template.adapter.add('fill', function(color, target) { 127 | if (target.dataItem && (target.dataItem.values.value.percent < 10)) { 128 | return am4core.color('#000'); 129 | } 130 | return color; 131 | }); 132 | "; 133 | } 134 | 135 | private function DonutMode(){ 136 | 137 | $valuename = $this->_Settings->ValueName; 138 | if($this->_Settings->DonutMode == true): 139 | $SumAll = 0; 140 | foreach($this->_Data as $item){ 141 | $SumAll = $SumAll + $item[$valuename]; 142 | } 143 | return " 144 | 145 | chart_$this->_Key.innerRadius = 50; 146 | 147 | var label_$this->_Key = chart_$this->_Key.seriesContainer.createChild(am4core.Label); 148 | 149 | label_$this->_Key.horizontalCenter = 'middle'; 150 | label_$this->_Key.verticalCenter = 'middle'; 151 | label_$this->_Key.fontSize = 45; 152 | label_$this->_Key.text = $SumAll; 153 | 154 | 155 | 156 | "; 157 | 158 | 159 | else: 160 | //SI NO SE ESTA SOLICITANDO EL MODO DONUT SE CONFIGURA EL SETTINGS 161 | return " 162 | pieSeries_$this->_Key.ticks.template.disabled = true; 163 | pieSeries_$this->_Key.alignLabels = false; 164 | pieSeries_$this->_Key.labels.template.text = '{value}'; 165 | pieSeries_$this->_Key.labels.template.radius = am4core.percent(-40); 166 | pieSeries_$this->_Key.labels.template.fill = am4core.color('white'); 167 | pieSeries_$this->_Key.legendSettings.valueText = '{value}'; 168 | "; 169 | 170 | endif; 171 | 172 | } 173 | 174 | 175 | 176 | } -------------------------------------------------------------------------------- Total de líneas: 176 ================================================================================ ================================================================================ ARCHIVO #327: src/Widget/Card.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/Card.php Tamaño: 3.58 KB -------------------------------------------------------------------------------- 1 | AddClasses($Classes); 37 | $this->AddClass('card'); 38 | 39 | // Styles 40 | $this->AddStyles($Styles); 41 | $this->AddStyle('background-color', '#ffffff'); 42 | 43 | // Shadow styles 44 | $this->AddStyle('-webkit-box-shadow', '0 ' . $Elevation . 'px ' . ($Elevation*2) . 'px rgb(0 0 0 / ' . $Transparency . '%)'); 45 | $this->AddStyle('box-shadow', '0 ' . $Elevation . 'px ' . ($Elevation*2) . 'px rgb(0 0 0 / ' . $Transparency . '%)'); 46 | $this->AddStyle('border-radius', $BorderRadius . 'px'); 47 | 48 | // PADDING 49 | if (!isset($Padding)) { 50 | $Padding = new Edge(Top: 10, Right: 10, Bottom: 10, Left: 10); 51 | } 52 | 53 | if (isset($Padding->Left)) { 54 | $this->AddStyle('padding-left', $Padding->Left . $Padding->Unit); 55 | } 56 | if (isset($Padding->Right)) { 57 | $this->AddStyle('padding-right', $Padding->Right . $Padding->Unit); 58 | } 59 | if (isset($Padding->Top)) { 60 | $this->AddStyle('padding-top', $Padding->Top . $Padding->Unit); 61 | } 62 | if (isset($Padding->Bottom)) { 63 | $this->AddStyle('padding-bottom', $Padding->Bottom . $Padding->Unit); 64 | } 65 | 66 | // MARGIN 67 | if (!isset($Margin)) { 68 | $Margin = new Edge(Top: 10, Right: 10, Bottom: 10, Left: 10); 69 | } 70 | 71 | if (isset($Margin->Left)) { 72 | $this->AddStyle('margin-left', $Margin->Left . $Margin->Unit); 73 | } 74 | if (isset($Margin->Right)) { 75 | $this->AddStyle('margin-right', $Margin->Right . $Margin->Unit); 76 | } 77 | if (isset($Margin->Top)) { 78 | $this->AddStyle('margin-top', $Margin->Top . $Margin->Unit); 79 | } 80 | if (isset($Margin->Bottom)) { 81 | $this->AddStyle('margin-bottom', $Margin->Bottom . $Margin->Unit); 82 | } 83 | 84 | // Attributes 85 | $this->AddAttributes($Attributes); 86 | 87 | if ($Key != '') { 88 | $this->AddAttribute('id', $this->Key); 89 | } 90 | 91 | // Properties 92 | $this->AddProperties($Properties); 93 | 94 | $builder = ""; 95 | foreach ($Children as $child) { 96 | if ($child instanceof GenericWidget) { 97 | if ($builder != "") { 98 | $builder = $builder . "\n"; 99 | } 100 | $builder .= $child->Draw(false); 101 | } 102 | } 103 | 104 | parent::__construct(Replace: [ 105 | 'CONTENT' => $builder, 106 | 'CLASSES' => $this->DrawClasses(), 107 | 'STYLES' => $this->DrawStyles(), 108 | 'ATTRIBUTES' => $this->DrawAttributes(), 109 | 'PROPERTIES' => $this->DrawProperties() 110 | ]); 111 | } 112 | } -------------------------------------------------------------------------------- Total de líneas: 112 ================================================================================ ================================================================================ ARCHIVO #328: src/Widget/CardAction.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/CardAction.php Tamaño: 2.52 KB -------------------------------------------------------------------------------- 1 | AddClasses($Classes); 39 | $this->AddClass('card text-center'); 40 | $this->AddClasses($ActionClasses, 'action'); 41 | 42 | // Styles 43 | $this->AddStyles($Styles); 44 | $this->AddStyles($ActionStyles, 'action'); 45 | 46 | // Attributes 47 | $this->AddAttributes($Attributes); 48 | $this->AddAttributes($ActionAttributes, 'action'); 49 | $this->AddAttribute('href', $Action, 'action'); 50 | 51 | if ($Key != '') { 52 | $this->AddAttribute('id', $this->Key); 53 | } 54 | 55 | // Properties 56 | $this->AddProperties($Properties); 57 | $this->AddProperties($ActionProperties, 'action'); 58 | 59 | parent::__construct(Replace: [ 60 | 'CONTENT' => $Content->Draw(false), 61 | 'CLASSES' => $this->DrawClasses(), 62 | 'STYLES' => $this->DrawStyles(), 63 | 'ATTRIBUTES' => $this->DrawAttributes(), 64 | 'PROPERTIES' => $this->DrawProperties(), 65 | 'ACTIONCLASSES' => $this->DrawClasses('action'), 66 | 'ACTIONSTYLES' => $this->DrawStyles('action'), 67 | 'ACTIONATTRIBUTES' => $this->DrawAttributes('action'), 68 | 'ACTIONPROPERTIES' => $this->DrawProperties('action') 69 | ]); 70 | } 71 | } -------------------------------------------------------------------------------- Total de líneas: 71 ================================================================================ ================================================================================ ARCHIVO #329: src/Widget/CardActionIconText.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/CardActionIconText.php Tamaño: 3.20 KB -------------------------------------------------------------------------------- 1 | AddClasses($Classes); 44 | $this->AddClass('card text-center'); 45 | $this->AddClasses($ActionClasses, 'action'); 46 | 47 | // Styles 48 | $this->AddStyles($Styles); 49 | $this->AddStyles($ActionStyles, 'action'); 50 | 51 | // Attributes 52 | $this->AddAttributes($Attributes); 53 | $this->AddAttributes($ActionAttributes, 'action'); 54 | $this->AddAttribute('href', $Action, 'action'); 55 | 56 | if ($Key != '') { 57 | $this->AddAttribute('id', $this->Key); 58 | } 59 | 60 | array_push($IconClasses, 'card-icon'); 61 | 62 | if ($Relevant) 63 | array_push($IconClasses, 'relevant'); 64 | 65 | array_push($TextClasses, 'card-title'); 66 | 67 | $icon = new FaIcon( 68 | Name: $IconName, 69 | Classes: $IconClasses, 70 | Styles: $IconStyles, 71 | Attributes: $IconAttributes, 72 | Properties: $Properties 73 | ); 74 | 75 | $text = new Text( 76 | Content: $Text, 77 | Classes: $TextClasses, 78 | Styles: $TextStyles, 79 | Attributes: $TextAttributes, 80 | Properties: $TextProperties 81 | ); 82 | 83 | // Properties 84 | $this->AddProperties($Properties); 85 | $this->AddProperties($ActionProperties, 'action'); 86 | 87 | parent::__construct(Replace: [ 88 | 'ICON' => $icon->Draw(false), 89 | 'TEXT' => $text->Draw(false), 90 | 'CLASSES' => $this->DrawClasses(), 91 | 'STYLES' => $this->DrawStyles(), 92 | 'ATTRIBUTES' => $this->DrawAttributes(), 93 | 'PROPERTIES' => $this->DrawProperties(), 94 | 'ACTIONCLASSES' => $this->DrawClasses('action'), 95 | 'ACTIONSTYLES' => $this->DrawStyles('action'), 96 | 'ACTIONATTRIBUTES' => $this->DrawAttributes('action'), 97 | 'ACTIONPROPERTIES' => $this->DrawProperties('action') 98 | ]); 99 | } 100 | } -------------------------------------------------------------------------------- Total de líneas: 100 ================================================================================ ================================================================================ ARCHIVO #330: src/Widget/CardActionImageText.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/CardActionImageText.php Tamaño: 3.59 KB -------------------------------------------------------------------------------- 1 | AddClasses($Classes); 50 | $this->AddClass('card text-center'); 51 | $this->AddClasses($ActionClasses, 'action'); 52 | 53 | // Styles 54 | $this->AddStyles($Styles); 55 | $this->AddStyles($ActionStyles, 'action'); 56 | 57 | // Attributes 58 | $this->AddAttributes($Attributes); 59 | $this->AddAttributes($ActionAttributes, 'action'); 60 | $this->AddAttribute('href', $Action, 'action'); 61 | 62 | if ($Key != '') { 63 | $this->AddAttribute('id', $this->Key); 64 | } 65 | 66 | array_push($ImageClasses, 'card-icon'); 67 | 68 | if ($Relevant) 69 | array_push($ImageClasses, 'relevant'); 70 | 71 | array_push($TextClasses, 'card-title'); 72 | 73 | $image = new Image( 74 | Source: $ImageSrc, 75 | Classes: $ImageClasses, 76 | Styles: $ImageStyles, 77 | Width: $Width, 78 | Height: $Height, 79 | Attributes: $ImageAttributes, 80 | Properties: $ImageProperties 81 | ); 82 | 83 | $text = new Text( 84 | Content: $Text, 85 | Classes: $TextClasses, 86 | Styles: $TextStyles, 87 | Attributes: $TextAttributes, 88 | Properties: $TextProperties 89 | ); 90 | 91 | // Properties 92 | $this->AddProperties($Properties); 93 | $this->AddProperties($ActionProperties, 'action'); 94 | 95 | parent::__construct(Replace: [ 96 | 'IMAGE' => $image->Draw(false), 97 | 'TEXT' => $text->Draw(false), 98 | 'CLASSES' => $this->DrawClasses(), 99 | 'STYLES' => $this->DrawStyles(), 100 | 'ATTRIBUTES' => $this->DrawAttributes(), 101 | 'PROPERTIES' => $this->DrawProperties(), 102 | 'ACTIONCLASSES' => $this->DrawClasses('action'), 103 | 'ACTIONSTYLES' => $this->DrawStyles('action'), 104 | 'ACTIONATTRIBUTES' => $this->DrawAttributes('action'), 105 | 'ACTIONPROPERTIES' => $this->DrawProperties('action') 106 | ]); 107 | } 108 | } -------------------------------------------------------------------------------- Total de líneas: 108 ================================================================================ ================================================================================ ARCHIVO #331: src/Widget/CardIconText.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/CardIconText.php Tamaño: 2.56 KB -------------------------------------------------------------------------------- 1 | AddClasses($Classes); 42 | $this->AddClass('card text-center'); 43 | 44 | // Styles 45 | $this->AddStyles($Styles); 46 | 47 | // Attributes 48 | $this->AddAttributes($Attributes); 49 | 50 | if ($Key != '') { 51 | $this->AddAttribute('id', $this->Key); 52 | } 53 | 54 | array_push($IconClasses, 'card-icon'); 55 | 56 | if ($Relevant) 57 | array_push($IconClasses, 'relevant'); 58 | 59 | array_push($TextClasses, 'card-title'); 60 | 61 | $icon = new FaIcon( 62 | Name: $IconName, 63 | Classes: $IconClasses, 64 | Styles: $IconStyles, 65 | Attributes: $IconAttributes, 66 | Properties: $Properties 67 | ); 68 | 69 | $text = new Text( 70 | Content: $Text, 71 | Classes: $TextClasses, 72 | Styles: $TextStyles, 73 | Attributes: $TextAttributes, 74 | Properties: $TextProperties 75 | ); 76 | 77 | // Properties 78 | $this->AddProperties($Properties); 79 | 80 | parent::__construct(Replace: [ 81 | 'ICON' => $icon->Draw(false), 82 | 'TEXT' => $text->Draw(false), 83 | 'CLASSES' => $this->DrawClasses(), 84 | 'STYLES' => $this->DrawStyles(), 85 | 'ATTRIBUTES' => $this->DrawAttributes(), 86 | 'PROPERTIES' => $this->DrawProperties() 87 | ]); 88 | } 89 | } -------------------------------------------------------------------------------- Total de líneas: 89 ================================================================================ ================================================================================ ARCHIVO #332: src/Widget/Chart.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/Chart.php Tamaño: 1.36 KB -------------------------------------------------------------------------------- 1 | AddClasses($Classes); 30 | $this->AddStyles($Styles); 31 | $this->AddAttributes($Attributes); 32 | $this->AddAttribute('id', $Key); 33 | $this->AddProperties($Properties); 34 | 35 | parent::__construct(Replace: [ 36 | 'ATTRIBUTES' => $this->DrawAttributes(), 37 | 'PROPERTIES' => $this->DrawProperties(), 38 | 'CLASSES' => $this->DrawClasses(), 39 | 'STYLES' => $this->DrawStyles(), 40 | //'SCRIPT' => $script->Draw(false), 41 | ]); 42 | } 43 | 44 | private function ScriptRootElement() { 45 | 46 | return "var root_" . $this->Key . " = am5.Root.new('" . $this->Key . "')"; 47 | 48 | } 49 | 50 | 51 | } 52 | -------------------------------------------------------------------------------- Total de líneas: 52 ================================================================================ ================================================================================ ARCHIVO #333: src/Widget/Container.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/Container.php Tamaño: 3.59 KB -------------------------------------------------------------------------------- 1 | AddClasses($Classes); 34 | 35 | // Styles 36 | $this->AddStyles($Styles); 37 | 38 | if (isset($Padding)) { 39 | if (isset($Padding->Left)) { 40 | $this->AddStyle('padding-left', $Padding->Left . $Padding->Unit); 41 | } 42 | if (isset($Padding->Right)) { 43 | $this->AddStyle('padding-right', $Padding->Right . $Padding->Unit); 44 | } 45 | if (isset($Padding->Top)) { 46 | $this->AddStyle('padding-top', $Padding->Top . $Padding->Unit); 47 | } 48 | if (isset($Padding->Bottom)) { 49 | $this->AddStyle('padding-bottom', $Padding->Bottom . $Padding->Unit); 50 | } 51 | } 52 | 53 | if (isset($Margin)) { 54 | if (isset($Margin->Left)) { 55 | $this->AddStyle('margin-left', $Margin->Left . $Margin->Unit); 56 | } 57 | if (isset($Margin->Right)) { 58 | $this->AddStyle('margin-right', $Margin->Right . $Margin->Unit); 59 | } 60 | if (isset($Margin->Top)) { 61 | $this->AddStyle('margin-top', $Margin->Top . $Margin->Unit); 62 | } 63 | if (isset($Margin->Bottom)) { 64 | $this->AddStyle('margin-bottom', $Margin->Bottom . $Margin->Unit); 65 | } 66 | } 67 | 68 | if (isset($Position)) { 69 | 70 | $this->AddStyle('position', $Position->Type); 71 | 72 | if (isset($Position->Left)) { 73 | $this->AddStyle('left', $Position->Left . $Position->Unit); 74 | } 75 | if (isset($Position->Right)) { 76 | $this->AddStyle('right', $Position->Right . $Position->Unit); 77 | } 78 | if (isset($Position->Top)) { 79 | $this->AddStyle('top', $Position->Top . $Position->Unit); 80 | } 81 | if (isset($Position->Bottom)) { 82 | $this->AddStyle('bottom', $Position->Bottom . $Position->Unit); 83 | } 84 | } 85 | 86 | // Attributes 87 | $this->AddAttributes($Attributes); 88 | 89 | if ($Key != '') { 90 | $this->AddAttribute('id', $this->Key); 91 | } 92 | 93 | // Properties 94 | $this->AddProperties($Properties); 95 | 96 | $builder = ""; 97 | foreach ($Children as $child) { 98 | if ($child instanceof GenericWidget) { 99 | if ($builder != "") { 100 | $builder = $builder . "\n"; 101 | } 102 | $builder .= $child->Draw(false); 103 | } 104 | } 105 | 106 | parent::__construct(Replace: [ 107 | 'CONTENT' => $builder, 108 | 'CLASSES' => $this->DrawClasses(), 109 | 'STYLES' => $this->DrawStyles(), 110 | 'ATTRIBUTES' => $this->DrawAttributes(), 111 | 'PROPERTIES' => $this->DrawProperties() 112 | ]); 113 | } 114 | } -------------------------------------------------------------------------------- Total de líneas: 114 ================================================================================ ================================================================================ ARCHIVO #334: src/Widget/DateAndTime.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/DateAndTime.php Tamaño: 2.79 KB -------------------------------------------------------------------------------- 1 | AddClasses($Classes); 39 | $this->AddClasses($DateClasses, 'date'); 40 | $this->AddClasses($TimeClasses, 'time'); 41 | 42 | // Styles 43 | $this->AddStyles($Styles); 44 | $this->AddStyles($DateStyles, 'date'); 45 | $this->AddStyles($TimeStyles, 'time'); 46 | 47 | // Attributes 48 | $this->AddAttributes($Attributes); 49 | $this->AddAttributes($DateAttributes, 'date'); 50 | $this->AddAttributes($TimeAttributes, 'time'); 51 | 52 | // Properties 53 | $this->AddProperties($Properties); 54 | $this->AddProperties($DateProperties, 'date'); 55 | $this->AddProperties($TimeProperties, 'time'); 56 | 57 | if ($Key != '') { 58 | $this->AddAttribute('id', $Key); 59 | } 60 | 61 | $date = $DateTime->format($CustomDateFormat); 62 | $time = $DateTime->format($CustomTimeFormat); 63 | 64 | parent::__construct(Replace: [ 65 | 'DATE' => $date, 66 | 'TIME' => $time, 67 | 'CLASSES' => $this->DrawClasses(), 68 | 'STYLES' => $this->DrawStyles(), 69 | 'ATTRIBUTES' => $this->DrawAttributes(), 70 | 'PROPERTIES' => $this->DrawProperties(), 71 | 'DATECLASSES' => $this->DrawClasses('date'), 72 | 'DATESTYLES' => $this->DrawStyles('date'), 73 | 'DATEATTRIBUTES' => $this->DrawAttributes('date'), 74 | 'DATEPROPERTIES' => $this->DrawProperties('date'), 75 | 'TIMECLASSES' => $this->DrawClasses('time'), 76 | 'TIMESTYLES' => $this->DrawStyles('time'), 77 | 'TIMEATTRIBUTES' => $this->DrawAttributes('time'), 78 | 'TIMEPROPERTIES' => $this->DrawProperties('time'), 79 | ]); 80 | } 81 | } -------------------------------------------------------------------------------- Total de líneas: 81 ================================================================================ ================================================================================ ARCHIVO #335: src/Widget/Definitions/Action/ActionTargetEnum.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/Definitions/Action/ActionTargetEnum.php Tamaño: 479 bytes -------------------------------------------------------------------------------- 1 | _LABEL = $LabelName; 25 | $this->_VALUE = $ValueName; 26 | $this->_DATETIMEFORMAT = $DateTime; 27 | } 28 | } -------------------------------------------------------------------------------- Total de líneas: 28 ================================================================================ ================================================================================ ARCHIVO #339: src/Widget/Definitions/AmChart/AmChartBarData.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/Definitions/AmChart/AmChartBarData.php Tamaño: 3.45 KB -------------------------------------------------------------------------------- 1 | _DATA = $Data; 39 | $this->_NodeChild = $ChildNode; 40 | $this->_AddData = $AddData; 41 | $this->GroupBy = $GroupBy; 42 | $this->GroupValue = $GroupValue; 43 | $this->DateFormat = $DateFormat; 44 | 45 | $this->_PRIMARYLABEL = $PrimaryDataName; 46 | $this->_PRIMARYVALUE = $PrimaryDataValue; 47 | 48 | if(!empty($GroupBy) AND !empty($GroupValue)): 49 | $this->Stacked_Data(); 50 | else: 51 | $this->Normal_Data(); 52 | endif; 53 | 54 | 55 | } 56 | 57 | 58 | 59 | private function Stacked_Data(){ 60 | 61 | } 62 | 63 | private function Normal_Data(){ 64 | $temporal_data = []; 65 | 66 | if(!empty($this->_DATA)): 67 | 68 | $PrimaryLabel = $this->_PRIMARYLABEL; 69 | $PrimaryValue = $this->_PRIMARYVALUE; 70 | 71 | 72 | foreach($this->_DATA as $item){ 73 | 74 | $temporal_array = [ 75 | $PrimaryLabel => $item->{$PrimaryLabel}, 76 | $PrimaryValue => $item->{$PrimaryValue}, 77 | 78 | ]; 79 | $subtemporal = []; 80 | //SI SE NECESITAN DATOS ADICIONALES SE AGREGAN 81 | if(!empty($this->_AddData)): 82 | foreach((object) $this->_AddData as $item_2){ 83 | $name = $item_2->LabelName ; 84 | $value = $item_2->ValueName ; 85 | 86 | $finalFormat =$item->{$value}; 87 | 88 | if($this->_DateFormat == $item_2->LabelName || $item_2->DateTime == true){ 89 | $y = (int) date("Y", strtotime($item->{$value})); 90 | $m = (int) date("m", strtotime($item->{$value})) -1; 91 | $d = (int) date("d", strtotime($item->{$value})); 92 | $h = (int) date("H", strtotime($item->{$value})); 93 | $i = (int) date("i", strtotime($item->{$value})); 94 | $finalFormat = "new Date($y, $m, $d,$h,$i)"; 95 | } 96 | 97 | $subtemporal = [ 98 | $name => $finalFormat, 99 | "Children" => 2 100 | ]; 101 | 102 | 103 | $temporal_array = array_merge($temporal_array,$subtemporal); 104 | 105 | } 106 | endif; 107 | 108 | $temporal_data[] = $temporal_array; 109 | } 110 | 111 | endif; 112 | 113 | $this->_DATA = $temporal_data; 114 | return $temporal_data; 115 | 116 | } 117 | 118 | } -------------------------------------------------------------------------------- Total de líneas: 118 ================================================================================ ================================================================================ ARCHIVO #340: src/Widget/Definitions/AmChart/AmChartColorEnum.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/Definitions/AmChart/AmChartColorEnum.php Tamaño: 508 bytes -------------------------------------------------------------------------------- 1 | _ScrollBarX = $ScrollBarX; 28 | $this->_ScrollBarY = $ScrollBarY; 29 | $this->_GraphCursor = $Cursor; 30 | } 31 | 32 | 33 | public function BuildAmChartControls($ChartKey,$ChartType){ 34 | 35 | $TemporalScript = ""; 36 | 37 | if( 38 | $this->_ScrollBarX AND 39 | $ChartType != AmChartTypeEnum::PIE_CHART AND 40 | $ChartType != AmChartTypeEnum::PIE_DRILLDOWN AND 41 | $ChartType != AmChartTypeEnum::DONUTH_CHART 42 | ): 43 | $TemporalScript .= " $ChartKey.scrollbarX = new am4core.Scrollbar(); "; 44 | endif; 45 | 46 | if( 47 | $this->_ScrollBarY AND 48 | $ChartType != AmChartTypeEnum::PIE_CHART AND 49 | $ChartType != AmChartTypeEnum::PIE_DRILLDOWN AND 50 | $ChartType != AmChartTypeEnum::DONUTH_CHART 51 | ): 52 | $TemporalScript .= " $ChartKey.scrollbarY = new am4core.Scrollbar(); "; 53 | endif; 54 | 55 | if($this->_GraphCursor): 56 | switch($ChartType){ 57 | case AmChartTypeEnum::BAR_CHART: 58 | case AmChartTypeEnum::BAR_CHART_HORIZONTAL: 59 | $TemporalScript .= " $ChartKey.cursor = new am4charts.XYCursor(); "; 60 | break; 61 | case AmChartTypeEnum::LINE_CHART: 62 | $TemporalScript .= "$ChartKey.cursor = new am4charts.XYCursor(); $ChartKey.cursor.xAxis = dateAxis; $ChartKey.cursor.maxTooltipDistance = 20;"; 63 | break; 64 | } 65 | endif; 66 | 67 | return $TemporalScript; 68 | 69 | } 70 | } -------------------------------------------------------------------------------- Total de líneas: 70 ================================================================================ ================================================================================ ARCHIVO #342: src/Widget/Definitions/AmChart/AmChartGeneric.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/Definitions/AmChart/AmChartGeneric.php Tamaño: 1.11 KB -------------------------------------------------------------------------------- 1 | AddClasses($Classes); 26 | $this->AddStyles($Styles); 27 | $this->AddAttributes($Attributes); 28 | $this->AddAttribute('id', $Key); 29 | $this->AddProperties($Properties); 30 | 31 | parent::__construct(Replace: [ 32 | 'ATTRIBUTES' => $this->DrawAttributes(), 33 | 'PROPERTIES' => $this->DrawProperties(), 34 | 'CLASSES' => $this->DrawClasses(), 35 | 'STYLES' => $this->DrawStyles(), 36 | 'SCRIPT' => $script->Draw(false), 37 | ]); 38 | */ 39 | } 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | } 48 | 49 | -------------------------------------------------------------------------------- Total de líneas: 49 ================================================================================ ================================================================================ ARCHIVO #343: src/Widget/Definitions/AmChart/AmChartGenericToAmData.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/Definitions/AmChart/AmChartGenericToAmData.php Tamaño: 4.14 KB -------------------------------------------------------------------------------- 1 | _DATACOLOR = $DataColor; 51 | endif; 52 | 53 | $this->_DATALABEL = $DataLabel; 54 | $this->_DATAVALUE = $DataValue; 55 | $this->_DATAGROUP = $GroupBy; 56 | $this->_GROUPVALUE = $GroupValue; 57 | $this->_ESTADOCOMRPOMISO = $EstadoCompromiso; 58 | 59 | if($Type != null) { 60 | 61 | //SE USAN LOS OBJETOS NUEVOS PARA GENERAR LA DATA 62 | switch($Type){ 63 | case AmChartTypeEnum::LINE_CHART: 64 | case AmChartTypeEnum::BAR_CHART: 65 | case AmChartTypeEnum::BAR_CHART_HORIZONTAL: 66 | $this->_DATA = (new AmChartBarData( 67 | Data : $Datos, 68 | AddData : $AddData, 69 | PrimaryDataName: $DataLabel, 70 | PrimaryDataValue: $DataValue 71 | ))->_DATA; 72 | break; 73 | case AmChartTypeEnum::PIE_CHART: 74 | case AmChartTypeEnum::DONUTH_CHART: 75 | $this->_DATA = (new AmChartPieData( 76 | Data : $Datos, 77 | AddData : $AddData, 78 | PrimaryDataName: $DataLabel, 79 | PrimaryDataValue: $DataValue 80 | ))->_DATA; 81 | break; 82 | } 83 | }; 84 | 85 | return $DataLabel; 86 | } 87 | 88 | 89 | private function FormatData($Datos){ 90 | 91 | $TemporalObject = []; 92 | 93 | $Label = $this->_DATALABEL; 94 | $Value = $this->_DATAVALUE; 95 | $Color = $this->_DATACOLOR; 96 | 97 | foreach($Datos as $item){ 98 | 99 | $TemporalItem = [ 100 | $Label => $item->{$Label}, 101 | $Value => $item->{$Value}, 102 | "Color" => $item->{$Color} 103 | ]; 104 | $TemporalObject[] = $TemporalItem; 105 | } 106 | 107 | $this->_DATA = $TemporalObject; 108 | } 109 | 110 | private function ReturnGroupedArray($Datos){ 111 | 112 | $TemporalFilter = []; 113 | 114 | $Label = $this->_DATALABEL; 115 | $Value = $this->_DATAVALUE; 116 | $Color = $this->_DATACOLOR; 117 | 118 | $GroupBy = $this->_DATAGROUP; 119 | 120 | foreach($Datos as $item){ 121 | 122 | $Filter = $item->{$GroupBy}; 123 | 124 | if(key_exists($Filter,$TemporalFilter)): 125 | $TemporalFilter[$Filter][] = $item; 126 | else: 127 | $TemporalFilter[$Filter][] = $item; 128 | endif; 129 | } 130 | 131 | 132 | return $TemporalFilter; 133 | 134 | } 135 | 136 | 137 | 138 | } -------------------------------------------------------------------------------- Total de líneas: 138 ================================================================================ ================================================================================ ARCHIVO #344: src/Widget/Definitions/AmChart/AmChartLegend.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/Definitions/AmChart/AmChartLegend.php Tamaño: 3.69 KB -------------------------------------------------------------------------------- 1 | _MaxHeight = $MaxHeight; 43 | $this->_MaxWidth = $MaxWidth; 44 | $this->_Scroll = $Scroll; 45 | $this->_Icon = $Icon; 46 | $this->_Height = $Height; 47 | $this->_Width = $Width; 48 | $this->_Position = $Position; 49 | $this->_Align = $Align; 50 | 51 | //CONSTRUCCIÓN DEL OBJETO 52 | 53 | 54 | 55 | 56 | } 57 | 58 | 59 | public function Build_Legend($ChartKey){ 60 | //SE GENERA UNA LEGENDA POR DEFECTO 61 | $TemporalLabel = " chart_$ChartKey.legend = new am4charts.Legend(); "; 62 | 63 | //DEFINE LA POSICIÓN DE LA LEGENDA 64 | $TemporalLabel .= 65 | " 66 | 67 | chart_$ChartKey.legend.position = '". strtolower($this->_Position) ."'; 68 | chart_$ChartKey.legend.contentAlign = '". strtolower($this->_Align). "'; 69 | chart_$ChartKey.legend.valueLabels.template.align = 'left'; 70 | chart_$ChartKey.legend.valueLabels.template.textAlign = 'end'; 71 | 72 | "; 73 | 74 | //SE DEFINE LA ALTURA DEL CONTENEDOR DE LA LEGENDA 75 | if($this->MaxHeight != 0): 76 | $TemporalLabel .= 77 | " chart_$ChartKey.legend.maxHeight = $this->MaxHeight ; "; 78 | endif; 79 | 80 | //SE DEFINE EL ANCHO DEL CONTENEDOR DE LA LEGENDA 81 | if($this->_MaxWidth != 0): 82 | $TemporalLabel .= 83 | " chart_$ChartKey.legend.maxWidth = $this->_MaxWidth ; "; 84 | endif; 85 | 86 | //APLICA UN PARAMETRO DE OVERFLOW AL CONTENEDOR DE LA LEGENDA 87 | if($this->_Scroll == true): 88 | $TemporalLabel .= 89 | " chart_$ChartKey.legend.scrollable = true; "; 90 | endif; 91 | 92 | //SI ES FALSE, SE OCULTA EL ICONO DE LA LEGENDA 93 | if($this->Icon != true): 94 | $TemporalLabel .= 95 | " chart_$ChartKey.legend.markers.template.disabled = true ; "; 96 | endif; 97 | 98 | //DEFINE EL ALTO DEL ICONO DE LA LEGENDA 99 | if(!empty($this->_Height)): 100 | $TemporalLabel .= 101 | " chart_$ChartKey.legend.markers.template.height = '$this->_Height' ; "; 102 | endif; 103 | 104 | // DEFINE EL ANCHO DEL ICONO DE LA LEGENDA 105 | if(!empty($this->_Width)): 106 | $TemporalLabel .= 107 | " chart_$ChartKey.legend.markers.template.width = '$this->_Width' ; "; 108 | endif; 109 | 110 | $this->_SCRIPT = $TemporalLabel; 111 | 112 | } 113 | } -------------------------------------------------------------------------------- Total de líneas: 113 ================================================================================ ================================================================================ ARCHIVO #345: src/Widget/Definitions/AmChart/AmChartPieData.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/Definitions/AmChart/AmChartPieData.php Tamaño: 2.60 KB -------------------------------------------------------------------------------- 1 | _DATA = $Data; 37 | $this->_NodeChild = $ChildNode; 38 | $this->_AddData = $AddData; 39 | $this->GroupBy = $GroupBy; 40 | $this->GroupValue = $GroupValue; 41 | 42 | $this->_PRIMARYLABEL = $PrimaryDataName; 43 | $this->_PRIMARYVALUE = $PrimaryDataValue; 44 | 45 | if(!empty($GroupBy) AND !empty($GroupValue)): 46 | $this->Stacked_Data(); 47 | else: 48 | $this->Normal_Data(); 49 | endif; 50 | 51 | 52 | } 53 | 54 | 55 | 56 | private function Stacked_Data(){ 57 | 58 | } 59 | 60 | private function Normal_Data(){ 61 | $temporal_data = []; 62 | 63 | if(!empty($this->_DATA)): 64 | 65 | $PrimaryLabel = $this->_PRIMARYLABEL; 66 | $PrimaryValue = $this->_PRIMARYVALUE; 67 | 68 | 69 | foreach($this->_DATA as $item){ 70 | 71 | $temporal_array = [ 72 | $PrimaryLabel => $item->{$PrimaryLabel}, 73 | $PrimaryValue => $item->{$PrimaryValue}, 74 | 75 | ]; 76 | $subtemporal = []; 77 | //SI SE NECESITAN DATOS ADICIONALES SE AGREGAN 78 | if(!empty($this->_AddData)): 79 | foreach((object) $this->_AddData as $item_2){ 80 | $name = $item_2->LabelName ; 81 | $value = $item_2->ValueName ; 82 | $subtemporal = [ 83 | $name=> $item->{$value} 84 | ]; 85 | 86 | $temporal_array = array_merge($temporal_array,$subtemporal); 87 | 88 | } 89 | endif; 90 | 91 | $temporal_data[] = $temporal_array; 92 | } 93 | 94 | endif; 95 | 96 | $this->_DATA = $temporal_data; 97 | return $temporal_data; 98 | 99 | } 100 | 101 | } -------------------------------------------------------------------------------- Total de líneas: 101 ================================================================================ ================================================================================ ARCHIVO #346: src/Widget/Definitions/AmChart/AmChartSeries.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/Definitions/AmChart/AmChartSeries.php Tamaño: 1.16 KB -------------------------------------------------------------------------------- 1 | 1, 33 | "StartAngle" => "-90", 34 | "EndAngle" => "-90", 35 | ] 36 | ) 37 | { 38 | 39 | $DataLabeKeyName = $DataLabel; 40 | 41 | 42 | } 43 | } -------------------------------------------------------------------------------- Total de líneas: 43 ================================================================================ ================================================================================ ARCHIVO #347: src/Widget/Definitions/AmChart/AmChartTypeEnum.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/Definitions/AmChart/AmChartTypeEnum.php Tamaño: 1007 bytes -------------------------------------------------------------------------------- 1 | $Key, 33 | 'PROPERTYNAME' => $PropertyName, 34 | 'ROTATION' => $rotate, 35 | 'ROOTKEY' => function() { return $this->RootKey; }, // debe ser funcion, para que evalúe el valor al momento de dibujarse y no en el constructor 36 | 'CHARTKEY' => function() { return $this->ChartKey; }, 37 | ] 38 | ); 39 | } 40 | } -------------------------------------------------------------------------------- Total de líneas: 40 ================================================================================ ================================================================================ ARCHIVO #350: src/Widget/Definitions/AmChart5/Axis/RoundedRectangleTitle.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/Definitions/AmChart5/Axis/RoundedRectangleTitle.php Tamaño: 2.20 KB -------------------------------------------------------------------------------- 1 | BorderColor = $FontColor; 37 | } 38 | 39 | parent::__construct( 40 | Text: $Text, 41 | Rotation: $Rotation, 42 | TextAlign: $TextAlign, 43 | FontSize: $FontSize, 44 | FontColor: $FontColor, 45 | Y: $Y, 46 | X: $X, 47 | CenterY: $CenterY, 48 | CenterX: $CenterX, 49 | FontWeight: $FontWeight, 50 | ); 51 | } 52 | 53 | public function Render() { 54 | 55 | $content = parent::RenderContent(); 56 | 57 | $content .= ",\n\t\t\t\t background: am5.RoundedRectangle.new([[ROOTKEY]], { 58 | cornerRadiusBL : " . $this->Radius . ", 59 | cornerRadiusBR : " . $this->Radius . ", 60 | cornerRadiusTL : " . $this->Radius . ", 61 | cornerRadiusTR : " . $this->Radius . ", 62 | stroke : '" . $this->BorderColor . "', 63 | fill : '" . $this->BackgroundColor . "', 64 | fillOpacity : 0 65 | }),\n"; 66 | 67 | return parent::RenderDefinition($content); 68 | } 69 | 70 | } -------------------------------------------------------------------------------- Total de líneas: 70 ================================================================================ ================================================================================ ARCHIVO #351: src/Widget/Definitions/AmChart5/Axis/Title.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/Definitions/AmChart5/Axis/Title.php Tamaño: 3.29 KB -------------------------------------------------------------------------------- 1 | RenderContent(); 88 | return $this->RenderDefinition($content); 89 | } 90 | 91 | protected function RenderContent() { 92 | 93 | $content = "\t\t\t\t text: '" . $this->Text . "',\n"; 94 | 95 | // Y 96 | $content .= $this->_($this->Y, "\t\t\t\t y: [[VAL]],\n"); 97 | 98 | // X 99 | $content .= $this->_($this->X, "\t\t\t\t x: [[VAL]],\n"); 100 | 101 | // CenterX 102 | $content .= $this->_($this->CenterX, "\t\t\t\t centerX: [[VAL]],\n"); 103 | 104 | // CenterY 105 | $content .= $this->_($this->CenterY, "\t\t\t\t centerY: [[VAL]],\n"); 106 | 107 | $content .= "\t\t\t\t rotation: " . $this->Rotation . ",\n"; 108 | 109 | if (isset($this->FontSize) && $this->FontSize > 0) { 110 | $content .= "\t\t\t\t fontSize: '" . $this->FontSize . "px',\n"; 111 | } 112 | 113 | if (isset($this->FontColor) && $this->FontColor != '') { 114 | $content .= "\t\t\t\t fill: '" . $this->FontColor . "',\n"; 115 | } 116 | 117 | $content .= "\t\t\t\t fontWeight: '" . $this->FontWeight . "'"; 118 | 119 | return $content; 120 | } 121 | 122 | } -------------------------------------------------------------------------------- Total de líneas: 122 ================================================================================ ================================================================================ ARCHIVO #352: src/Widget/Definitions/AmChart5/Axis/ValueAxis.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/Definitions/AmChart5/Axis/ValueAxis.php Tamaño: 1.83 KB -------------------------------------------------------------------------------- 1 | Render(); 37 | $axisTitle = str_replace('[[KEY]]', $Key, $axisTitle); 38 | } 39 | 40 | parent::__construct( 41 | Key : $Key, 42 | Replace: [ 43 | 'KEY' => $Key, 44 | 'RENDEROPTIONS' => $options, 45 | 'TITLE' => ((isset($axisTitle) && $axisTitle != '') ? $axisTitle : ''), 46 | 'ROOTKEY' => function() { return $this->RootKey; }, // debe ser funcion, para que evalúe el valor al momento de dibujarse y no en el constructor 47 | 'CHARTKEY' => function() { return $this->ChartKey; }, 48 | 'MIN' => ((isset($Min)) ? 'min: ' . $Min . "\n," : ''), 49 | 'MAX' => ((isset($Max)) ? 'max: ' . $Max . "\n" : ''), 50 | 'STRICTMINMAX' => ((isset($StrictMin)) ? ('strictMinMax: ' . ( $StrictMin ? 'true,' : 'false,') ) : ''), 51 | ] 52 | ); 53 | } 54 | } -------------------------------------------------------------------------------- Total de líneas: 54 ================================================================================ ================================================================================ ARCHIVO #353: src/Widget/Definitions/AmChart5/Axis/XAxis.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/Definitions/AmChart5/Axis/XAxis.php Tamaño: 557 bytes -------------------------------------------------------------------------------- 1 | Key = $Key; 24 | parent::__construct(Replace: $Replace); 25 | } 26 | 27 | public function BuildOptionList(array $Options, int $Tabs = 0, bool $UseBraces = false) { 28 | 29 | $resultTabs = ""; 30 | if ($UseBraces) { 31 | $optionTabs = str_repeat("\t", $Tabs + 1); 32 | $resultTabs = str_repeat("\t", $Tabs); 33 | } 34 | else { 35 | $optionTabs = str_repeat("\t", $Tabs); 36 | } 37 | 38 | $result = ""; 39 | foreach($Options as $option) { 40 | if ($option != '') { 41 | $option .= ",\n"; 42 | } 43 | $result .= $optionTabs . $option; 44 | } 45 | 46 | if ($UseBraces) { 47 | $result .= $resultTabs . "{\n" . $result . "\n" . $resultTabs . "}\n"; 48 | } 49 | 50 | return $result; 51 | } 52 | 53 | public function BuildOption(string $Option, $Value) : string { 54 | 55 | $optionValue = ""; 56 | 57 | if (is_bool($Value)) 58 | $optionValue = ($Value) ? "true" : "false"; 59 | elseif (is_numeric($Value)) 60 | $optionValue = $Value; 61 | else 62 | $optionValue = '"' . $Value . '"'; 63 | 64 | return $Option . ": " . $optionValue; 65 | } 66 | 67 | public function AddOption(array $OptionSet, string $Option, $Value) { 68 | 69 | if (isset($Value)) { 70 | $OptionSet[] = $this->BuildOption(Option: $Option, Value: $Value); 71 | } 72 | 73 | return $OptionSet; 74 | } 75 | 76 | public function Draw($echoResult = true): string { 77 | 78 | $this->AddReplace(Search: 'ROOTKEY', Replacement: $this->RootKey); 79 | return parent::Draw($echoResult); 80 | 81 | } 82 | } -------------------------------------------------------------------------------- Total de líneas: 82 ================================================================================ ================================================================================ ARCHIVO #355: src/Widget/Definitions/AmChart5/Chart/Chart.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/Definitions/AmChart5/Chart/Chart.php Tamaño: 1.24 KB -------------------------------------------------------------------------------- 1 | Data = new DataCollection( 34 | DataItems : $Data, 35 | Category : $Category, 36 | ); 37 | 38 | parent::__construct( 39 | Key : $Key, 40 | Replace : $Replace, 41 | ); 42 | 43 | } 44 | 45 | } -------------------------------------------------------------------------------- Total de líneas: 45 ================================================================================ ================================================================================ ARCHIVO #356: src/Widget/Definitions/AmChart5/Chart/ChartOrientationEnum.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/Definitions/AmChart5/Chart/ChartOrientationEnum.php Tamaño: 393 bytes -------------------------------------------------------------------------------- 1 | XAxis->RootKey = $this->RootKey; 28 | $this->XAxis->ChartKey = $this->Key; 29 | 30 | // YAxes 31 | // 32 | foreach($this->YAxis as $item) { 33 | // Asignar el RootKey 34 | $item->RootKey = $this->RootKey; 35 | $item->ChartKey = $this->Key; 36 | } 37 | 38 | // Series 39 | // 40 | foreach($this->Series as $serie) { 41 | $serie->RootKey = $this->RootKey; 42 | $serie->ChartKey = $this->Key; 43 | } 44 | 45 | parent::OnBeforeDraw(); 46 | } 47 | 48 | public function __construct( 49 | string $Key, 50 | public XAxis $XAxis, 51 | public array $YAxis, 52 | public array $Series, 53 | ?array $Data = null, 54 | ?bool $ShowLegend = null, 55 | ?bool $Vertical = true 56 | ) { 57 | // Verificar YAxis 58 | foreach($YAxis as $item) { 59 | if (!($item instanceof Axis)) { 60 | throw new \Exception("Un elemento de los ejes Y no es una instancia de Axis o sus clases derivadas"); 61 | } 62 | } 63 | 64 | // Verificar Series 65 | // Series 66 | foreach($Series as $serie) { 67 | if (!($serie instanceof Series)) { 68 | throw new \Exception("Un elemento de las series no es una instancia de Series o sus clases derivadas"); 69 | } 70 | } 71 | 72 | $dataset = ""; 73 | $dataset .= "\t\t\t\txAxis_" . $XAxis->Key . ".data.setAll([[ROOTKEY]]_data);\n"; 74 | 75 | // foreach ($YAxis as $item) { 76 | // $dataset .= "\t\t\t\tyAxis_" . $item->Key . ".data.setAll([[ROOTKEY]]_data);\n"; 77 | // } 78 | 79 | foreach ($Series as $child) { 80 | $dataset .= "\t\t\t\t[[ROOTKEY]]_series_" . $child->Key . ".data.setAll([[ROOTKEY]]_data);\n"; 81 | $dataset .= "\t\t\t\t[[ROOTKEY]]_series_" . $child->Key . ".appear(1000);\n"; 82 | $dataset .= "\t\t\t\tchart_" . $Key . ".appear(1000, 100);\n"; 83 | } 84 | 85 | $legend = ''; 86 | if (isset($ShowLegend) && $ShowLegend) { 87 | $legend = "\t\t\t\tvar legend_$Key = chart_$Key.children.unshift(am5.Legend.new([[ROOTKEY]], { 88 | layout: [[ROOTKEY]].horizontalLayout, 89 | y: am5.percent(100), 90 | x: am5.percent(50), 91 | centerX: am5.percent(50), 92 | marginTop: 10, 93 | marginBottom: 10, 94 | paddingTop: 20 95 | }));\n"; 96 | } 97 | 98 | $CategoryAxis = ($Vertical) ? $XAxis : $YAxis; 99 | $ValueAxis = (!$Vertical) ? $XAxis : $YAxis; 100 | 101 | 102 | parent::__construct( 103 | Key : $Key, 104 | Category : $XAxis->PropertyName, 105 | Replace : [ 106 | 'LEGEND' => $legend, 107 | 'KEY' => $Key, 108 | 'XAXIS' => $CategoryAxis, 109 | 'YAXIS' => $ValueAxis, 110 | 'SERIES' => $Series, 111 | 'DATACOLLECTION' => function () { return $this->Data; }, 112 | 'DATASET' => $dataset, 113 | 'ROOTKEY' => function () { return $this->RootKey; }, 114 | ], 115 | Data: $Data 116 | ); 117 | } 118 | 119 | } -------------------------------------------------------------------------------- Total de líneas: 119 ================================================================================ ================================================================================ ARCHIVO #358: src/Widget/Definitions/AmChart5/Chart/ChartXY2.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/Definitions/AmChart5/Chart/ChartXY2.php Tamaño: 3.93 KB -------------------------------------------------------------------------------- 1 | CategoryAxis->RootKey = $this->RootKey; 28 | $this->CategoryAxis->ChartKey = $this->Key; 29 | 30 | // Value Axes 31 | // 32 | foreach($this->ValueAxis as $item) { 33 | // Asignar el RootKey 34 | $item->RootKey = $this->RootKey; 35 | $item->ChartKey = $this->Key; 36 | } 37 | 38 | // Series 39 | // 40 | foreach($this->Series as $serie) { 41 | $serie->RootKey = $this->RootKey; 42 | $serie->ChartKey = $this->Key; 43 | } 44 | 45 | parent::OnBeforeDraw(); 46 | } 47 | 48 | public function __construct( 49 | string $Key, 50 | public Axis $CategoryAxis, 51 | public array $ValueAxes, 52 | public array $Series, 53 | ?array $Data = null, 54 | ?bool $ShowLegend = null, 55 | ChartOrientationEnum $Orientation = ChartOrientationEnum::VERTICAL 56 | ) { 57 | 58 | $legend = ''; 59 | if (isset($ShowLegend) && $ShowLegend) { 60 | $legend = "\t\t\t\tvar legend_$Key = chart_$Key.children.unshift(am5.Legend.new([[ROOTKEY]], { 61 | layout: [[ROOTKEY]].horizontalLayout, 62 | y: am5.percent(100), 63 | x: am5.percent(50), 64 | centerX: am5.percent(50), 65 | marginTop: 10, 66 | marginBottom: 10, 67 | paddingTop: 20 68 | }));\n"; 69 | } 70 | 71 | // Verificar Values Axis 72 | foreach($ValueAxes as $item) { 73 | if (!($item instanceof Axis)) { 74 | throw new \Exception("Un elemento de los ejes de valores no es una instancia de Axis o sus clases derivadas"); 75 | } 76 | } 77 | 78 | // Verificar Series 79 | // Series 80 | foreach($Series as $serie) { 81 | if (!($serie instanceof Series)) { 82 | throw new \Exception("Un elemento de las series no es una instancia de Series o sus clases derivadas"); 83 | } 84 | } 85 | 86 | $dataset = ""; 87 | $dataset .= "\t\t\t\txAxis_" . $CategoryAxis->Key . ".data.setAll([[ROOTKEY]]_data);\n"; 88 | 89 | // foreach ($ValueAxes as $item) { 90 | // $dataset .= "\t\t\t\tyAxis_" . $item->Key . ".data.setAll([[ROOTKEY]]_data);\n"; 91 | // } 92 | 93 | foreach ($Series as $child) { 94 | $dataset .= "\t\t\t\t[[ROOTKEY]]_series_" . $child->Key . ".data.setAll([[ROOTKEY]]_data);\n"; 95 | $dataset .= "\t\t\t\t[[ROOTKEY]]_series_" . $child->Key . ".appear(1000);\n"; 96 | $dataset .= "\t\t\t\tchart_" . $Key . ".appear(1000, 100);\n"; 97 | } 98 | 99 | parent::__construct( 100 | Key : $Key, 101 | Category : $CategoryAxis->PropertyName, 102 | Replace : [ 103 | 'LEGEND' => $legend, 104 | 'KEY' => $Key, 105 | 'XAXIS' => $CategoryAxis, 106 | 'YAXIS' => $ValueAxes, 107 | 'SERIES' => $Series, 108 | 'DATACOLLECTION' => function () { return $this->Data; }, 109 | 'DATASET' => $dataset, 110 | 'ROOTKEY' => function () { return $this->RootKey; }, 111 | ], 112 | Data: $Data, 113 | Orientation : $Orientation 114 | ); 115 | } 116 | 117 | } -------------------------------------------------------------------------------- Total de líneas: 117 ================================================================================ ================================================================================ ARCHIVO #359: src/Widget/Definitions/AmChart5/Data/DataCollection.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/Definitions/AmChart5/Data/DataCollection.php Tamaño: 1.09 KB -------------------------------------------------------------------------------- 1 | Draw(false); 30 | } 31 | } 32 | 33 | parent::__construct( 34 | Replace: [ 35 | 'DATA' => $data, 36 | ] 37 | ); 38 | 39 | } 40 | 41 | } -------------------------------------------------------------------------------- Total de líneas: 41 ================================================================================ ================================================================================ ARCHIVO #360: src/Widget/Definitions/AmChart5/Data/DataItem.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/Definitions/AmChart5/Data/DataItem.php Tamaño: 1.27 KB -------------------------------------------------------------------------------- 1 | Value) && $item->PropertyName != $Category) { 34 | $value = $item->Value*1; 35 | } 36 | else { 37 | $value = '"' . $item->Value . '"'; 38 | } 39 | 40 | $result .= "\t\t\t\t\t " . $item->PropertyName . ': ' . $value; 41 | } 42 | 43 | $data = $result; 44 | 45 | parent::__construct( 46 | Replace: [ 47 | 'DATA' => $data, 48 | ] 49 | ); 50 | 51 | } 52 | 53 | } -------------------------------------------------------------------------------- Total de líneas: 53 ================================================================================ ================================================================================ ARCHIVO #361: src/Widget/Definitions/AmChart5/Data/DataItemDefinition.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/Definitions/AmChart5/Data/DataItemDefinition.php Tamaño: 844 bytes -------------------------------------------------------------------------------- 1 | Sum('Mujeres'); 30 | $totalHombres = $beneficiariosComuna->Sum('Hombres'); 31 | $totalNoEspecificado = $beneficiariosComuna->Sum('NoEspeficicado'); 32 | $totalIndigena = $beneficiariosComuna->Sum('Indigena'); 33 | $totalNoIndigena = $beneficiariosComuna->Sum('NoIndigena'); 34 | '#4cbad5', '#7c75d5', '#384b68', '#41c594', '#ff7512' 35 | */ -------------------------------------------------------------------------------- Total de líneas: 35 ================================================================================ ================================================================================ ARCHIVO #364: src/Widget/Definitions/AmChart5/Enum/VerticalAlignEnum.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/Definitions/AmChart5/Enum/VerticalAlignEnum.php Tamaño: 431 bytes -------------------------------------------------------------------------------- 1 | Charts as $chart) { 22 | // Asignar Rootkey 23 | $chart->RootKey = $this->Key; 24 | } 25 | } 26 | 27 | public function __construct( 28 | string $Key, 29 | public string $DivContainer, 30 | public array $Charts, // array of charts to include 31 | public ?string $Timezone = null, 32 | public ?int $FPS = null, 33 | public ?bool $UseSafeResolution = null, 34 | public ?bool $Animate = true, 35 | 36 | ) { 37 | // Validar Charts y asignar RootKey 38 | // 39 | foreach($Charts as $chart) { 40 | if (!($chart instanceof Chart)) { 41 | throw new \Exception("Uno de los elementos de la colección no es una instancia de -Chart-"); 42 | } 43 | } 44 | 45 | $this->RootKey = $Key; 46 | 47 | // configuraciones 48 | $rootConfiguration = []; 49 | 50 | // agregar configuraciones 51 | // TO-DO 52 | $rootConfiguration = $this->AddOption($rootConfiguration, 'useSafeResolution', $UseSafeResolution); 53 | 54 | $config = $this->BuildOptionList(Options: $rootConfiguration, Tabs: 6); 55 | 56 | $rootContent = "\t\t\t\t\t\"$DivContainer\""; 57 | 58 | if ($config != "") { 59 | $rootContent .= ", " . $config; 60 | } 61 | 62 | parent::__construct( 63 | Key : $Key, 64 | Replace : [ 65 | 'ROOTKEY' => $this->RootKey, 66 | 'ROOTCONFIGURATION' => $rootContent, 67 | 'SETTINGS' => '', 68 | 'USEANIMATION' => ($Animate) ? 'true' : 'false', 69 | 'CHARTS' => $Charts, 70 | ] 71 | ); 72 | } 73 | } -------------------------------------------------------------------------------- Total de líneas: 73 ================================================================================ ================================================================================ ARCHIVO #366: src/Widget/Definitions/AmChart5/Series/AxisDefinition.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/Definitions/AmChart5/Series/AxisDefinition.php Tamaño: 445 bytes -------------------------------------------------------------------------------- 1 | Stacked)) { 38 | $options = Concat::AddWithCommaLine($options, "\t\t\t\t\t\tstacked: " . ( $Definition->Stacked ? 'true' : 'false' )); 39 | } 40 | 41 | if (isset($Definition->LegendLabelText)) { 42 | $options = Concat::AddWithCommaLine($options, "\t\t\t\t\t\tlegendLabelText: \"" . $Definition->LegendLabelText . "\""); 43 | } 44 | 45 | if (isset($Definition->LegendRangeLabelText)) { 46 | $options = Concat::AddWithCommaLine($options, "\t\t\t\t\t\tlegendRangeLabelText: \"" . $Definition->LegendRangeLabelText. "\""); 47 | } 48 | 49 | // Fill Color 50 | if (isset($Definition->FillColor)) { 51 | $options = Concat::AddWithCommaLine($options, "\t\t\t\t\t\tfill: am5.color(\"" . $Definition->FillColor . "\")"); 52 | $needColor = false; 53 | } 54 | 55 | // Stroke Color 56 | if (isset($Definition->StrokeColor)) { 57 | $options = Concat::AddWithCommaLine($options, "\t\t\t\t\t\tstroke: am5.color(\"" . $Definition->StrokeColor . "\")"); 58 | $needColor = false; 59 | } 60 | 61 | // Fill Opacity 62 | if (isset($Definition->FillOpacity)) 63 | $template = Concat::AddWithCommaLine($template, "\t\t\t\t\tfillOpacity: " . $Definition->FillOpacity); 64 | 65 | // Stroke Width 66 | if (isset($Definition->StrokeWidth)) 67 | $template = Concat::AddWithCommaLine($template, "\t\t\t\t\tstrokeWidth: " . $Definition->StrokeWidth); 68 | 69 | // Corner Radius 70 | if (isset($Definition->TopLeftRadius)) 71 | $template = Concat::AddWithCommaLine($template, "\t\t\t\t\tcornerRadiusTL: " . $Definition->TopLeftRadius); 72 | if (isset($Definition->TopRightRadius)) 73 | $template = Concat::AddWithCommaLine($template, "\t\t\t\t\tcornerRadiusTR: " . $Definition->TopRightRadius); 74 | 75 | // Tooltip 76 | $template = Concat::AddWithCommaLine($template, "\t\t\t\t\ttooltipText: \"\${valueY}\""); 77 | 78 | if ($template == '') { 79 | 80 | $template = " 81 | [[ROOTKEY]]_series_" . $Key . ".columns.template.setAll({ 82 | cornerRadiusTL: 5, cornerRadiusTR: 5 83 | }); 84 | 85 | [[ROOTKEY]]_series_" . $Key . ".columns.template.adapters.add( 86 | \"fill\", 87 | function(fill, target) { 88 | return chart_[[CHARTKEY]].get(\"colors\").getIndex( 89 | [[ROOTKEY]]_series_" . $Key . ".columns.indexOf(target) 90 | ); 91 | } 92 | ); 93 | "; 94 | } 95 | else { 96 | 97 | 98 | $template = " 99 | [[ROOTKEY]]_series_" . $Key . ".columns.template.setAll({ 100 | " . $template . " 101 | }); 102 | "; 103 | 104 | if ($needColor) { 105 | $template .= " 106 | [[ROOTKEY]]_series_" . $Key . ".columns.template.adapters.add( 107 | \"fill\", 108 | function(fill, target) { 109 | return chart_[[CHARTKEY]].get(\"colors\").getIndex( 110 | [[ROOTKEY]]_series_" . $Key . ".columns.indexOf(target) 111 | ); 112 | } 113 | ); 114 | "; 115 | } 116 | 117 | } 118 | 119 | $bulletsVertical = " 120 | [[ROOTKEY]]_series_" . $Key . ".bullets.push(function () { 121 | return am5.Bullet.new([[ROOTKEY]], { 122 | locationX: 0.5, 123 | locationY: 1, 124 | sprite: am5.Label.new([[ROOTKEY]], { 125 | centerX: am5.p50, 126 | centerY: am5.p100, 127 | text: \"{valueY}\", 128 | populateText: true 129 | }) 130 | }); 131 | }); 132 | "; 133 | 134 | if ($Definition->ShowDataBullet) { 135 | $template .= $bulletsVertical; 136 | } 137 | 138 | } 139 | else if ($Definition instanceof LineSeriesDefinition) { 140 | if (isset($Definition->FillColor)) { 141 | $options = Concat::AddWithCommaLine($options, "\t\t\t\t\t\tfill: am5.color(\"" . $Definition->FillColor . "\")"); 142 | $needColor = false; 143 | } 144 | 145 | if (isset($Definition->LegendLabelText)) { 146 | $options = Concat::AddWithCommaLine($options, "\t\t\t\t\t\tlegendLabelText: \"" . $Definition->LegendLabelText. "\""); 147 | } 148 | 149 | if (isset($Definition->LegendRangeLabelText)) { 150 | $options = Concat::AddWithCommaLine($options, "\t\t\t\t\t\tlegendRangeLabelText: \"" . $Definition->LegendRangeLabelText. "\""); 151 | } 152 | 153 | // Stroke Color 154 | if (isset($Definition->StrokeColor)) { 155 | $options = Concat::AddWithCommaLine($options, "\t\t\t\t\t\tstroke: am5.color(\"" . $Definition->StrokeColor . "\")"); 156 | $needColor = false; 157 | } 158 | 159 | // Fill Opacity y Visible 160 | if (isset($Definition->FillOpacity)) 161 | $fillTemplate = Concat::AddWithCommaLine($fillTemplate, "\t\t\t\t\tfillOpacity: " . $Definition->FillOpacity); 162 | 163 | if (isset($Definition->Visible)) { 164 | $fillTemplate = Concat::AddWithCommaLine($fillTemplate, "\t\t\t\t\tvisible: " . ( $Definition->Visible ? 'true' : 'false' )); 165 | } 166 | 167 | // Stroke Width 168 | if (isset($Definition->StrokeWidth)) 169 | $strokeTemplate = Concat::AddWithCommaLine($strokeTemplate, "\t\t\t\t\tstrokeWidth: " . $Definition->StrokeWidth); 170 | 171 | // Stroke Dash 172 | if (isset($Definition->StrokeDash) && is_array($Definition->StrokeDash) && count($Definition->StrokeDash) == 2) { 173 | $strokeTemplate = Concat::AddWithCommaLine($strokeTemplate, "\t\t\t\t\tstrokeDasharray: [" . $Definition->StrokeDash[0] . "," . $Definition->StrokeDash[1] . "]"); 174 | } 175 | } 176 | else { 177 | throw new \Exception('La definicion de series debe ser Columna o Linea'); 178 | } 179 | 180 | if ($strokeTemplate != '') { 181 | $template .= " 182 | [[ROOTKEY]]_series_" . $Key . ".strokes.template.setAll({ 183 | $strokeTemplate 184 | }); 185 | "; 186 | } 187 | 188 | if ($fillTemplate != '') { 189 | $template .= " 190 | [[ROOTKEY]]_series_" . $Key . ".fills.template.setAll({ 191 | $fillTemplate 192 | }); 193 | "; 194 | } 195 | 196 | } 197 | 198 | if (isset($Definition->LegendLabelText)) { 199 | $template .= " 200 | legend_[[CHARTKEY]].data.push([[ROOTKEY]]_series_" . $Key ."); 201 | "; 202 | } 203 | 204 | parent::__construct( 205 | Key : $Key, 206 | Replace : [ 207 | 'KEY' => $Key, 208 | 'NAME' => $Key, 209 | 'SERIESTYPE' => $SeriesType, 210 | 'XAXIS' => $XAxis->AxisKey, 211 | 'XVALUEFIELD' => $XAxis->PropertyName, 212 | 'YAXIS' => $YAxis->AxisKey, 213 | 'YVALUEFIELD' => $YAxis->PropertyName, 214 | 'OPTIONS' => (($options != "") ? $options . ',' : ''), 215 | 'TOOLTIPLABEL' => $Definition->SeriesTooltipText, 216 | 'TEMPLATE' => $template, 217 | 'ROOTKEY' => function() { return $this->RootKey; }, // debe ser funcion, para que evalúe el valor al momento de dibujarse y no en el constructor 218 | 'CHARTKEY' => function() { return $this->ChartKey; }, 219 | ] 220 | ); 221 | 222 | } 223 | 224 | } -------------------------------------------------------------------------------- Total de líneas: 224 ================================================================================ ================================================================================ ARCHIVO #372: src/Widget/Definitions/AmChart5/Series/SeriesDefinition.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/Definitions/AmChart5/Series/SeriesDefinition.php Tamaño: 888 bytes -------------------------------------------------------------------------------- 1 | $this->Key, 33 | 'GRAF_TITULO' => $this->Titulo, 34 | 'GRAF_TIPO' => $this->Tipo, 35 | 'LEGEND_BORDERWIDTH' => $this->Borderwidth, 36 | 'LABEL_PROGRAMADO' => $this->lblProgramado, 37 | 'GRAF_BACKGROUNDCOLOR' => $this->BackgroundColor, 38 | 'GRAF_FONTCOLOR' => $this->FontColor, 39 | 'LEGEND_BACKGROUNDCOLOR' => $this->LegendBackgroundColor, 40 | 'GRAF_RULES' => (isset($this->Series)) ? $this->Series->GetRules() : '', 41 | 'SCALEX_LABELS' => (isset($this->Series)) ? $this->Series->GetLabels() : '', 42 | 'SCALEY_SERIES' => (isset($this->Series)) ? $this->Series->GetSeries() : '', 43 | ] 44 | ); 45 | 46 | 47 | } 48 | } -------------------------------------------------------------------------------- Total de líneas: 48 ================================================================================ ================================================================================ ARCHIVO #396: src/Widget/Definitions/ZingChart/ZLabel.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/Definitions/ZingChart/ZLabel.php Tamaño: 443 bytes -------------------------------------------------------------------------------- 1 | _Serie; 19 | } 20 | 21 | public function __construct( 22 | public string $Name, 23 | public array $Values 24 | ) 25 | { 26 | $serie = "\t\t{\n"; 27 | $serie .= "\t\t\ttext: '" . $this->Name . "',\n"; 28 | $serie .= "\t\t\tvalues: [" . implode(',', $Values) . "]\n"; 29 | $serie .= "\t\t}\n"; 30 | 31 | $this->_Serie = $serie; 32 | } 33 | } -------------------------------------------------------------------------------- Total de líneas: 33 ================================================================================ ================================================================================ ARCHIVO #398: src/Widget/Definitions/ZingChart/ZSeries.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/Definitions/ZingChart/ZSeries.php Tamaño: 1.88 KB -------------------------------------------------------------------------------- 1 | _Rules; 21 | } 22 | 23 | public function GetLabels() : string { 24 | return $this->_Labels; 25 | } 26 | 27 | public function GetSeries() : string { 28 | return $this->_Series; 29 | } 30 | 31 | public function __construct( 32 | public array $Series, 33 | public array $Labels, 34 | ) 35 | { 36 | // Revisar los colores 37 | $rules = "\t\t[\n"; 38 | $labels = "\t\t[\n"; 39 | $lblItems = ""; 40 | 41 | $idrule = 0; 42 | foreach ($Labels as $lbl) { 43 | 44 | if (isset($lbl->BackgroundColor)) { 45 | 46 | $rules .= "\t\t{\n"; 47 | $rules .= "\t\t\tbackgroundColor: '" . $lbl->BackgroundColor . "',\n"; 48 | $rules .= "\t\t\trule: '%i==" . $idrule . "'\n"; 49 | $rules .= "\t\t\n}"; 50 | 51 | $idrule++; 52 | } 53 | 54 | if ($lblItems != "") { 55 | $lblItems .= ", "; 56 | } 57 | else { 58 | $lblItems = "\t\t\t"; 59 | } 60 | $lblItems .= "'" . $lbl->Text . "'"; 61 | } 62 | 63 | $rules .= "\t\t],\n"; 64 | $labels .= $lblItems . "\n\t\t]\n"; 65 | 66 | /* 67 | series: [ 68 | { 69 | values: [23, 18, 3, 20, 24], 70 | }, 71 | ] 72 | */ 73 | 74 | $series = "\tseries: [\n"; 75 | 76 | foreach($Series as $serie) { 77 | $series .= $serie->GetSerie(); 78 | } 79 | 80 | $series .= "\t]\n"; 81 | 82 | $this->_Rules = $rules; 83 | $this->_Labels = $labels; 84 | $this->_Series = $series; 85 | } 86 | } -------------------------------------------------------------------------------- Total de líneas: 86 ================================================================================ ================================================================================ ARCHIVO #399: src/Widget/ExcelInput.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/ExcelInput.php Tamaño: 1.49 KB -------------------------------------------------------------------------------- 1 | AddClasses($Classes); 30 | 31 | // Styles 32 | $this->AddStyles($Styles); 33 | 34 | // Attributes 35 | $this->AddAttributes($Attributes); 36 | $this->AddAttributes([ 37 | ['id', $Key], 38 | ['type', 'file'], 39 | ['name', $Key . (($Multiple) ? '[]' : '')] 40 | ]); 41 | 42 | // Properties 43 | $this->AddProperties($this->Properties); 44 | $this->AddProperty('disabled', $Disabled); 45 | 46 | if ($Multiple) 47 | $this->AddProperty('multiple', true); 48 | 49 | parent::__construct(Replace: [ 50 | 'ATTRIBUTES' => $this->DrawAttributes(), 51 | 'PROPERTIES' => $this->DrawProperties(), 52 | 'CLASSES' => $this->DrawClasses(), 53 | 'STYLES' => $this->DrawStyles() 54 | ]); 55 | } 56 | } -------------------------------------------------------------------------------- Total de líneas: 56 ================================================================================ ================================================================================ ARCHIVO #400: src/Widget/FaIcon.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/FaIcon.php Tamaño: 1.25 KB -------------------------------------------------------------------------------- 1 | AddClasses($this->Classes); 29 | $this->AddClass($this->BaseClass); 30 | $this->AddClass($this->Name); 31 | 32 | // Styles 33 | $this->AddStyles($this->Styles); 34 | 35 | // Attributes 36 | $this->AddAttributes($this->Attributes); 37 | 38 | // Properties 39 | $this->AddProperties($this->Properties); 40 | 41 | parent::__construct(Replace: [ 42 | 'CLASSES' => $this->DrawClasses(), 43 | 'STYLES' => $this->DrawStyles(), 44 | 'ATTRIBUTES' => $this->DrawAttributes(), 45 | 'PROPERTIES' => $this->DrawProperties() 46 | ]); 47 | } 48 | } -------------------------------------------------------------------------------- Total de líneas: 48 ================================================================================ ================================================================================ ARCHIVO #401: src/Widget/FaIconText.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/FaIconText.php Tamaño: 1.92 KB -------------------------------------------------------------------------------- 1 | AddClasses($Classes); 33 | $this->AddClass('fa'); 34 | $this->AddClass($Name); 35 | 36 | $this->AddClasses($TextClasses, 'text'); 37 | 38 | // Styles 39 | $this->AddStyles($Styles); 40 | $this->AddStyle('margin-right', '8px'); 41 | $this->AddStyles($Styles, 'text'); 42 | 43 | // Attributes 44 | $this->AddAttributes($Attributes); 45 | $this->AddAttributes($TextAttributes, 'text'); 46 | 47 | // Properties 48 | $this->AddProperties($Properties); 49 | $this->AddProperties($TextProperties, 'text'); 50 | 51 | parent::__construct(Replace: [ 52 | 'CLASSES' => $this->DrawClasses(), 53 | 'STYLES' => $this->DrawStyles(), 54 | 'ATTRIBUTES' => $this->DrawAttributes(), 55 | 'PROPERTIES' => $this->DrawProperties(), 56 | 'TEXTCLASSES' => $this->DrawClasses('text'), 57 | 'TEXTSTYLES' => $this->DrawStyles('text'), 58 | 'TEXTATTRIBUTES' => $this->DrawAttributes('text'), 59 | 'TEXTPROPERTIES' => $this->DrawProperties('text'), 60 | 'TEXT' => $Text 61 | ]); 62 | } 63 | } -------------------------------------------------------------------------------- Total de líneas: 63 ================================================================================ ================================================================================ ARCHIVO #402: src/Widget/FileInput.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/FileInput.php Tamaño: 1.48 KB -------------------------------------------------------------------------------- 1 | AddClasses($Classes); 30 | 31 | // Styles 32 | $this->AddStyles($Styles); 33 | 34 | // Attributes 35 | $this->AddAttributes($Attributes); 36 | $this->AddAttributes([ 37 | ['id', $Key], 38 | ['type', 'file'], 39 | ['name', $Key . (($Multiple) ? '[]' : '')] 40 | ]); 41 | 42 | // Properties 43 | $this->AddProperties($this->Properties); 44 | $this->AddProperty('disabled', $Disabled); 45 | 46 | if ($Multiple) 47 | $this->AddProperty('multiple', true); 48 | 49 | parent::__construct(Replace: [ 50 | 'ATTRIBUTES' => $this->DrawAttributes(), 51 | 'PROPERTIES' => $this->DrawProperties(), 52 | 'CLASSES' => $this->DrawClasses(), 53 | 'STYLES' => $this->DrawStyles() 54 | ]); 55 | } 56 | } -------------------------------------------------------------------------------- Total de líneas: 56 ================================================================================ ================================================================================ ARCHIVO #403: src/Widget/FlexGroup.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/FlexGroup.php Tamaño: 1.92 KB -------------------------------------------------------------------------------- 1 | AddClasses($Classes); 32 | 33 | // Styles 34 | $this->AddStyles($Styles); 35 | $this->AddStyle('display', 'flex'); 36 | 37 | if ($Wrap) { 38 | $this->AddStyles([ 39 | ['-webkit-flex-wrap','wrap'], 40 | ['flex-wrap','wrap'] 41 | ]); 42 | } 43 | 44 | // Attributes 45 | $this->AddAttributes($Attributes); 46 | 47 | if ($Key != '') { 48 | $this->AddAttribute('id', $this->Key); 49 | } 50 | 51 | // Properties 52 | $this->AddProperties($Properties); 53 | 54 | $items = ''; 55 | foreach($Children as $child) { 56 | if ($child instanceof FlexItem) { 57 | if ($items != '') { 58 | $items .= "\n"; 59 | } 60 | $items .= $child->Draw(false); 61 | } 62 | } 63 | 64 | parent::__construct(Replace: [ 65 | 'ITEMS' => $items, 66 | 'CLASSES' => $this->DrawClasses(), 67 | 'STYLES' => $this->DrawStyles(), 68 | 'ATTRIBUTES' => $this->DrawAttributes(), 69 | 'PROPERTIES' => $this->DrawProperties() 70 | ]); 71 | } 72 | } -------------------------------------------------------------------------------- Total de líneas: 72 ================================================================================ ================================================================================ ARCHIVO #404: src/Widget/FlexItem.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/FlexItem.php Tamaño: 1.60 KB -------------------------------------------------------------------------------- 1 | AddClasses($Classes); 32 | 33 | // Styles 34 | $this->AddStyles($Styles); 35 | 36 | // Attributes 37 | $this->AddAttributes($Attributes); 38 | 39 | if ($Key != '') { 40 | $this->AddAttribute('id', $this->Key); 41 | } 42 | 43 | if (isset($Grow)) { 44 | $this->AddStyle('flex-grow', $Grow); 45 | } 46 | 47 | // Properties 48 | $this->AddProperties($Properties); 49 | 50 | parent::__construct(Replace: [ 51 | 'ITEMS' => $Child->Draw(false), 52 | 'CLASSES' => $this->DrawClasses(), 53 | 'STYLES' => $this->DrawStyles(), 54 | 'ATTRIBUTES' => $this->DrawAttributes(), 55 | 'PROPERTIES' => $this->DrawProperties() 56 | ]); 57 | } 58 | } -------------------------------------------------------------------------------- Total de líneas: 58 ================================================================================ ================================================================================ ARCHIVO #405: src/Widget/Form.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/Form.php Tamaño: 1.89 KB -------------------------------------------------------------------------------- 1 | AddClasses($Classes); 33 | 34 | // Styles 35 | $this->AddStyles($Styles); 36 | 37 | // Attributes 38 | $this->AddAttributes($Attributes); 39 | $this->AddAttributes( 40 | [ 41 | ['id', $this->Key], 42 | ['method', $this->Method], 43 | ['enctype', $this->EncriptionType] 44 | ]); 45 | 46 | // Properties 47 | $this->AddProperties($Properties); 48 | 49 | $builder = ""; 50 | foreach ($FormGroups as $child) { 51 | if ($child instanceof FormGroup) { 52 | if ($builder != "") { 53 | $builder = $builder . "\n"; 54 | } 55 | $builder .= $child->Draw(false); 56 | } 57 | } 58 | 59 | parent::__construct(Replace: [ 60 | 'GROUPS' => $builder, 61 | 'CLASSES' => $this->DrawClasses(), 62 | 'STYLES' => $this->DrawStyles(), 63 | 'ATTRIBUTES' => $this->DrawAttributes(), 64 | 'PROPERTIES' => $this->DrawProperties() 65 | ]); 66 | } 67 | } -------------------------------------------------------------------------------- Total de líneas: 67 ================================================================================ ================================================================================ ARCHIVO #406: src/Widget/FormGroup.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/FormGroup.php Tamaño: 1.82 KB -------------------------------------------------------------------------------- 1 | AddClasses($Classes); 30 | $this->AddClass('form-group'); 31 | 32 | // Styles 33 | $this->AddStyles($Styles); 34 | 35 | // Attributes 36 | $this->AddAttributes($Attributes); 37 | $this->AddAttribute('id', $this->Key); 38 | 39 | // Properties 40 | $this->AddProperties($Properties); 41 | 42 | // Agregamos las filas 43 | $first = true; 44 | $formGroupRows = ''; 45 | 46 | if (isset($Rows)) { 47 | foreach($Rows as $row) { 48 | if ($row instanceof FormGroupRow) { 49 | $row->First = $first; 50 | $first = false; 51 | 52 | $formGroupRows .= $row->Draw(false); 53 | } 54 | else if ($row instanceof FormGroupSeparator) { 55 | $formGroupRows .= $row->Draw(false); 56 | } 57 | } 58 | } 59 | 60 | parent::__construct(Replace: [ 61 | 'ROWS' => $formGroupRows, 62 | 'CLASSES' => $this->DrawClasses(), 63 | 'STYLES' => $this->DrawStyles(), 64 | 'ATTRIBUTES' => $this->DrawAttributes(), 65 | 'PROPERTIES' => $this->DrawProperties() 66 | ]); 67 | } 68 | } -------------------------------------------------------------------------------- Total de líneas: 68 ================================================================================ ================================================================================ ARCHIVO #407: src/Widget/FormGroupColumn.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/FormGroupColumn.php Tamaño: 2.34 KB -------------------------------------------------------------------------------- 1 | AddClasses($Classes); 37 | 38 | if ($Layout == TipoLayoutFilaEnum::BOOTSTRAP) { 39 | $this->AddClass('col-sm-' . $Colspan); 40 | } 41 | else if ($Layout == TipoLayoutFilaEnum::FLEXBOX) { 42 | $this->AddStyle('flex-grow', $Colspan); 43 | $this->AddStyle('margin-left', '5px'); 44 | $this->AddStyle('margin-right', '5px'); 45 | } 46 | 47 | if ($this->Required) { 48 | $this->AddClass('required'); 49 | } 50 | 51 | $this->AddClasses($LabelClasses, 'label'); 52 | $this->AddClass('control-label', 'label'); 53 | 54 | // Styles 55 | $this->AddStyles($Styles); 56 | $this->AddStyles($LabelStyles, 'label'); 57 | 58 | // Attributes 59 | $this->AddAttributes($Attributes); 60 | $this->AddAttribute('id', $this->Key); 61 | 62 | // Properties 63 | $this->AddProperties($Properties); 64 | 65 | parent::__construct(Replace: [ 66 | 'CLASSES' => $this->DrawClasses(), 67 | 'LABELDESC' => $this->Label, 68 | 'LABELCLASSES' => $this->DrawClasses('label'), 69 | 'STYLES' => $this->DrawStyles(), 70 | 'LABELSTYLES' => $this->DrawStyles('label'), 71 | 'INPUT' => $this->Input->Draw(false), 72 | 'ATTRIBUTES' => $this->DrawAttributes(), 73 | 'PROPERTIES' => $this->DrawProperties() 74 | ]); 75 | } 76 | } -------------------------------------------------------------------------------- Total de líneas: 76 ================================================================================ ================================================================================ ARCHIVO #408: src/Widget/FormGroupColumnContent.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/FormGroupColumnContent.php Tamaño: 1.88 KB -------------------------------------------------------------------------------- 1 | AddClasses($Classes); 32 | 33 | if ($Layout == TipoLayoutFilaEnum::BOOTSTRAP) { 34 | $this->AddClass('col-sm-' . $Colspan); 35 | } 36 | else if ($Layout == TipoLayoutFilaEnum::FLEXBOX) { 37 | $this->AddStyle('flex-grow', $Colspan); 38 | $this->AddStyle('margin-left', '5px'); 39 | $this->AddStyle('margin-right', '5px'); 40 | } 41 | 42 | // Styles 43 | $this->AddStyles($Styles); 44 | 45 | // Attributes 46 | $this->AddAttributes($Attributes); 47 | 48 | // Properties 49 | $this->AddProperties($Properties); 50 | 51 | if ($this->Key != '') { 52 | $this->AddAttribute('id', $this->Key); 53 | } 54 | 55 | parent::__construct(Replace: [ 56 | 'CONTENT' => $this->Child->Draw(false), 57 | 'CLASSES' => $this->DrawClasses(), 58 | 'STYLES' => $this->DrawStyles(), 59 | 'ATTRIBUTES' => $this->DrawAttributes(), 60 | 'PROPERTIES' => $this->DrawProperties() 61 | ]); 62 | } 63 | } -------------------------------------------------------------------------------- Total de líneas: 63 ================================================================================ ================================================================================ ARCHIVO #409: src/Widget/FormGroupColumnEmpty.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/FormGroupColumnEmpty.php Tamaño: 1.60 KB -------------------------------------------------------------------------------- 1 | AddClasses($Classes); 30 | 31 | if ($Layout == TipoLayoutFilaEnum::BOOTSTRAP) { 32 | $this->AddClass('col-sm-' . $Colspan); 33 | } 34 | else if ($Layout == TipoLayoutFilaEnum::FLEXBOX) { 35 | $this->AddStyle('flex-grow', $Colspan); 36 | $this->AddStyle('margin-left', '5px'); 37 | $this->AddStyle('margin-right', '5px'); 38 | } 39 | 40 | // Styles 41 | $this->AddStyles($Styles); 42 | 43 | // Attributes 44 | $this->AddAttributes($Attributes); 45 | 46 | // Properties 47 | $this->AddProperties($Properties); 48 | 49 | parent::__construct(Replace: [ 50 | 'CLASSES' => $this->DrawClasses(), 51 | 'STYLES' => $this->DrawStyles(), 52 | 'ATTRIBUTES' => $this->DrawAttributes(), 53 | 'PROPERTIES' => $this->DrawProperties() 54 | ]); 55 | } 56 | } -------------------------------------------------------------------------------- Total de líneas: 56 ================================================================================ ================================================================================ ARCHIVO #410: src/Widget/FormGroupColumnLabel.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/FormGroupColumnLabel.php Tamaño: 4.21 KB -------------------------------------------------------------------------------- 1 | AddClasses($Classes); 46 | 47 | if ($Layout == TipoLayoutFilaEnum::BOOTSTRAP) { 48 | $this->AddClass('col-sm-' . $Colspan); 49 | } 50 | else if ($Layout == TipoLayoutFilaEnum::FLEXBOX) { 51 | $this->AddStyle('flex-grow', $Colspan); 52 | $this->AddStyle('margin-left', '5px'); 53 | $this->AddStyle('margin-right', '5px'); 54 | } 55 | 56 | $this->AddClasses($LabelClasses, 'label'); 57 | $this->AddClass('control-label', 'label'); 58 | $this->AddClasses($ContentClasses, 'content'); 59 | $this->AddClasses($HiddenClasses, 'hidden'); 60 | 61 | // Styles 62 | $this->AddStyles($Styles); 63 | $this->AddStyles($LabelStyles, 'label'); 64 | $this->AddStyle('display', 'block', 'label'); 65 | $this->AddStyles($ContentStyles, 'content'); 66 | $this->AddStyles($HiddenStyles, 'hidden'); 67 | 68 | // Attributes 69 | $this->AddAttributes($Attributes); 70 | $this->AddAttributes($LabelAttributes, 'label'); 71 | $this->AddAttributes($ContentAttributes, 'content'); 72 | $this->AddAttribute('id', $Key . '-content', 'content'); 73 | $this->AddAttributes($HiddenAttributes, 'hidden'); 74 | $this->AddAttribute('id', $Key, 'hidden'); 75 | 76 | // Properties 77 | $this->AddProperties($Properties); 78 | $this->AddProperties($LabelProperties, 'label'); 79 | $this->AddProperties($ContentProperties, 'content'); 80 | $this->AddProperties($HiddenProperties, 'hidden'); 81 | 82 | if (isset($HiddenValue)) { 83 | $input = (new InputText( 84 | Key: $Key, 85 | Type: 'hidden', 86 | Value: $HiddenValue, 87 | Classes: $HiddenClasses, 88 | Styles: $HiddenStyles, 89 | Attributes: $HiddenAttributes, 90 | Properties: $HiddenProperties 91 | ))->Draw(false); 92 | } 93 | else { 94 | $input = ''; 95 | } 96 | 97 | parent::__construct(Replace: [ 98 | 'LABELCONTENT' => $this->Content, 99 | 'LABELDESC' => $this->Label, 100 | 'INPUT' => $input, 101 | 'CLASSES' => $this->DrawClasses(), 102 | 'STYLES' => $this->DrawStyles(), 103 | 'ATTRIBUTES' => $this->DrawAttributes(), 104 | 'PROPERTIES' => $this->DrawProperties(), 105 | 'LABELCLASSES' => $this->DrawClasses('label'), 106 | 'LABELSTYLES' => $this->DrawStyles('label'), 107 | 'LABELATTRIBUTES' => $this->DrawAttributes('label'), 108 | 'LABELPROPERTIES' => $this->DrawProperties('label'), 109 | 'CONTENTCLASSES' => $this->DrawClasses('content'), 110 | 'CONTENTSTYLES' => $this->DrawStyles('content'), 111 | 'CONTENTATTRIBUTES' => $this->DrawAttributes('content'), 112 | 'CONTENTPROPERTIES' => $this->DrawProperties('content'), 113 | ]); 114 | } 115 | } -------------------------------------------------------------------------------- Total de líneas: 115 ================================================================================ ================================================================================ ARCHIVO #411: src/Widget/FormGroupRow.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/FormGroupRow.php Tamaño: 2.04 KB -------------------------------------------------------------------------------- 1 | AddClasses($Classes); 31 | 32 | if ($Layout == TipoLayoutFilaEnum::BOOTSTRAP) { 33 | $this->AddClass('row'); 34 | } 35 | else if ($Layout == TipoLayoutFilaEnum::FLEXBOX) { 36 | $this->AddStyle('display', 'flex'); 37 | } 38 | 39 | if (!$First) { 40 | $this->AddClass('inputline'); 41 | } 42 | 43 | // Styles 44 | $this->AddStyles($Styles); 45 | 46 | // Attributes 47 | $this->AddAttributes($Attributes); 48 | 49 | // Properties 50 | $this->AddProperties($Properties); 51 | 52 | // Agregamos las columnas 53 | $formGroupColumns = ''; 54 | 55 | if (isset($Columns)) { 56 | foreach($Columns as $col) { 57 | if ($col instanceof GenericWidget || $col instanceof FormGroupColumn || $col instanceof FormGroupColumnEmpty || $col instanceof FormGroupColumnLabel) { 58 | $formGroupColumns .= $col->Draw(false); 59 | } 60 | } 61 | } 62 | 63 | parent::__construct(Replace: [ 64 | 'COLUMNS' => $formGroupColumns, 65 | 'CLASSES' => $this->DrawClasses(), 66 | 'STYLES' => $this->DrawStyles(), 67 | 'ATTRIBUTES' => $this->DrawAttributes(), 68 | 'PROPERTIES' => $this->DrawProperties() 69 | ]); 70 | } 71 | } -------------------------------------------------------------------------------- Total de líneas: 71 ================================================================================ ================================================================================ ARCHIVO #412: src/Widget/FormGroupSeparator.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/FormGroupSeparator.php Tamaño: 1.23 KB -------------------------------------------------------------------------------- 1 | AddClasses($Classes); 28 | $this->AddClass('modal-group-title'); 29 | 30 | // Styles 31 | $this->AddStyles($Styles); 32 | 33 | // Attributes 34 | $this->AddAttributes($Attributes); 35 | 36 | // Properties 37 | $this->AddProperties($Properties); 38 | 39 | parent::__construct(Replace: [ 40 | 'TITLE' => $this->Title, 41 | 'CLASSES' => $this->DrawClasses(), 42 | 'STYLES' => $this->DrawStyles(), 43 | 'ATTRIBUTES' => $this->DrawAttributes(), 44 | 'PROPERTIES' => $this->DrawProperties() 45 | ]); 46 | } 47 | } -------------------------------------------------------------------------------- Total de líneas: 47 ================================================================================ ================================================================================ ARCHIVO #413: src/Widget/GenericWidget.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/GenericWidget.php Tamaño: 9.34 KB -------------------------------------------------------------------------------- 1 | FindAttributeClass(Widget::class); 40 | 41 | if (!isset($widgetDef) || !isset($widgetDef->attribute)) { 42 | return; 43 | } 44 | 45 | $widget = $widgetDef->attribute; 46 | 47 | $tieneTemplates = isset($widget->Templates) && is_array($widget->Templates) && count($widget->Templates) > 0; 48 | $tieneTemplate = isset($widget->Template) || $widget->Template != ''; 49 | 50 | if (!$tieneTemplate && !$tieneTemplates) { 51 | return; 52 | } 53 | 54 | // Obtener la ruta donde se encuentra la clase "derivada" de este widget 55 | // 56 | $rc = new ReflectionClass(get_class($this)); 57 | $ruta = dirname($rc->getFileName()); 58 | 59 | // Componer la ruta hacia los archivos de template 60 | // 61 | if ($tieneTemplates) { 62 | foreach($widget->Templates as $template) { 63 | $this->__Contents[$template->Template] = $this->LeerTemplate($ruta, $template); 64 | } 65 | } 66 | else if ($tieneTemplate) { 67 | 68 | $this->__TemplatePath = $ruta . '/' . $widget->Path . '/' . $widget->Template . $widget->Extension; 69 | 70 | // Leer el template 71 | // 72 | $content = $this->LeerTemplate($ruta, new Template( 73 | Path: $widget->Path, Template: $widget->Template, Extension: $widget->Extension 74 | )); 75 | 76 | $this->__Content = $content; 77 | } 78 | 79 | } 80 | 81 | private function LeerTemplate (string $ClassPath, Template $template) { 82 | 83 | $filePath = $ClassPath . '/' . $template->Path . '/' . $template->Template . $template->Extension; 84 | 85 | if (!file_exists($filePath)) { 86 | throw new \Exception('No se encuentra el contenido del template: ' . $filePath); 87 | } 88 | 89 | return file_get_contents($filePath); 90 | } 91 | 92 | function SetReplace(array $Replace) { 93 | $this->Replace = $Replace; 94 | } 95 | 96 | function AddReplace(string $Search, string $Replacement) { 97 | $this->Replace = array_merge($this->Replace, [ 98 | $Search => $Replacement 99 | ]); 100 | } 101 | 102 | public function OnBeforeDraw() { 103 | 104 | } 105 | 106 | public function Draw($echoResult = true) { 107 | 108 | $this->OnBeforeDraw(); 109 | 110 | if (!isset($this->__Content) || $this->__Content == '') { 111 | return ''; 112 | } 113 | 114 | if (!isset($this->Replace) || count($this->Replace) <= 0) { 115 | return $this->__Content; 116 | } 117 | 118 | $builder = $this->__Content; 119 | 120 | foreach($this->Replace as $key => $replace) { 121 | 122 | if (is_callable($replace)) { 123 | $callResult = $replace(); 124 | 125 | if ($callResult instanceof IDrawable) { 126 | $result = $callResult->Draw(false); 127 | } 128 | elseif (is_array($callResult)) { 129 | $result = ""; 130 | foreach($callResult as $drawable) { 131 | if ($drawable instanceof IDrawable) { 132 | $result .= $drawable->Draw(false) . "\n\n"; 133 | } 134 | } 135 | } 136 | else { 137 | $result = $callResult; 138 | } 139 | } 140 | else if ($replace instanceof IDrawable) { 141 | $result = $replace->Draw(false); 142 | } 143 | else if (is_array($replace)) { 144 | $result = ""; 145 | foreach($replace as $drawable) { 146 | if ($drawable instanceof IDrawable) { 147 | $result .= $drawable->Draw(false) . "\n\n"; 148 | } 149 | } 150 | } 151 | else { 152 | $result = $replace; 153 | } 154 | 155 | $builder = str_replace('[[' . strtoupper($key) . ']]', $result, $builder); 156 | } 157 | 158 | if ($echoResult) { 159 | echo $builder; 160 | } 161 | 162 | return $builder; 163 | } 164 | 165 | protected function AddStyle(string $style, string $value, string $group = 'default') { 166 | 167 | if (!isset($this->__Styles[$group])) { 168 | $this->__Styles[$group] = ''; 169 | } 170 | 171 | if ($this->__Styles[$group] != '') { 172 | $this->__Styles[$group] .= ' '; 173 | } 174 | 175 | $this->__Styles[$group] .= $style . ': ' . $value . '; '; 176 | } 177 | 178 | protected function AddStyles(array $styles, string $group = 'default') { 179 | 180 | foreach($styles as $style) { 181 | if (is_array($style) && count($style) == 2) { 182 | $this->AddStyle($style[0], $style[1], $group); 183 | } 184 | } 185 | 186 | } 187 | 188 | protected function DrawStyles(string $group = 'default') { 189 | 190 | if (isset($this->__Styles[$group]) && $this->__Styles[$group] != '') { 191 | return 'style="' . $this->__Styles[$group] . '"'; 192 | } 193 | else { 194 | return ''; 195 | } 196 | } 197 | 198 | protected function AddClass(string $class, string $group = 'default') { 199 | 200 | if (!isset($this->__Classes[$group])) { 201 | $this->__Classes[$group] = ''; 202 | } 203 | 204 | if ($this->__Classes[$group] != '') { 205 | $this->__Classes[$group] .= ' '; 206 | } 207 | 208 | $this->__Classes[$group] .= $class; 209 | } 210 | 211 | protected function AddClasses(array $classes, string $group = 'default') { 212 | foreach($classes as $class) { 213 | $this->AddClass($class, $group); 214 | } 215 | } 216 | 217 | protected function DrawClasses(string $group = 'default') { 218 | 219 | if (isset($this->__Classes[$group]) && $this->__Classes[$group] != '') { 220 | return 'class="' . $this->__Classes[$group] . '"'; 221 | } 222 | else { 223 | return ''; 224 | } 225 | } 226 | 227 | /** 228 | * AddAttribute 229 | * 230 | * Agrega una propiedad del tipo 231 | * 232 | * @param string $property El nombre de la propiedad (ej: disabled, required, selected, etc) 233 | * @param string $value El valor del atributo, si es falso, el atributo NO SERA AGREGADO 234 | */ 235 | protected function AddProperty(string $property, bool $value, string $group = 'default') { 236 | 237 | if ($value) { 238 | if (!isset($this->__Properties[$group])) { 239 | $this->__Properties[$group] = []; 240 | } 241 | 242 | $this->__Properties[$group][$property] = $value; 243 | } 244 | 245 | } 246 | 247 | /** 248 | * AddAttribute 249 | * 250 | * Agrega un atributo del tipo ='', no se admiten valores NULL 251 | * 252 | * @param string $attribute El nombre del atributo 253 | * @param string $value El valor del atributo, si es NULL el atributo NO SERA AGREGADO 254 | */ 255 | protected function AddAttribute(string $attribute, $value = null, string $group = 'default') { 256 | if (isset($value)) { 257 | if (!isset($this->__Attributes[$group])) { 258 | $this->__Attributes[$group] = []; 259 | } 260 | 261 | $this->__Attributes[$group][$attribute] = $value; 262 | } 263 | } 264 | 265 | protected function AddAttributes(array $attributes, string $group = 'default') { 266 | foreach($attributes as $key => $attribute) { 267 | if (is_array($attribute) && count($attribute) == 2) { 268 | $this->AddAttribute($attribute[0], $attribute[1], $group); 269 | } 270 | else if ($key != '' && !is_numeric($key)) { 271 | $this->AddAttribute($key, $attribute, $group); 272 | } 273 | } 274 | } 275 | 276 | protected function AddProperties(array $properties, string $group = 'default') { 277 | foreach($properties as $key => $property) { 278 | if (is_array($property) && count($property) == 2) { 279 | $this->AddProperty($property[0], $property[1], $group); 280 | } 281 | else if ($key != '' && !is_numeric($key)) { 282 | $this->AddProperty($key, $property, $group); 283 | } 284 | } 285 | } 286 | 287 | protected function DrawAttributes(string $group = 'default') { 288 | 289 | $attributes = ''; 290 | 291 | if (isset($this->__Attributes[$group])) { 292 | 293 | foreach($this->__Attributes[$group] as $attribute => $value) { 294 | if ($attributes != '') { 295 | $attributes .= ' '; 296 | } 297 | 298 | $attributes .= $attribute . '="' . $value . '"'; 299 | } 300 | } 301 | 302 | return $attributes; 303 | } 304 | 305 | protected function DrawProperties(string $group = 'default') { 306 | 307 | $properties = ''; 308 | if (isset($this->__Properties[$group])) { 309 | 310 | foreach($this->__Properties[$group] as $properties => $value) { 311 | if ($properties != '') { 312 | $properties .= ' '; 313 | } 314 | 315 | $properties .= $properties . ' '; 316 | } 317 | } 318 | 319 | return $properties; 320 | } 321 | } -------------------------------------------------------------------------------- Total de líneas: 321 ================================================================================ ================================================================================ ARCHIVO #414: src/Widget/Html.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/Html.php Tamaño: 560 bytes -------------------------------------------------------------------------------- 1 | $Content 24 | ]); 25 | } 26 | } -------------------------------------------------------------------------------- Total de líneas: 26 ================================================================================ ================================================================================ ARCHIVO #415: src/Widget/IDrawable.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/IDrawable.php Tamaño: 366 bytes -------------------------------------------------------------------------------- 1 | AddAttribute('title', $Title); 37 | 38 | if ($Alt != '') 39 | $this->AddAttribute('alt', $Alt); 40 | 41 | if ($LazyLoad) { 42 | $this->AddAttribute('data-src', $Source); 43 | $this->AddAttribute('src', ''); 44 | $this->AddClass('lazyautosizes'); 45 | $this->AddClass('lazyloaded'); 46 | } 47 | else { 48 | $this->AddAttribute('src', $Source); 49 | } 50 | 51 | if ($Sizes > 0) { 52 | $this->AddAttribute('data-sizes', 'auto'); 53 | $this->AddAttribute('sizes', $Width . $Unit); 54 | } 55 | else { 56 | if ($this->Width != 'auto') { 57 | $this->AddAttribute('width', $this->Width . $Unit); 58 | } 59 | else { 60 | $this->AddAttribute('width', $this->Width); 61 | } 62 | 63 | if ($this->Height != 'auto') { 64 | $this->AddAttribute('height', $this->Height . $Unit); 65 | } 66 | else { 67 | $this->AddAttribute('height', $this->Height); 68 | } 69 | } 70 | 71 | $this->AddClasses($Classes); 72 | $this->AddStyles($Styles); 73 | 74 | // Attributes 75 | $this->AddAttributes($Attributes); 76 | $this->AddAttribute('id', $this->Key); 77 | 78 | // Properties 79 | $this->AddProperties($Properties); 80 | 81 | parent::__construct(Replace: [ 82 | 'CLASSES' => $this->DrawClasses(), 83 | 'STYLES' => $this->DrawStyles(), 84 | 'ATTRIBUTES' => $this->DrawAttributes(), 85 | 'PROPERTIES' => $this->DrawProperties() 86 | ]); 87 | } 88 | } -------------------------------------------------------------------------------- Total de líneas: 88 ================================================================================ ================================================================================ ARCHIVO #417: src/Widget/Input.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/Input.php Tamaño: 373 bytes -------------------------------------------------------------------------------- 1 | AddClasses($Classes); 29 | $this->AddClass('input-group-addon'); 30 | 31 | // Styles 32 | $this->AddStyles($Styles); 33 | 34 | // Attributes 35 | $this->AddAttributes($Attributes); 36 | 37 | // Properties 38 | $this->AddProperties($Properties); 39 | 40 | $faicon = ''; 41 | if (isset($Icon)) { 42 | $faicon = $Icon->Draw(false); 43 | } 44 | 45 | parent::__construct(Replace: [ 46 | 'ICON' => $faicon, 47 | 'CLASSES' => $this->DrawClasses(), 48 | 'STYLES' => $this->DrawStyles(), 49 | 'ATTRIBUTES' => $this->DrawAttributes(), 50 | 'PROPERTIES' => $this->DrawProperties() 51 | ]); 52 | } 53 | } -------------------------------------------------------------------------------- Total de líneas: 53 ================================================================================ ================================================================================ ARCHIVO #419: src/Widget/InputCheck.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/InputCheck.php Tamaño: 3.20 KB -------------------------------------------------------------------------------- 1 | AddClasses($this->Classes); 40 | $this->AddClass('checkbox-container'); 41 | $this->AddClasses($this->InputClasses, 'input'); 42 | $this->AddClass('checkbox-incluir', 'input'); 43 | $this->AddClasses($this->LabelClasses, 'label'); 44 | //$this->AddClass('checkbox'); 45 | $this->AddClass('checkbox-' . $this->CheckStyle); 46 | 47 | // Styles 48 | $this->AddStyles($this->Styles); 49 | $this->AddStyles($this->InputStyles, 'input'); 50 | $this->AddStyles($this->LabelStyles, 'label'); 51 | 52 | // Attributes 53 | $this->AddAttributes($this->Attributes); 54 | $this->AddAttributes($this->InputAttributes, 'input'); 55 | $this->AddAttributes($this->LabelAttributes, 'label'); 56 | $this->AddAttribute('id', $this->Key, 'input'); 57 | $this->AddAttribute('type', 'checkbox', 'input'); 58 | 59 | if ($this->Checked) 60 | $this->AddProperty('checked', true, 'input'); 61 | 62 | $this->AddAttribute('for', $this->Key, 'label'); 63 | $this->AddAttribute('id', $this->Key . '-label', 'label'); 64 | 65 | // Properties 66 | $this->AddProperties($this->Properties); 67 | $this->AddProperties($this->InputProperties, 'input'); 68 | $this->AddProperties($this->LabelProperties, 'label'); 69 | 70 | parent::__construct(Replace: [ 71 | 'TITLE' => $this->Label, 72 | 'CLASSES' => $this->DrawClasses(), 73 | 'STYLES' => $this->DrawStyles(), 74 | 'ATTRIBUTES' => $this->DrawAttributes(), 75 | 'PROPERTIES' => $this->DrawProperties(), 76 | 'INPUTCLASSES' => $this->DrawClasses('input'), 77 | 'INPUTSTYLES' => $this->DrawStyles('input'), 78 | 'INPUTATTRIBUTES' => $this->DrawAttributes('input'), 79 | 'INPUTPROPERTIES' => $this->DrawProperties('input'), 80 | 'LABELCLASSES' => $this->DrawClasses('label'), 81 | 'LABELSTYLES' => $this->DrawStyles('label'), 82 | 'LABELATTRIBUTES' => $this->DrawAttributes('label'), 83 | 'LABELPROPERTIES' => $this->DrawProperties('label'), 84 | ]); 85 | } 86 | } -------------------------------------------------------------------------------- Total de líneas: 86 ================================================================================ ================================================================================ ARCHIVO #420: src/Widget/InputColor.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/InputColor.php Tamaño: 1.76 KB -------------------------------------------------------------------------------- 1 | AddClasses($Classes); 33 | $this->AddClass('form-control'); 34 | 35 | // Styles 36 | $this->AddStyles($Styles); 37 | 38 | // Attributes 39 | $this->AddAttributes($this->Attributes); 40 | $this->AddAttributes([ 41 | ['id', $this->Key], 42 | ['type', $this->Type], 43 | ['value', $this->Value], 44 | ['name', $this->Key], 45 | 46 | ]); 47 | 48 | // Properties 49 | $this->AddProperties($this->Properties); 50 | $this->AddProperty('required', $this->Required); 51 | $this->AddProperty('disabled', $this->Disabled); 52 | 53 | parent::__construct(Replace: [ 54 | 'ATTRIBUTES' => $this->DrawAttributes(), 55 | 'PROPERTIES' => $this->DrawProperties(), 56 | 'CLASSES' => $this->DrawClasses(), 57 | 'STYLES' => $this->DrawStyles(), 58 | 'SUBTITLE_PLACEHOLDRE' => $Placeholder 59 | ]); 60 | } 61 | } -------------------------------------------------------------------------------- Total de líneas: 61 ================================================================================ ================================================================================ ARCHIVO #421: src/Widget/InputDate.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/InputDate.php Tamaño: 2.88 KB -------------------------------------------------------------------------------- 1 | AddClasses($Classes); 40 | $this->AddClass('input-group'); 41 | 42 | switch($Type) { 43 | case 'date': 44 | case 'datetime': 45 | $this->AddClass('date'); 46 | break; 47 | case 'time': 48 | $this->AddClass('clockpicker'); 49 | break; 50 | default: 51 | $this->AddClass('date'); 52 | break; 53 | } 54 | 55 | $this->AddClass('new'); 56 | 57 | // Styles 58 | $this->AddStyles($Styles); 59 | 60 | // Attributes 61 | $this->AddAttributes($this->Attributes); 62 | array_push($DateAttributes, ['id', $this->Key]); 63 | 64 | // Properties 65 | array_push($DateProperties, ['required', $this->Required]); 66 | array_push($DateProperties, ['disabled', $this->Disabled]); 67 | 68 | // Icon 69 | $inputAddon = ''; 70 | if (isset($Icon)) { 71 | $inputAddon = (new InputAddon( 72 | Icon: $this->Icon 73 | ))->Draw(false); 74 | } 75 | 76 | $input = (new InputText( 77 | Key: $this->Key, 78 | Type: FormRowFieldTypeEnum::INPUT_TEXT, 79 | Classes: $DateClasses, 80 | Required: $Required, 81 | Styles: $DateStyles, 82 | Value: $this->Value, 83 | Placeholder: $this->Placeholder, 84 | Attributes: $DateAttributes, 85 | Properties: $DateProperties 86 | ))->Draw(false); 87 | 88 | parent::__construct(Replace: [ 89 | 'INPUTADDON' => $inputAddon, 90 | 'INPUT' => $input, 91 | 'CLASSES' => $this->DrawClasses(), 92 | 'STYLES' => $this->DrawStyles(), 93 | 'ATTRIBUTES' => $this->DrawAttributes(), 94 | 'PROPERTIES' => $this->DrawProperties() 95 | ]); 96 | } 97 | } -------------------------------------------------------------------------------- Total de líneas: 97 ================================================================================ ================================================================================ ARCHIVO #422: src/Widget/InputDateRange.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/InputDateRange.php Tamaño: 2.59 KB -------------------------------------------------------------------------------- 1 | AddClasses($Classes); 39 | $this->AddClass('input-group'); 40 | $this->AddClass('date'); 41 | $this->AddClass('new'); 42 | 43 | // Styles 44 | $this->AddStyles($Styles); 45 | 46 | // Attributes 47 | $this->AddAttributes($this->Attributes); 48 | array_push($DateAttributes, ['id', $this->Key]); 49 | 50 | // Properties 51 | array_push($DateProperties, ['required', $this->Required]); 52 | 53 | // Icon 54 | $inputAddon = ''; 55 | if (isset($Icon)) { 56 | $inputAddon = (new InputAddon( 57 | Icon: $this->Icon 58 | ))->Draw(false); 59 | } 60 | 61 | $input = (new InputText( 62 | Key: $this->Key, 63 | Type: FormRowFieldTypeEnum::INPUT_TEXT, 64 | Classes: $DateClasses, 65 | Required: $Required, 66 | Styles: $DateStyles, 67 | Value: $this->Value, 68 | Placeholder: $this->Placeholder, 69 | Attributes: $DateAttributes, 70 | Properties: $DateProperties 71 | ))->Draw(false); 72 | 73 | parent::__construct(Replace: [ 74 | 'INPUTADDON' => $inputAddon, 75 | 'INPUT' => $input, 76 | 'CLASSES' => $this->DrawClasses(), 77 | 'STYLES' => $this->DrawStyles(), 78 | 'ATTRIBUTES' => $this->DrawAttributes(), 79 | 'PROPERTIES' => $this->DrawProperties() 80 | ]); 81 | } 82 | } -------------------------------------------------------------------------------- Total de líneas: 82 ================================================================================ ================================================================================ ARCHIVO #423: src/Widget/InputSelect.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/InputSelect.php Tamaño: 4.72 KB -------------------------------------------------------------------------------- 1 | AddClasses($Classes); 40 | $this->AddClass('js-source-states'); 41 | 42 | if($Required == true){ 43 | $this->AddClass('frm-required-input'); 44 | } 45 | 46 | // Styles 47 | $this->AddStyles($Styles); 48 | $this->AddStyle('width', '100%'); 49 | 50 | // Attributes 51 | $this->AddAttributes($Attributes); 52 | $this->AddAttribute('id', $Key); 53 | if( $MultipleSelection == true ){ 54 | $this->AddAttribute('multiple', "multiple"); 55 | } 56 | 57 | // Properties 58 | $this->AddProperties($Properties); 59 | $this->AddProperty('required', $Required); 60 | $this->AddProperty('disabled', $Disabled); 61 | 62 | // Generar las opciones 63 | if (isset($GroupCollectionName) && $GroupCollectionName != "") { 64 | $parts = explode('|', $GroupCollectionName, 2); 65 | $CollectionName = $parts[0]; 66 | $GroupName = $parts[1]; 67 | $groups = $Values; 68 | } 69 | else { 70 | $CollectionName = 'SinGrupo'; 71 | $GroupName = ''; 72 | 73 | $group = new \stdClass(); 74 | $group->Label = ''; 75 | $group->$CollectionName = $Values; 76 | 77 | $groups = [$group]; 78 | } 79 | 80 | $options = ''; 81 | foreach ($groups as $group) { 82 | if ($GroupName != "") { 83 | if (!isset($group->$CollectionName) || !is_array($group->$CollectionName) || count($group->$CollectionName) == 0) { 84 | continue; 85 | } 86 | 87 | $options .= ""; 88 | } 89 | 90 | foreach ($group->$CollectionName as $row) { 91 | // atributos del option 92 | $attr = []; 93 | 94 | foreach($OptionAttributeNames as $optionattr) { 95 | $attrValue = Mapper::EvaluateKeyMultilevel($row, $optionattr); 96 | //array_push($attr, ['data-' . $optionattr, $row->$optionattr]); 97 | array_push($attr, ['data-' . str_replace('->', '-', $optionattr), $attrValue]); 98 | } 99 | 100 | $PropertyNameValue = ( is_string($ValueField) && strpos($ValueField, "[]") !== false ) ? str_replace('[]','',$ValueField) : $ValueField ; 101 | 102 | $value =$row->$PropertyNameValue; 103 | 104 | if (isset($DescriptionFunction) && is_callable($DescriptionFunction)) { 105 | $description = $DescriptionFunction($row->$ValueField, $row->$DescriptionField, $row); 106 | } 107 | else { 108 | $description = $row->$DescriptionField; 109 | } 110 | 111 | if ($MultipleSelection == true) { 112 | $selected = in_array($value, $SelectedValues); 113 | } 114 | else { 115 | $selected = ($value == $SelectedValue); 116 | } 117 | 118 | $option = new InputSelectOption( 119 | Value: $value ?? '', 120 | Description: $description ?? '', 121 | Selected: $selected, 122 | Attributes: $attr 123 | ); 124 | 125 | if ($options == '') { 126 | $options .= "\n"; 127 | } 128 | $options .= $option->Draw(false); 129 | } 130 | 131 | if ($GroupName != "") { 132 | $options .= ""; 133 | } 134 | 135 | } 136 | 137 | 138 | parent::__construct(Replace: [ 139 | 'OPTIONS' => $options, 140 | 'CLASSES' => $this->DrawClasses(), 141 | 'STYLES' => $this->DrawStyles(), 142 | 'ATTRIBUTES' => $this->DrawAttributes(), 143 | 'PROPERTIES' => $this->DrawProperties() 144 | ]); 145 | } 146 | } -------------------------------------------------------------------------------- Total de líneas: 146 ================================================================================ ================================================================================ ARCHIVO #424: src/Widget/InputSelectMultiple.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/InputSelectMultiple.php Tamaño: 3.13 KB -------------------------------------------------------------------------------- 1 | AddClasses($Classes); 37 | $this->AddClass('js-source-states'); 38 | 39 | // Styles 40 | $this->AddStyles($Styles); 41 | $this->AddStyle('width', '100%'); 42 | 43 | // Attributes 44 | $this->AddAttributes($Attributes); 45 | $this->AddAttribute('id', $Key); 46 | 47 | // Properties 48 | $this->AddProperties($Properties); 49 | $this->AddProperty('required', $Required); 50 | $this->AddProperty('disabled', $Disabled); 51 | 52 | 53 | 54 | // Generar las opciones 55 | $options = ''; 56 | foreach($Values as $row) { 57 | 58 | // atributos del option 59 | $attr = []; 60 | 61 | foreach($OptionAttributeNames as $optionattr) { 62 | $attrValue = Mapper::EvaluateKeyMultilevel($row, $optionattr); 63 | //array_push($attr, ['data-' . $optionattr, $row->$optionattr]); 64 | array_push($attr, ['data-' . str_replace('->', '-', $optionattr), $attrValue]); 65 | } 66 | 67 | $PropertyNameValue = ( is_string($ValueField) && strpos($ValueField, "[]") !== false ) ? str_replace('[]','',$ValueField) : $ValueField ; 68 | 69 | $value =$row->$PropertyNameValue; 70 | 71 | if (isset($DescriptionFunction) && is_callable($DescriptionFunction)) { 72 | $description = $DescriptionFunction($row->$ValueField, $row->$DescriptionField, $row); 73 | } 74 | else { 75 | $description = $row->$DescriptionField; 76 | } 77 | 78 | $selected = ($value == $SelectedValue); 79 | 80 | $option = new InputSelectOption( 81 | Value: $value, 82 | Description: $description, 83 | Selected: $selected, 84 | Attributes: $attr 85 | ); 86 | 87 | if ($options == '') { 88 | $options .= "\n"; 89 | } 90 | $options .= $option->Draw(false); 91 | } 92 | 93 | parent::__construct(Replace: [ 94 | 'OPTIONS' => $options, 95 | 'CLASSES' => $this->DrawClasses(), 96 | 'STYLES' => $this->DrawStyles(), 97 | 'ATTRIBUTES' => $this->DrawAttributes(), 98 | 'PROPERTIES' => $this->DrawProperties() 99 | ]); 100 | } 101 | } -------------------------------------------------------------------------------- Total de líneas: 101 ================================================================================ ================================================================================ ARCHIVO #425: src/Widget/InputSelectOption.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/InputSelectOption.php Tamaño: 938 bytes -------------------------------------------------------------------------------- 1 | AddAttributes($this->Attributes); 26 | $this->AddAttribute('value', $this->Value); 27 | 28 | parent::__construct(Replace: [ 29 | 'DESCRIPTION' => $this->Description, 30 | 'SELECTED' => ($Selected) ? ' selected ' : '', 31 | 'ATTRIBUTES' => $this->DrawAttributes() 32 | ]); 33 | } 34 | } -------------------------------------------------------------------------------- Total de líneas: 34 ================================================================================ ================================================================================ ARCHIVO #426: src/Widget/InputText.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/InputText.php Tamaño: 1.81 KB -------------------------------------------------------------------------------- 1 | AddClasses($Classes); 33 | $this->AddClass('form-control'); 34 | 35 | // Styles 36 | $this->AddStyles($Styles); 37 | 38 | // Attributes 39 | $this->AddAttributes($this->Attributes); 40 | $this->AddAttributes([ 41 | ['id', $this->Key], 42 | ['type', $this->Type], 43 | ['value', $this->Value], 44 | ['name', $this->Key], 45 | ['placeholder', $this->Placeholder] 46 | ]); 47 | 48 | // Properties 49 | $this->AddProperties($this->Properties); 50 | if($this->Required == true){ 51 | $this->AddClass('frm-required-input'); 52 | } 53 | $this->AddProperty('required', $this->Required); 54 | $this->AddProperty('disabled', $this->Disabled); 55 | 56 | parent::__construct(Replace: [ 57 | 'ATTRIBUTES' => $this->DrawAttributes(), 58 | 'PROPERTIES' => $this->DrawProperties(), 59 | 'CLASSES' => $this->DrawClasses(), 60 | 'STYLES' => $this->DrawStyles() 61 | ]); 62 | } 63 | } -------------------------------------------------------------------------------- Total de líneas: 63 ================================================================================ ================================================================================ ARCHIVO #427: src/Widget/InputTextArea.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/InputTextArea.php Tamaño: 1.97 KB -------------------------------------------------------------------------------- 1 | AddClasses($Classes); 35 | $this->AddClass('form-control'); 36 | 37 | // Styles 38 | $this->AddStyles($Styles); 39 | 40 | // Attributes 41 | $this->AddAttributes($this->Attributes); 42 | $this->AddAttributes([ 43 | ['id', $this->Key], 44 | ['type', $this->Type], 45 | ['value', $this->Value], 46 | ['name', $this->Key], 47 | ['placeholder', $this->Placeholder], 48 | ['rows', $this->Lines] 49 | ]); 50 | 51 | if (!$Resize) { 52 | $this->AddStyle('resize', 'none'); 53 | } 54 | 55 | // Properties 56 | $this->AddProperties($this->Properties); 57 | $this->AddProperty('required', $this->Required); 58 | $this->AddProperty('disabled', $this->Disabled); 59 | 60 | parent::__construct(Replace: [ 61 | 'CONTENT' => (isset($Value)) ? $Value : '', 62 | 'ATTRIBUTES' => $this->DrawAttributes(), 63 | 'PROPERTIES' => $this->DrawProperties(), 64 | 'CLASSES' => $this->DrawClasses(), 65 | 'STYLES' => $this->DrawStyles() 66 | ]); 67 | } 68 | } -------------------------------------------------------------------------------- Total de líneas: 68 ================================================================================ ================================================================================ ARCHIVO #428: src/Widget/JSTableContent.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/JSTableContent.php Tamaño: 726 bytes -------------------------------------------------------------------------------- 1 | $PropertyName, 28 | ]); 29 | } 30 | } -------------------------------------------------------------------------------- Total de líneas: 30 ================================================================================ ================================================================================ ARCHIVO #429: src/Widget/JSTableRow.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/JSTableRow.php Tamaño: 617 bytes -------------------------------------------------------------------------------- 1 | Recibe dos inputs por defecto ($element, y $roles) 17 | */ 18 | 19 | #[Widget(Template: 'ScriptDirect')] 20 | class JSTableScriptFilter extends GenericWidget { 21 | 22 | public function __construct( 23 | public string $FunctionName, 24 | public array $Script 25 | ) 26 | { 27 | $id = (new \DateTime())->format('YmdHis') . random_int(1,5000); 28 | 29 | parent::__construct(Replace: [ 30 | 'EVENTS' => $Script, 31 | 'IDSCRIPT' => $id 32 | ]); 33 | } 34 | } -------------------------------------------------------------------------------- Total de líneas: 34 ================================================================================ ================================================================================ ARCHIVO #431: src/Widget/Label.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/Label.php Tamaño: 1.58 KB -------------------------------------------------------------------------------- 1 | AddClass('label'); 33 | $this->AddClass($LabelStyle); 34 | $this->AddClass($LabelSize); 35 | $this->AddClasses($Classes); 36 | 37 | // Styles 38 | $this->AddStyles($Styles); 39 | 40 | // Attributes 41 | $this->AddAttributes($Attributes); 42 | $this->AddAttribute('id', $this->Key); 43 | 44 | // Properties 45 | $this->AddProperties($Properties); 46 | 47 | parent::__construct(Replace: [ 48 | 'CONTENT' => $Content, 49 | 'CLASSES' => $this->DrawClasses(), 50 | 'STYLES' => $this->DrawStyles(), 51 | 'ATTRIBUTES' => $this->DrawAttributes(), 52 | 'PROPERTIES' => $this->DrawProperties() 53 | ]); 54 | } 55 | } -------------------------------------------------------------------------------- Total de líneas: 55 ================================================================================ ================================================================================ ARCHIVO #432: src/Widget/LeftItem.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/LeftItem.php Tamaño: 2.96 KB -------------------------------------------------------------------------------- 1 | AddClasses($Classes); 41 | $this->AddClass('menu-level-1'); 42 | 43 | // Styles 44 | $this->AddStyles($Styles); 45 | 46 | // Attributes 47 | $this->AddAttributes($Attributes); 48 | 49 | if ($Key != '') { 50 | $this->AddAttribute('id', $this->Key); 51 | } 52 | 53 | array_push($ImageClasses, 'left-item-image'); 54 | array_push($TextClasses, 'left-item-text pull-left'); 55 | 56 | // $image = new Image( 57 | // Source: $ImageSource, 58 | // Classes: $ImageClasses, 59 | // Styles: $ImageStyles, 60 | // Attributes: $ImageAttributes, 61 | // Properties: $ImageProperties 62 | // ); 63 | 64 | $image = new Container( 65 | Classes: ['pull-left'], 66 | Children: [ 67 | new Image( 68 | Source: $ImageSource, 69 | Classes: $ImageClasses, 70 | Styles: $ImageStyles, 71 | Attributes: $ImageAttributes, 72 | Properties: $ImageProperties 73 | ) 74 | ], 75 | ); 76 | 77 | 78 | $text = new Container( 79 | Children: [new Text($Text)], 80 | Classes: $TextClasses, 81 | Styles: $TextStyles, 82 | Attributes: $TextAttributes, 83 | Properties: $TextProperties 84 | ); 85 | 86 | // Properties 87 | $this->AddProperties($Properties); 88 | 89 | $content = $text->Draw(false); 90 | 91 | parent::__construct(Replace: [ 92 | 'IMAGE' => $image->Draw(false), 93 | 'CONTENT' => $content, 94 | 'CLASSES' => $this->DrawClasses(), 95 | 'STYLES' => $this->DrawStyles(), 96 | 'ATTRIBUTES' => $this->DrawAttributes(), 97 | 'PROPERTIES' => $this->DrawProperties() 98 | ]); 99 | } 100 | } -------------------------------------------------------------------------------- Total de líneas: 100 ================================================================================ ================================================================================ ARCHIVO #433: src/Widget/Menu.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/Menu.php Tamaño: 1.59 KB -------------------------------------------------------------------------------- 1 | AddClass($class, 'container'); 27 | } 28 | 29 | foreach($MenuClasses as $class) { 30 | $this->AddClass($class, 'menu'); 31 | } 32 | 33 | $this->AddStyle('cursor', 'pointer'); 34 | 35 | $menuItems = ''; 36 | 37 | // Agregamos los "menús" del menú 38 | if (isset($Items)) { 39 | foreach($Items as $menu) { 40 | if ($menu instanceof ActionMenu || $menu instanceof MenuItem || $menu instanceof ActionMenuTitleSubtitle) { 41 | if ($menuItems != '') { 42 | $menuItems .= "\n"; 43 | } 44 | $menuItems .= $menu->Draw(false); 45 | } 46 | } 47 | } 48 | 49 | parent::__construct(Replace: [ 50 | 'MENUITEMS' => $menuItems, 51 | 'CONTAINERCLASSES' => $this->DrawClasses('container'), 52 | 'MENUCLASSES' => $this->DrawClasses('menu'), 53 | 'STYLES' => $this->DrawStyles() 54 | ]); 55 | } 56 | } -------------------------------------------------------------------------------- Total de líneas: 56 ================================================================================ ================================================================================ ARCHIVO #434: src/Widget/MenuItem.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/MenuItem.php Tamaño: 1.61 KB -------------------------------------------------------------------------------- 1 | AddStyle('display', 'block'); 30 | $this->AddStyle('cursor', 'pointer'); 31 | 32 | if (!isset($Icon) || $Title == '') { 33 | $this->AddClass('action-menu-title', 'title'); 34 | } 35 | else { 36 | $this->AddClass('action-menu-title-withicon', 'title'); 37 | } 38 | 39 | $this->AddClasses($Classes); 40 | $this->AddClasses($TitleClasses, 'title'); 41 | $this->AddStyles($Styles); 42 | 43 | $faicon = ''; 44 | if (isset($Icon)) { 45 | $faicon = $Icon->Draw(false); 46 | } 47 | 48 | if ($Active) { 49 | $this->AddClass('active'); 50 | } 51 | 52 | parent::__construct(Replace: [ 53 | 'MENUTITLE' => $Title, 54 | 'ACTION' => $Action, 55 | 'ICON' => $faicon, 56 | 'CLASSES' => $this->DrawClasses(), 57 | 'TITLECLASSES' => $this->DrawClasses('title'), 58 | 'STYLES' => $this->DrawStyles() 59 | ]); 60 | } 61 | } -------------------------------------------------------------------------------- Total de líneas: 61 ================================================================================ ================================================================================ ARCHIVO #435: src/Widget/Nav.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/Nav.php Tamaño: 1.81 KB -------------------------------------------------------------------------------- 1 | AddClasses($Classes); 32 | 33 | // Styles 34 | $this->AddStyles($Styles); 35 | 36 | // Attributes 37 | $this->AddAttributes($Attributes); 38 | 39 | if ($Key != '') { 40 | $this->AddAttribute('id', $this->Key); 41 | } 42 | 43 | if ($Rol != '') { 44 | $this->AddAttribute('role', $this->Rol); 45 | } 46 | 47 | // Properties 48 | $this->AddProperties($Properties); 49 | 50 | $builder = ""; 51 | foreach ($Children as $child) { 52 | if ($child instanceof GenericWidget) { 53 | if ($builder != "") { 54 | $builder = $builder . "\n"; 55 | } 56 | $builder .= $child->Draw(false); 57 | } 58 | } 59 | 60 | parent::__construct(Replace: [ 61 | 'CONTENT' => $builder, 62 | 'CLASSES' => $this->DrawClasses(), 63 | 'STYLES' => $this->DrawStyles(), 64 | 'ATTRIBUTES' => $this->DrawAttributes(), 65 | 'PROPERTIES' => $this->DrawProperties() 66 | ]); 67 | } 68 | } -------------------------------------------------------------------------------- Total de líneas: 68 ================================================================================ ================================================================================ ARCHIVO #436: src/Widget/PageHeader.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/PageHeader.php Tamaño: 2.89 KB -------------------------------------------------------------------------------- 1 | AddClasses($Classes); 33 | $this->AddClasses(['normalheader', 'small-header']); 34 | 35 | // Styles 36 | $this->AddStyles($Styles); 37 | 38 | // Attributes 39 | $this->AddAttributes($Attributes); 40 | 41 | if ($this->Key != '') 42 | $this->AddAttribute('id', $this->Key); 43 | 44 | // Properties 45 | $this->AddProperties($Properties); 46 | 47 | // Content 48 | if (isset($AditionalContent)) { 49 | $content = (new Container( 50 | Styles: [ 51 | ['display', 'flex'] 52 | ], 53 | Children: [ 54 | new Container( 55 | Styles: [ 56 | ['flex-grow', '1'] 57 | ], 58 | Children: [ 59 | new TitleDescription( 60 | Title: $this->Title, 61 | Description: $this->Description, 62 | IconName: $IconName, 63 | IconColor: $IconColor, 64 | Classes: ['text-page-title'] 65 | ) 66 | ] 67 | ), 68 | new Container( 69 | Children: [$AditionalContent] 70 | ) 71 | ] 72 | ))->Draw(false); 73 | } 74 | else { 75 | $content = (new TitleDescription( 76 | Title: $this->Title, 77 | Description: $this->Description, 78 | IconName: $IconName, 79 | IconColor: $IconColor, 80 | Classes: ['text-page-title'] 81 | ))->Draw(false); 82 | } 83 | 84 | parent::__construct(Replace: [ 85 | 'CONTENT' => $content, 86 | 'CLASSES' => $this->DrawClasses(), 87 | 'STYLES' => $this->DrawStyles(), 88 | 'ATTRIBUTES' => $this->DrawAttributes(), 89 | 'PROPERTIES' => $this->DrawProperties() 90 | ]); 91 | } 92 | } -------------------------------------------------------------------------------- Total de líneas: 92 ================================================================================ ================================================================================ ARCHIVO #437: src/Widget/PageHeaderActionCard.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/PageHeaderActionCard.php Tamaño: 5.05 KB -------------------------------------------------------------------------------- 1 | AddClasses($Classes); 53 | $this->AddClasses($ActionClasses, 'action'); 54 | $this->AddClasses($CardClasses, 'card'); 55 | $this->AddClass('card small text-center', 'card'); 56 | $this->AddClasses($ImageClasses, 'image'); 57 | $this->AddClasses($TextClasses, 'text'); 58 | $this->AddClass('card-text', 'text'); 59 | 60 | // Styles 61 | $this->AddStyles($Styles); 62 | $this->AddStyles([ 63 | ['margin-top', '-18px'], ['margin-bottom', '-18px'] 64 | ]); 65 | $this->AddStyles($ActionStyles, 'action'); 66 | $this->AddStyles($CardStyles, 'card'); 67 | $this->AddStyles($ImageStyles, 'image'); 68 | $this->AddStyles($TextStyles, 'text'); 69 | 70 | // Attributes 71 | $this->AddAttributes($Attributes); 72 | $this->AddAttributes($ActionAttributes, 'action'); 73 | $this->AddAttribute('href', $Action, 'action'); 74 | $this->AddAttribute('target', $ActionTarget, 'action'); 75 | $this->AddAttributes($CardAttributes, 'card'); 76 | $this->AddAttributes($ImageAttributes, 'image'); 77 | $this->AddAttribute('src', $Source, 'image'); 78 | $this->AddAttribute('alt', $Alt, 'image'); 79 | $this->AddAttribute('width', $Width, 'image'); 80 | $this->AddAttribute('height', $Height, 'image'); 81 | 82 | $this->AddAttributes($TextAttributes, 'action'); 83 | 84 | if ($Key != '') { 85 | $this->AddAttribute('id', $this->Key); 86 | } 87 | 88 | // Properties 89 | $this->AddProperties($Properties); 90 | $this->AddProperties($ActionProperties, 'action'); 91 | $this->AddProperties($CardProperties, 'card'); 92 | $this->AddProperties($ImageProperties, 'image'); 93 | $this->AddProperties($TextProperties, 'text'); 94 | 95 | parent::__construct(Replace: [ 96 | 'TEXT' => $Text, 97 | 'CLASSES' => $this->DrawClasses(), 98 | 'STYLES' => $this->DrawStyles(), 99 | 'ATTRIBUTES' => $this->DrawAttributes(), 100 | 'PROPERTIES' => $this->DrawProperties(), 101 | 'ACTIONCLASSES' => $this->DrawClasses('action'), 102 | 'ACTIONSTYLES' => $this->DrawStyles('action'), 103 | 'ACTIONATTRIBUTES' => $this->DrawAttributes('action'), 104 | 'ACTIONPROPERTIES' => $this->DrawProperties('action'), 105 | 'CARDCLASSES' => $this->DrawClasses('card'), 106 | 'CARDSTYLES' => $this->DrawStyles('card'), 107 | 'CARDATTRIBUTES' => $this->DrawAttributes('card'), 108 | 'CARDPROPERTIES' => $this->DrawProperties('card'), 109 | 'IMAGECLASSES' => $this->DrawClasses('image'), 110 | 'IMAGESTYLES' => $this->DrawStyles('image'), 111 | 'IMAGEATTRIBUTES' => $this->DrawAttributes('image'), 112 | 'IMAGEPROPERTIES' => $this->DrawProperties('image'), 113 | 'TEXTCLASSES' => $this->DrawClasses('text'), 114 | 'TEXTSTYLES' => $this->DrawStyles('text'), 115 | 'TEXTATTRIBUTES' => $this->DrawAttributes('text'), 116 | 'TEXTPROPERTIES' => $this->DrawProperties('text'), 117 | ]); 118 | } 119 | } -------------------------------------------------------------------------------- Total de líneas: 119 ================================================================================ ================================================================================ ARCHIVO #438: src/Widget/Panel.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/Panel.php Tamaño: 3.94 KB -------------------------------------------------------------------------------- 1 | AddClasses($Classes); 38 | $this->AddClasses(['hpanel', 'contact-panel']); 39 | 40 | if ($UltraNarrow) { 41 | $this->AddClass('ultra-narrow'); 42 | } 43 | else if ($Narrow) { 44 | $this->AddClass('narrow'); 45 | } 46 | 47 | // Styles 48 | $this->AddStyles($Styles); 49 | 50 | // Attributes 51 | $this->AddAttributes($Attributes); 52 | 53 | // Properties 54 | $this->AddProperties($Properties); 55 | 56 | // Header 57 | $header = ''; 58 | if (isset($this->Header)) { 59 | 60 | if ($UltraNarrow) { 61 | $header = (new Container( 62 | Classes: ['panel-heading-ultra-narrow', 'hbuilt'], 63 | Children: [$this->Header] 64 | ))->Draw(false); 65 | } 66 | else if ($Narrow) { 67 | $header = (new Container( 68 | Classes: ['panel-heading-narrow', 'hbuilt'], 69 | Children: [$this->Header] 70 | ))->Draw(false); 71 | } 72 | else { 73 | $header = (new Container( 74 | Classes: ['panel-heading' , 'hbuilt'], 75 | Children: [$this->Header] 76 | ))->Draw(false); 77 | } 78 | } 79 | 80 | if ($UltraNarrow) { 81 | $bodyClasses = ['panel-body-ultra-narrow']; 82 | } 83 | else if ($Narrow) { 84 | $bodyClasses = ['panel-body-narrow']; 85 | } 86 | else { 87 | $bodyClasses = ['panel-body']; 88 | } 89 | 90 | // Body 91 | foreach($BodyClasses as $class) { 92 | $bodyClasses[] = $class; 93 | } 94 | $body = ( 95 | new Container( 96 | Classes: $bodyClasses, 97 | Styles : $BodyStyles, 98 | Attributes : $BodyAttributes, 99 | Properties : $BodyProperties, 100 | Children: [$this->Body] 101 | ) 102 | )->Draw(false); 103 | 104 | // Footer 105 | $footer = ''; 106 | if (isset($this->Footer)) { 107 | $footer = (new Container( 108 | Classes: ['panel-footer'], 109 | Children: [$this->Footer] 110 | ))->Draw(false); 111 | } 112 | 113 | $colorLine = ''; 114 | if (isset($ColorLine)) { 115 | $colorLine = (new Container( 116 | Classes: ['color-mantencion color-line ' . $ColorLine], 117 | Children: [new Html(' ')] 118 | ))->Draw(false); 119 | } 120 | 121 | parent::__construct(Replace: [ 122 | 'COLORLINE' => $colorLine, 123 | 'BODY' => $body, 124 | 'HEADER' => $header, 125 | 'FOOTER' => $footer, 126 | 'CLASSES' => $this->DrawClasses(), 127 | 'STYLES' => $this->DrawStyles(), 128 | 'ATTRIBUTES' => $this->DrawAttributes(), 129 | 'PROPERTIES' => $this->DrawProperties() 130 | ]); 131 | } 132 | } -------------------------------------------------------------------------------- Total de líneas: 132 ================================================================================ ================================================================================ ARCHIVO #439: src/Widget/Photo.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/Photo.php Tamaño: 2.06 KB -------------------------------------------------------------------------------- 1 | AddClasses($Classes); 36 | $this->AddClass('photo-item'); 37 | 38 | // Styles 39 | $this->AddStyles($Styles); 40 | 41 | // Attributes 42 | $this->AddAttributes($Attributes); 43 | 44 | if ($Key != '') 45 | $this->AddAttribute('id', $this->Key); 46 | 47 | // Properties 48 | $this->AddProperties($Properties); 49 | 50 | $fecha = $Date->format('d-m-Y'); 51 | $hora = $Date->format('H:i'); 52 | 53 | parent::__construct(Replace: [ 54 | 'DATE' => $fecha, 55 | 'TIME' => $hora, 56 | 'DATETITLE' => $DateTitle, 57 | 'AVATAR' => $AvatarUrl, 58 | 'IMAGEURL' => $ImageUrl, 59 | 'FOOTERLEFT' => $Username, 60 | 'FOOTERRIGHT' => $Origin, 61 | 'CLASSES' => $this->DrawClasses(), 62 | 'STYLES' => $this->DrawStyles(), 63 | 'ATTRIBUTES' => $this->DrawAttributes(), 64 | 'PROPERTIES' => $this->DrawProperties(), 65 | 'OBSERVACION' => $Comentario ?: "" 66 | ]); 67 | } 68 | } -------------------------------------------------------------------------------- Total de líneas: 68 ================================================================================ ================================================================================ ARCHIVO #440: src/Widget/PhotoGallery.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/PhotoGallery.php Tamaño: 2.17 KB -------------------------------------------------------------------------------- 1 | AddClasses($Classes); 31 | $this->AddClass('tz-gallery'); 32 | 33 | // Styles 34 | $this->AddStyles($Styles); 35 | 36 | // Attributes 37 | $this->AddAttributes($Attributes); 38 | 39 | $this->AddAttribute('id', $this->Key); 40 | 41 | // Properties 42 | $this->AddProperties($Properties); 43 | 44 | $items = ''; 45 | 46 | foreach($Items as $item) { 47 | 48 | if ($item instanceof PhotoDefinition) { 49 | $new = new Photo( 50 | Key: $item->Key, 51 | ImageUrl: $item->ImageUrl, 52 | Date: $item->Date, 53 | DateTitle: $item->DateTitle, 54 | AvatarUrl: $item->AvatarUrl, 55 | Username: $item->Username, 56 | Origin: $item->Origin, 57 | Comentario: $item->Comentario 58 | ); 59 | 60 | if ($items != '') { 61 | $items .= "\n"; 62 | } 63 | 64 | $items .= $new->Draw(false); 65 | } 66 | } 67 | 68 | 69 | parent::__construct(Replace: [ 70 | 'ITEMS' => $items, 71 | 'KEY' => $Key, 72 | 'CLASSES' => $this->DrawClasses(), 73 | 'STYLES' => $this->DrawStyles(), 74 | 'ATTRIBUTES' => $this->DrawAttributes(), 75 | 'PROPERTIES' => $this->DrawProperties() 76 | ]); 77 | } 78 | } -------------------------------------------------------------------------------- Total de líneas: 78 ================================================================================ ================================================================================ ARCHIVO #441: src/Widget/PopUpContent.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/PopUpContent.php Tamaño: 2.86 KB -------------------------------------------------------------------------------- 1 | AddClass('color-line ' . $ColorLineStyle); 38 | $this->AddClass('modal-title', 'title'); 39 | $this->AddClass('text-bold', 'subtitle'); 40 | 41 | $this->AddClasses($TitleClasses, 'title'); 42 | $this->AddClasses($SubTitleClasses, 'subtitle'); 43 | 44 | if (count($BodyStyles) == 0) { 45 | // por defecto 46 | $BodyStyles = [['height', 'auto'], ['max-height', 'calc(100vh - 280px)'], ['overflow-y', 'scroll']]; 47 | } 48 | 49 | $this->AddClasses($BodyClasses, 'body'); 50 | $this->AddStyles($BodyStyles, 'body'); 51 | 52 | $buttons = ''; 53 | foreach($Buttons as $action) { 54 | if ($action instanceof ActionButton) { 55 | if ($buttons != '') { 56 | $buttons .= "\n"; 57 | } 58 | $buttons .= $action->Draw(false); 59 | } 60 | } 61 | 62 | parent::__construct(Replace: [ 63 | 'DISMISSBUTTONKEY' => 'btnDismiss' . $Key, 64 | 'DISMISSBUTTONTEXT' => $DismissButtonText, 65 | 'DISMISSBUTTONSTYLE' => $DismissButtonStyle, 66 | 'CLASSES' => $this->DrawClasses(), 67 | 'TITLECLASSES' => $this->DrawClasses('title'), 68 | 'SUBTITLECLASSES' => $this->DrawClasses('subtitle'), 69 | 'BODYCLASSES' => $this->DrawClasses('body'), 70 | 'BODYSTYLES' => $this->DrawStyles('body'), 71 | 'TITLE' => $Title, 72 | 'SUBTITLE' => $SubTitle, 73 | 'CONTENT' => $Content->Draw(false), 74 | 'BUTTONS' => $buttons, 75 | ]); 76 | } 77 | } -------------------------------------------------------------------------------- Total de líneas: 77 ================================================================================ ================================================================================ ARCHIVO #442: src/Widget/Progress.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/Progress.php Tamaño: 1.84 KB -------------------------------------------------------------------------------- 1 | AddClasses($Classes); 36 | 37 | // Styles 38 | $this->AddStyles($Styles); 39 | 40 | // Attributes 41 | $this->AddAttributes($Attributes); 42 | $this->AddAttribute('id', $this->Key); 43 | 44 | // Properties 45 | $this->AddProperties($Properties); 46 | 47 | parent::__construct(Replace: [ 48 | 'CONTENT' => $Content, 49 | 'CLASSES' => $this->DrawClasses(), 50 | 'STYLES' => $this->DrawStyles(), 51 | 'ATTRIBUTES' => $this->DrawAttributes(), 52 | 'PROPERTIES' => $this->DrawProperties(), 53 | 'PERCENTAGE' => $this->Percentage, 54 | 'LABELSTYLE' => $this->LabelStyle . ' ' . $this->LabelSize, 55 | 'PROGRESSSTYLE' => $this->ProgressStyle, 56 | ]); 57 | } 58 | } -------------------------------------------------------------------------------- Total de líneas: 58 ================================================================================ ================================================================================ ARCHIVO #443: src/Widget/Script.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/Script.php Tamaño: 844 bytes -------------------------------------------------------------------------------- 1 | format('YmdHis') . random_int(1,5000); 24 | 25 | foreach($Scripts as $script) { 26 | if ($events != '') { 27 | $events .= "\n"; 28 | } 29 | $events .= $script; 30 | } 31 | 32 | parent::__construct(Replace: [ 33 | 'EVENTS' => $events, 34 | 'IDSCRIPT' => $id 35 | ]); 36 | } 37 | } -------------------------------------------------------------------------------- Total de líneas: 37 ================================================================================ ================================================================================ ARCHIVO #444: src/Widget/ScriptDirect.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/ScriptDirect.php Tamaño: 945 bytes -------------------------------------------------------------------------------- 1 | format('YmdHis') . random_int(1,5000); 25 | 26 | foreach($Scripts as $script) { 27 | if ($events != '') { 28 | $events .= "\n"; 29 | } 30 | $events .= $script; 31 | } 32 | 33 | parent::__construct(Replace: [ 34 | 'EVENTS' => $events, 35 | 'IDSCRIPT' => $id 36 | ]); 37 | } 38 | } -------------------------------------------------------------------------------- Total de líneas: 38 ================================================================================ ================================================================================ ARCHIVO #445: src/Widget/ScriptDirectSimple.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/ScriptDirectSimple.php Tamaño: 1.62 KB -------------------------------------------------------------------------------- 1 | format('YmdHis') . random_int(1,5000); 26 | 27 | foreach($Scripts as $script) { 28 | if ($events != '') { 29 | $events .= "\n"; 30 | } 31 | $events .= $script; 32 | } 33 | 34 | parent::__construct(Replace: [ 35 | 'EVENTS' => $events, 36 | 'IDSCRIPT' => $id, 37 | 'TIMEOUT' => $Timeout 38 | ]); 39 | } 40 | 41 | /* 42 | public function __construct( 43 | public array $Scripts, 44 | public ?string $Key = '', 45 | public ?int $Timeout = 60, 46 | ) 47 | { 48 | $events = ''; 49 | $id = (($Key != '') ? $Key . '_' : 'dynamicloaded_') . (new \DateTime())->format('YmdHis') . random_int(1,5000); 50 | 51 | foreach($Scripts as $script) { 52 | if ($events != '') { 53 | $events .= "\n"; 54 | } 55 | $events .= $script; 56 | } 57 | 58 | parent::__construct(Replace: [ 59 | 'EVENTS' => $events, 60 | 'IDSCRIPT' => $id, 61 | 'TIMEOUT' => $Timeout 62 | ]); 63 | } 64 | */ 65 | } -------------------------------------------------------------------------------- Total de líneas: 65 ================================================================================ ================================================================================ ARCHIVO #446: src/Widget/SexyTab.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/SexyTab.php Tamaño: 4.25 KB -------------------------------------------------------------------------------- 1 | AddClasses($Classes); 45 | $this->AddClasses(['sexytab-item ui-state-default ui-corner-top']); 46 | 47 | if ($Order == 1) { 48 | $this->AddClasses(['ui-tabs-active ui-state-active']); 49 | } 50 | 51 | $this->AddClasses($ActionClasses, 'action'); 52 | $this->AddClass('ui-tabs-anchor', 'action'); 53 | 54 | $this->AddClasses($TitleClasses, 'title'); 55 | 56 | // STYLES 57 | $this->AddStyles($Styles); 58 | $this->AddStyle('cursor', 'pointer'); 59 | 60 | $this->AddStyles($ActionStyles, 'action'); 61 | $this->AddStyles($TitleStyles, 'title'); 62 | 63 | // ATTRIBUTES 64 | $this->AddAttributes($Attributes); 65 | $this->AddAttributes([ 66 | 'id' => $Key, 67 | 'role' => 'tab', 68 | 'tabindex' => '0', 69 | 'aria-controls' => $key, 70 | 'aria-labelledby' => 'ui-id-' . $Order + 3, 71 | 'aria-selected' => ($Order == 1) ? 'true' : 'false', 72 | 'aria-expanded' => ($Order == 1) ? 'true' : 'false' 73 | ]); 74 | 75 | if ($Order == 1) { 76 | $this->AddAttribute('id', 'activas-init'); 77 | } 78 | 79 | $this->AddAttributes([ 80 | 'id' => 'ui-id-' . $Order + 3, 81 | 'href' => '#' . $key, 82 | 'role' => 'presentation', 83 | 'tabindex' => '-1' 84 | ], 'action'); 85 | 86 | // PROPERTIES 87 | $this->AddProperties($Properties); 88 | $this->AddProperties($ActionProperties, 'action'); 89 | $this->AddProperties($TitleProperties, 'title'); 90 | 91 | 92 | $icon = ''; 93 | if ($Icon != '') { 94 | $icon = (new FaIcon( 95 | Name: $Icon, 96 | Classes: ['fas', 'tab-icon'], 97 | Styles: [ 98 | 'font-size' => '20px', 99 | 'position' => 'relative', 100 | 'left' => '-8px', 101 | 'top' => '-5px' 102 | ] 103 | ))->Draw(false); 104 | } 105 | 106 | $title = (new Text( 107 | Content: $Title, 108 | Styles: [ 109 | 'top' => '0px' 110 | ] 111 | ))->Draw(false); 112 | 113 | parent::__construct(Replace: [ 114 | 'ICON' => $icon, 115 | 'TITLE' => $title, 116 | 'CLASSES' => $this->DrawClasses(), 117 | 'STYLES' => $this->DrawStyles(), 118 | 'ATTRIBUTES' => $this->DrawAttributes(), 119 | 'PROPERTIES' => $this->DrawProperties(), 120 | 'ACTIONCLASSES' => $this->DrawClasses('action'), 121 | 'ACTIONSTYLES' => $this->DrawStyles('action'), 122 | 'ACTIONATTRIBUTES' => $this->DrawAttributes('action'), 123 | 'ACTIONPROPERTIES' => $this->DrawProperties('action'), 124 | 'TITLECLASSES' => $this->DrawClasses('title'), 125 | 'TITLESTYLES' => $this->DrawStyles('title'), 126 | 'TITLEATTRIBUTES' => $this->DrawAttributes('title'), 127 | 'TITLEPROPERTIES' => $this->DrawProperties('title') 128 | ]); 129 | } 130 | } -------------------------------------------------------------------------------- Total de líneas: 130 ================================================================================ ================================================================================ ARCHIVO #447: src/Widget/SexyTabGroup.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/SexyTabGroup.php Tamaño: 3.63 KB -------------------------------------------------------------------------------- 1 | AddClasses($Classes); 38 | $this->AddClasses(['sexytabs ui-tabs ui-widget ui-widget-content ui-corner-all']); 39 | 40 | $this->AddClasses($ListClasses, 'list'); 41 | $this->AddClasses(['activas-ul ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all'], 'list'); 42 | 43 | $this->AddClasses($ContentClasses, 'content'); 44 | $this->AddClass('contents', 'content'); 45 | 46 | // STYLES 47 | $this->AddStyles($Styles); 48 | $this->AddStyles($ListStyles, 'list'); 49 | $this->AddStyles($ContentStyles, 'content'); 50 | 51 | // ATTRIBUTES 52 | $this->AddAttributes($Attributes); 53 | $this->AddAttribute('id', $Key); 54 | 55 | $this->AddAttributes($ListAttributes, 'list'); 56 | $this->AddAttributes($ContentAttributes, 'content'); 57 | 58 | $this->AddAttributes([ 59 | 'role' => 'tablist' 60 | ], 'list'); 61 | 62 | // PROPERTIES 63 | $this->AddProperties($Properties); 64 | $this->AddProperties($ListProperties, 'list'); 65 | $this->AddProperties($ContentProperties, 'content'); 66 | 67 | $items = ''; 68 | foreach($Tabs as $tab) { 69 | if ($tab instanceof SexyTab) { 70 | if ($items != '') { 71 | $items .= "\n"; 72 | } 73 | 74 | $items .= $tab->Draw(false); 75 | } 76 | } 77 | 78 | $contents = ''; 79 | foreach($Pages as $page) { 80 | if ($page instanceof SexyTabPage) { 81 | if ($contents != '') { 82 | $contents .= "\n"; 83 | } 84 | 85 | $contents .= $page->Draw(false); 86 | } 87 | } 88 | 89 | parent::__construct(Replace: [ 90 | 'TABS' => $items, 91 | 'PAGES' => $contents, 92 | 'CLASSES' => $this->DrawClasses(), 93 | 'STYLES' => $this->DrawStyles(), 94 | 'ATTRIBUTES' => $this->DrawAttributes(), 95 | 'PROPERTIES' => $this->DrawProperties(), 96 | 'LISTCLASSES' => $this->DrawClasses('list'), 97 | 'LISTSTYLES' => $this->DrawStyles('list'), 98 | 'LISTATTRIBUTES' => $this->DrawAttributes('list'), 99 | 'LISTPROPERTIES' => $this->DrawProperties('list'), 100 | 'CONTENTCLASSES' => $this->DrawClasses('content'), 101 | 'CONTENTSTYLES' => $this->DrawStyles('content'), 102 | 'CONTENTATTRIBUTES' => $this->DrawAttributes('content'), 103 | 'CONTENTPROPERTIES' => $this->DrawProperties('content'), 104 | ]); 105 | } 106 | } -------------------------------------------------------------------------------- Total de líneas: 106 ================================================================================ ================================================================================ ARCHIVO #448: src/Widget/SexyTabPage.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/SexyTabPage.php Tamaño: 3.27 KB -------------------------------------------------------------------------------- 1 | AddClasses($Classes); 41 | $this->AddClasses(['ui-tabs-panel ui-widget-content ui-corner-bottom']); 42 | 43 | if ($Order == 1) { 44 | $this->AddClasses(['ui-tabs-active ui-state-active']); 45 | } 46 | 47 | $this->AddClasses($ContentClasses, 'content'); 48 | 49 | // STYLES 50 | $this->AddStyles($Styles); 51 | $this->AddStyles($ContentStyles, 'content'); 52 | 53 | // ATTRIBUTES 54 | $this->AddAttributes($Attributes); 55 | $this->AddAttributes([ 56 | 'id' => $key, 57 | 'aria-labelledby' => 'ui-id-' . $Order + 3, 58 | 'role' => 'tabpanel', 59 | 'aria-hidden' => 'false', 60 | ]); 61 | 62 | if ($Order > 1) { 63 | $this->AddStyle('display', 'none'); 64 | } 65 | 66 | // PROPERTIES 67 | $this->AddProperties($Properties); 68 | $this->AddProperties($ContentProperties, 'content'); 69 | 70 | $topButtons = []; 71 | foreach($TopButtons as $button) { 72 | if ($button instanceof ActionButton) { 73 | array_push($topButtons, $button); 74 | } 75 | } 76 | 77 | $botonera = new Container( 78 | Classes: ['refresh-button-container'], 79 | Children: [ 80 | new Container( 81 | Classes: ['refresh-button-div'], 82 | Styles: [ 83 | 'z-index' => '999', 84 | ], 85 | Children: $topButtons 86 | ) 87 | ] 88 | ); 89 | 90 | parent::__construct(Replace: [ 91 | 'TOPBUTTONS' => $botonera->Draw(false), 92 | 'CONTENT' => $Content, 93 | 'CLASSES' => $this->DrawClasses(), 94 | 'STYLES' => $this->DrawStyles(), 95 | 'ATTRIBUTES' => $this->DrawAttributes(), 96 | 'PROPERTIES' => $this->DrawProperties(), 97 | 'CONTENTCLASSES' => $this->DrawClasses('content'), 98 | 'CONTENTSTYLES' => $this->DrawStyles('content'), 99 | 'CONTENTATTRIBUTES' => $this->DrawAttributes('content'), 100 | 'CONTENTPROPERTIES' => $this->DrawProperties('content'), 101 | ]); 102 | } 103 | } -------------------------------------------------------------------------------- Total de líneas: 103 ================================================================================ ================================================================================ ARCHIVO #449: src/Widget/SimpleList.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/SimpleList.php Tamaño: 2.15 KB -------------------------------------------------------------------------------- 1 | AddClasses($this->Classes); 33 | 34 | // Styles 35 | $this->AddStyles($this->Styles); 36 | $this->AddStyle('padding-left', '18px'); 37 | 38 | // Attributes 39 | $this->AddAttributes($this->Attributes); 40 | 41 | // Properties 42 | $this->AddProperties($this->Properties); 43 | 44 | if ($this->Key != '') { 45 | $this->AddAttribute('id', $this->Key); 46 | } 47 | 48 | $items = ''; 49 | foreach($this->Items as $item) { 50 | 51 | if (is_string($item)) { 52 | 53 | if ($items != '') { 54 | $items .= "\n"; 55 | } 56 | 57 | $items .= ( 58 | new SimpleListItem( 59 | Content: $item, 60 | Classes: $this->ItemClasses, 61 | Styles: $this->ItemStyles, 62 | Attributes: $this->ItemAttributes, 63 | Properties: $this->ItemProperties 64 | ) 65 | )->Draw(false); 66 | } 67 | } 68 | 69 | parent::__construct(Replace: [ 70 | 'ITEMS' => isset($items) ? $items : '', 71 | 'CLASSES' => $this->DrawClasses(), 72 | 'STYLES' => $this->DrawStyles(), 73 | 'ATTRIBUTES' => $this->DrawAttributes(), 74 | 'PROPERTIES' => $this->DrawProperties() 75 | ]); 76 | } 77 | } -------------------------------------------------------------------------------- Total de líneas: 77 ================================================================================ ================================================================================ ARCHIVO #450: src/Widget/SimpleListItem.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/SimpleListItem.php Tamaño: 1.24 KB -------------------------------------------------------------------------------- 1 | AddClasses($this->Classes); 28 | 29 | // Styles 30 | $this->AddStyles($this->Styles); 31 | 32 | // Attributes 33 | $this->AddAttributes($this->Attributes); 34 | 35 | // Properties 36 | $this->AddProperties($this->Properties); 37 | 38 | parent::__construct(Replace: [ 39 | 'CONTENT' => isset($Content) ? $Content : ' ', 40 | 'CLASSES' => $this->DrawClasses(), 41 | 'STYLES' => $this->DrawStyles(), 42 | 'ATTRIBUTES' => $this->DrawAttributes(), 43 | 'PROPERTIES' => $this->DrawProperties() 44 | ]); 45 | } 46 | } -------------------------------------------------------------------------------- Total de líneas: 46 ================================================================================ ================================================================================ ARCHIVO #451: src/Widget/SimpleScript.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/SimpleScript.php Tamaño: 856 bytes -------------------------------------------------------------------------------- 1 | format('YmdHis') . random_int(1,5000); 24 | 25 | foreach($Scripts as $script) { 26 | if ($events != '') { 27 | $events .= "\n"; 28 | } 29 | $events .= $script; 30 | } 31 | 32 | parent::__construct(Replace: [ 33 | 'EVENTS' => $events, 34 | 'IDSCRIPT' => $id 35 | ]); 36 | } 37 | } -------------------------------------------------------------------------------- Total de líneas: 37 ================================================================================ ================================================================================ ARCHIVO #452: src/Widget/Table.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/Table.php Tamaño: 2.79 KB -------------------------------------------------------------------------------- 1 | AddClass('table'); 32 | $this->AddClass('table-bordered'); 33 | 34 | $this->AddClasses($Classes); 35 | $this->AddStyles($Styles); 36 | $this->AddAttributes($Attributes); 37 | $this->AddProperties($Properties); 38 | 39 | if ($this->Key != '') { 40 | $this->AddAttribute('id', $this->Key); 41 | } 42 | 43 | // HEADER 44 | // 45 | $header = $this->Header->Draw(false); 46 | 47 | // BODY 48 | // 49 | if (count($this->Body->Rows) == 0) { 50 | // Crear un body vacío 51 | // cantidad de columnas las dicta la última fila del header (para casos multi-fila) 52 | if($JSRenderTheTable == true){ 53 | $body = (new TableBody( 54 | Rows: [ 55 | 56 | ] 57 | ))->Draw(false); 58 | }else{ 59 | $span = count($this->Header->Rows[count($this->Header->Rows)-1]->Columns); 60 | 61 | $body = (new TableBody( 62 | Rows: [ 63 | new TableRow( 64 | Columns: [ 65 | new TableColumn( 66 | Content: $this->EmptyMessage, 67 | Attributes: [ 68 | ['colspan', $span] 69 | ] 70 | ) 71 | ] 72 | ) 73 | ] 74 | ))->Draw(false); 75 | } 76 | } 77 | else { 78 | $body = $this->Body->Draw(false); 79 | } 80 | 81 | parent::__construct(Replace: [ 82 | 'HEADER' => $header, 83 | 'BODY' => $body, 84 | 'CLASSES' => $this->DrawClasses(), 85 | 'STYLES' => $this->DrawStyles(), 86 | 'ATTRIBUTES' => $this->DrawAttributes(), 87 | 'PROPERTIES' => $this->DrawProperties() 88 | ]); 89 | } 90 | } -------------------------------------------------------------------------------- Total de líneas: 90 ================================================================================ ================================================================================ ARCHIVO #453: src/Widget/TableBody.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/TableBody.php Tamaño: 1.06 KB -------------------------------------------------------------------------------- 1 | Rows as $row) { 31 | if ($row instanceof TableRow) { 32 | 33 | if ($rows != '') { 34 | $rows .= "\n"; 35 | } 36 | $rows .= $row->Draw(false); 37 | } 38 | } 39 | 40 | parent::__construct(Replace: [ 41 | 'ROWS' => $rows, 42 | ]); 43 | } 44 | } -------------------------------------------------------------------------------- Total de líneas: 44 ================================================================================ ================================================================================ ARCHIVO #454: src/Widget/TableColumn.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/TableColumn.php Tamaño: 1.67 KB -------------------------------------------------------------------------------- 1 | AddClasses($Classes); 30 | $this->AddStyles($Styles); 31 | $this->AddAttributes($Attributes); 32 | $this->AddProperties($Properties); 33 | 34 | if (isset($this->Object) && isset($this->FormatFunction) ) { 35 | // el objeto es un OBJECT o un ARRAY asociativo? 36 | if (is_array($this->Object)) { 37 | $obj = (object)$this->Object; 38 | } 39 | else { 40 | $obj = $this->Object; 41 | } 42 | 43 | // obtener el contenido evaluando la funcion 44 | $result = $FormatFunction($obj); 45 | } 46 | else { 47 | $result = $this->Content; 48 | } 49 | 50 | parent::__construct(Replace: [ 51 | 'CONTENT' => $result, 52 | 'CLASSES' => $this->DrawClasses(), 53 | 'STYLES' => $this->DrawStyles(), 54 | 'ATTRIBUTES' => $this->DrawAttributes(), 55 | 'PROPERTIES' => $this->DrawProperties() 56 | ]); 57 | } 58 | } -------------------------------------------------------------------------------- Total de líneas: 58 ================================================================================ ================================================================================ ARCHIVO #455: src/Widget/TableHeader.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/TableHeader.php Tamaño: 1010 bytes -------------------------------------------------------------------------------- 1 | Rows as $row) { 29 | if ($row instanceof TableHeaderRow) { 30 | if ($rows != '') { 31 | $rows .= "\n"; 32 | } 33 | $rows .= $row->Draw(false); 34 | } 35 | } 36 | 37 | parent::__construct(Replace: [ 38 | 'ROWS' => $rows, 39 | ]); 40 | } 41 | } -------------------------------------------------------------------------------- Total de líneas: 41 ================================================================================ ================================================================================ ARCHIVO #456: src/Widget/TableHeaderColumn.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/TableHeaderColumn.php Tamaño: 1.65 KB -------------------------------------------------------------------------------- 1 | WidthPercent)) { 31 | $this->AddStyle('width', $this->WidthPercent . '%'); 32 | } 33 | 34 | if ($this->Key != '') { 35 | $this->AddAttribute('id', $this->Key); 36 | } 37 | 38 | if ($this->Colspan != 1) { 39 | $this->AddAttribute('colspan', $this->Colspan); 40 | } 41 | 42 | if ($this->Rowspan != 1) { 43 | $this->AddAttribute('rowspan', $this->Rowspan); 44 | } 45 | 46 | $this->AddClasses($Classes); 47 | $this->AddStyles($Styles); 48 | $this->AddAttributes($Attributes); 49 | $this->AddProperties($Properties); 50 | 51 | parent::__construct(Replace: [ 52 | 'CONTENT' => $this->Title, 53 | 'CLASSES' => $this->DrawClasses(), 54 | 'STYLES' => $this->DrawStyles(), 55 | 'ATTRIBUTES' => $this->DrawAttributes(), 56 | 'PROPERTIES' => $this->DrawProperties() 57 | ]); 58 | } 59 | } -------------------------------------------------------------------------------- Total de líneas: 59 ================================================================================ ================================================================================ ARCHIVO #457: src/Widget/TableHeaderRow.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/TableHeaderRow.php Tamaño: 2.35 KB -------------------------------------------------------------------------------- 1 | Key != '') { 31 | $this->AddAttribute('id', $this->Key); 32 | } 33 | 34 | if ($this->Colspan != 1) { 35 | $this->AddAttribute('colspan', $this->Colspan); 36 | } 37 | 38 | $this->AddClasses($Classes); 39 | $this->AddStyles($Styles); 40 | $this->AddAttributes($Attributes); 41 | $this->AddProperties($Properties); 42 | 43 | $columns = ''; 44 | foreach($this->Columns as $column) { 45 | 46 | if ($column instanceof TableHeaderColumn) { 47 | if ($columns != "") { 48 | $columns .= "\n"; 49 | } 50 | $columns .= $column->Draw(false); 51 | } 52 | } 53 | 54 | 55 | parent::__construct(Replace: [ 56 | 'COLUMNS' => $columns, 57 | 'CLASSES' => $this->DrawClasses(), 58 | 'STYLES' => $this->DrawStyles(), 59 | 'ATTRIBUTES' => $this->DrawAttributes(), 60 | 'PROPERTIES' => $this->DrawProperties() 61 | ]); 62 | } 63 | 64 | public static function FromDefinitionArray(array $HeaderColumnDefinitions = []) { 65 | 66 | $columns = []; 67 | 68 | foreach($HeaderColumnDefinitions as $colDef) { 69 | 70 | $newCol = new TableHeaderColumn( 71 | Title: $colDef->Title, 72 | Rowspan: $colDef->Rowspan, 73 | Colspan: $colDef->Colspan, 74 | Classes: $colDef->Classes, 75 | Styles: $colDef->Styles, 76 | Attributes: $colDef->Attributes, 77 | Properties: $colDef->Properties 78 | ); 79 | 80 | array_push($columns, $newCol); 81 | } 82 | 83 | return new TableHeaderRow(Columns: $columns); 84 | } 85 | } -------------------------------------------------------------------------------- Total de líneas: 85 ================================================================================ ================================================================================ ARCHIVO #458: src/Widget/TableRow.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/TableRow.php Tamaño: 4.04 KB -------------------------------------------------------------------------------- 1 | AddClasses($Classes); 30 | $this->AddStyles($Styles); 31 | $this->AddAttributes($Attributes); 32 | $this->AddProperties($Properties); 33 | 34 | $columns = ''; 35 | foreach($this->Columns as $column) { 36 | 37 | if ($column instanceof TableColumn) { 38 | if ($columns != "") { 39 | $columns .= "\n"; 40 | } 41 | 42 | if ($column->PropertyName != '' && isset($this->FormatFunctions[$column->PropertyName])) { 43 | $column->FormatFunction = $this->FormatFunctions[$column->PropertyName]; 44 | } 45 | 46 | $columns .= $column->Draw(false); 47 | } 48 | } 49 | 50 | parent::__construct(Replace: [ 51 | 'COLUMNS' => $columns, 52 | 'CLASSES' => $this->DrawClasses(), 53 | 'STYLES' => $this->DrawStyles(), 54 | 'ATTRIBUTES' => $this->DrawAttributes(), 55 | 'PROPERTIES' => $this->DrawProperties() 56 | ]); 57 | } 58 | 59 | public static function FromArray(array $rows, array $formatFunctions = []) { 60 | 61 | $rows = []; 62 | 63 | foreach($rows as $cols) { 64 | $columns = []; 65 | foreach($cols as $name => $value) { 66 | 67 | if (isset($formatFunctions[$name])) { 68 | $formatFunction = $formatFunctions[$name]; 69 | } 70 | else { 71 | $formatFunction = null; 72 | } 73 | 74 | 75 | $newCol = new TableColumn( 76 | Content: $value, 77 | PropertyName: $name, 78 | FormatFunction: $formatFunction, 79 | Object: $cols 80 | ); 81 | 82 | array_push($columns, $newCol); 83 | } 84 | 85 | array_push( 86 | $rows, 87 | new TableRow(Columns: $columns) 88 | ); 89 | } 90 | 91 | return $rows; 92 | } 93 | 94 | public static function FromCollection(GenericCollection | null $Values, array $ColumnDefinitions = []) { 95 | 96 | $colDefs = []; 97 | 98 | foreach($ColumnDefinitions as $def) { 99 | $colDefs[$def->PropertyName] = $def; 100 | } 101 | 102 | $rows = []; 103 | 104 | if (isset($Values) && $Values->Count() > 0) { 105 | 106 | foreach($Values as $object) { 107 | $columns = []; 108 | foreach($colDefs as $prop => $colDef) { 109 | 110 | if (isset($colDef->FormatFunction)) { 111 | $formatFunction = $colDef->FormatFunction; 112 | } 113 | else { 114 | $formatFunction = null; 115 | } 116 | 117 | $newCol = new TableColumn( 118 | Content: isset($object->$prop) ? $object->$prop : '', 119 | PropertyName: $prop, 120 | Classes: $colDef->Classes, 121 | Styles: $colDef->Styles, 122 | Attributes: $colDef->Attributes, 123 | Properties: $colDef->Properties, 124 | FormatFunction: $formatFunction, 125 | Object: $object 126 | ); 127 | 128 | array_push($columns, $newCol); 129 | } 130 | 131 | array_push( 132 | $rows, 133 | new TableRow(Columns: $columns) 134 | ); 135 | } 136 | } 137 | 138 | return $rows; 139 | 140 | } 141 | } -------------------------------------------------------------------------------- Total de líneas: 141 ================================================================================ ================================================================================ ARCHIVO #459: src/Widget/Text.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/Text.php Tamaño: 1.34 KB -------------------------------------------------------------------------------- 1 | AddClasses($this->Classes); 29 | 30 | // Styles 31 | $this->AddStyles($this->Styles); 32 | 33 | // Attributes 34 | $this->AddAttributes($this->Attributes); 35 | 36 | // Properties 37 | $this->AddProperties($this->Properties); 38 | 39 | if ($this->Key != '') { 40 | $this->AddAttribute('id', $this->Key); 41 | } 42 | 43 | parent::__construct(Replace: [ 44 | 'CONTENT' => isset($Content) ? $Content : ' ', 45 | 'CLASSES' => $this->DrawClasses(), 46 | 'STYLES' => $this->DrawStyles(), 47 | 'ATTRIBUTES' => $this->DrawAttributes(), 48 | 'PROPERTIES' => $this->DrawProperties() 49 | ]); 50 | } 51 | } -------------------------------------------------------------------------------- Total de líneas: 51 ================================================================================ ================================================================================ ARCHIVO #460: src/Widget/TimeLineContainer.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/TimeLineContainer.php Tamaño: 3.77 KB -------------------------------------------------------------------------------- 1 | AddClasses(["v-timeline vertical-container animate-panel"]); 34 | $this->AddClasses($Classes); 35 | 36 | // Styles 37 | $this->AddStyles($Styles); 38 | 39 | if (isset($Padding)) { 40 | if (isset($Padding->Left)) { 41 | $this->AddStyle('padding-left', $Padding->Left . $Padding->Unit); 42 | } 43 | if (isset($Padding->Right)) { 44 | $this->AddStyle('padding-right', $Padding->Right . $Padding->Unit); 45 | } 46 | if (isset($Padding->Top)) { 47 | $this->AddStyle('padding-top', $Padding->Top . $Padding->Unit); 48 | } 49 | if (isset($Padding->Bottom)) { 50 | $this->AddStyle('padding-bottom', $Padding->Bottom . $Padding->Unit); 51 | } 52 | } 53 | 54 | if (isset($Margin)) { 55 | if (isset($Margin->Left)) { 56 | $this->AddStyle('margin-left', $Margin->Left . $Margin->Unit); 57 | } 58 | if (isset($Margin->Right)) { 59 | $this->AddStyle('margin-right', $Margin->Right . $Margin->Unit); 60 | } 61 | if (isset($Margin->Top)) { 62 | $this->AddStyle('margin-top', $Margin->Top . $Margin->Unit); 63 | } 64 | if (isset($Margin->Bottom)) { 65 | $this->AddStyle('margin-bottom', $Margin->Bottom . $Margin->Unit); 66 | } 67 | } 68 | 69 | if (isset($Position)) { 70 | 71 | $this->AddStyle('position', $Position->Type); 72 | 73 | if (isset($Position->Left)) { 74 | $this->AddStyle('left', $Position->Left . $Position->Unit); 75 | } 76 | if (isset($Position->Right)) { 77 | $this->AddStyle('right', $Position->Right . $Position->Unit); 78 | } 79 | if (isset($Position->Top)) { 80 | $this->AddStyle('top', $Position->Top . $Position->Unit); 81 | } 82 | if (isset($Position->Bottom)) { 83 | $this->AddStyle('bottom', $Position->Bottom . $Position->Unit); 84 | } 85 | } 86 | 87 | // Attributes 88 | $this->AddAttributes($Attributes); 89 | 90 | if ($Key != '') { 91 | $this->AddAttribute('id', $this->Key); 92 | } 93 | 94 | // Properties 95 | $this->AddProperties([ 96 | ["child","vertical-timeline-block"] 97 | ]); 98 | $this->AddProperties($Properties); 99 | 100 | 101 | $builder = ""; 102 | foreach ($Children as $child) { 103 | if ($child instanceof GenericWidget) { 104 | if ($builder != "") { 105 | $builder = $builder . "\n"; 106 | } 107 | $builder .= $child->Draw(false); 108 | } 109 | } 110 | 111 | parent::__construct(Replace: [ 112 | 'CONTENT' => $builder, 113 | 'CLASSES' => $this->DrawClasses(), 114 | 'STYLES' => $this->DrawStyles(), 115 | 'ATTRIBUTES' => $this->DrawAttributes(), 116 | 'PROPERTIES' => $this->DrawProperties() 117 | ]); 118 | } 119 | } -------------------------------------------------------------------------------- Total de líneas: 119 ================================================================================ ================================================================================ ARCHIVO #461: src/Widget/TimeLineItem.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/TimeLineItem.php Tamaño: 6.29 KB -------------------------------------------------------------------------------- 1 | AddClasses(["vertical-timeline-block"]); 49 | $this->AddClasses($Classes); 50 | 51 | // Styles 52 | $this->AddStyles($Styles); 53 | 54 | if (isset($Padding)) { 55 | if (isset($Padding->Left)) { 56 | $this->AddStyle('padding-left', $Padding->Left . $Padding->Unit); 57 | } 58 | if (isset($Padding->Right)) { 59 | $this->AddStyle('padding-right', $Padding->Right . $Padding->Unit); 60 | } 61 | if (isset($Padding->Top)) { 62 | $this->AddStyle('padding-top', $Padding->Top . $Padding->Unit); 63 | } 64 | if (isset($Padding->Bottom)) { 65 | $this->AddStyle('padding-bottom', $Padding->Bottom . $Padding->Unit); 66 | } 67 | } 68 | 69 | if (isset($Margin)) { 70 | if (isset($Margin->Left)) { 71 | $this->AddStyle('margin-left', $Margin->Left . $Margin->Unit); 72 | } 73 | if (isset($Margin->Right)) { 74 | $this->AddStyle('margin-right', $Margin->Right . $Margin->Unit); 75 | } 76 | if (isset($Margin->Top)) { 77 | $this->AddStyle('margin-top', $Margin->Top . $Margin->Unit); 78 | } 79 | if (isset($Margin->Bottom)) { 80 | $this->AddStyle('margin-bottom', $Margin->Bottom . $Margin->Unit); 81 | } 82 | } 83 | 84 | if (isset($Position)) { 85 | 86 | $this->AddStyle('position', $Position->Type); 87 | 88 | if (isset($Position->Left)) { 89 | $this->AddStyle('left', $Position->Left . $Position->Unit); 90 | } 91 | if (isset($Position->Right)) { 92 | $this->AddStyle('right', $Position->Right . $Position->Unit); 93 | } 94 | if (isset($Position->Top)) { 95 | $this->AddStyle('top', $Position->Top . $Position->Unit); 96 | } 97 | if (isset($Position->Bottom)) { 98 | $this->AddStyle('bottom', $Position->Bottom . $Position->Unit); 99 | } 100 | } 101 | 102 | // Attributes 103 | $this->AddAttributes($Attributes); 104 | 105 | if ($Key != '') { 106 | $this->AddAttribute('id', $this->Key); 107 | } 108 | 109 | // Properties 110 | $this->AddProperties([ 111 | ["child","vertical-timeline-block"] 112 | ]); 113 | $this->AddProperties($Properties); 114 | 115 | // ---------------------------------------------------------------------------------- 116 | // DEFINICIÓN ESPECIAL DEL WIDGET 117 | // ---------------------------------------------------------------------------------- 118 | 119 | //-- definicion del avatar por defecto en caso de que se encuentre vacio 120 | if(empty($AvatarUrl)){ 121 | $AvatarUrl = "/assets/avatar/default/USER.png"; 122 | } 123 | //-- definicion de la fecha de creación 124 | setlocale(LC_ALL,"es_ES"); 125 | $daynumber = $FechaCreacion->format('w'); 126 | $dias = ["Domingo","Lunes","Martes","Miercoles","Jueves","Viernes","Sábado"]; 127 | $WG_DAYNAME = $dias[$daynumber]; 128 | $WG_FechaCreacion = $FechaCreacion->format('d-m-Y'); 129 | $WG_HoraCreacion = $FechaCreacion->format('H:i'); 130 | 131 | //--- verifico si viene la fecha en la que se sincronizo la bitacora 132 | $Sincronizado = ""; 133 | if(!empty($FechaSincronizado) AND $FechaSincronizado instanceof DateTime){ 134 | 135 | $Sincronizado = " Sincronizado: ". $FechaSincronizado->format('d-m-Y H:i') . " Hrs"; 136 | 137 | } 138 | 139 | //--- verifico que venga un label de decoración 140 | $LabelHtml = ""; 141 | if($Label instanceof GenericWidget){ 142 | $LabelHtml = $Label->Draw(false); 143 | } 144 | 145 | 146 | parent::__construct(Replace: [ 147 | // DEFINICION ESTANDAR DEL WIDGET 148 | 'CLASSES' => $this->DrawClasses(), 149 | 'STYLES' => $this->DrawStyles(), 150 | 'ATTRIBUTES' => $this->DrawAttributes(), 151 | 'PROPERTIES' => $this->DrawProperties(), 152 | // DEFINICION ESPECIAL DEL WIDGET 153 | 'AVATAR_URL' => $AvatarUrl, 154 | 'ORIGEN_SRC' => $Origen, 155 | 'FECHA_CREACION' => $WG_FechaCreacion, 156 | 'HORA_CREACION' => $WG_HoraCreacion, 157 | 'DAY_NAME' => $WG_DAYNAME, 158 | 'CONTENT' => $Content, 159 | 'USERNAME' => $Username, 160 | 'SINCRONIZADO' => $Sincronizado, 161 | 'LABEL' => $LabelHtml, 162 | 'TIMELINESTYLE' => $TimeLineStyle 163 | 164 | ]); 165 | } 166 | } -------------------------------------------------------------------------------- Total de líneas: 166 ================================================================================ ================================================================================ ARCHIVO #462: src/Widget/TitleDescription.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/TitleDescription.php Tamaño: 3.62 KB -------------------------------------------------------------------------------- 1 | AddClasses($Classes); 39 | $this->AddClasses($TitleClasses, 'title'); 40 | $this->AddClasses(['font-light title-text'], 'title'); 41 | $this->AddClasses($DescriptionClasses, 'description'); 42 | $this->AddClasses(['font-light description-text'], 'description'); 43 | 44 | // Styles 45 | $this->AddStyles($Styles); 46 | $this->AddStyles($TitleStyles, 'title'); 47 | $this->AddStyles($DescriptionStyles, 'description'); 48 | 49 | // Attributes 50 | $this->AddAttributes($Attributes); 51 | $this->AddAttributes($TitleAttributes, 'title'); 52 | $this->AddAttributes($DescriptionAttributes, 'description'); 53 | 54 | // Properties 55 | $this->AddProperties($Properties); 56 | $this->AddProperties($TitleProperties, 'title'); 57 | $this->AddProperties($DescriptionProperties, 'description'); 58 | 59 | if (isset($IconName)) { 60 | $icon = ( 61 | new FaIcon( 62 | Name: $IconName, 63 | Styles: [ 64 | ['font-size', '36px'], ['color', $IconColor] 65 | ] 66 | ) 67 | )->Draw(false); 68 | $this->AddStyle('display', 'flex', 'main'); 69 | $this->AddStyle('flex-grow', '1'); 70 | $this->AddStyle('width', '52px', 'icon'); 71 | } 72 | else { 73 | $icon = ''; 74 | } 75 | 76 | parent::__construct(Replace: [ 77 | 'TITLE' => $this->Title, 78 | 'DESCRIPTION' => $this->Description, 79 | 'ICON' => $icon, 80 | 'MAINSTYLES' => $this->DrawStyles('main'), 81 | 'ICONSTYLES' => $this->DrawStyles('icon'), 82 | 'CLASSES' => $this->DrawClasses(), 83 | 'STYLES' => $this->DrawStyles(), 84 | 'ATTRIBUTES' => $this->DrawAttributes(), 85 | 'PROPERTIES' => $this->DrawProperties(), 86 | 'TITLECLASSES' => $this->DrawClasses('title'), 87 | 'TITLESTYLES' => $this->DrawStyles('title'), 88 | 'TITLEATTRIBUTES' => $this->DrawAttributes('title'), 89 | 'TITLEPROPERTIES' => $this->DrawProperties('title'), 90 | 'DESCRIPTIONCLASSES' => $this->DrawClasses('description'), 91 | 'DESCRIPTIONSTYLES' => $this->DrawStyles('description'), 92 | 'DESCRIPTIONATTRIBUTES' => $this->DrawAttributes('description'), 93 | 'DESCRIPTIONPROPERTIES' => $this->DrawProperties('description') 94 | ]); 95 | } 96 | } -------------------------------------------------------------------------------- Total de líneas: 96 ================================================================================ ================================================================================ ARCHIVO #463: src/Widget/Waiting.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/Waiting.php Tamaño: 1.40 KB -------------------------------------------------------------------------------- 1 | AddClasses($this->Classes); 30 | 31 | if ($Hidden) { 32 | $this->AddClass('hide'); 33 | } 34 | 35 | // Styles 36 | $this->AddStyles($this->Styles); 37 | 38 | // Attributes 39 | $this->AddAttributes($this->Attributes); 40 | 41 | // Properties 42 | $this->AddProperties($this->Properties); 43 | 44 | parent::__construct(Replace: [ 45 | 'TITLE' => $Title, 46 | 'SUBTITLE' => $SubTitle, 47 | 'CLASSES' => $this->DrawClasses(), 48 | 'STYLES' => $this->DrawStyles(), 49 | 'ATTRIBUTES' => $this->DrawAttributes(), 50 | 'PROPERTIES' => $this->DrawProperties() 51 | ]); 52 | } 53 | } -------------------------------------------------------------------------------- Total de líneas: 53 ================================================================================ ================================================================================ ARCHIVO #464: src/Widget/ZingChart.php ================================================================================ Ruta: /var/www/html/intouch/v4/framework/src/Widget/ZingChart.php Tamaño: 1.57 KB -------------------------------------------------------------------------------- 1 | AddClasses($Classes); 29 | $this->AddStyles($Styles); 30 | $this->AddAttributes($Attributes); 31 | $this->AddProperties($Properties); 32 | 33 | $script = new ScriptDirectSimple( 34 | Key: 'chart_' . $ZChart->Key, 35 | Scripts: [ 36 | $ZChart->Draw(false) 37 | ], 38 | Timeout: $Timeout 39 | ); 40 | 41 | $scriptContent = $script->Draw(false); 42 | 43 | parent::__construct(Replace: [ 44 | 'KEY' => $ZChart->Key, 45 | 'ATTRIBUTES' => $this->DrawAttributes(), 46 | 'PROPERTIES' => $this->DrawProperties(), 47 | 'CLASSES' => $this->DrawClasses(), 48 | 'STYLES' => $this->DrawStyles(), 49 | 'SCRIPT' => $scriptContent, 50 | ] 51 | ); 52 | } 53 | } -------------------------------------------------------------------------------- Total de líneas: 53 ================================================================================ ================================================================================ FIN DE LA DOCUMENTACIÓN ================================================================================ Generado el: 2025-11-03 20:16:06 Total de archivos documentados: 464 Tamaño total del código fuente: 1.52 MB Esta documentación ha sido generada para el registro del InTouch Framework en el Departamento de Derechos Intelectuales de Chile. Autor: Claudio Alfonso González Almeyda Copyright 2018 - 2025. Todos los derechos reservados.