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