api.yalfsysconf.php 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. <?php
  2. /**
  3. * System configuration editor class
  4. */
  5. class YalfSysConf {
  6. /**
  7. * Contains configs array editable from web as filePath=>just name
  8. *
  9. * @var array
  10. */
  11. protected $editableConfigs = array();
  12. /**
  13. * Message helper system object placeholder
  14. *
  15. * @var object
  16. */
  17. protected $messages = '';
  18. /**
  19. * Some URLs, routes.. etc
  20. */
  21. const URL_ME = '?module=sysconf';
  22. const ROUTE_EDIT = 'editconfig';
  23. const ROUTE_PHPINFO = 'phpinfo';
  24. const PROUTE_FILEPATH = 'editfilepath';
  25. const PROUTE_FILECONTENT = 'editfilecontent';
  26. public function __construct() {
  27. $this->initMessages();
  28. $this->loadEditableConfigs();
  29. }
  30. /**
  31. * Inits system messages helper for further usage
  32. *
  33. * @return void
  34. */
  35. protected function initMessages() {
  36. $this->messages = new UbillingMessageHelper();
  37. }
  38. /**
  39. * Loads config files editable from web
  40. *
  41. * @return void
  42. */
  43. protected function loadEditableConfigs() {
  44. global $system;
  45. $rawConf = parse_ini_file($system::YALF_CONF_PATH);
  46. if (!empty($rawConf)) {
  47. if (isset($rawConf['YALF_EDITABLE_CONFIGS'])) {
  48. if (!empty($rawConf['YALF_EDITABLE_CONFIGS'])) {
  49. $rawOption = explode(',', $rawConf['YALF_EDITABLE_CONFIGS']);
  50. if (!empty($rawOption)) {
  51. foreach ($rawOption as $index => $eachConfig) {
  52. $this->editableConfigs[$eachConfig] = basename($eachConfig);
  53. }
  54. }
  55. }
  56. }
  57. }
  58. }
  59. /**
  60. * Renders list of available and required PHP extensions
  61. *
  62. * @return string
  63. */
  64. protected function checkPHPExtensions() {
  65. $result = '';
  66. $result = '';
  67. if (file_exists(CONFIG_PATH . 'optsextcfg')) {
  68. $allRequired = file_get_contents(CONFIG_PATH . 'optsextcfg');
  69. if (!empty($allRequired)) {
  70. $allRequired = explodeRows($allRequired);
  71. if (!empty($allRequired)) {
  72. foreach ($allRequired as $io => $each) {
  73. if (!empty($each)) {
  74. $each = trim($each);
  75. $notice = '';
  76. if (!extension_loaded($each)) {
  77. switch ($each) {
  78. case 'mysql':
  79. $notice = ' ' . __('Deprecated in') . ' PHP 7.0';
  80. break;
  81. case 'ereg':
  82. $notice = ' ' . __('Deprecated in') . ' PHP 7.0';
  83. break;
  84. case 'memcache':
  85. $notice = ' ' . __('Deprecated in') . ' PHP 7.0';
  86. break;
  87. case 'xhprof':
  88. $notice = ' ' . __('May require manual installation');
  89. break;
  90. }
  91. $result .= wf_tag('span', false, 'alert_error') . __('PHP extension not found') . ': ' . $each . $notice . wf_tag('span', true);
  92. } else {
  93. $result .= wf_tag('span', false, 'alert_success') . __('PHP extension loaded') . ': ' . $each . wf_tag('span', true);
  94. }
  95. }
  96. }
  97. }
  98. }
  99. } else {
  100. $result .= $this->messages->getStyledMessage(__('Strange exeption') . ': OPTSEXTCFG_NOT_FOUND', 'error');
  101. }
  102. return($result);
  103. }
  104. /**
  105. * Renders module controls
  106. *
  107. * @return string
  108. */
  109. public function renderControls() {
  110. $result = '';
  111. if (!empty($this->editableConfigs)) {
  112. foreach ($this->editableConfigs as $eachPath => $eachName) {
  113. $encPath = base64_encode($eachPath);
  114. $result .= wf_Link(self::URL_ME . '&' . self::ROUTE_EDIT . '=' . $encPath, web_edit_icon() . ' ' . $eachName, false, 'ubButton');
  115. }
  116. }
  117. $sysInfoData = '';
  118. $phpInfoCode = wf_modal(wf_img('skins/icon_puzzle.png') . ' ' . __('Check required PHP extensions'), __('Check required PHP extensions'), $this->checkPHPExtensions(), 'ubButton', '800', '600');
  119. $phpInfoCode .= wf_tag('br');
  120. $phpInfoCode .= wf_tag('iframe', false, '', 'src="' . self::URL_ME . '&' . self::ROUTE_PHPINFO . '=true" width="1000" height="500" frameborder="0"') . wf_tag('iframe', true);
  121. $result .= wf_modalAuto(wf_img('skins/icon_php.png') . ' ' . __('Information about PHP version'), __('Information about PHP version'), $phpInfoCode, 'ubButton');
  122. return($result);
  123. }
  124. /**
  125. * Returns simple text editing form
  126. *
  127. * @param string $path
  128. * @param string $content
  129. *
  130. * @return string
  131. */
  132. protected function fileEditorForm($path, $content) {
  133. $result = '';
  134. $content = htmlentities($content, ENT_COMPAT, "UTF-8");
  135. $inputs = wf_HiddenInput(self::PROUTE_FILEPATH, $path);
  136. $inputs .= wf_tag('textarea', false, 'fileeditorarea', 'name="' . self::PROUTE_FILECONTENT . '" cols="145" rows="30"');
  137. $inputs .= $content;
  138. $inputs .= wf_tag('textarea', true);
  139. $inputs .= wf_tag('br');
  140. $inputs .= wf_Submit(__('Save'));
  141. $result .= wf_Form('', 'POST', $inputs, 'glamour');
  142. $result .= wf_delimiter();
  143. $result .= wf_BackLink(self::URL_ME);
  144. return ($result);
  145. }
  146. /**
  147. * Catches editing request and render edit area if required
  148. *
  149. * @return string
  150. */
  151. public function renderFileEditor() {
  152. $result = '';
  153. if (ubRouting::checkGet(self::ROUTE_EDIT)) {
  154. $fileToEdit = base64_decode(ubRouting::get(self::ROUTE_EDIT));
  155. if (file_exists($fileToEdit)) {
  156. if (is_readable($fileToEdit)) {
  157. if (is_writable($fileToEdit)) {
  158. $fileContent = file_get_contents($fileToEdit);
  159. $result .= $this->fileEditorForm($fileToEdit, $fileContent);
  160. } else {
  161. $result .= $this->messages->getStyledMessage(__('File is not writable') . ': ' . $fileToEdit, 'error');
  162. }
  163. } else {
  164. $result .= $this->messages->getStyledMessage(__('Cant read file') . ': ' . $fileToEdit, 'error');
  165. }
  166. } else {
  167. $result .= $this->messages->getStyledMessage(__('File not exists') . ': ' . $fileToEdit, 'error');
  168. }
  169. }
  170. return($result);
  171. }
  172. /**
  173. * Saves editing file if its exists/readable/writable on receiving expected POST variables
  174. *
  175. * @return void/string on error
  176. */
  177. public function saveFile() {
  178. $result = '';
  179. if (ubRouting::checkPost(array(self::PROUTE_FILECONTENT, self::PROUTE_FILEPATH))) {
  180. $fileToEdit = ubRouting::post(self::PROUTE_FILEPATH);
  181. if (file_exists($fileToEdit)) {
  182. if (is_readable($fileToEdit)) {
  183. if (is_writable($fileToEdit)) {
  184. $fileContent = ubRouting::post(self::PROUTE_FILECONTENT);
  185. if (ispos($fileContent, "\r\n")) {
  186. //cleanup to unix EOL
  187. $fileContent = str_replace("\r\n", "\n", $fileContent);
  188. }
  189. file_put_contents($fileToEdit, $fileContent);
  190. log_register('SYSCONF UPDATE FILE `' . $fileToEdit . '`');
  191. } else {
  192. $result .= __('File is not writable') . ': ' . $fileToEdit;
  193. }
  194. } else {
  195. $result .= __('Cant read file') . ': ' . $fileToEdit;
  196. }
  197. } else {
  198. $result .= __('File not exists') . ': ' . $fileToEdit;
  199. }
  200. }
  201. return($result);
  202. }
  203. }