3
1

TemplateController.php 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. <?php namespace Kanboard\Plugin\OMITemplateModder\Controller;
  2. use Kanboard\Controller\BaseController;
  3. /**
  4. * TemplateController Controller
  5. *
  6. * @package Kanboard\Plugin\OMITemplateModder
  7. * @author Dwayne @ OMI NZ
  8. */
  9. class TemplateController extends BaseController {
  10. /**
  11. * Show all the available templates.
  12. */
  13. public function show() {
  14. $templates = $this->getEditableTemplates();
  15. $missingTemplates = array_diff($this->getCoreTemplates(), $this->getPluginTemplates());
  16. $extraTemplates = array_diff($this->getPluginTemplates(), $this->getCoreTemplates());
  17. $modifiedStatus = $this->getModifiedStatus();
  18. $this->response->html($this->helper->layout->config("OMITemplateModder:config/index", [
  19. "title" => t("OMI - Notification Template Modder"),
  20. "templates" => $templates,
  21. "missing_templates" => $missingTemplates,
  22. "extra_templates" => $extraTemplates,
  23. "modified_status" => $modifiedStatus,
  24. ]));
  25. }
  26. /**
  27. * Get a list of editable templates from the plugin's directory.
  28. *
  29. * @return array
  30. */
  31. private function getEditableTemplates() {
  32. $templates = [];
  33. $templateDir = ETM_PLUGIN_ROOT_DIR . "/Template/notification";
  34. foreach (glob($templateDir . "/*.php") as $filename) {
  35. $templateName = basename($filename, ".php");
  36. $templates[] = "notification/" . $templateName;
  37. }
  38. return $templates;
  39. }
  40. /**
  41. * Get a list of core notification templates.
  42. *
  43. * @return array
  44. */
  45. private function getCoreTemplates() {
  46. $templates = [];
  47. // Use the new custom constant defined in Plugin.php
  48. $templateDir = KB_APP_DIR . "/Template/notification";
  49. foreach (glob($templateDir . "/*.php") as $filename) {
  50. $templates[] = basename($filename, ".php");
  51. }
  52. return $templates;
  53. }
  54. /**
  55. * Get a list of plugin notification templates.
  56. *
  57. * @return array
  58. */
  59. private function getPluginTemplates() {
  60. $templates = [];
  61. $templateDir = ETM_PLUGIN_ROOT_DIR . "/Template/notification";
  62. foreach (glob($templateDir . "/*.php") as $filename) {
  63. $templates[] = basename($filename, ".php");
  64. }
  65. return $templates;
  66. }
  67. /**
  68. * Compares core and plugin templates by file content to check for modifications.
  69. *
  70. * @return array
  71. */
  72. private function getModifiedStatus()
  73. {
  74. $modified = [];
  75. $pluginTemplateDir = ETM_PLUGIN_ROOT_DIR . '/Template/notification';
  76. $coreTemplateDir = KB_APP_DIR . '/Template/notification';
  77. foreach (glob($pluginTemplateDir . '/*.php') as $filename) {
  78. $templateName = basename($filename);
  79. $pluginFile = $pluginTemplateDir . '/' . $templateName;
  80. $coreFile = $coreTemplateDir . '/' . $templateName;
  81. // Only compare if the core file exists
  82. if (file_exists($coreFile)) {
  83. $pluginContent = file_get_contents($pluginFile);
  84. $coreContent = file_get_contents($coreFile);
  85. // Compare the file contents
  86. if ($pluginContent !== $coreContent) {
  87. $modified[$templateName] = true;
  88. }
  89. }
  90. }
  91. return $modified;
  92. }
  93. /**
  94. * Show the form to edit a template
  95. */
  96. public function edit() {
  97. $templateIndex = $this->request->getIntegerParam("template_index");
  98. $templates = $this->getEditableTemplates();
  99. if (!isset($templates[$templateIndex])) {
  100. $this->flash->failure(t("Template not found!"));
  101. return $this->response->redirect($this->helper->url->to("TemplateController", "show", ["plugin" => "OMITemplateModder"]));
  102. }
  103. $templateName = $templates[$templateIndex];
  104. $templatePath = $this->getTemplatePath($templateName);
  105. if (!file_exists($templatePath)) {
  106. $this->flash->failure(t("Template file not found!"));
  107. return $this->response->redirect($this->helper->url->to("TemplateController", "show", ["plugin" => "OMITemplateModder"]));
  108. }
  109. $templateContent = file_get_contents($templatePath);
  110. // Use the layout helper to render the page with the full Kanboard layout.
  111. $this->response->html($this->helper->layout->config("OMITemplateModder:config/edit", [
  112. "title" => t("OMI - Notification Template Modder"),
  113. "subtitle" => t("Edit Template: %s", $templateName),
  114. "templateName" => $templateName,
  115. "templateContent" => htmlspecialchars($templateContent),
  116. "templateIndex" => $templateIndex // Pass the index for the form action
  117. ]));
  118. }
  119. /**
  120. * Save the edited template
  121. */
  122. public function save() {
  123. $templateIndex = $this->request->getIntegerParam("template_index");
  124. $templates = $this->getEditableTemplates();
  125. if (!isset($templates[$templateIndex])) {
  126. $this->flash->failure(t("Template not found! Check your Kanboard version is compatible with this plugin."));
  127. return $this->response->redirect($this->helper->url->to("TemplateController", "show", ["plugin" => "OMITemplateModder"]));
  128. }
  129. $templateName = $templates[$templateIndex];
  130. $templateContent = $this->request->getValue("content");
  131. $templatePath = $this->getTemplatePath($templateName);
  132. //check if the realpath of the file to be saved begins with the realpath of the allowed directory.
  133. $allowedDir = realpath(\ETM_PLUGIN_ROOT_DIR . "/Template/notification");
  134. $realTemplatePath = realpath($templatePath);
  135. if ($realTemplatePath === false || strpos($realTemplatePath, $allowedDir) !== 0) {
  136. $this->flash->failure(t("Invalid template path."));
  137. return $this->response->redirect($this->helper->url->to("TemplateController", "show", ["plugin" => "OMITemplateModder"]));
  138. }
  139. // Try to save the file
  140. if (file_put_contents($templatePath, $templateContent) !== false) {
  141. $this->flash->success(t("Template saved successfully."));
  142. } else {
  143. $this->flash->failure(t("Unable to save template. Please check file permissions and directory '_DIR_' set up."));
  144. }
  145. return $this->response->redirect($this->helper->url->to("TemplateController", "edit", ["plugin" => "OMITemplateModder", "template_index" => $templateIndex]));
  146. }
  147. /**
  148. * Get the full path to a template file
  149. *
  150. * @param string $templateName
  151. * @return string
  152. */
  153. private function getTemplatePath($templateName) {
  154. return \ETM_PLUGIN_ROOT_DIR . "/Template/" . $templateName . ".php";
  155. }
  156. }
  157. #-
  158. #plugins/OMITemplateModder/Controller/TemplateController.php