1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15:
16:
17: defined('CON_FRAMEWORK') || die('Illegal call: Missing framework initialization - request aborted.');
18:
19: cInclude('external', 'codemirror/class.codemirror.php');
20: cInclude('includes', 'functions.file.php');
21:
22: 23: 24: 25: 26: 27:
28: class cModuleTemplateHandler extends cModuleHandler {
29:
30:
31: private $_code;
32:
33: private $_file;
34:
35: private $_tmpFile;
36:
37: private $_area;
38:
39: private $_frame;
40:
41: private $_status;
42:
43: private $_action;
44:
45: private $_new;
46:
47: private $_delete;
48:
49: private $_selectedFile;
50:
51: private $_reloadScript;
52:
53: private $_page = NULL;
54:
55: private $_notification = NULL;
56:
57: 58: 59: 60: 61:
62: private $_templateFileEnding = 'html';
63:
64: 65: 66: 67: 68:
69: private $_newFileName = 'newfilename';
70:
71: 72: 73: 74: 75:
76: private $_actionCreate = 'htmltpl_create';
77:
78: 79: 80: 81: 82:
83: private $_actionEdit = 'htmltpl_edit';
84:
85: 86: 87: 88: 89:
90: private $_actionDelete = 'htmltpl_delete';
91:
92: 93: 94: 95: 96:
97: private $_testArea = 'htmltpl';
98:
99: public function __construct($idmod, $page) {
100: parent::__construct($idmod);
101: $this->_page = $page;
102: $this->_notification = new cGuiNotification();
103: }
104:
105: 106: 107: 108: 109: 110: 111:
112: public function setNewDelete($new, $delete) {
113: $this->_new = $new;
114: $this->_delete = $delete;
115: }
116:
117: 118: 119: 120: 121:
122: public function setCode($code) {
123: $this->_code = stripslashes($code);
124: }
125:
126: 127: 128: 129: 130:
131: public function setSelectedFile($selectedFile) {
132: $this->_selectedFile = $selectedFile;
133: }
134:
135: 136: 137: 138: 139: 140: 141:
142: public function setFiles($file, $tmpFile) {
143: $this->_file = $file;
144: $this->_tmpFile = $tmpFile;
145: }
146:
147: 148: 149: 150: 151:
152: public function setStatus($status) {
153: $this->_status = $status;
154: }
155:
156: 157: 158: 159: 160: 161: 162:
163: public function setFrameIdmodArea($frame, $idmod, $area) {
164: $this->_frame = $frame;
165: $this->_idmod = $idmod;
166: $this->_area = $area;
167: }
168:
169: 170: 171: 172: 173:
174: public function setAction($action) {
175: $this->_action = $action;
176: }
177:
178: 179: 180: 181: 182: 183:
184: public function checkWritePermissions() {
185: if ($this->moduleWriteable('template') == false && cFileHandler::exists(parent::getModulePath() . $this->_directories['template'])) {
186: return $this->_notification->displayNotification(cGuiNotification::LEVEL_WARNING, i18n("You have no write permissions for this module"));
187: } else {
188: return true;
189: }
190: }
191:
192: 193: 194: 195: 196: 197: 198:
199: private function _getAction() {
200: global $newModTpl, $deleteModTpl;
201:
202: if (isset($this->_status)) {
203:
204: if (isset($newModTpl)) {
205: return 'new';
206: }
207:
208: if (isset($deleteModTpl)) {
209: return 'delete';
210: }
211:
212: if (isset($this->_file) && isset($this->_tmpFile)) {
213: if ($this->_file == $this->_tmpFile) {
214:
215:
216: if (empty($this->_file)) {
217: return 'empty';
218: } else {
219: return 'save';
220: }
221: }
222:
223: if ($this->_file != $this->_tmpFile) {
224: return 'rename';
225: }
226: } else {
227:
228: throw new cException(i18n('Field of the file name is empty!'));
229: }
230: } else {
231: return 'default';
232: }
233: }
234:
235: 236: 237: 238: 239:
240: private function _hasSelectedFileChanged() {
241: if ($this->_file != $this->_selectedFile) {
242: return true;
243: } else {
244: return false;
245: }
246: }
247:
248: 249: 250:
251: private function _save() {
252:
253: if ($this->_hasSelectedFileChanged()) {
254: $this->_file = $this->_selectedFile;
255: $this->_tmpFile = $this->_selectedFile;
256: }
257:
258: if (isset($this->_code)) {
259:
260: $tpl = cSmartyFrontend::getInstance();
261: $tpl->clearCache($this->getTemplatePath($this->_file));
262:
263:
264: $ret = $this->createModuleFile('template', $this->_file, $this->_code);
265:
266: if (true === $ret) {
267: $this->_notification->displayNotification(cGuiNotification::LEVEL_INFO, i18n('Saved changes successfully!'));
268: }
269: }
270: }
271:
272: 273: 274: 275: 276:
277: private function _rename() {
278:
279: $tpl = cSmartyFrontend::getInstance();
280: $tpl->clearCache($this->getTemplatePath($this->_tmpFile));
281: $tpl->clearCache($this->getTemplatePath($this->_file));
282:
283: if ($this->renameModuleFile('template', $this->_tmpFile, $this->_file) == false) {
284: throw new cException(i18n('Rename of the file failed!'));
285: } else {
286: $this->createModuleFile('template', $this->_file, $this->_code);
287: $this->_notification->displayNotification(cGuiNotification::LEVEL_INFO, i18n('Renamed the template file successfully!'));
288: $this->_tmpFile = $this->_file;
289: }
290: }
291:
292: 293: 294:
295: private function _new() {
296: $fileName = $this->_newFileName;
297:
298:
299: if ($this->existFile('template', $this->_newFileName . '.' . $this->_templateFileEnding)) {
300: $fileName = $this->_newFileName . $this->getRandomCharacters(5);
301: }
302: $fileName = $fileName . '.' . $this->_templateFileEnding;
303: $this->createModuleFile('template', $fileName, '');
304: $this->_notification->displayNotification(cGuiNotification::LEVEL_INFO, i18n('Created a new template file successfully!'));
305:
306:
307: $tpl = cSmartyFrontend::getInstance();
308: $tpl->clearCache($this->getTemplatePath($fileName));
309:
310:
311: $this->_file = $fileName;
312: $this->_tmpFile = $fileName;
313: }
314:
315: 316: 317:
318: private function _delete() {
319:
320: $tpl = cSmartyFrontend::getInstance();
321: $tpl->clearCache($this->getTemplatePath($this->_tmpFile));
322:
323: $ret = $this->deleteFile('template', $this->_tmpFile);
324: if ($ret == true) {
325: $this->_notification->displayNotification(cGuiNotification::LEVEL_INFO, i18n('Deleted the template file successfully!'));
326: }
327: $files = $this->getAllFilesFromDirectory('template');
328:
329: if (is_array($files)) {
330: if (!array_key_exists('0', $files)) {
331: $this->_file = '';
332: $this->_tmpFile = '';
333: } else {
334: $this->_file = $files[0];
335: $this->_tmpFile = $files[0];
336: }
337: }
338: }
339:
340: 341: 342:
343: public function _default() {
344: $files = $this->getAllFilesFromDirectory('template');
345:
346:
347: if (count($files) > 0) {
348: $this->_tmpFile = $files[0];
349: $this->_file = $files[0];
350: } else {
351:
352: $this->_file = '';
353: $this->_tmpFile = '';
354: }
355: }
356:
357: 358: 359: 360: 361: 362: 363: 364: 365:
366: private function _havePremission($perm, $notification, $action) {
367: switch ($action) {
368: case 'new':
369: if (!$perm->have_perm_area_action($this->_testArea, $this->_actionCreate)) {
370: $notification->displayNotification('error', i18n('Permission denied'));
371: return -1;
372: }
373: break;
374: case 'save':
375: case 'rename':
376: if (!$perm->have_perm_area_action($this->_testArea, $this->_actionEdit)) {
377: $notification->displayNotification('error', i18n('Permission denied'));
378: return -1;
379: }
380: break;
381: case 'delete':
382: if (!$perm->have_perm_area_action($this->_testArea, $this->_actionDelete)) {
383: $notification->displayNotification('error', i18n('Permission denied'));
384: return -1;
385: }
386: break;
387: default:
388: return true;
389: break;
390: }
391: }
392:
393: 394: 395: 396: 397:
398: private function _validateHTML($notification) {
399:
400: if (getEffectiveSetting('layout', 'htmlvalidator', 'true') == 'true' && $this->_code !== '') {
401: $v = new cHTMLValidator();
402: $v->validate($this->_code);
403: $msg = '';
404:
405: foreach ($v->missingNodes as $value) {
406: $idQualifier = '';
407:
408: $attr = array();
409:
410: if ($value['name'] != '') {
411: $attr['name'] = "name '" . $value['name'] . "'";
412: }
413:
414: if ($value['id'] != '') {
415: $attr['id'] = "id '" . $value['id'] . "'";
416: }
417:
418: $idQualifier = implode(', ', $attr);
419:
420: if ($idQualifier != '') {
421: $idQualifier = "($idQualifier)";
422: }
423: $msg .= sprintf(i18n("Tag '%s' %s has no end tag (start tag is on line %s char %s)"), $value['tag'], $idQualifier, $value['line'], $value['char']) . '<br>';
424: }
425:
426: if ($msg != '') {
427: $notification->displayNotification('warning', $msg) . '<br>';
428: }
429: }
430: }
431:
432: private function _makeFormular($belang, $readOnly) {
433: $fileForm = new cGuiTableForm("file__chooser");
434: $fileForm->addHeader(i18n('Choose file'));
435: $fileForm->setTableid('choose_mod_template_file');
436: $fileForm->setVar('area', $this->_area);
437: $fileForm->setVar('action', $this->_action);
438: $fileForm->setVar('frame', $this->_frame);
439: $fileForm->setVar('status', 'send');
440: $fileForm->setVar('tmp_file', $this->_tmpFile);
441: $fileForm->setVar('idmod', $this->_idmod);
442: $fileForm->setVar('file', $this->_file);
443:
444: $form = new cGuiTableForm('file_editor');
445: $form->setTableid('mod_template');
446: $form->addHeader(i18n('Edit file'));
447: $form->setVar('area', $this->_area);
448: $form->setVar('action', $this->_action);
449: $form->setVar('frame', $this->_frame);
450: $form->setVar('status', 'send');
451: $form->setVar('tmp_file', $this->_tmpFile);
452: $form->setVar('idmod', $this->_idmod);
453: $form->setVar('file', $this->_file);
454: $form->setVar('selectedFile', $this->_file);
455:
456: $selectFile = new cHTMLSelectElement('selectedFile');
457: $selectFile->setClass("fileChooser");
458:
459: $filesArray = $this->getAllFilesFromDirectory('template');
460:
461: if (true === is_array($filesArray)) {
462:
463:
464: foreach ($filesArray as $key => $file) {
465:
466:
467: if (is_dir($file)) {
468: continue;
469: }
470:
471: $optionField = new cHTMLOptionElement($file, $file);
472:
473:
474: if ($file == $this->_file) {
475: $optionField->setAttribute('selected', 'selected');
476: }
477:
478: $selectFile->addOptionElement($key, $optionField);
479: }
480:
481: }
482:
483: $aDelete = new cHTMLLink('main.php');
484: $aDelete->setId("deleteLink");
485: $aDelete->setContent(i18n("Delete HTML-template"));
486: $aDelete->setClass('deletefunction');
487: $aDelete->setCustom("deleteModTpl", "1");
488: $aDelete->setCustom('area', $this->_area);
489: $aDelete->setCustom('action', $this->_actionDelete);
490: $aDelete->setCustom('frame', $this->_frame);
491: $aDelete->setCustom('status', 'send');
492: $aDelete->setCustom('idmod', $this->_idmod);
493: $aDelete->setCustom('file', $this->_file);
494: $aDelete->setCustom('tmp_file', $this->_tmpFile);
495:
496: $aAdd = new cHTMLLink('main.php');
497: $aAdd->setContent(i18n('New HTML-template'));
498: $aAdd->setClass('addfunction');
499: $aAdd->setCustom("newModTpl", "1");
500: $aAdd->setCustom('area', $this->_area);
501: $aAdd->setCustom('action', $this->_actionCreate);
502: $aAdd->setCustom('frame', $this->_frame);
503: $aAdd->setCustom('status', 'send');
504: $aAdd->setCustom('tmp_file', $this->_tmpFile);
505: $aAdd->setCustom('idmod', $this->_idmod);
506: $aAdd->setCustom('file', $this->_file);
507:
508:
509: $oName = new cHTMLTextbox('file', $this->_file, 60);
510:
511: $oCode = new cHTMLTextarea('code', conHtmlSpecialChars($this->_code), 100, 35, 'code');
512:
513: $oCode->setStyle('font-family: monospace;width: 100%;');
514:
515: $oCode->updateAttributes(array(
516: 'wrap' => getEffectiveSetting('html_editor', 'wrap', 'off')
517: ));
518:
519: $fileForm->add(i18n('Action'), $aAdd->toHTML());
520:
521: if ($this->_file) {
522: $fileForm->add(i18n('Action'), $aDelete->toHTML());
523: $fileForm->add(i18n('File'), $selectFile);
524: }
525:
526: if($readOnly) {
527: $oName->setDisabled('disabled');
528: }
529:
530:
531: if ($this->_file) {
532: $form->add(i18n('Name'), $oName);
533: $form->add(i18n('Code'), $oCode);
534: }
535: $this->_page->setContent(array(
536: $fileForm
537: ));
538: if ($this->_file) {
539: $this->_page->appendContent($form);
540: }
541:
542: $oCodeMirror = new CodeMirror('code', 'html', substr(strtolower($belang), 0, 2), true, $this->_cfg);
543: if($readOnly) {
544: $oCodeMirror->setProperty("readOnly", "true");
545:
546: $form->setActionButton('submit', cRegistry::getBackendUrl() . 'images/but_ok_off.gif', i18n('Overwriting files is disabled'), 's');
547: }
548: $this->_page->addScript($oCodeMirror->renderScript());
549:
550:
551: }
552:
553: 554: 555: 556: 557: 558: 559: 560:
561: public function display($perm, $notification, $belang, $readOnly) {
562: $myAction = $this->_getAction();
563:
564:
565: if ($this->_havePremission($perm, $notification, $myAction) === -1) {
566: return;
567: }
568:
569: try {
570: switch ($myAction) {
571: case 'save':
572: if(!$readOnly) {
573: $this->_save();
574: }
575: break;
576: case 'rename':
577: if(!$readOnly) {
578: $this->_rename();
579: }
580: break;
581: case 'new':
582: if(!$readOnly) {
583: $this->_new();
584: }
585: break;
586: case 'delete':
587: if(!$readOnly) {
588: $this->_delete();
589: }
590: break;
591: default:
592: $this->_default();
593: break;
594: }
595:
596: $this->_code = $this->getFilesContent('template', '', $this->_file);
597: $this->_validateHTML($notification);
598: $this->_makeFormular($belang, $readOnly);
599: } catch (Exception $e) {
600: $this->_page->displayError(i18n($e->getMessage()));
601: }
602: }
603:
604: }