diff --git a/.htaccess b/.htaccess index 1f3a113..4449202 100644 --- a/.htaccess +++ b/.htaccess @@ -319,6 +319,7 @@ AddDefaultCharset utf-8 # Файл sitemap.xml RewriteRule ^sitemap.xml$ inc/sitemap.php [QSA,L] + RewriteRule ^sitemap-([0-9]+).xml$ inc/sitemap.php?id=$1 [QSA,L] #--start-ave-editor--# diff --git a/README.md b/README.md index b79c5e7..1304dd9 100644 --- a/README.md +++ b/README.md @@ -21,10 +21,8 @@ * ПО WEB сервера: * Apache >= 1.3 * Nginx >= 1.6.2 - * IIS >= 5 - * PHP >= 5.5 - * PHP >= 5.5.x ... <= 5.6.x разрешить использовать короткие теги short_open_tag = On (zlib, cURL, mbString, JSON) - * PHP >= 7.x ... <= 7.1.x + * PHP >= 5.6.x разрешить использовать короткие теги short_open_tag = On (zlib, cURL, mbString, JSON) + * PHP >= 7.x ... <= 7.2.x ## Модули @@ -55,7 +53,7 @@ 1. Распакуйте содержимое архива в новую папку на вашем локальном компьютере. 2. Загрузить эту папку целиком через FTP-клиент на ваш хост. -3. Вам также может потребоваться установить права доступа (CHMOD 777) рекурсивно, на папки /cache/, /session/ и /uploads/, если ваш хостинг не установливает это по умолчанию. +3. Вам также может потребоваться установить права доступа (CHMOD 777) рекурсивно, на папки /tmp/cache/, /tmp/session/ и /uploads/, если ваш хостинг не установливает это по умолчанию. 4. Также вам может потребоваться установить права доступа (CHMOD 777) рекурсивно, на файлы inc/db.config.php и inc/config.inc.php, если ваш хостинг не установливает это по умолчанию. 5. Наберите http://адрес вашего сайта/ в браузере. 6. Следуйте инструкциям. diff --git a/admin/admin.php b/admin/admin.php index 7b04b1f..5c5cdff 100644 --- a/admin/admin.php +++ b/admin/admin.php @@ -15,7 +15,7 @@ define('ACPL', 1); define('BASE_DIR', str_replace("\\", "/", dirname(dirname(__FILE__)))); - if (! @filesize(BASE_DIR . '/inc/db.config.php')) + if (! @filesize(BASE_DIR . '/config/db.config.php')) { header('Location:/install/index.php'); exit; diff --git a/admin/dbsettings.php b/admin/dbsettings.php index ee164a2..55284ca 100644 --- a/admin/dbsettings.php +++ b/admin/dbsettings.php @@ -46,7 +46,7 @@ exit; case 'restore': - $AVE_DB_Service->databaseDumpImport(BASE_DIR . "/" . ATTACH_DIR . "/"); + $AVE_DB_Service->databaseDumpImport(BASE_DIR . "/tmp/" . ATTACH_DIR . "/"); break; case 'download': diff --git a/admin/functions/func.admin.common.php b/admin/functions/func.admin.common.php index 931494f..00b87ad 100644 --- a/admin/functions/func.admin.common.php +++ b/admin/functions/func.admin.common.php @@ -48,22 +48,22 @@ $log404 = array(); $logsql = array(); - $_404dir = BASE_DIR . '/cache/404.php'; - $_logdir = BASE_DIR . '/cache/log.php'; - $_sqldir = BASE_DIR . '/cache/sql.php'; + $_404dir = BASE_DIR . '/tmp/logs/404.php'; + $_logdir = BASE_DIR . '/tmp/logs/log.php'; + $_sqldir = BASE_DIR . '/tmp/logs/sql.php'; - if(file_exists($_logdir)) - @eval('?>' . file_get_contents($_logdir) . '' . file_get_contents($_logdir) . '' . file_get_contents($_404dir) . '' . file_get_contents($_404dir) . '' . file_get_contents($_sqldir) . '' . file_get_contents($_sqldir) . 'Query("SELECT * FROM ".PREFIX."_users WHERE last_visit>".$time." ORDER BY last_visit DESC"); @@ -283,7 +284,7 @@ foreach ($modules AS $module) { - if ($module['ModuleAdminEdit'] == 1 && $module['status']) + if ($module['ModuleAdminEdit'] == 1 && $module['ModuleStatus']) $modules_instaled[] = array( 'ModuleName' => $module['ModuleName'], 'ModuleSysName' => $module['ModuleSysName'] @@ -503,7 +504,7 @@ $row->canDelete = 0; $row->canEndDel = 0; $row->canOpenClose = 0; - $row->rubric_admin_teaser_template=@eval2var('?>'.($row->rubric_admin_teaser_template>'' ? @showrequestelement($row,$row->rubric_admin_teaser_template) : '').'rubric_admin_teaser_template=@eval2var(' ?>'.($row->rubric_admin_teaser_template>'' ? @showrequestelement($row,$row->rubric_admin_teaser_template) : '').'assign('content', $config_vars['MAIN_NO_PERMISSION']); diff --git a/admin/rubs.php b/admin/rubs.php index 80ca6a8..554f5dc 100755 --- a/admin/rubs.php +++ b/admin/rubs.php @@ -1,659 +1,670 @@ config_load(BASE_DIR . '/admin/lang/' . $_SESSION['admin_language'] . '/rubs.txt', 'rubs'); - -switch($_REQUEST['action']) -{ - case '' : - if(check_permission('rubric_view')) - { + /** + * AVE.cms + * + * @package AVE.cms + * @version 3.x + * @filesource + * @copyright © 2007-2014 AVE.cms, http://www.ave-cms.ru + * + * @license GPL v.2 + */ + + if (!defined('ACP')) + { + header('Location:index.php'); + exit; + } + + require(BASE_DIR . '/class/class.rubs.php'); + $AVE_Rubric = new AVE_Rubric; + + $AVE_Template->config_load(BASE_DIR . '/admin/lang/' . $_SESSION['admin_language'] . '/rubs.txt', 'rubs'); + + switch($_REQUEST['action']) + { + case '' : + if(check_permission('rubric_view')) + { + if(check_permission('rubric_edit')) + { + switch($_REQUEST['sub']) + { + case 'quicksave': + $AVE_Rubric->quickSave(); + break; + } + } + $AVE_Rubric->rubricList(); + $AVE_Template->assign('templates', get_all_templates()); + $AVE_Template->assign('content', $AVE_Template->fetch('rubs/list.tpl')); + } + else + { + $AVE_Template->assign('erorr', $AVE_Template->get_config_vars('RUBRIK_NO_VIEW')); + $AVE_Template->assign('content', $AVE_Template->fetch('error.tpl')); + } + break; + + case 'new': + if(check_permission('rubric_edit')) + { + $AVE_Template->assign('templates', get_all_templates()); + $AVE_Rubric->rubricNew(); + } + else + { + $AVE_Template->assign('erorr', $AVE_Template->get_config_vars('RUBRIK_NO_CHANGE3')); + $AVE_Template->assign('content', $AVE_Template->fetch('error.tpl')); + } + break; + + case 'template': if(check_permission('rubric_edit')) { switch($_REQUEST['sub']) { - case 'quicksave': - $AVE_Rubric->quickSave(); + case '': + $AVE_Rubric->rubricTemplateShow(); break; - } - } - $AVE_Rubric->rubricList(); - $AVE_Template->assign('templates', get_all_templates()); - $AVE_Template->assign('content', $AVE_Template->fetch('rubs/list.tpl')); - } - else - { - $AVE_Template->assign('erorr', $AVE_Template->get_config_vars('RUBRIK_NO_VIEW')); - $AVE_Template->assign('content', $AVE_Template->fetch('error.tpl')); - } - break; - - case 'new': - if(check_permission('rubric_edit')) - { - $AVE_Template->assign('templates', get_all_templates()); - $AVE_Rubric->rubricNew(); - } - else - { - $AVE_Template->assign('erorr', $AVE_Template->get_config_vars('RUBRIK_NO_CHANGE3')); - $AVE_Template->assign('content', $AVE_Template->fetch('error.tpl')); - } - break; - - case 'template': - if(check_permission('rubric_edit')) - { - switch($_REQUEST['sub']) - { - case '': - $AVE_Rubric->rubricTemplateShow(); - break; - - case 'save': - - $Rtemplate = $_POST['rubric_template']; - $Htemplate = $_POST['rubric_header_template']; - $Ftemplate = $_POST['rubric_footer_template']; - $Ttemplate = $_POST['rubric_teaser_template']; - $Atemplate = $_POST['rubric_admin_teaser_template']; - - $check_code = strtolower($Rtemplate.$Htemplate.$Ttemplate.$Atemplate.$Ftemplate); - - $ok = true; - - if ((is_php_code($check_code)) && !check_permission('rubric_php') ) - { - $AVE_Template->assign('php_forbidden', 1); - $ok = false; - } + case 'save': - if (! $ok) - { - $message = $AVE_Template->get_config_vars('RUBRIC_SAVED_PHP_ERR'); - $header = $AVE_Template->get_config_vars('RUBRIC_ERROR'); - $theme = 'error'; + $Rtemplate = $_POST['rubric_template']; + $Htemplate = $_POST['rubric_header_template']; + $Ftemplate = $_POST['rubric_footer_template']; + $Ttemplate = $_POST['rubric_teaser_template']; + $Atemplate = $_POST['rubric_admin_teaser_template']; + + $check_code = strtolower($Rtemplate.$Htemplate.$Ttemplate.$Atemplate.$Ftemplate); - if (isAjax()) + $ok = true; + + if ((is_php_code($check_code)) && !check_permission('rubric_php') ) { - echo json_encode(array('message' => $message, 'header' => $header, 'theme' => $theme)); - exit; + $AVE_Template->assign('php_forbidden', 1); + + $ok = false; + } + + if (! $ok) + { + $message = $AVE_Template->get_config_vars('RUBRIC_SAVED_PHP_ERR'); + $header = $AVE_Template->get_config_vars('RUBRIC_ERROR'); + $theme = 'error'; + + if (isAjax()) + { + echo json_encode(array('message' => $message, 'header' => $header, 'theme' => $theme)); + exit; + } + else + { + $AVE_Rubric->rubricTemplateShow(1); + } } else { - $AVE_Rubric->rubricTemplateShow(1); + $AVE_Rubric->rubricTemplateSave($Rtemplate, $Htemplate, $Ttemplate, $Atemplate, $Ftemplate); } - } - else - { - $AVE_Rubric->rubricTemplateSave($Rtemplate, $Htemplate, $Ttemplate, $Atemplate, $Ftemplate); - } - break; - } - } - else - { - $AVE_Template->assign('erorr', $AVE_Template->get_config_vars('RUBRIK_NO_CHANGE2')); - $AVE_Template->assign('content', $AVE_Template->fetch('error.tpl')); - } - break; - - case 'delete': - if(check_permission('rubric_edit')) - { - $AVE_Rubric->rubricDelete(); - } - else - { - $AVE_Template->assign('erorr', $AVE_Template->get_config_vars('RUBRIK_NO_PERMISSION')); - $AVE_Template->assign('content', $AVE_Template->fetch('error.tpl')); - } - break; - - case 'multi': - if(check_permission('rubric_edit')) - { - switch($_REQUEST['sub']) - { - case 'save': - $AVE_Rubric->rubricCopy(); - break; - } - $AVE_Template->assign('content', $AVE_Template->fetch('rubs/multi.tpl')); - } - else - { - $AVE_Template->assign('erorr', $AVE_Template->get_config_vars('RUBRIK_NO_MULTIPLY')); - $AVE_Template->assign('content', $AVE_Template->fetch('error.tpl')); - } - break; - - case 'edit': - if(check_permission('rubric_edit')) - { - switch($_REQUEST['sub']) - { - case '': - switch($_REQUEST['submit']) - { - case 'saveperms': - if (check_permission('rubric_perms')){ - $AVE_Rubric->rubricPermissionSave((int)$_REQUEST['Id']); - } - break; + break; + } + } + else + { + $AVE_Template->assign('erorr', $AVE_Template->get_config_vars('RUBRIK_NO_CHANGE2')); + $AVE_Template->assign('content', $AVE_Template->fetch('error.tpl')); + } + break; - case 'save': - $AVE_Rubric->rubricFieldSave((int)$_REQUEST['Id']); - break; + case 'delete': + if(check_permission('rubric_edit')) + { + $AVE_Rubric->rubricDelete(); + } + else + { + $AVE_Template->assign('erorr', $AVE_Template->get_config_vars('RUBRIK_NO_PERMISSION')); + $AVE_Template->assign('content', $AVE_Template->fetch('error.tpl')); + } + break; - case 'linked_rubric': - $AVE_Rubric->rubricShow(1); - break; + case 'multi': + if(check_permission('rubric_edit')) + { + switch($_REQUEST['sub']) + { + case 'save': + $AVE_Rubric->rubricCopy(); + break; + } + $AVE_Template->assign('content', $AVE_Template->fetch('rubs/multi.tpl')); + } + else + { + $AVE_Template->assign('erorr', $AVE_Template->get_config_vars('RUBRIK_NO_MULTIPLY')); + $AVE_Template->assign('content', $AVE_Template->fetch('error.tpl')); + } + break; - case 'code': - if (check_permission('rubric_code')){ - $AVE_Rubric->rubricCode((int)$_REQUEST['Id']); - } - break; + case 'edit': + if(check_permission('rubric_edit')) + { + switch($_REQUEST['sub']) + { + case '': + switch($_REQUEST['submit']) + { + case 'saveperms': + if (check_permission('rubric_perms')){ + $AVE_Rubric->rubricPermissionSave((int)$_REQUEST['Id']); + } + break; + + case 'save': + $AVE_Rubric->rubricFieldSave((int)$_REQUEST['Id']); + break; + + case 'linked_rubric': + $AVE_Rubric->rubricShow(1); + break; + + case 'code': + if (check_permission('rubric_code')){ + $AVE_Rubric->rubricCode((int)$_REQUEST['Id']); + } + break; + + case 'description': + $AVE_Rubric->rubricDesc((int)$_REQUEST['Id']); + break; + } + } + $AVE_Rubric->rubricFieldShow((int)$_REQUEST['Id'], null); + break; + } + else + { + $AVE_Template->assign('erorr', $AVE_Template->get_config_vars('RUBRIK_NO_CHANGE1')); + $AVE_Template->assign('content', $AVE_Template->fetch('error.tpl')); + } + break; - case 'description': - $AVE_Rubric->rubricDesc((int)$_REQUEST['Id']); - break; - } + case 'alias_add': + if(check_permission_acp('rubric_edit')) + { + $AVE_Rubric->rubricAliasAdd(); } - $AVE_Rubric->rubricFieldShow((int)$_REQUEST['Id'], null); - break; - } - else - { - $AVE_Template->assign('erorr', $AVE_Template->get_config_vars('RUBRIK_NO_CHANGE1')); - $AVE_Template->assign('content', $AVE_Template->fetch('error.tpl')); - } - break; - - case 'alias_add': - if(check_permission_acp('rubric_edit')) - { - $AVE_Rubric->rubricAliasAdd(); - } - break; - - case 'code': - if (check_permission('rubric_code')) - { - $AVE_Rubric->rubricCodeEdit($_REQUEST['Id']); - } - break; - - case 'field_template': - if(check_permission_acp('rubric_edit')) - { - $AVE_Rubric->rubricFieldTemplate(); - } - break; - - case 'field_template_save': - if(check_permission_acp('rubric_edit')) - { - $AVE_Rubric->rubricFieldTemplateSave((int)$_REQUEST['field_id'], (int)$_REQUEST['rubric_id']); - } - break; - - case 'fieldssort': - if(check_permission_acp('rubric_edit')) - { - $AVE_Rubric->rubricFieldsSort((array)$_REQUEST['sort']); - } - exit; + break; - case 'rubssort': - if(check_permission_acp('rubric_edit')) - { - $AVE_Rubric->rubricsSort((array)$_REQUEST['sort']); - } - exit; + case 'code': + if (check_permission('rubric_code')) + { + $AVE_Rubric->rubricCodeEdit($_REQUEST['Id']); + } + break; - case 'alias_check': - if(check_permission_acp('rubric_edit')) - { - $AVE_Rubric->rubricAliasCheck((int)$_REQUEST['rubric_id'],(int)$_REQUEST['field_id'], $_REQUEST['rubric_field_alias']); - } - break; - - case 'newfield': - if(check_permission_acp('rubric_edit')) - { - $AVE_Rubric->rubricFieldNew((int)$_REQUEST['Id'], $_REQUEST['ajax']); - } - break; - - case 'fields': - if(check_permission_acp('rubric_edit')) - { - $AVE_Rubric->rubricFieldShow((int)$_REQUEST['Id'], $_REQUEST['ajax']); - } - break; - - case 'change': - if(check_permission_acp('rubric_edit')) - { - $AVE_Rubric->rubricFieldChange((int)$_REQUEST['field_id'], (int)$_REQUEST['rubric_id']); - } - break; - - case 'changesave': - if(check_permission_acp('rubric_edit')) - { - $AVE_Rubric->rubricFieldChangeSave((int)$_REQUEST['field_id'], (int)$_REQUEST['rubric_id']); - } - break; - - case 'changegroup': - if(check_permission_acp('rubric_edit')) - { - $AVE_Rubric->rubricFieldGroupChange((int)$_REQUEST['field_id'], (int)$_REQUEST['rubric_id']); - } - break; - - case 'changegroupsave': - if(check_permission_acp('rubric_edit')) - { - $AVE_Rubric->rubricFieldGroupChangeSave((int)$_REQUEST['field_id'], (int)$_REQUEST['rubric_id']); - } - break; - - case 'fieldsgroups': - if(check_permission_acp('rubric_edit')) - { - $AVE_Rubric->rubricFieldsGroups((int)$_REQUEST['Id']); - } - break; - - case 'newfieldsgroup': - if(check_permission_acp('rubric_edit')) - { - $AVE_Rubric->rubricNewGroupFields((int)$_REQUEST['Id']); - } - break; - - case 'savefieldsgroup': - if(check_permission_acp('rubric_edit')) - { - $AVE_Rubric->rubricEditGroupFields((int)$_REQUEST['Id']); - } - break; - - case 'delfieldsgroup': - if(check_permission_acp('rubric_edit')) - { - $AVE_Rubric->rubricDelGroupFields((int)$_REQUEST['Id'], (int)$_REQUEST['rubric_id']); - } - break; - - case 'fieldsgroupssort': - if(check_permission_acp('rubric_edit')) - { - $AVE_Rubric->rubricFieldsGroupsSort((array)$_REQUEST['sort']); - } - exit; + case 'field_template': + if(check_permission_acp('rubric_edit')) + { + $AVE_Rubric->rubricFieldTemplate(); + } + break; - case 'tmpls': - if (check_permission_acp('rubric_edit')) - { - $AVE_Rubric->tmplsList(); - $AVE_Template->assign('content', $AVE_Template->fetch('rubs/tmpls.tpl')); - } - break; + case 'field_template_save': + if(check_permission_acp('rubric_edit')) + { + $AVE_Rubric->rubricFieldTemplateSave((int)$_REQUEST['field_id'], (int)$_REQUEST['rubric_id']); + } + break; - case 'tmpls_edit': - if(check_permission('rubric_edit')) - { - switch($_REQUEST['sub']) + case 'fieldssort': + if(check_permission_acp('rubric_edit')) { - case '': - $AVE_Rubric->tmplsEdit(); - break; + $AVE_Rubric->rubricFieldsSort((array)$_REQUEST['sort']); + } + exit; - case 'save': + case 'rubssort': + if(check_permission_acp('rubric_edit')) + { + $AVE_Rubric->rubricsSort((array)$_REQUEST['sort']); + } + exit; - $title = $_POST['template_title']; - $template = $_POST['rubric_template']; + case 'alias_check': + if(check_permission_acp('rubric_edit')) + { + $AVE_Rubric->rubricAliasCheck((int)$_REQUEST['rubric_id'],(int)$_REQUEST['field_id'], $_REQUEST['rubric_field_alias']); + } + break; - $check_code = strtolower($template); + case 'newfield': + if(check_permission_acp('rubric_edit')) + { + $AVE_Rubric->rubricFieldNew((int)$_REQUEST['Id'], $_REQUEST['ajax']); + } + break; - $ok = true; + case 'fields': + if(check_permission_acp('rubric_edit')) + { + $AVE_Rubric->rubricFieldShow((int)$_REQUEST['Id'], $_REQUEST['ajax']); + } + break; - if((is_php_code($check_code)) && !check_permission('rubric_php') ) - { - $AVE_Template->assign('php_forbidden', 1); + case 'change': + if(check_permission_acp('rubric_edit')) + { + $AVE_Rubric->rubricFieldChange((int)$_REQUEST['field_id'], (int)$_REQUEST['rubric_id']); + } + break; - $ok = false; - } + case 'changesave': + if(check_permission_acp('rubric_edit')) + { + $AVE_Rubric->rubricFieldChangeSave((int)$_REQUEST['field_id'], (int)$_REQUEST['rubric_id']); + } + break; - if(! $ok) - { - $message = $AVE_Template->get_config_vars('RUBRIC_SAVED_PHP_ERR'); - $header = $AVE_Template->get_config_vars('RUBRIC_ERROR'); - $theme = 'error'; + case 'changegroup': + if(check_permission_acp('rubric_edit')) + { + $AVE_Rubric->rubricFieldGroupChange((int)$_REQUEST['field_id'], (int)$_REQUEST['rubric_id']); + } + break; + + case 'changegroupsave': + if(check_permission_acp('rubric_edit')) + { + $AVE_Rubric->rubricFieldGroupChangeSave((int)$_REQUEST['field_id'], (int)$_REQUEST['rubric_id']); + } + break; + + case 'fieldsgroups': + if(check_permission_acp('rubric_edit')) + { + $AVE_Rubric->rubricFieldsGroups((int)$_REQUEST['Id']); + } + break; + + case 'newfieldsgroup': + if(check_permission_acp('rubric_edit')) + { + $AVE_Rubric->rubricNewGroupFields((int)$_REQUEST['Id']); + } + break; + + case 'savefieldsgroup': + if(check_permission_acp('rubric_edit')) + { + $AVE_Rubric->rubricEditGroupFields((int)$_REQUEST['Id']); + } + break; + + case 'delfieldsgroup': + if(check_permission_acp('rubric_edit')) + { + $AVE_Rubric->rubricDelGroupFields((int)$_REQUEST['Id'], (int)$_REQUEST['rubric_id']); + } + break; + + case 'fieldsgroupssort': + if(check_permission_acp('rubric_edit')) + { + $AVE_Rubric->rubricFieldsGroupsSort((array)$_REQUEST['sort']); + } + exit; + + case 'tmpls': + if (check_permission_acp('rubric_edit')) + { + $AVE_Rubric->tmplsList(); + $AVE_Template->assign('content', $AVE_Template->fetch('rubs/tmpls.tpl')); + } + break; + + case 'tmpls_edit': + if(check_permission('rubric_edit')) + { + switch($_REQUEST['sub']) + { + case '': + $AVE_Rubric->tmplsEdit(); + break; + + case 'save': - if (isAjax()) + $title = $_POST['template_title']; + $template = $_POST['rubric_template']; + + $check_code = strtolower($template); + + $ok = true; + + if((is_php_code($check_code)) && !check_permission('rubric_php') ) { - echo json_encode(array('message' => $message, 'header' => $header, 'theme' => $theme)); - exit; + $AVE_Template->assign('php_forbidden', 1); + + $ok = false; + } + + if(! $ok) + { + $message = $AVE_Template->get_config_vars('RUBRIC_SAVED_PHP_ERR'); + $header = $AVE_Template->get_config_vars('RUBRIC_ERROR'); + $theme = 'error'; + + if (isAjax()) + { + echo json_encode(array('message' => $message, 'header' => $header, 'theme' => $theme)); + exit; + } + else + { + $AVE_Rubric->tmplsEdit(); + } } else { - $AVE_Rubric->tmplsEdit(); + $AVE_Rubric->tmplsSave($template, $title); } - } - else - { - $AVE_Rubric->tmplsSave($template, $title); - } - break; + break; + } } - } - else - { - $AVE_Template->assign('erorr', $AVE_Template->get_config_vars('RUBRIK_NO_CHANGE2')); - $AVE_Template->assign('content', $AVE_Template->fetch('error.tpl')); - } - break; - - case 'tmpls_new': - if(check_permission('rubric_edit')) - { - switch($_REQUEST['sub']) + else { - case '': - $AVE_Rubric->tmplsEdit(); - break; + $AVE_Template->assign('erorr', $AVE_Template->get_config_vars('RUBRIK_NO_CHANGE2')); + $AVE_Template->assign('content', $AVE_Template->fetch('error.tpl')); + } + break; - case 'save': + case 'tmpls_new': + if(check_permission('rubric_edit')) + { + switch($_REQUEST['sub']) + { + case '': + $AVE_Rubric->tmplsEdit(); + break; - $title = $_POST['template_title']; - $template = $_POST['rubric_template']; + case 'save': - $check_code = strtolower($template); + $title = $_POST['template_title']; + $template = $_POST['rubric_template']; - $ok = true; + $check_code = strtolower($template); - if((is_php_code($check_code)) && !check_permission('rubric_php') ) - { - $AVE_Template->assign('php_forbidden', 1); + $ok = true; - $ok = false; - } + if((is_php_code($check_code)) && !check_permission('rubric_php') ) + { + $AVE_Template->assign('php_forbidden', 1); - if(! $ok) - { - $message = $AVE_Template->get_config_vars('RUBRIC_SAVED_PHP_ERR'); - $header = $AVE_Template->get_config_vars('RUBRIC_ERROR'); - $theme = 'error'; + $ok = false; + } - if (isAjax()) + if(! $ok) { - echo json_encode(array('message' => $message, 'header' => $header, 'theme' => $theme)); - exit; + $message = $AVE_Template->get_config_vars('RUBRIC_SAVED_PHP_ERR'); + $header = $AVE_Template->get_config_vars('RUBRIC_ERROR'); + $theme = 'error'; + + if (isAjax()) + { + echo json_encode(array('message' => $message, 'header' => $header, 'theme' => $theme)); + exit; + } + else + { + $AVE_Rubric->tmplsEdit(); + } } else { - $AVE_Rubric->tmplsEdit(); + $AVE_Rubric->tmplsSave($template, $title); } - } - else - { - $AVE_Rubric->tmplsSave($template, $title); - } - break; + break; + } } - } - else - { - $AVE_Template->assign('erorr', $AVE_Template->get_config_vars('RUBRIK_NO_CHANGE2')); - $AVE_Template->assign('content', $AVE_Template->fetch('error.tpl')); - } - break; + else + { + $AVE_Template->assign('erorr', $AVE_Template->get_config_vars('RUBRIK_NO_CHANGE2')); + $AVE_Template->assign('content', $AVE_Template->fetch('error.tpl')); + } + break; - case 'tmpls_from': - if(check_permission('rubric_edit')) - { - switch($_REQUEST['sub']) + case 'tmpls_from': + if(check_permission('rubric_edit')) { - case '': - $AVE_Rubric->tmplsEdit(); - break; + switch($_REQUEST['sub']) + { + case '': + $AVE_Rubric->tmplsEdit(); + break; - case 'save': + case 'save': - $title = $_POST['template_title']; - $template = $_POST['rubric_template']; + $title = $_POST['template_title']; + $template = $_POST['rubric_template']; - $check_code = strtolower($template); + $check_code = strtolower($template); - $ok = true; + $ok = true; - if((is_php_code($check_code)) && !check_permission('rubric_php') ) - { - $AVE_Template->assign('php_forbidden', 1); - - $ok = false; - } + if((is_php_code($check_code)) && !check_permission('rubric_php') ) + { + $AVE_Template->assign('php_forbidden', 1); - if(! $ok) - { - $message = $AVE_Template->get_config_vars('RUBRIC_SAVED_PHP_ERR'); - $header = $AVE_Template->get_config_vars('RUBRIC_ERROR'); - $theme = 'error'; + $ok = false; + } - if (isAjax()) + if(! $ok) { - echo json_encode(array('message' => $message, 'header' => $header, 'theme' => $theme)); - exit; + $message = $AVE_Template->get_config_vars('RUBRIC_SAVED_PHP_ERR'); + $header = $AVE_Template->get_config_vars('RUBRIC_ERROR'); + $theme = 'error'; + + if (isAjax()) + { + echo json_encode(array('message' => $message, 'header' => $header, 'theme' => $theme)); + exit; + } + else + { + $AVE_Rubric->tmplsEdit(); + } } else { - $AVE_Rubric->tmplsEdit(); + $AVE_Rubric->tmplsSave($template, $title); } - } - else - { - $AVE_Rubric->tmplsSave($template, $title); - } - break; + break; + } } - } - else - { - $AVE_Template->assign('erorr', $AVE_Template->get_config_vars('RUBRIK_NO_CHANGE2')); - $AVE_Template->assign('content', $AVE_Template->fetch('error.tpl')); - } - break; - - case 'tmpls_copy': - if(check_permission('rubric_edit')) - { - switch($_REQUEST['sub']) + else { - case '': - $AVE_Rubric->tmplsEdit(); - break; + $AVE_Template->assign('erorr', $AVE_Template->get_config_vars('RUBRIK_NO_CHANGE2')); + $AVE_Template->assign('content', $AVE_Template->fetch('error.tpl')); + } + break; - case 'save': + case 'tmpls_copy': + if(check_permission('rubric_edit')) + { + switch($_REQUEST['sub']) + { + case '': + $AVE_Rubric->tmplsEdit(); + break; - $title = $_POST['template_title']; - $template = $_POST['rubric_template']; + case 'save': - $check_code = strtolower($template); + $title = $_POST['template_title']; + $template = $_POST['rubric_template']; - $ok = true; + $check_code = strtolower($template); - if((is_php_code($check_code)) && !check_permission('rubric_php') ) - { - $AVE_Template->assign('php_forbidden', 1); + $ok = true; - $ok = false; - } + if((is_php_code($check_code)) && !check_permission('rubric_php') ) + { + $AVE_Template->assign('php_forbidden', 1); - if(! $ok) - { - $message = $AVE_Template->get_config_vars('RUBRIC_SAVED_PHP_ERR'); - $header = $AVE_Template->get_config_vars('RUBRIC_ERROR'); - $theme = 'error'; + $ok = false; + } - if (isAjax()) + if(! $ok) { - echo json_encode(array('message' => $message, 'header' => $header, 'theme' => $theme)); - exit; + $message = $AVE_Template->get_config_vars('RUBRIC_SAVED_PHP_ERR'); + $header = $AVE_Template->get_config_vars('RUBRIC_ERROR'); + $theme = 'error'; + + if (isAjax()) + { + echo json_encode(array('message' => $message, 'header' => $header, 'theme' => $theme)); + exit; + } + else + { + $AVE_Rubric->tmplsEdit(); + } } else { - $AVE_Rubric->tmplsEdit(); + $AVE_Rubric->tmplsSave($template, $title); } - } - else - { - $AVE_Rubric->tmplsSave($template, $title); - } - break; - } - } - else - { - $AVE_Template->assign('erorr', $AVE_Template->get_config_vars('RUBRIK_NO_CHANGE2')); - $AVE_Template->assign('content', $AVE_Template->fetch('error.tpl')); - } - break; - - case 'tmpls_del': - if(check_permission('rubric_edit')) - { - $AVE_Rubric->tmplsDelete(); - } - else - { - $AVE_Template->assign('erorr', $AVE_Template->get_config_vars('RUBRIK_NO_PERMISSION')); - $AVE_Template->assign('content', $AVE_Template->fetch('error.tpl')); - } - break; - - case 'rules': - if (check_permission('rubric_edit')) - { - switch($_REQUEST['sub']) - { - case '': - switch($_REQUEST['submit']) - { - case 'saveperms': - if (check_permission('rubric_perms')) - $AVE_Rubric->rubricPermissionSave((int)$_REQUEST['Id']); - break; - } + break; + } + } + else + { + $AVE_Template->assign('erorr', $AVE_Template->get_config_vars('RUBRIK_NO_CHANGE2')); + $AVE_Template->assign('content', $AVE_Template->fetch('error.tpl')); } - $AVE_Rubric->rubricRulesShow((int)$_REQUEST['Id'], null); - break; - } - else - { - $AVE_Template->assign('erorr', $AVE_Template->get_config_vars('RUBRIK_NO_CHANGE1')); - $AVE_Template->assign('content', $AVE_Template->fetch('error.tpl')); - } - break; - - case 'ftlist': - if (check_permission('rubric_edit')) - { - $AVE_Rubric->ShowFields(); - } - else - { - $AVE_Template->assign('erorr', $AVE_Template->get_config_vars('RUBRIK_NO_PERMISSION')); - $AVE_Template->assign('content', $AVE_Template->fetch('error.tpl')); - } - break; - - case 'ftshowfield': - if (check_permission('rubric_edit')) - { - $AVE_Rubric->ShowFieldsByType($_REQUEST['type']); - } - else - { - $AVE_Template->assign('erorr', $AVE_Template->get_config_vars('RUBRIK_NO_PERMISSION')); - $AVE_Template->assign('content', $AVE_Template->fetch('error.tpl')); - } - break; - - - case 'ftcreate': - if (check_permission('rubric_edit')) - { - $AVE_Rubric->EditFieldTpl((int)$_REQUEST['id'], $_REQUEST['fld'], $_REQUEST['type']); - } - else - { - $AVE_Template->assign('erorr', $AVE_Template->get_config_vars('RUBRIK_NO_PERMISSION')); - $AVE_Template->assign('content', $AVE_Template->fetch('error.tpl')); - } - break; - - case 'ftedit': - if (check_permission('rubric_edit')) - { - $AVE_Rubric->EditFieldTpl((int)$_REQUEST['id'], $_REQUEST['fld'], $_REQUEST['type']); - } - else - { - $AVE_Template->assign('erorr', $AVE_Template->get_config_vars('RUBRIK_NO_PERMISSION')); - $AVE_Template->assign('content', $AVE_Template->fetch('error.tpl')); - } - break; - - case 'ftsave': - if (check_permission('rubric_edit')) - { - $AVE_Rubric->SaveFieldTpl((int)$_REQUEST['field_id'], $_REQUEST['field_name'], $_REQUEST['field_type'], $_REQUEST['func']); - } - else - { - $AVE_Template->assign('erorr', $AVE_Template->get_config_vars('RUBRIK_NO_PERMISSION')); - $AVE_Template->assign('content', $AVE_Template->fetch('error.tpl')); - } - break; - - - case 'ftdelete': - if (check_permission('rubric_edit')) - { - $AVE_Rubric->DeleteFieldTpl((int)$_REQUEST['id'], $_REQUEST['fld'], $_REQUEST['type'], $_REQUEST['func']); - } - else - { - $AVE_Template->assign('erorr', $AVE_Template->get_config_vars('RUBRIK_NO_PERMISSION')); - $AVE_Template->assign('content', $AVE_Template->fetch('error.tpl')); - } - break; -} - -?> + break; + + case 'tmpls_del': + if(check_permission('rubric_edit')) + { + $AVE_Rubric->tmplsDelete(); + } + else + { + $AVE_Template->assign('erorr', $AVE_Template->get_config_vars('RUBRIK_NO_PERMISSION')); + $AVE_Template->assign('content', $AVE_Template->fetch('error.tpl')); + } + break; + + case 'rules': + if (check_permission('rubric_edit')) + { + switch($_REQUEST['sub']) + { + case '': + switch($_REQUEST['submit']) + { + case 'saveperms': + if (check_permission('rubric_perms')) + $AVE_Rubric->rubricPermissionSave((int)$_REQUEST['Id']); + break; + } + } + $AVE_Rubric->rubricRulesShow((int)$_REQUEST['Id'], null); + break; + } + else + { + $AVE_Template->assign('erorr', $AVE_Template->get_config_vars('RUBRIK_NO_CHANGE1')); + $AVE_Template->assign('content', $AVE_Template->fetch('error.tpl')); + } + break; + + case 'ftlist': + if (check_permission('rubric_edit')) + { + $AVE_Rubric->ShowFields(); + } + else + { + $AVE_Template->assign('erorr', $AVE_Template->get_config_vars('RUBRIK_NO_PERMISSION')); + $AVE_Template->assign('content', $AVE_Template->fetch('error.tpl')); + } + break; + + case 'ftshowfield': + if (check_permission('rubric_edit')) + { + $AVE_Rubric->ShowFieldsByType($_REQUEST['type']); + } + else + { + $AVE_Template->assign('erorr', $AVE_Template->get_config_vars('RUBRIK_NO_PERMISSION')); + $AVE_Template->assign('content', $AVE_Template->fetch('error.tpl')); + } + break; + + + case 'ftcreate': + if (check_permission('rubric_edit')) + { + $AVE_Rubric->EditFieldTpl((int)$_REQUEST['id'], $_REQUEST['fld'], $_REQUEST['type']); + } + else + { + $AVE_Template->assign('erorr', $AVE_Template->get_config_vars('RUBRIK_NO_PERMISSION')); + $AVE_Template->assign('content', $AVE_Template->fetch('error.tpl')); + } + break; + + case 'ftedit': + if (check_permission('rubric_edit')) + { + $AVE_Rubric->EditFieldTpl((int)$_REQUEST['id'], $_REQUEST['fld'], $_REQUEST['type']); + } + else + { + $AVE_Template->assign('erorr', $AVE_Template->get_config_vars('RUBRIK_NO_PERMISSION')); + $AVE_Template->assign('content', $AVE_Template->fetch('error.tpl')); + } + break; + + case 'ftempledit': + if (check_permission('rubric_edit')) + { + $AVE_Rubric->EditFieldTpl('', $_REQUEST['fld'], $_REQUEST['type']); + } + else + { + $AVE_Template->assign('erorr', $AVE_Template->get_config_vars('RUBRIK_NO_PERMISSION')); + $AVE_Template->assign('content', $AVE_Template->fetch('error.tpl')); + } + break; + + case 'ftsave': + if (check_permission('rubric_edit')) + { + $AVE_Rubric->SaveFieldTpl((int)$_REQUEST['field_id'], $_REQUEST['field_name'], $_REQUEST['field_type'], $_REQUEST['func']); + } + else + { + $AVE_Template->assign('erorr', $AVE_Template->get_config_vars('RUBRIK_NO_PERMISSION')); + $AVE_Template->assign('content', $AVE_Template->fetch('error.tpl')); + } + break; + + + case 'ftdelete': + if (check_permission('rubric_edit')) + { + $AVE_Rubric->DeleteFieldTpl((int)$_REQUEST['id'], $_REQUEST['fld'], $_REQUEST['type'], $_REQUEST['func']); + } + else + { + $AVE_Template->assign('erorr', $AVE_Template->get_config_vars('RUBRIK_NO_PERMISSION')); + $AVE_Template->assign('content', $AVE_Template->fetch('error.tpl')); + } + break; + } +?> \ No newline at end of file diff --git a/admin/start.php b/admin/start.php index 040683b..f380260 100644 --- a/admin/start.php +++ b/admin/start.php @@ -1,35 +1,34 @@ config_load(BASE_DIR . '/admin/lang/' . $_SESSION['admin_language'] . '/main.txt', 'index'); -$AVE_Template->assign('php_version', (@PHP_VERSION != '') ? @PHP_VERSION : 'unknow'); -$AVE_Template->assign('domain', $_SERVER["HTTP_HOST"]); -$AVE_Template->assign('mysql_version', $GLOBALS['AVE_DB']->mysql_version()); -$AVE_Template->assign('mysql_size', get_mysql_size()); -$AVE_Template->assign('navi', $AVE_Template->fetch('navi/navi.tpl')); -$AVE_Template->assign('navi_top', $AVE_Template->fetch('navi/navi_top.tpl')); -$AVE_Template->assign('content', $AVE_Template->fetch('start.tpl')); + get_ave_info(); + getInstaledModules(); + DisplayMainDocuments(); + get_online_users(); + getLogRecords(); + //$AVE_Template->config_load(BASE_DIR . '/admin/lang/' . $_SESSION['admin_language'] . '/main.txt', 'index'); + $AVE_Template->assign('php_version', (@PHP_VERSION != '') ? @PHP_VERSION : 'unknow'); + $AVE_Template->assign('domain', $_SERVER["HTTP_HOST"]); + $AVE_Template->assign('mysql_version', $GLOBALS['AVE_DB']->mysql_version()); + $AVE_Template->assign('mysql_size', get_mysql_size()); + $AVE_Template->assign('navi', $AVE_Template->fetch('navi/navi.tpl')); + $AVE_Template->assign('navi_top', $AVE_Template->fetch('navi/navi_top.tpl')); + $AVE_Template->assign('content', $AVE_Template->fetch('start.tpl')); ?> \ No newline at end of file diff --git a/admin/templates/browser/browser_upload.tpl b/admin/templates/browser/browser_upload.tpl index 6ec1f1f..ee3ff5d 100644 --- a/admin/templates/browser/browser_upload.tpl +++ b/admin/templates/browser/browser_upload.tpl @@ -39,7 +39,7 @@ $(function() { {title : "Image files", extensions : "jpg,jpeg,jpe,gif,png"}, {title : "Video files", extensions : "mp4,avi,mov,wmv,wmf"}, {title : "Music files", extensions : "mp3"}, - {title : "Documents", extensions : "doc,xls,pdf"}, + {title : "Documents", extensions : "doc,docx,xls,xlsx,pdf"}, {title : "Zip files", extensions : "zip,rar"} ], // Flash settings diff --git a/admin/templates/modules/modules.tpl b/admin/templates/modules/modules.tpl index 8948a5e..290d220 100644 --- a/admin/templates/modules/modules.tpl +++ b/admin/templates/modules/modules.tpl @@ -88,7 +88,7 @@ $(document).ready(function(){ldelim} {if check_permission('modules_admin')} - {if $module.ModuleAdminEdit && $module.status && $module.permission} + {if $module.ModuleAdminEdit && $module.ModuleStatus && $module.permission} {$module.ModuleName} {if (isset($module.ModuleTagLink) && $module.ModuleTagLink != "")}
{$module.ModuleTagLink} @@ -104,7 +104,7 @@ $(document).ready(function(){ldelim} {if $module.template} {assign var=module_id value=$module.id} - {if $module.status && $module.permission} + {if $module.ModuleStatus && $module.permission} {html_options name=Template[$module_id] options=$all_templates selected=$module.template style="width: 200px"} {else} {html_options name=Template[$module_id] options=$all_templates selected=$module.template style="width: 200px" disabled="disabled"} @@ -120,7 +120,7 @@ $(document).ready(function(){ldelim} {if check_permission('modules_system')} - {if $module.status} + {if $module.ModuleStatus} {else} diff --git a/admin/templates/rubs/_field_code.tpl b/admin/templates/rubs/_field_code.tpl index fef66cf..c49f2c5 100755 --- a/admin/templates/rubs/_field_code.tpl +++ b/admin/templates/rubs/_field_code.tpl @@ -59,7 +59,7 @@ -{include file="$codemirror_editor" conn_id="ftpl" textarea_id='code_text' ctrls='$("#code_templ").ajaxSubmit(sett_options);' height=400} +{include file="$codemirror_editor" conn_id="ftpl" textarea_id='code_text' ctrls='$("#code_templ").ajaxSubmit(sett_options);' height=400 mode='smartymixed'} '; + $out .= PHP_EOL; + $out .= ' +
+
+ + '; + $out .= PHP_EOL; + $out .= ''; + + $out .= PHP_EOL; + $out .= ''; + + $out .= PHP_EOL; + $out .= ''; + + $out .= PHP_EOL; + $out .= ''; + + $out .= PHP_EOL; + $out .= ''; + + $out .= PHP_EOL; + $out .= '
'; + + echo $out; + } } ?> \ No newline at end of file diff --git a/class/class.docs.php b/class/class.docs.php index 22ff970..1ad6aa6 100755 --- a/class/class.docs.php +++ b/class/class.docs.php @@ -322,7 +322,7 @@ class AVE_Document $sql_where_field = ''; $field_link = ''; - if ($_REQUEST['field_id'] && (int)$_REQUEST['field_id'] > 0) + if (isset($_REQUEST['field_id']) && (int)$_REQUEST['field_id'] > 0) { $sql_join_field = " LEFT JOIN @@ -415,6 +415,8 @@ class AVE_Document $nav_lang = '&lang_id=' . $_REQUEST['lang_id']; } + else + $nav_lang = ''; // Поиск с выводом всех результатов из всех рубрик if (@$_REQUEST['rubric_id'] == 'all') @@ -699,9 +701,9 @@ class AVE_Document $row->canDelete = 0; $row->canEndDel = 0; $row->canOpenClose = 0; - $row->rubric_admin_teaser_template = @eval2var('?>'.($row->rubric_admin_teaser_template>'' + $row->rubric_admin_teaser_template = @eval2var(' ?>'.($row->rubric_admin_teaser_template>'' ? @showrequestelement($row, $row->rubric_admin_teaser_template) - : '').'document_title = stripslashes(htmlspecialchars_decode($row->document_title)); $row->document_breadcrum_title = stripslashes(htmlspecialchars_decode($row->document_breadcrum_title)); @@ -915,7 +917,7 @@ class AVE_Document { $key = trim(mb_substr($v, 0, 254)); - $res= $AVE_DB->Query("INSERT INTO ".PREFIX."_document_keywords + $res = $AVE_DB->Query("INSERT INTO ".PREFIX."_document_keywords ( document_id, keyword @@ -1511,7 +1513,7 @@ class AVE_Document } } - unset($sql, $query); + unset ($sql, $query); $where = ($oper == 'UPDATE' ? 'WHERE Id = ' . $document_id : ''); $author = ($oper != 'UPDATE' ? 'document_author_id = ' . $_SESSION['user_id'] . ',' : ''); @@ -1521,6 +1523,10 @@ class AVE_Document ? $data['document_breadcrum_title'] : ''; + $document_tags = isset($data['document_tags']) + ? $data['document_tags'] + : ''; + // Сохраняем все параметры документа $sql = " $operator @@ -1531,7 +1537,7 @@ class AVE_Document document_title = '" . htmlspecialchars(clean_no_print_char($data['document_title']), ENT_QUOTES) . "', document_breadcrum_title = '" . htmlspecialchars(clean_no_print_char($breadcrumb_title), ENT_QUOTES) . "', document_alias = '" . $data['document_alias'] . "', - document_alias_history = '" . $data['document_alias_log'] . "', + document_alias_history = '" . $data['document_alias_history'] . "', document_published = '" . $data["document_published"] . "', document_expire = '" . $data["document_expire"] . "', document_changed = '" . $data["document_changed"] . "', @@ -1544,7 +1550,7 @@ class AVE_Document document_sitemap_pr = '" . $data['document_sitemap_pr'] . "', document_status = '" . $data['document_status'] . "', document_linked_navi_id = '" . (int)$data['document_linked_navi_id'] . "', - document_tags = '" . addslashes(htmlspecialchars(clean_no_print_char($data['document_tags']))). "', + document_tags = '" . addslashes(htmlspecialchars(clean_no_print_char($document_tags))). "', document_lang = '" . (empty($data['document_lang']) ? DEFAULT_LANGUAGE : $data['document_lang']). "', document_lang_group = '" . (empty($data['document_lang_group']) ? '0' : (int)$data['document_lang_group']). "', document_property = '" . (empty($data['document_property']) ? '' : $data['document_property']). "' @@ -1757,17 +1763,27 @@ class AVE_Document doc_id = '" . $document_id . "' "); + $field_module = isset($data['field_module']) + ? $data['field_module'] + : ''; + // Запускаем триггер после сохранения - Hooks::trigger('DocumentAfterSave', array('rubric_id' => $rubric_id, 'document_id' => $document_id, 'data' => $data, 'field_module' => $data['field_module'])); + Hooks::trigger('DocumentAfterSave', array('rubric_id' => $rubric_id, 'document_id' => $document_id, 'data' => $data, 'field_module' => $field_module)); // Выполняем код рубрики, после сохранения if ($rubric_code) - eval ('?>' . $_rubric->rubric_code_end . '' . $_rubric->rubric_code_end . 'clearcache('rub_' . $rubric_id); $AVE_DB->clearcache('doc_' . $document_id); $AVE_DB->clearcompile('doc_' . $document_id); + $AVE_DB->clearCacheUrl('url_' . $hash_url); $AVE_DB->clearcacherequest('doc_' . $document_id); unset ($_rubric, $fields); diff --git a/class/class.hooks.php b/class/class.hooks.php index da62262..82bf230 100644 --- a/class/class.hooks.php +++ b/class/class.hooks.php @@ -1,174 +1,175 @@ $function + ); + } + } + else { // Store the action hook in the $hooks array - self::$hooks[$item][$priority][$function] = array( + self::$hooks[$name][$priority][$function] = array( "function" => $function ); } - } - else - { - // Store the action hook in the $hooks array - self::$hooks[$name][$priority][$function] = array( - "function" => $function - ); - } - return true; - } + return true; + } - /** - * Do Hook - */ - public static function trigger($name, $arguments = "") - { - // Oh, no you didn't. Are you trying to run an action hook that doesn't exist? - if (! isset(self::$hooks[$name])) + /** + * Do Hook + */ + public static function trigger($name, $arguments = "") { - return $arguments; - } + // Oh, no you didn't. Are you trying to run an action hook that doesn't exist? + if (! isset(self::$hooks[$name])) + { + return $arguments; + } - // Set the current running hook to this - self::$current_hook = $name; + // Set the current running hook to this + self::$current_hook = $name; - // Key sort our action hooks - ksort(self::$hooks[$name]); - foreach (self::$hooks[$name] AS $priority => $names) - { - if (is_array($names)) + // Key sort our action hooks + ksort(self::$hooks[$name]); + foreach (self::$hooks[$name] AS $priority => $names) { - foreach ($names AS $name) + if (is_array($names)) { - $return = call_user_func_array($name['function'], array( - &$arguments - )); - - if ($return) + foreach ($names AS $name) { - $arguments = $return; - } + $return = call_user_func_array($name['function'], array( + &$arguments + )); + + if ($return) + { + $arguments = $return; + } - self::$run_hooks[$name][$priority]; + self::$run_hooks[$name][$priority]; + } } } - } - self::$current_hook = ''; + self::$current_hook = ''; - return $arguments; - } - - /** - * Remove Hook - */ - public static function unregister($name, $function, $priority = 10) - { - // If the action hook doesn't, just return true - if (!isset(self::$hooks[$name][$priority][$function])) - { - return true; + return $arguments; } - // Remove the action hook from our hooks array - unset(self::$hooks[$name][$priority][$function]); - - return ''; - } + /** + * Remove Hook + */ + public static function unregister($name, $function, $priority = 10) + { + // If the action hook doesn't, just return true + if (!isset(self::$hooks[$name][$priority][$function])) + { + return true; + } + // Remove the action hook from our hooks array + unset(self::$hooks[$name][$priority][$function]); - /** - * Current Hook - * - * Get the currently running action hook - * - */ - public static function current() - { - return self::$current_hook; - } + return ''; + } - /** - * Has Run - */ - public static function has($hook, $priority = 10) - { - if (isset(self::$hooks[$hook][$priority])) - { - return true; - } - else + /** + * Current Hook + * + * Get the currently running action hook + * + */ + public static function current() { - return false; + return self::$current_hook; } - } - /** - * Hook Exists - */ - public static function exists($name) - { - if (isset(self::$hooks[$name])) + /** + * Has Run + */ + public static function has($hook, $priority = 10) { - return true; + if (isset(self::$hooks[$hook][$priority])) + { + return true; + } + else + { + return false; + } } - else + + + /** + * Hook Exists + */ + public static function exists($name) { - return false; + if (isset(self::$hooks[$name])) + { + return true; + } + else + { + return false; + } } } -} +?> \ No newline at end of file diff --git a/class/class.logs.php b/class/class.logs.php index 227fe4d..1dd4a12 100644 --- a/class/class.logs.php +++ b/class/class.logs.php @@ -1,350 +1,349 @@ _logdir; + /** + * Внешние методы класса + */ - if(file_exists($logfile)) - @eval('?>'.file_get_contents($logfile).'assign('logs', $logdata); - $AVE_Template->assign('content', $AVE_Template->fetch('logs/logs.tpl')); - } + $logfile = BASE_DIR.$this->_logdir; - /** - * Метод, предназначенный для отображения всех записей Журнала событий 404 - * - */ - function List404() - { - global $AVE_Template; + if(file_exists($logfile)) + @eval(' ?>'.file_get_contents($logfile).'_404dir; + // Передаем данные в шаблон для вывода и отображаем страницу + $AVE_Template->assign('logs', $logdata); + $AVE_Template->assign('content', $AVE_Template->fetch('logs/logs.tpl')); + } - if(file_exists($logfile)) - include($logfile); + /** + * Метод, предназначенный для отображения всех записей Журнала событий 404 + * + */ + function List404() + { + global $AVE_Template; - arsort($log404); + $log404 = array(); - // Передаем данные в шаблон для вывода и отображаем страницу - $AVE_Template->assign('logs', $log404); - $AVE_Template->assign('content', $AVE_Template->fetch('logs/404.tpl')); - } + $logfile = BASE_DIR . $this->_404dir; - /** - * Метод, предназначенный для отображения всех записей Журнала событий 404 - * - */ - function ListSql() - { - global $AVE_Template; + if(file_exists($logfile)) + include($logfile); - $logsql = array(); + arsort($log404); - $logfile = BASE_DIR . $this->_sqldir; + // Передаем данные в шаблон для вывода и отображаем страницу + $AVE_Template->assign('logs', $log404); + $AVE_Template->assign('content', $AVE_Template->fetch('logs/404.tpl')); + } - if(file_exists($logfile)) - include($logfile); + /** + * Метод, предназначенный для отображения всех записей Журнала событий 404 + * + */ + function ListSql() + { + global $AVE_Template; - arsort($logsql); + $logsql = array(); - // Передаем данные в шаблон для вывода и отображаем страницу - $AVE_Template->assign('logs', $logsql); - $AVE_Template->assign('content', $AVE_Template->fetch('logs/sql.tpl')); - } + $logfile = BASE_DIR . $this->_sqldir; - /** - * Метод, предназначенный для удаление записей Журнала событий - * - */ - function logDelete() - { - global $AVE_Template; + if(file_exists($logfile)) + include($logfile); - $logfile = BASE_DIR . $this->_logdir; + arsort($logsql); - if(file_exists($logfile)) - unlink($logfile); + // Передаем данные в шаблон для вывода и отображаем страницу + $AVE_Template->assign('logs', $logsql); + $AVE_Template->assign('content', $AVE_Template->fetch('logs/sql.tpl')); + } - // Сохраняем системное сообщение в журнал - reportLog($AVE_Template->get_config_vars('LOGS_CLEAN')); + /** + * Метод, предназначенный для удаление записей Журнала событий + * + */ + function logDelete() + { + global $AVE_Template; - header('Location:index.php?do=logs&cp=' . SESSION); - exit; - } + $logfile = BASE_DIR . $this->_logdir; - /** - * Метод, предназначенный для удаление записей Журнала событий 404 - * - */ - function DeleteSql() - { - global $AVE_Template; + if(file_exists($logfile)) + unlink($logfile); - $logfile = BASE_DIR . $this->_sqldir; + // Сохраняем системное сообщение в журнал + reportLog($AVE_Template->get_config_vars('LOGS_CLEAN')); - if(file_exists($logfile)) - unlink($logfile); + header('Location:index.php?do=logs&cp=' . SESSION); + exit; + } - // Сохраняем системное сообщение в журнал - reportLog($AVE_Template->get_config_vars('LOGS_SQL_CLEAN')); + /** + * Метод, предназначенный для удаление записей Журнала событий 404 + * + */ + function DeleteSql() + { + global $AVE_Template; - header('Location:index.php?do=logs&action=logsql&cp=' . SESSION); - exit; - } + $logfile = BASE_DIR . $this->_sqldir; - /** - * Метод, предназначенный для удаление записей Журнала событий 404 - * - */ - function Delete404() - { - global $AVE_Template; + if(file_exists($logfile)) + unlink($logfile); - $logfile = BASE_DIR . $this->_404dir; + // Сохраняем системное сообщение в журнал + reportLog($AVE_Template->get_config_vars('LOGS_SQL_CLEAN')); - if(file_exists($logfile)) - unlink($logfile); + header('Location:index.php?do=logs&action=logsql&cp=' . SESSION); + exit; + } - // Сохраняем системное сообщение в журнал - reportLog($AVE_Template->get_config_vars('LOGS_404_CLEAN')); + /** + * Метод, предназначенный для удаление записей Журнала событий 404 + * + */ + function Delete404() + { + global $AVE_Template; - header('Location:index.php?do=logs&action=log404&cp=' . SESSION); - exit; - } + $logfile = BASE_DIR . $this->_404dir; - /** - * Метод, предназначенный для экспорта системных сообщений - * - */ - function logExport() - { - global $AVE_Template; - - // Определяем тип файла (CSV), формат имени файла, разделители и т.д. - $datstring = ''; - $dattype = 'text/csv'; - $datname = 'system_log_' . date('dmyhis', time()) . '.csv'; - - $separator = ';'; - $enclosed = '"'; - - // Выполняем запрос к БД на получение списка всех системных сообщений - $logdata=array(); - $logfile = BASE_DIR.$this->_logdir; - if(file_exists($logfile)) - @eval('?>'.file_get_contents($logfile).'$v) - $datstring .= $enclosed . $k . $enclosed . $separator; - $datstring .= PHP_EOL; - - // Циклически обрабатываем данные и формируем CSV файл с учетом указаны выше параметров - foreach($logdata as $k=>$v) + if(file_exists($logfile)) + unlink($logfile); + + // Сохраняем системное сообщение в журнал + reportLog($AVE_Template->get_config_vars('LOGS_404_CLEAN')); + + header('Location:index.php?do=logs&action=log404&cp=' . SESSION); + exit; + } + + /** + * Метод, предназначенный для экспорта системных сообщений + * + */ + function logExport() { - foreach ($v as $key => $val) + global $AVE_Template; + + // Определяем тип файла (CSV), формат имени файла, разделители и т.д. + $datstring = ''; + $dattype = 'text/csv'; + $datname = 'system_log_' . date('dmyhis', time()) . '.csv'; + + $separator = ';'; + $enclosed = '"'; + + // Выполняем запрос к БД на получение списка всех системных сообщений + $logdata=array(); + $logfile = BASE_DIR.$this->_logdir; + if(file_exists($logfile)) + @eval(' ?>'.file_get_contents($logfile).'$v) + $datstring .= $enclosed . $k . $enclosed . $separator; + $datstring .= PHP_EOL; + + // Циклически обрабатываем данные и формируем CSV файл с учетом указаны выше параметров + foreach($logdata as $k=>$v) { - $val = ($key=='log_time') ? date('d-m-Y, H:i:s', $val) : $val; - $datstring .= ($val == '') ? $separator : $enclosed . stripslashes($val) . $enclosed . $separator; + foreach ($v as $key => $val) + { + $val = ($key=='log_time') ? date('d-m-Y, H:i:s', $val) : $val; + $datstring .= ($val == '') ? $separator : $enclosed . stripslashes($val) . $enclosed . $separator; + } + $datstring .= PHP_EOL; } - $datstring .= PHP_EOL; - } - // Определяем заголовки документа - header('Content-Encoding: windows-1251'); - header('Content-type: text/csv; charset=windows-1251'); - header('Expires: ' . gmdate('D, d M Y H:i:s') . ' GMT'); - header('Content-Disposition: attachment; filename="' . $datname . '"'); - header('Content-Length: ' . strlen($datstring)); - header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); - header('Pragma: public'); + // Определяем заголовки документа + header('Content-Encoding: windows-1251'); + header('Content-type: text/csv; charset=windows-1251'); + header('Expires: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + header('Content-Disposition: attachment; filename="' . $datname . '"'); + header('Content-Length: ' . strlen($datstring)); + header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); + header('Pragma: public'); - // Выводим данные - echo mb_convert_encoding($datstring, 'windows-1251', 'UTF-8'); + // Выводим данные + echo mb_convert_encoding($datstring, 'windows-1251', 'UTF-8'); - // Сохраняем системное сообщение в журнал - reportLog($AVE_Template->get_config_vars('LOGS_EXPORT')); + // Сохраняем системное сообщение в журнал + reportLog($AVE_Template->get_config_vars('LOGS_EXPORT')); - exit; - } + exit; + } - /** - * Метод, предназначенный для экспорта сообщений 404 - * - */ - function Export404() - { - global $AVE_Template; + /** + * Метод, предназначенный для экспорта сообщений 404 + * + */ + function Export404() + { + global $AVE_Template; - // Определяем тип файла (CSV), формат имени файла, разделители и т.д. - $datstring = ''; - $dattype = 'text/csv'; - $datname = 'system_log_' . date('dmyhis', time()) . '.csv'; + // Определяем тип файла (CSV), формат имени файла, разделители и т.д. + $datstring = ''; + $dattype = 'text/csv'; + $datname = 'system_log_' . date('dmyhis', time()) . '.csv'; - $separator = ';'; - $enclosed = '"'; + $separator = ';'; + $enclosed = '"'; - // Выполняем запрос к БД на получение списка всех системных сообщений - $log404 = array(); + // Выполняем запрос к БД на получение списка всех системных сообщений + $log404 = array(); - $logfile = BASE_DIR.$this->_404dir; + $logfile = BASE_DIR.$this->_404dir; - if(file_exists($logfile)) - include($logfile); + if(file_exists($logfile)) + include($logfile); - arsort($log404); + arsort($log404); - $fieldcount = count($log404[0]); + $fieldcount = count($log404[0]); - foreach($log404[0] as $k=>$v) - $datstring .= $enclosed . $k . $enclosed . $separator; + foreach($log404[0] as $k=>$v) + $datstring .= $enclosed . $k . $enclosed . $separator; - $datstring .= PHP_EOL; + $datstring .= PHP_EOL; - // Циклически обрабатываем данные и формируем CSV файл с учетом указаны выше параметров - foreach($log404 as $k=>$v) - { - foreach ($v as $key => $val) + // Циклически обрабатываем данные и формируем CSV файл с учетом указаны выше параметров + foreach($log404 as $k=>$v) { - $val = ($key=='log_time') ? date('d-m-Y, H:i:s', $val) : $val; - $datstring .= ($val == '') ? $separator : $enclosed . stripslashes($val) . $enclosed . $separator; + foreach ($v as $key => $val) + { + $val = ($key=='log_time') ? date('d-m-Y, H:i:s', $val) : $val; + $datstring .= ($val == '') ? $separator : $enclosed . stripslashes($val) . $enclosed . $separator; + } + $datstring .= PHP_EOL; } - $datstring .= PHP_EOL; - } - // Определяем заголовки документа - header('Content-Encoding: windows-1251'); - header('Content-type: text/csv; charset=windows-1251'); - header('Expires: ' . gmdate('D, d M Y H:i:s') . ' GMT'); - header('Content-Disposition: attachment; filename="' . $datname . '"'); - header('Content-Length: ' . strlen($datstring)); - header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); - header('Pragma: public'); + // Определяем заголовки документа + header('Content-Encoding: windows-1251'); + header('Content-type: text/csv; charset=windows-1251'); + header('Expires: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + header('Content-Disposition: attachment; filename="' . $datname . '"'); + header('Content-Length: ' . strlen($datstring)); + header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); + header('Pragma: public'); - // Выводим данные - echo mb_convert_encoding(strip_tags($datstring), 'windows-1251', 'UTF-8'); + // Выводим данные + echo mb_convert_encoding(strip_tags($datstring), 'windows-1251', 'UTF-8'); - // Сохраняем системное сообщение в журнал - reportLog($AVE_Template->get_config_vars('LOGS_404_EXPORT')); + // Сохраняем системное сообщение в журнал + reportLog($AVE_Template->get_config_vars('LOGS_404_EXPORT')); - exit; - } + exit; + } - /** - * Метод, предназначенный для экспорта сообщений 404 - * - */ - function ExportSql() - { - global $AVE_Template; + /** + * Метод, предназначенный для экспорта сообщений 404 + * + */ + function ExportSql() + { + global $AVE_Template; - // Определяем тип файла (CSV), формат имени файла, разделители и т.д. - $datstring = ''; - $dattype = 'text/csv'; - $datname = 'system_log_' . date('dmyhis', time()) . '.csv'; + // Определяем тип файла (CSV), формат имени файла, разделители и т.д. + $datstring = ''; + $dattype = 'text/csv'; + $datname = 'system_log_' . date('dmyhis', time()) . '.csv'; - $separator = ';'; - $enclosed = '"'; + $separator = ';'; + $enclosed = '"'; - // Выполняем запрос к БД на получение списка всех системных сообщений - $logsql = array(); + // Выполняем запрос к БД на получение списка всех системных сообщений + $logsql = array(); - $logfile = BASE_DIR . $this->_sqldir; + $logfile = BASE_DIR . $this->_sqldir; - if(file_exists($logfile)) - include($logfile); + if(file_exists($logfile)) + include($logfile); - arsort($logsql); + arsort($logsql); - $fieldcount = count($logsql[0]); + $fieldcount = count($logsql[0]); - foreach($logsql[0] as $k=>$v) - $datstring .= $enclosed . $k . $enclosed . $separator; + foreach($logsql[0] as $k=>$v) + $datstring .= $enclosed . $k . $enclosed . $separator; - $datstring .= PHP_EOL; + $datstring .= PHP_EOL; - // Циклически обрабатываем данные и формируем CSV файл с учетом указаны выше параметров - foreach($logsql as $k => $v) - { - foreach ($v as $key => $val) + // Циклически обрабатываем данные и формируем CSV файл с учетом указаны выше параметров + foreach($logsql as $k => $v) { - $val = ($key == 'log_time') ? date('d-m-Y, H:i:s', $val) : $val; - $val = ($key == 'log_text') ? serialize($val) : $val; - $datstring .= ($val == '') ? $separator : $enclosed . stripslashes($val) . $enclosed . $separator; + foreach ($v as $key => $val) + { + $val = ($key == 'log_time') ? date('d-m-Y, H:i:s', $val) : $val; + $val = ($key == 'log_text') ? serialize($val) : $val; + $datstring .= ($val == '') ? $separator : $enclosed . stripslashes($val) . $enclosed . $separator; + } + $datstring .= PHP_EOL; } - $datstring .= PHP_EOL; - } - - // Определяем заголовки документа - header('Content-Encoding: windows-1251'); - header('Content-type: text/csv; charset=windows-1251'); - header('Expires: ' . gmdate('D, d M Y H:i:s') . ' GMT'); - header('Content-Disposition: attachment; filename="' . $datname . '"'); - header('Content-Length: ' . strlen($datstring)); - header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); - header('Pragma: public'); - // Выводим данные - echo mb_convert_encoding(strip_tags($datstring), 'windows-1251', 'UTF-8'); + // Определяем заголовки документа + header('Content-Encoding: windows-1251'); + header('Content-type: text/csv; charset=windows-1251'); + header('Expires: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + header('Content-Disposition: attachment; filename="' . $datname . '"'); + header('Content-Length: ' . strlen($datstring)); + header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); + header('Pragma: public'); - // Сохраняем системное сообщение в журнал - reportLog($AVE_Template->get_config_vars('LOGS_SQL_EXPORT')); + // Выводим данные + echo mb_convert_encoding(strip_tags($datstring), 'windows-1251', 'UTF-8'); - exit; - } + // Сохраняем системное сообщение в журнал + reportLog($AVE_Template->get_config_vars('LOGS_SQL_EXPORT')); -} + exit; + } + } ?> \ No newline at end of file diff --git a/class/class.modules.php b/class/class.modules.php index 2750951..026bbf2 100644 --- a/class/class.modules.php +++ b/class/class.modules.php @@ -63,9 +63,9 @@ $module = array(); + // Если не удалось подключить основной файл модуля module.php - Фиксируем ошибку if (! (is_file($module_dir . '/info.php') && @include_once($module_dir . '/info.php'))) { - // Если не удалось подключить основной файл модуля module.php - Фиксируем ошибку $modules['errors'][] = $entry; continue; } @@ -89,18 +89,20 @@ // установленные модули if ($row) { - $module['status'] = $row->ModuleStatus; $module['id'] = $row->Id; $module['need_update'] = ($row->ModuleVersion != $module['ModuleVersion']); $module['template'] = ($row->ModuleTemplate ? $row->ModuleTemplate : 0); + $module['ModuleAveTag'] = $row->ModuleAveTag; + $module['ModulePHPTag'] = $row->ModulePHPTag; + $module['ModuleStatus'] = $row->ModuleStatus; $module['ModuleVersion'] = $row->ModuleVersion; } // неустановленные модули else { - $module['status'] = false; $module['id'] = $module['ModuleSysName']; $module['template'] = (! empty($module['ModuleTemplate']) ? $module['ModuleTemplate'] : ''); + $module['ModuleStatus'] = false; } // записываем в массив @@ -151,7 +153,7 @@ ? '

' : "

$author_title
" . $module['ModuleAutor'] . "
") . '
' . $module['ModuleCopyright'] . ''; // установленные модули - if ($module['status'] !== false) + if ($module['ModuleStatus'] !== false) $installed_modules[$module['ModuleSysName']] = $module; // неустановленные модули else @@ -203,7 +205,7 @@ { foreach ($this->_modules AS $k => $v) { - if ($status && $v['status'] != $status) + if ($status && $v['ModuleStatus'] != $status) continue; $modules[$k] = $v; @@ -218,7 +220,7 @@ // Выполняем запрос к БД и получаем список документов, // согласно статусу, либо все модули, если статус не указан - $sql = $AVE_DB->Query(" + $sql = " SELECT * FROM @@ -226,9 +228,11 @@ " . $where_status . " ORDER BY ModuleName ASC - "); + "; - while ($row = $sql->FetchRow()) + $query = $AVE_DB->Query($sql, SYSTEM_CACHE_LIFETIME, 'modules'); + + while ($row = $query->FetchRow()) $modules[$row->ModuleSysName] = $row; } @@ -259,6 +263,8 @@ "); } + $this->clearModulesCache(); + // Выполянем обновление страницы со списком модулей header('Location:index.php?do=modules&cp=' . SESSION); exit; @@ -276,7 +282,7 @@ // Получаем данные модуля $modules = $this->_modules; - $modul = $modules[MODULE_PATH]; + $module = $modules[MODULE_PATH]; // Удаляем информацию о модуле в таблице module $AVE_DB->Query(" @@ -288,13 +294,13 @@ "); // Определяем, имеет ли модуль возможность настройки в Панели управления - $modul['ModuleAdminEdit'] = (!empty($modul['ModuleAdminEdit'])) - ? $modul['ModuleAdminEdit'] + $module['ModuleAdminEdit'] = (!empty($module['ModuleAdminEdit'])) + ? $module['ModuleAdminEdit'] : 0; // Определяем, имеет ли модуль возможность смены шаблона - $modul['ModuleTemplate'] = ($modul['ModuleTemplate']) - ? $modul['ModuleTemplate'] + $module['ModuleTemplate'] = ($module['ModuleTemplate']) + ? $module['ModuleTemplate'] : 0; // Добавляем информацию о модуле в таблицу module @@ -302,16 +308,16 @@ INSERT INTO " . PREFIX . "_module SET - ModuleName = '" . $modul['ModuleName'] . "', + ModuleName = '" . $module['ModuleName'] . "', ModuleStatus = '1', - ModuleAveTag = '" . $modul['ModuleAveTag'] . "', - ModulePHPTag = '" . $modul['ModulePHPTag'] . "', - ModuleFunction = '" . $modul['ModuleFunction'] . "', - ModuleIsFunction = '" . $modul['ModuleIsFunction'] . "', + ModuleAveTag = '" . $module['ModuleAveTag'] . "', + ModulePHPTag = '" . $module['ModulePHPTag'] . "', + ModuleFunction = '" . $module['ModuleFunction'] . "', + ModuleIsFunction = '" . $module['ModuleIsFunction'] . "', ModuleSysName = '" . MODULE_PATH . "', - ModuleVersion = '" . $modul['ModuleVersion'] . "', - ModuleTemplate = '" . $modul['ModuleTemplate'] . "', - ModuleAdminEdit = '" . $modul['ModuleAdminEdit'] . "' + ModuleVersion = '" . $module['ModuleVersion'] . "', + ModuleTemplate = '" . $module['ModuleTemplate'] . "', + ModuleAdminEdit = '" . $module['ModuleAdminEdit'] . "' "); // Подключаем файл с запросами к БД для данного модуля @@ -325,20 +331,22 @@ // из массива $module_sql_deinstall файла sql.php foreach ($module_sql_deinstall as $sql) { - $AVE_DB->Query(str_replace('CPPREFIX', PREFIX, $sql)); + $AVE_DB->Query(str_replace('%%PRFX%%', PREFIX, $sql)); } // Выполняем запросы создания таблиц и данных модуля // из массива $module_sql_install файла sql.php foreach ($module_sql_install as $sql) { - $AVE_DB->Query(str_replace('CPPREFIX', PREFIX, $sql)); + $AVE_DB->Query(str_replace('%%PRFX%%', PREFIX, $sql)); } } // Сохраняем системное сообщение в журнал ($_REQUEST['action'] == "reinstall") - ? reportLog($AVE_Template->get_config_vars('MODULES_ACTION_REINSTALL') . ' (' . $modul['ModuleName'] . ')') - : reportLog($AVE_Template->get_config_vars('MODULES_ACTION_INSTALL') . ' (' . $modul['ModuleName'] . ')'); + ? reportLog($AVE_Template->get_config_vars('MODULES_ACTION_REINSTALL') . ' (' . $module['ModuleName'] . ')') + : reportLog($AVE_Template->get_config_vars('MODULES_ACTION_INSTALL') . ' (' . $module['ModuleName'] . ')'); + + $this->clearModulesCache(); // Выполняем обновление страницы со списком модулей header('Location:index.php?do=modules&cp=' . SESSION); @@ -359,38 +367,38 @@ $sql_file = BASE_DIR . '/modules/' . MODULE_PATH . '/sql.php'; - $mod_file = BASE_DIR . '/modules/' . MODULE_PATH . '/module.php'; + $mod_file = BASE_DIR . '/modules/' . MODULE_PATH . '/info.php'; if (file_exists($mod_file) && file_exists($sql_file)) { - include($mod_file); - include($sql_file); + include ($mod_file); + include ($sql_file); + // Выполняем запросы обновления модуля // из массива $module_sql_update файла sql.php foreach ($module_sql_update as $sql) { - $AVE_DB->Query(str_replace('CPPREFIX', PREFIX, $sql)); + $AVE_DB->Query(str_replace('%%PRFX%%', PREFIX, $sql)); } } // Обновляем модуль, если в нем не применяется (отсутствует) файл sql.php elseif (file_exists($mod_file) && file_exists($sql_file) === false) { - include($mod_file); + include_once ($mod_file); $AVE_DB->Query(" UPDATE " . PREFIX . "_module SET - ModuleName = '" . $modul['ModuleName'] . "', - ModuleStatus = '1', - ModuleAveTag = '" . $modul['ModuleAveTag'] . "', - ModulePHPTag = '" . $modul['ModulePHPTag'] . "', - ModuleFunction = '" . $modul['ModuleFunction'] . "', - ModuleIsFunction = '" . $modul['ModuleIsFunction'] . "', + ModuleAveTag = '" . $module['ModuleAveTag'] . "', + ModulePHPTag = '" . $module['ModulePHPTag'] . "', + ModuleFunction = '" . $module['ModuleFunction'] . "', + ModuleIsFunction = '" . $module['ModuleIsFunction'] . "', ModuleSysName = '" . MODULE_PATH . "', - ModuleVersion = '" . $modul['ModuleVersion'] . "', - ModuleTemplate = '" . $modul['ModuleTemplate'] . "', - ModuleAdminEdit = '" . $modul['ModuleAdminEdit'] . "' + ModuleVersion = '" . $module['ModuleVersion'] . "', + ModuleTemplate = '" . $module['ModuleTemplate'] . "', + ModuleAdminEdit = '" . $module['ModuleAdminEdit'] . "', + ModuleStatus = '1' WHERE ModuleSysName = '" . MODULE_PATH . "' "); @@ -398,6 +406,8 @@ // Сохраняем системное сообщение в журнал reportLog ($AVE_Template->get_config_vars('MODULES_ACTION_UPDATE') . ' (' . MODULE_PATH . ')'); + $this->clearModulesCache(); + // Выполянем обновление страницы со списком модулей header('Location:index.php?do=modules&cp=' . SESSION); exit; @@ -423,7 +433,7 @@ // из массива $module_sql_deinstall файла sql.php foreach ($module_sql_deinstall as $sql) { - $AVE_DB->Query(str_replace('CPPREFIX', PREFIX, $sql)); + $AVE_DB->Query(str_replace('%%PRFX%%', PREFIX, $sql)); } } @@ -436,6 +446,8 @@ ModuleSysName = '" . MODULE_PATH . "' "); + $this->clearModulesCache(); + // Сохраняем системное сообщение в журнал reportLog ($AVE_Template->get_config_vars('MODULES_ACTION_DELETE') .' (' . MODULE_PATH . ')'); @@ -477,6 +489,8 @@ ModuleSysName = '" . MODULE_PATH . "' "); + $this->clearModulesCache(); + // Сохраняем системное сообщение в журнал reportLog ((($ModuleStatus == "0") ? $AVE_Template->get_config_vars('MODULES_ACTION_OFFLINE') @@ -506,6 +520,8 @@ rrmdir ($directory); + $this->clearModulesCache(); + // Сохраняем системное сообщение в журнал reportLog ($AVE_Template->get_config_vars('MODULES_ACTION_REMOVE') . ' (' . $dir . ')'); @@ -513,5 +529,17 @@ header('Location:index.php?do=modules&cp=' . SESSION); exit; } + + + /** + * Функция очищает кеш системных настроек + * + */ + function clearModulesCache() + { + $cache_dir = BASE_DIR . '/tmp/cache/sql/modules/'; + + return rrmdir($cache_dir); + } } ?> \ No newline at end of file diff --git a/class/class.navigation.php b/class/class.navigation.php index f30e777..0772d16 100644 --- a/class/class.navigation.php +++ b/class/class.navigation.php @@ -244,6 +244,7 @@ //-- Стираем кеш навигации $this->clearCache($navigation_id, $_REQUEST['alias']); $this->clearCacheId($navigation_id, $_REQUEST['alias']); + $this->clearCacheNav($navigation_id, $_REQUEST['alias']); if ($sql === false) { @@ -400,6 +401,8 @@ " . PREFIX . "_navigation "); + $items = null; + //-- Циклически обрабатываем полученные данные while ($navigation = $sql->FetchRow()) { @@ -1264,24 +1267,24 @@ function clearCache($id, $alias = '') { - if (file_exists(BASE_DIR . '/cache/sql/nav/template-' . $id . '.cache')) - unlink(BASE_DIR . '/cache/sql/nav/template-' . $id . '.cache'); + if (file_exists(BASE_DIR . '/tmp/cache/sql/nav/template-' . $id . '.cache')) + unlink(BASE_DIR . '/tmp/cache/sql/nav/template-' . $id . '.cache'); - if (file_exists(BASE_DIR . '/cache/sql/nav/template-' . $alias . '.cache')) - unlink(BASE_DIR . '/cache/sql/nav/template-' . $alias . '.cache'); + if (file_exists(BASE_DIR . '/tmp/cache/sql/nav/template-' . $alias . '.cache')) + unlink(BASE_DIR . '/tmp/cache/sql/nav/template-' . $alias . '.cache'); - if (file_exists(BASE_DIR . '/cache/sql/nav/items-' . $id . '.cache')) - unlink(BASE_DIR . '/cache/sql/nav/items-' . $id . '.cache'); + if (file_exists(BASE_DIR . '/tmp/cache/sql/nav/items-' . $id . '.cache')) + unlink(BASE_DIR . '/tmp/cache/sql/nav/items-' . $id . '.cache'); - if (file_exists(BASE_DIR . '/cache/sql/nav/items-' . $alias . '.cache')) - unlink(BASE_DIR . '/cache/sql/nav/items-' . $alias . '.cache'); + if (file_exists(BASE_DIR . '/tmp/cache/sql/nav/items-' . $alias . '.cache')) + unlink(BASE_DIR . '/tmp/cache/sql/nav/items-' . $alias . '.cache'); } function clearCacheId($id, $alias = '') { - $dir_id = BASE_DIR . '/cache/sql/nav_' . $id; - $dir_alias = BASE_DIR . '/cache/sql/nav_' . $alias; + $dir_id = BASE_DIR . '/tmp/cache/sql/nav_' . $id; + $dir_alias = BASE_DIR . '/tmp/cache/sql/nav_' . $alias; if (file_exists($dir_id)) { @@ -1299,5 +1302,28 @@ } } } + + + function clearCacheNav($id, $alias) + { + $cache_id = str_replace('nav_', '', $id); + $cache_id = 'nav/' . substr($cache_id, 0, 3); + + $cache_dir = BASE_DIR . '/tmp/cache/sql/' . (trim($cache_id) > '' + ? trim($cache_id) . '/' + : ''); + + rrmdir($cache_dir); + + + $cache_id = str_replace('nav_', '', $alias); + $cache_id = 'nav/' . substr($cache_id, 0, 3); + + $cache_dir = BASE_DIR . '/tmp/cache/sql/' . (trim($cache_id) > '' + ? trim($cache_id) . '/' + : ''); + + rrmdir($cache_dir); + } } ?> diff --git a/class/class.rubs.php b/class/class.rubs.php index 44ac4b2..f949b42 100755 --- a/class/class.rubs.php +++ b/class/class.rubs.php @@ -869,17 +869,24 @@ $sql = $AVE_DB->Query(" SELECT - Id + Id, + document_alias FROM " . PREFIX . "_documents WHERE rubric_id = " . $rubric_id . " "); - while ($row = $sql->GetCell()) + while ($row = $sql->FetchRow()) { - $AVE_DB->clearcache('doc_' . $row); - $AVE_DB->clearcompile('doc_' . $row); + if ($row->Id == 1) + $hash_url = md5(''); + else + $hash_url = md5($row->document_alias); + + $AVE_DB->clearCacheUrl('url_'.$hash_url); + $AVE_DB->clearcache('doc_' . $row->Id); + $AVE_DB->clearcompile('doc_' . $row->Id); } if ($sql->_result === false) @@ -1003,10 +1010,16 @@ WHERE rub_id = '" . $rubric_id . "' "); - $sql = $AVE_DB->Query("SELECT Id FROM " . PREFIX . "_documents WHERE rubric_id = ".$rubric_id); + $sql = $AVE_DB->Query("SELECT Id,document_alias FROM " . PREFIX . "_documents WHERE rubric_id = ".$rubric_id); while ($row = $sql->FetchRow()) { + if ($row->Id == 1) + $hash_url = md5(''); + else + $hash_url = md5($row->document_alias); + + $AVE_DB->clearCacheUrl('url_'.$hash_url); $AVE_DB->clearcache('doc_'.$row->Id); $AVE_DB->clearcompile('doc_'.$row->Id); $AVE_DB->clearcacherequest('doc_'.$row->Id); @@ -1044,10 +1057,16 @@ $AVE_DB->clearcache('rub_'.$rubric_id); - $sql = $AVE_DB->Query("SELECT Id FROM " . PREFIX . "_documents WHERE rubric_id = ".$rubric_id); + $sql = $AVE_DB->Query("SELECT Id,document_alias FROM " . PREFIX . "_documents WHERE rubric_id = ".$rubric_id); while ($row = $sql->FetchRow()) { + if ($row->Id == 1) + $hash_url = md5(''); + else + $hash_url = md5($row->document_alias); + + $AVE_DB->clearCacheUrl('url_'.$hash_url); $AVE_DB->clearcache('doc_'.$row->Id); $AVE_DB->clearcompile('doc_'.$row->Id); } @@ -1272,10 +1291,16 @@ reportLog($AVE_Template->get_config_vars('RUBRIK_REPORT_TEMPL_RUB') . ' (' . stripslashes(htmlspecialchars($this->rubricNameByIdGet($rubric_id)->rubric_title)) . ') (Id:' . $rubric_id . ')'); } - $sql = $AVE_DB->Query("SELECT Id FROM " . PREFIX . "_documents WHERE rubric_id = ".$rubric_id); + $sql = $AVE_DB->Query("SELECT Id, document_alias FROM " . PREFIX . "_documents WHERE rubric_id = ".$rubric_id); while ($row = $sql->FetchRow()) { + if ($row->Id == 1) + $hash_url = md5(''); + else + $hash_url = md5($row->document_alias); + + $AVE_DB->clearCacheUrl('url_'.$hash_url); $AVE_DB->clearcache('doc_'.$row->Id); $AVE_DB->clearcompile('doc_'.$row->Id); } @@ -1532,7 +1557,9 @@ $AVE_Template->assign('content', $AVE_Template->fetch('rubs/field_template.tpl')); } - function rubricFieldTemplateSave($id, $rubric_id) { + + function rubricFieldTemplateSave($id, $rubric_id) + { global $AVE_DB, $AVE_Template; $sql = $AVE_DB->Query(" @@ -1546,7 +1573,8 @@ Id = '" . $id . "' "); - if ($sql->_result === false) { + if ($sql->_result === false) + { $message = $AVE_Template->get_config_vars('RUBRIC_SAVED_FLDTPL_ERR'); $header = $AVE_Template->get_config_vars('RUBRIK_ERROR'); $theme = 'error'; @@ -1559,14 +1587,21 @@ exit; } - }else{ - + } + else + { $AVE_DB->clearcache('rub_'.$rubric_id); - $sql = $AVE_DB->Query("SELECT Id FROM " . PREFIX . "_documents"); + $sql = $AVE_DB->Query("SELECT Id, document_alias FROM " . PREFIX . "_documents WHERE rubric_id = '".$rubric_id."'"); while ($row = $sql->FetchRow()) { + if ($row->Id == 1) + $hash_url = md5(''); + else + $hash_url = md5($row->document_alias); + + $AVE_DB->clearCacheUrl('url_'.$hash_url); $AVE_DB->clearcache('doc_'.$row->Id); $AVE_DB->clearcompile('doc_'.$row->Id); $AVE_DB->clearcacherequest('doc_'.$row->Id); @@ -2072,7 +2107,8 @@ $sql = $AVE_DB->Query(" SELECT - Id + Id, + document_alias FROM " . PREFIX . "_documents WHERE @@ -2083,6 +2119,12 @@ while ($row = $sql->FetchRow()) { + if ($row->Id == 1) + $hash_url = md5(''); + else + $hash_url = md5($row->document_alias); + + $AVE_DB->clearCacheUrl('url_'.$hash_url); $AVE_DB->clearcache('doc_'.$row->Id); $AVE_DB->clearcompile('doc_'.$row->Id); } diff --git a/class/class.session.files.php b/class/class.session.files.php index 5fc5b8e..b68083a 100644 --- a/class/class.session.files.php +++ b/class/class.session.files.php @@ -1,140 +1,142 @@ sess_lifetime = (defined('SESSION_LIFETIME') && is_numeric(SESSION_LIFETIME)) - ? SESSION_LIFETIME - : (get_cfg_var("session.gc_maxlifetime") < 1440 ? 1440 : get_cfg_var("session.gc_maxlifetime")); + public $sess_lifetime; - return true; - } - - /* Open session */ - function _open($sess_save_path, $session_name) - { - global $sess_save_path, $sess_session_name; - - $sess_save_path = BASE_DIR . '/session'; - $sess_session_name = $session_name; - - return true; - } + function __construct() + { + ini_set('session.save_handler', 'user'); - /* Close session */ - function _close() - { - $this->_gc($this->sess_lifetime); - return true; - } + $this->sess_lifetime = (defined('SESSION_LIFETIME') && is_numeric(SESSION_LIFETIME)) + ? SESSION_LIFETIME + : (get_cfg_var("session.gc_maxlifetime") < 1440 ? 1440 : get_cfg_var("session.gc_maxlifetime")); - /* Read session */ - function _read($id) - { - global $sess_save_path, $sess_session_name, $sess_session_id; + return true; + } - $sess_session_id = $id; - $sess_file = $this->_folder() . '/' . $id . '.sess'; + /* Open session */ + function _open($sess_save_path, $session_name) + { + global $sess_save_path, $sess_session_name; - if (!file_exists($sess_file)) return ""; + $sess_save_path = BASE_DIR . '/tmp/session'; + $sess_session_name = $session_name; - if ($fp = @fopen($sess_file, "r")) - { - $sess_data = fread($fp, filesize($sess_file)); - return($sess_data); + return true; } - else + + /* Close session */ + function _close() { - return ''; + $this->_gc($this->sess_lifetime); + return true; } - } - /* Write new data */ - function _write ($id, $sess_data) - { - global $sess_save_path, $sess_session_name, $sess_session_id; + /* Read session */ + function _read($id) + { + global $sess_save_path, $sess_session_name, $sess_session_id; - $sess_session_id = $id; - $sess_file = $this->_folder() . '/' . $id . '.sess'; + $sess_session_id = $id; + $sess_file = $this->_folder() . '/' . $id . '.sess'; - if(!file_exists($this->_folder())) - mkdir($this->_folder(), 0777, true); + if (!file_exists($sess_file)) return ""; - if ($fp = @fopen($sess_file, "w")) - { - return fwrite($fp, $sess_data); + if ($fp = @fopen($sess_file, "r")) + { + $sess_data = fread($fp, filesize($sess_file)); + return($sess_data); + } + else + { + return ''; + } } - else + + /* Write new data */ + function _write ($id, $sess_data) { - return false; - } - } + global $sess_save_path, $sess_session_name, $sess_session_id; - /* Destroy session */ - function _destroy ($id) - { - global $sess_save_path, $sess_session_name, $sess_session_id; + $sess_session_id = $id; + $sess_file = $this->_folder() . '/' . $id . '.sess'; - $sess_session_id = $id; - $sess_dir = $this->_folder(); - $sess_file = $sess_dir . '/' . $id . '.sess'; + if(!file_exists($this->_folder())) + mkdir($this->_folder(), 0777, true); - return @unlink($sess_file); - } + if ($fp = @fopen($sess_file, "w")) + { + return fwrite($fp, $sess_data); + } + else + { + return false; + } + } - /* Garbage collection, deletes old sessions */ - function _gc ($maxlifetime) - { - global $sess_save_path, $sess_session_id; + /* Destroy session */ + function _destroy ($id) + { + global $sess_save_path, $sess_session_name, $sess_session_id; - $this->_clear($sess_save_path, 'sess', $maxlifetime); + $sess_session_id = $id; + $sess_dir = $this->_folder(); + $sess_file = $sess_dir . '/' . $id . '.sess'; - return true; - } + return @unlink($sess_file); + } - function _clear($dir, $mask, $maxlifetime) - { - foreach(glob($dir . '/*') as $filename) { + /* Garbage collection, deletes old sessions */ + function _gc ($maxlifetime) + { + global $sess_save_path, $sess_session_id; - if(strtolower(substr($filename, strlen($filename) - strlen($mask), strlen($mask))) == strtolower($mask)) { - if((filemtime($filename) + $maxlifetime) < time()) - @unlink($filename); - } + $this->_clear($sess_save_path, 'sess', $maxlifetime); - if(is_dir($filename)) - if (!count(glob($filename.'/*'))) @rmdir($filename); - self::_clear($filename, $mask, $maxlifetime); + return true; } - } - function _folder() - { - global $sess_session_id, $sess_save_path; + function _clear($dir, $mask, $maxlifetime) + { + foreach(glob($dir . '/*') as $filename) + { + if (strtolower(substr($filename, strlen($filename) - strlen($mask), strlen($mask))) == strtolower($mask)) + { + if ((filemtime($filename) + $maxlifetime) < time()) + @unlink($filename); + } + + if (is_dir($filename)) + if (! count(glob($filename.'/*'))) + @rmdir($filename); + + self::_clear($filename, $mask, $maxlifetime); + } + } - return $sess_save_path . '/' . mb_substr($sess_session_id, 0, 3); - } + function _folder() + { + global $sess_session_id, $sess_save_path; - function __destruct () - { - register_shutdown_function('session_write_close'); - } + return $sess_save_path . '/' . mb_substr($sess_session_id, 0, 3); + } -} + function __destruct () + { + register_shutdown_function('session_write_close'); + } + } ?> \ No newline at end of file diff --git a/class/class.session.php b/class/class.session.php index 06a0b08..03cbcf2 100644 --- a/class/class.session.php +++ b/class/class.session.php @@ -58,7 +58,7 @@ class AVE_Session_DB function __construct() { // Подключаем конфигурационный файл с параметрами подключения - require (BASE_DIR . '/inc/db.config.php'); + require (BASE_DIR . '/config/db.config.php'); $this->db_host = $config['dbhost']; $this->db_user = $config['dbuser']; diff --git a/class/class.settings.php b/class/class.settings.php index 07eb18b..9ef5819 100644 --- a/class/class.settings.php +++ b/class/class.settings.php @@ -103,7 +103,7 @@ class AVE_Settings $set .= '?>'; - $result = file_put_contents(BASE_DIR . '/inc/config.inc.php', $set); + $result = file_put_contents(BASE_DIR . '/config/config.inc.php', $set); if ($result > 0) { @@ -227,12 +227,15 @@ class AVE_Settings reportLog($AVE_Template->get_config_vars('SETTINGS_SAVE_MAIN')); } - if (isset($_REQUEST['ajax']) && $_REQUEST['ajax'] = '1') { + if (isset($_REQUEST['ajax']) && $_REQUEST['ajax'] = '1') + { echo json_encode(array('message' => $message, 'header' => $header, 'theme' => $theme)); - } else { - $AVE_Template->assign('message', $message); - header('Location:index.php?do=settings&cp=' . SESSION); } + else + { + $AVE_Template->assign('message', $message); + header('Location:index.php?do=settings&cp=' . SESSION); + } exit; } @@ -253,6 +256,7 @@ class AVE_Settings ); $countries = array(); + while ($row = $sql->FetchAssocArray()) { array_push($countries, $row); @@ -599,7 +603,7 @@ class AVE_Settings */ function clearSettingsCache() { - $cache_dir = BASE_DIR . '/cache/sql/settings/'; + $cache_dir = BASE_DIR . '/tmp/cache/sql/settings/'; return rrmdir($cache_dir); } diff --git a/class/class.sysblocks.php b/class/class.sysblocks.php index b693423..fabdfbe 100644 --- a/class/class.sysblocks.php +++ b/class/class.sysblocks.php @@ -111,11 +111,7 @@ $theme = 'accept'; //-- Стираем кеш сисблока - if (file_exists(BASE_DIR . '/cache/sql/sysblock/' . $sysblock_id . '.cache')) - unlink(BASE_DIR . '/cache/sql/sysblock/' . $sysblock_id . '.cache'); - - if ($sysblock_alias != '' && file_exists(BASE_DIR . '/cache/sql/sysblock/' . $sysblock_alias . '.cache')) - unlink(BASE_DIR . '/cache/sql/sysblock/' . $sysblock_alias . '.cache'); + $this->clearCache($sysblock_id, $_REQUEST['sysblock_alias']); //-- Сохраняем системное сообщение в журнал reportLog($AVE_Template->get_config_vars('SYSBLOCK_SQLUPDATE') . " (" . stripslashes($_REQUEST['sysblock_name']) . ") (id: $sysblock_id)"); @@ -275,11 +271,7 @@ "); //-- Стираем кеш сисблока - if (file_exists(BASE_DIR . '/cache/sql/sysblock-' . $sysblock_id . '.cache')) - unlink(BASE_DIR . '/cache/sql/sysblock/' . $sysblock_id . '.cache'); - - if ($row->sysblock_alias != '') - unlink(BASE_DIR . '/cache/sql/sysblock/' . $row->sysblock_alias . '.cache'); + $this->clearCache($sysblock_id, $row->sysblock_alias); //-- Сохраняем системное сообщение в журнал reportLog($AVE_Template->get_config_vars('SYSBLOCK_SQLDEL') . " (" . stripslashes($row->sysblock_name) . ") (id: $sysblock_id)"); @@ -287,5 +279,21 @@ header('Location:index.php?do=sysblocks&cp=' . SESSION); } + + + function clearCache ($id, $alias = null) + { + $cache_id = md5('sysblock' . $id); + $cache_alias = md5('sysblock' . $alias); + + $cache_id_file = BASE_DIR . '/tmp/cache/sql/sysblock/' . $cache_id . '.cache'; + $cache_alias_file = BASE_DIR . '/tmp/cache/sql/sysblock/' . $cache_alias . '.cache'; + + if (file_exists($cache_id_file)) + unlink($cache_id_file); + + if (file_exists($cache_alias_file)) + unlink($cache_alias_file); + } } ?> \ No newline at end of file diff --git a/class/class.template.php b/class/class.template.php index 6b599f0..16eb1c4 100644 --- a/class/class.template.php +++ b/class/class.template.php @@ -42,32 +42,32 @@ class AVE_Template extends Smarty /** * Имя каталога, в котором хранятся компилированные шаблоны. */ - $this->compile_dir = BASE_DIR . '/cache/smarty'; + $this->compile_dir = BASE_DIR . '/tmp/cache/smarty'; /** * Имя каталога, в котором хранится кэш. */ - $this->cache_dir_root = BASE_DIR . '/cache'; + $this->cache_dir_root = BASE_DIR . '/tmp/cache'; /** * Имя каталога, в котором хранится кэш шаблонов. */ - $this->cache_dir = BASE_DIR . '/cache/tpl'; + $this->cache_dir = BASE_DIR . '/tmp/cache/tpl'; /** * Имя каталога, в котором хранится кэш модулей. */ - $this->module_cache_dir = BASE_DIR . '/cache/module'; + $this->module_cache_dir = BASE_DIR . '/tmp/cache/module'; /** * Имя каталога, в котором хранится сессии пользователей. */ - $this->session_dir = BASE_DIR . '/session'; + $this->session_dir = BASE_DIR . '/tmp/session'; /** * Имя каталога, в котором хранится сессии пользователей. */ - $this->sql_cache_dir = BASE_DIR . '/cache/sql'; + $this->sql_cache_dir = BASE_DIR . '/tmp/cache/sql'; /** * Использование поддиректорий для хранения кэша и скомпилированных шаблонов. @@ -217,13 +217,14 @@ class AVE_Template extends Smarty { $this->clear_all_cache(); - foreach (glob($this->cache_dir_root."/cache_*") as $filename) + foreach (glob($this->cache_dir_root . "/cache_*") as $filename) { @unlink($filename); } $filename = $this->cache_dir . '/.htaccess'; - if (!file_exists($filename)) + + if (! file_exists($filename)) { $fp = @fopen($filename, 'w'); if ($fp) @@ -233,7 +234,7 @@ class AVE_Template extends Smarty } } - if($_REQUEST['ajax'] && Memcached_Server && Memcached_Port) + if ($_REQUEST['ajax'] && Memcached_Server && Memcached_Port) { $memcache = new Memcache; $memcache->connect(Memcached_Server, Memcached_Port); diff --git a/class/class.templates.php b/class/class.templates.php index bf40c74..d4e3d24 100644 --- a/class/class.templates.php +++ b/class/class.templates.php @@ -142,6 +142,12 @@ { global $AVE_DB, $AVE_Template; + $template_id = (int)$_REQUEST['Id']; + + $cache = 'template_' . $template_id; + + $cache_file = BASE_DIR . '/tmp/cache/templates/' . $cache . '.inc'; + $row = $AVE_DB->Query(" SELECT * @@ -159,8 +165,15 @@ $AVE_Template->assign('read_only', 'readonly'); } - $row->template_text = pretty_chars($row->template_text); - $row->template_text = stripslashes($row->template_text); + if (file_exists($cache_file) && filesize($cache_file)) + { + $row->template_text = file_get_contents($cache_file); + } + else + { + $row->template_text = pretty_chars($row->template_text); + $row->template_text = stripslashes($row->template_text); + } $AVE_Template->assign('row', $row); $AVE_Template->assign('content', $AVE_Template->fetch('templates/form.tpl')); @@ -173,6 +186,8 @@ if (isset($_REQUEST['Id']) AND is_numeric($_REQUEST['Id'])) { + $template_id = $_REQUEST['Id']; + $ok = true; $check_code = strtolower($_REQUEST['template_text']); @@ -190,6 +205,10 @@ $theme = 'error'; } + $cache = 'template_' . $template_id; + + $cache_file = BASE_DIR . '/tmp/cache/templates/' . $cache . '.inc'; + if ($ok === false) { if (isset($_REQUEST['ajax']) && $_REQUEST['ajax'] = '1') @@ -212,7 +231,7 @@ template_title = '" . $_REQUEST['template_title'] . "', template_text = '" . addslashes(pretty_chars($_REQUEST['template_text'])) . "' WHERE - Id = '" . (int)$_REQUEST['Id'] . "' + Id = '" . $template_id . "' "); if ($sql === false) @@ -223,6 +242,11 @@ } else { + if (! file_exists(dirname($cache_file))) + mkdir(dirname($cache_file), 0766, true); + + file_put_contents($cache_file, stripslashes(pretty_chars($_REQUEST['template_text']))); + $message = $AVE_Template->get_config_vars('TEMPLATES_SAVED'); $header = $AVE_Template->get_config_vars('TEMPLATES_SUCCESS'); $theme = 'accept'; @@ -295,6 +319,15 @@ $iid = $AVE_DB->InsertId(); + $cache = 'template_' . $iid; + + $cache_file = BASE_DIR . '/tmp/cache/templates/' . $cache . '.inc'; + + if (! file_exists(dirname($cache_file))) + mkdir(dirname($cache_file), 0766, true); + + file_put_contents($cache_file, stripslashes(pretty_chars($_REQUEST['template_text']))); + reportLog($AVE_Template->get_config_vars('TEMPLATES_REPORT_NEW') . '(' . stripslashes(htmlspecialchars($_REQUEST['template_text'], ENT_QUOTES)) . ') (Id:' . (int)$iid . ')'); if (!$_REQUEST['next_edit']) @@ -440,7 +473,7 @@ { case 'save': - $dir = BASE_DIR.'/templates/'.DEFAULT_THEME_FOLDER.'/css/'.$_REQUEST['name_file']; + $dir = BASE_DIR . '/templates/' . DEFAULT_THEME_FOLDER . '/css/' . $_REQUEST['name_file']; $check_code = stripcslashes($_REQUEST['code_text']); diff --git a/config/.htaccess b/config/.htaccess new file mode 100644 index 0000000..3418e55 --- /dev/null +++ b/config/.htaccess @@ -0,0 +1 @@ +deny from all \ No newline at end of file diff --git a/inc/config.inc.php b/config/config.inc.php similarity index 100% rename from inc/config.inc.php rename to config/config.inc.php diff --git a/inc/db.config.php b/config/db.config.php similarity index 100% rename from inc/db.config.php rename to config/db.config.php diff --git a/fields/checkbox/field.php b/fields/checkbox/field.php index 99bc427..280e5fc 100644 --- a/fields/checkbox/field.php +++ b/fields/checkbox/field.php @@ -1,4 +1,4 @@ - 1) + list ($path, $watermark, $position, $transparency) = $default; + else + { + list ($path) = $default; + $watermark = false; + $position = null; + $transparency = null; + } if (preg_match("/%id/i", $path)) { @@ -288,15 +296,18 @@ break; case 'save': - foreach ($field_value as $v) + if (is_array($field_value)) { - if (! empty($v['url'])) + foreach ($field_value as $v) { + if (! empty($v['url'])) + { - $field_value_new[] = $v['url'] - . ($v['title'] ? '|' . stripslashes(htmlspecialchars($v['title'], ENT_QUOTES)) : '|') - . ($v['description'] ? '|' . stripslashes(htmlspecialchars($v['description'], ENT_QUOTES)) : '|') - . ($v['link'] ? '|' . ltrim($v['link'], '/') : '|'); + $field_value_new[] = $v['url'] + . ($v['title'] ? '|' . stripslashes(htmlspecialchars($v['title'], ENT_QUOTES)) : '|') + . ($v['description'] ? '|' . stripslashes(htmlspecialchars($v['description'], ENT_QUOTES)) : '|') + . ($v['link'] ? '|' . ltrim($v['link'], '/') : '|'); + } } } diff --git a/fields/image_single/field.php b/fields/image_single/field.php index 0d46452..5a50e13 100644 --- a/fields/image_single/field.php +++ b/fields/image_single/field.php @@ -1,4 +1,4 @@ - 0 ? false : true; } @@ -105,7 +108,7 @@ */ function clean_php($text) { - return str_replace(array('', '', ' &$value) @@ -1063,6 +1066,7 @@ return (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && (strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest')); } + /** * Функция делает html в 1 строчку, удаляет лишние пробелы, комментарии и т.д. * @@ -1124,7 +1128,4 @@ echo $content; } - - - ?> \ No newline at end of file diff --git a/functions/func.custom.php b/functions/func.custom.php index 1f7460d..eddd14b 100644 --- a/functions/func.custom.php +++ b/functions/func.custom.php @@ -1,4 +1,4 @@ - 0) + 0) { + for ($i=0; $i <= $count_matches; $i++) + { - $hidden_text = substr(@$matches[$i][3], 1); + $hidden_text = substr(@$matches[$i][3], 1); - if ($hidden_text == "") - $hidden_text = trim(get_settings('hidden_text')); + if ($hidden_text == "") + $hidden_text = trim(get_settings('hidden_text')); - $data = preg_replace('/\[tag:hide:(\d+,)*'. UGROUP .'(,\d+)*(:.*?)?].*?\[\/tag:hide]/s', $hidden_text, $data, 1); + $data = preg_replace('/\[tag:hide:(\d+,)*'. UGROUP .'(,\d+)*(:.*?)?].*?\[\/tag:hide]/s', $hidden_text, $data, 1); + } } - } - $data = preg_replace('/\[tag:hide:\d+(,\d+)*.*?](.*?)\[\/tag:hide]/s', '\\2', $data); + $data = preg_replace('/\[tag:hide:\d+(,\d+)*.*?](.*?)\[\/tag:hide]/s', '\\2', $data); - return $data; -} + return $data; + } ?> \ No newline at end of file diff --git a/functions/func.locale.php b/functions/func.locale.php index 8211bb3..a76ee7f 100644 --- a/functions/func.locale.php +++ b/functions/func.locale.php @@ -1,4 +1,4 @@ -'.file_get_contents($logfile).'time(), - 'log_ip' =>$_SERVER['REMOTE_ADDR'], - 'log_url' =>$_SERVER['QUERY_STRING'], - 'log_user_id' =>(isset($_SESSION['user_id']) ? $_SESSION['user_id'] : '0'), - 'log_user_name' =>(isset($_SESSION['user_name']) ? $_SESSION['user_name'] : 'Anonymous'), - 'log_text' =>$message, - 'log_type' =>(int)$typ, - 'log_rubric' =>(int)$rub - ); - $messlimit = 1000; - $logdata = array_slice($logdata,-1*$messlimit); - file_put_contents($logfile,''); -} - -/** - * Запись события в лог для Sql ошибок - * - * @param string $message Текст сообщения - * @return - */ -function reportSqlLog($message) -{ - $logsql = array(); - - $logfile = BASE_DIR . '/cache/sql.php'; - - if(file_exists($logfile)) - @eval('?>'.file_get_contents($logfile).'time(), - 'log_ip' =>$_SERVER['REMOTE_ADDR'], - 'log_url' =>$_SERVER['QUERY_STRING'], - 'log_user_id' =>$_SESSION['user_id'], - 'log_user_name' =>$_SESSION['user_name'], - 'log_text' =>$message - ); - - $messlimit = 1000; - - $logsql = array_slice($logsql,-1*$messlimit); - - file_put_contents($logfile, ''); -} - -/** - * Запись события в лог для 404 ошибок - * - * @param string $message Текст сообщения - * @return - */ -function report404() -{ - $log404 = array(); - - $logfile = BASE_DIR . '/cache/404.php'; - - if(file_exists($logfile)) - @include($logfile); - - $log404[] = array( - 'log_time' => time(), - 'log_ip' => @$_SERVER['REMOTE_ADDR'], - 'log_query' => @$_SERVER['QUERY_STRING'], - 'log_user_agent' => @$_SERVER['HTTP_USER_AGENT'], - 'log_user_referer' => (isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : ''), - 'log_request_uri' => @$_SERVER['REQUEST_URI'] - ); - - $messlimit = 1000; - - $log404 = array_slice($log404, -1*$messlimit); - - file_put_contents($logfile,''); -} + /** + * AVE.cms + * + * @package AVE.cms + * @version 3.x + * @filesource + * @copyright © 2007-2014 AVE.cms, http://www.ave-cms.ru + * + * @license GPL v.2 + */ + + + /** + * Запись события в лог + * + * @param string $message Текст сообщения + * @param int $typ тип сообщения + * @param int $rub номер рубрики + * @return + */ + function reportLog($message, $typ = 0, $rub = 0) + { + $logdata=array(); + + $logfile = BASE_DIR . '/tmp/logs/log.php'; + + if (file_exists($logfile)) + @eval(' ?'.'>' . file_get_contents($logfile) . ' time(), + 'log_ip' => $_SERVER['REMOTE_ADDR'], + 'log_url' => $_SERVER['QUERY_STRING'], + 'log_user_id' => (isset($_SESSION['user_id']) ? $_SESSION['user_id'] : '0'), + 'log_user_name' => (isset($_SESSION['user_name']) ? $_SESSION['user_name'] : 'Anonymous'), + 'log_text' => $message, + 'log_type' => (int)$typ, + 'log_rubric' => (int)$rub + ); + + $messlimit = 1000; + + $logdata = array_slice($logdata,-1*$messlimit); + + file_put_contents($logfile,''); + } + + /** + * Запись события в лог для Sql ошибок + * + * @param string $message Текст сообщения + * @return + */ + function reportSqlLog($message) + { + $logsql = array(); + + $logfile = BASE_DIR . '/tmp/logs/sql.php'; + + if (file_exists($logfile)) + @eval(' ?'.'>' . file_get_contents($logfile) . ' time(), + 'log_ip' => $_SERVER['REMOTE_ADDR'], + 'log_url' => $_SERVER['QUERY_STRING'], + 'log_user_id' => $_SESSION['user_id'], + 'log_user_name' => $_SESSION['user_name'], + 'log_text' => $message + ); + + $messlimit = 1000; + + $logsql = array_slice($logsql,-1*$messlimit); + + file_put_contents($logfile, ''); + } + + /** + * Запись события в лог для 404 ошибок + * + * @param string $message Текст сообщения + * @return + */ + function report404() + { + $log404 = array(); + + $logfile = BASE_DIR . '/tmp/logs/404.php'; + + if (file_exists($logfile)) + @include($logfile); + + $log404[] = array( + 'log_time' => time(), + 'log_ip' => @$_SERVER['REMOTE_ADDR'], + 'log_query' => @$_SERVER['QUERY_STRING'], + 'log_user_agent' => @$_SERVER['HTTP_USER_AGENT'], + 'log_user_referer' => (isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : ''), + 'log_request_uri' => @$_SERVER['REQUEST_URI'] + ); + + $messlimit = 1000; + + $log404 = array_slice($log404, -1*$messlimit); + + file_put_contents($logfile,''); + } ?> \ No newline at end of file diff --git a/functions/func.mail.php b/functions/func.mail.php index bcfc7f5..05ecec6 100644 --- a/functions/func.mail.php +++ b/functions/func.mail.php @@ -114,7 +114,7 @@ if ( ! function_exists('send_mail')) // Сохраняем вложения в ATTACH_DIR, если просили if ($attach && $saveattach) { - $attach_dir = BASE_DIR . '/' . ATTACH_DIR . '/'; + $attach_dir = BASE_DIR . '/tmp/' . ATTACH_DIR . '/'; foreach ($attach as $file_path) { if ($file_path && file_exists($file_path)) diff --git a/functions/func.navigation.php b/functions/func.navigation.php index 7b2b9fa..cc4bc53 100644 --- a/functions/func.navigation.php +++ b/functions/func.navigation.php @@ -47,7 +47,7 @@ $navi = ''; - $cache_file = BASE_DIR . '/cache/sql/nav/template-' . $navi_id . '.cache'; + $cache_file = BASE_DIR . '/tmp/cache/sql/nav/template-' . $navi_id . '.cache'; // Если включен DEV MODE, то отключаем кеширование запросов if (defined('DEV_MODE') AND DEV_MODE || $expnad_ext != 1) @@ -201,7 +201,7 @@ } } - $cache_items = BASE_DIR . '/cache/sql/nav/items-' . $navi_id . '.cache'; + $cache_items = BASE_DIR . '/tmp/cache/sql/nav/items-' . $navi_id . '.cache'; $navi_items = array(); @@ -464,7 +464,7 @@ if (empty($navi)) $navi = ''; - $navi .= eval2var('?>' . $item . '' . $item . 'rubric_id) . "'" )->GetCell()); - $cachefile_docid = BASE_DIR . '/cache/sql/request/' . $row->Id . '/request-' . md5($template) . '.cache'; + $cachefile_docid = BASE_DIR . '/tmp/cache/sql/request/' . $row->Id . '/request-' . md5($template) . '.cache'; // Если включен DEV MODE, то отключаем кеширование запросов if (defined('DEV_MODE') AND DEV_MODE) @@ -799,6 +799,7 @@ // Составляем запрос к БД $sql = " ?> + #REQUEST = $request->Id SELECT STRAIGHT_JOIN SQL_CALC_FOUND_ROWS a.* " . $request_select_str . " @@ -1026,8 +1027,8 @@ $main_template = str_replace('[tag:docauthorid]', $AVE_Core->curentdoc->document_author_id, $main_template); //-- Имя автора - if (preg_match('[tag:docauthor]', $main_content)) - $main_content = str_replace('[tag:docauthor]', get_username_by_id($AVE_Core->curentdoc->document_author_id), $main_content); + if (preg_match('[tag:docauthor]', $main_template)) + $main_template = str_replace('[tag:docauthor]', get_username_by_id($AVE_Core->curentdoc->document_author_id), $main_template); //-- Время - 1 день назад $main_template = str_replace('[tag:humandate]', human_date($AVE_Core->curentdoc->document_published), $main_template); @@ -1128,8 +1129,8 @@ */ function request_get_document_field_value($rubric_id, $document_id, $maxlength = 0) { - - if (! is_numeric($rubric_id) || $rubric_id < 1 || ! is_numeric($document_id) || $document_id < 1) return ''; + if (! is_numeric($rubric_id) || $rubric_id < 1 || ! is_numeric($document_id) || $document_id < 1) + return ''; $document_fields = get_document_fields($document_id); @@ -1153,7 +1154,9 @@ $maxlength = abs($maxlength); } - $field_value = mb_substr($field_value, 0, $maxlength) . (strlen($field_value) > $maxlength ? '... ' : ''); + $field_value = mb_substr($field_value, 0, $maxlength) . (strlen($field_value) > $maxlength + ? '... ' + : ''); } return $field_value; diff --git a/functions/func.sysblock.php b/functions/func.sysblock.php index 0ed1808..759c307 100644 --- a/functions/func.sysblock.php +++ b/functions/func.sysblock.php @@ -33,7 +33,7 @@ $cache = md5('sysblock' . $id); - $cache_file = BASE_DIR . '/cache/sql/sysblock/' . $cache . '.cache'; + $cache_file = BASE_DIR . '/tmp/cache/sql/sysblock/' . $cache . '.cache'; // Если включен DEV MODE, то отключаем кеширование запросов if (defined('DEV_MODE') AND DEV_MODE) diff --git a/inc/antispam.php b/inc/antispam.php index 232fcac..f9c1e8b 100644 --- a/inc/antispam.php +++ b/inc/antispam.php @@ -1,77 +1,77 @@ \ No newline at end of file diff --git a/inc/config.php b/inc/config.php index 57f2b77..24822e8 100755 --- a/inc/config.php +++ b/inc/config.php @@ -92,7 +92,7 @@ $GLOBALS['CMS_CONFIG']['ADMIN_CAPTCHA'] = array('DESCR' => 'Использовать капчу при входе в админку','default'=>false,'TYPE'=>'bool','VARIANT'=>''); $GLOBALS['CMS_CONFIG']['ADMIN_EDITMENU'] = array('DESCR' => 'Использовать всплывающие "Действия" в системе','default'=>true,'TYPE'=>'bool','VARIANT'=>''); - $GLOBALS['CMS_CONFIG']['ATTACH_DIR'] = array('DESCR' => 'Директория для хранения вложений','default'=>'cache/attachments','TYPE'=>'string','VARIANT'=>''); + $GLOBALS['CMS_CONFIG']['ATTACH_DIR'] = array('DESCR' => 'Директория для хранения вложений','default'=>'attachments','TYPE'=>'string','VARIANT'=>''); $GLOBALS['CMS_CONFIG']['UPLOAD_DIR'] = array('DESCR' => 'Директория для хранения файлов','default'=>'uploads','TYPE'=>'string','VARIANT'=>''); $GLOBALS['CMS_CONFIG']['UPLOAD_SHOP_DIR'] = array('DESCR' => 'Директория для хранения миниатюр Магазина','default'=>'uploads/shop','TYPE'=>'string','VARIANT'=>''); $GLOBALS['CMS_CONFIG']['UPLOAD_GALLERY_DIR'] = array('DESCR' => 'Директория для хранения миниатюр Галерей','default'=>'uploads/gallery','TYPE'=>'string','VARIANT'=>''); @@ -124,6 +124,7 @@ $GLOBALS['CMS_CONFIG']['SMARTY_USE_SUB_DIRS'] = array('DESCR' => 'Создание папок для кэширования Установите это в false если ваше окружение PHP не разрешает создание директорий от имени Smarty. Поддиректории более эффективны, так что используйте их, если можете.','default'=>true,'TYPE'=>'bool','VARIANT'=>''); $GLOBALS['CMS_CONFIG']['CACHE_DOC_TPL'] = array('DESCR' => 'Кэширование скомпилированных шаблонов документов','default'=>true,'TYPE'=>'bool','VARIANT'=>''); $GLOBALS['CMS_CONFIG']['CACHE_DOC_FILE'] = array('DESCR' => 'Кэширование скомпилированных шаблонов документов в файлах','default'=>true,'TYPE'=>'bool','VARIANT'=>''); + $GLOBALS['CMS_CONFIG']['CACHE_DOC_SQL'] = array('DESCR' => 'Кэширование SQL запроса информации о документе','default'=>0,'TYPE'=>'integer','VARIANT'=>''); $GLOBALS['CMS_CONFIG']['SYSTEM_CACHE_LIFETIME'] = array('DESCR' => 'Время жизни кеша запроса к настройкам системы (60*60*24*14 - 2 недели)','default'=>0,'TYPE'=>'integer','VARIANT'=>''); $GLOBALS['CMS_CONFIG']['YANDEX_MAP_API_KEY'] = array('DESCR' => 'Yandex MAP API REY','default'=>'','TYPE'=>'string','VARIANT'=>''); @@ -152,7 +153,8 @@ $GLOBALS['CMS_CONFIG']['DEV_MODE'] = array('DESCR' => 'Режим разработчика (Отключено кеширование SQL)', 'default'=>false, 'TYPE'=>'bool', 'VARIANT'=>''); $GLOBALS['CMS_CONFIG']['SQL_QUERY_SANITIZE'] = array('DESCR' => 'Принудительно проверять SQL запросы', 'default'=>false, 'TYPE'=>'bool', 'VARIANT'=>''); - include_once(dirname(dirname(__FILE__)) . '/inc/config.inc.php'); + if (file_exists(dirname(dirname(__FILE__)) . '/config/config.inc.php')) + include_once(dirname(dirname(__FILE__)) . '/config/config.inc.php'); foreach($GLOBALS['CMS_CONFIG'] as $k => $v) if(! defined($k)) diff --git a/inc/init.php b/inc/init.php index a21121d..b824495 100644 --- a/inc/init.php +++ b/inc/init.php @@ -16,26 +16,32 @@ if (! defined('BASE_DIR')) exit; - // Подключаем файл настроек + //-- Подключаем файл настроек require_once (BASE_DIR . '/inc/config.php'); if (PHP_DEBUGGING_FILE && ! defined('ACP')) include_once BASE_DIR . '/inc/errors.php'; - /** - * Удаление глобальных массивов - * - */ + //-- Удаление глобальных массивов function unsetGlobals() { if (! ini_get('register_globals')) return; - $allowed = array('_ENV'=>1, '_GET'=>1, '_POST'=>1, '_COOKIE'=>1, '_FILES'=>1, '_SERVER'=>1, '_REQUEST'=>1, 'GLOBALS'=>1); + $allowed = array( + '_ENV' => 1, + '_GET' => 1, + '_POST' => 1, + '_COOKIE' => 1, + '_FILES' => 1, + '_SERVER' => 1, + '_REQUEST' => 1, + 'GLOBALS' => 1 + ); foreach ($GLOBALS as $key => $value) { - if (!isset($allowed[$key])) + if (! isset($allowed[$key])) unset($GLOBALS[$key]); } } @@ -44,10 +50,10 @@ if (isset($HTTP_POST_VARS)) { - $_GET = $HTTP_GET_VARS; - $_POST = $HTTP_POST_VARS; - $_REQUEST = array_merge($_POST, $_GET); - $_COOKIE = $HTTP_COOKIE_VARS; + $_GET = $HTTP_GET_VARS; + $_POST = $HTTP_POST_VARS; + $_REQUEST = array_merge($_POST, $_GET); + $_COOKIE = $HTTP_COOKIE_VARS; } /** @@ -75,14 +81,14 @@ if (! get_magic_quotes_gpc()) { - $_GET = add_slashes($_GET); - $_POST = add_slashes($_POST); - $_REQUEST = array_merge($_POST, $_GET); - $_COOKIE = add_slashes($_COOKIE); + $_GET = add_slashes($_GET); + $_POST = add_slashes($_POST); + $_REQUEST = array_merge($_POST, $_GET); + $_COOKIE = add_slashes($_COOKIE); } - function is_ssl() + function isSSL() { if (isset($_SERVER['HTTPS'])) { @@ -93,21 +99,22 @@ return true; } elseif (isset($_SERVER['SERVER_PORT']) && ('443' == $_SERVER['SERVER_PORT'])) - { - return true; - } + { + return true; + } return false; } - function set_host() + function setHost() { if (isset($_SERVER['HTTP_HOST'])) { // Все символы $_SERVER['HTTP_HOST'] приводим к строчным и проверяем // на наличие запрещённых символов в соответствии с RFC 952 и RFC 2181. $_SERVER['HTTP_HOST'] = strtolower($_SERVER['HTTP_HOST']); + if (! preg_match('/^\[?(?:[a-z0-9-:\]_]+\.?)+$/', $_SERVER['HTTP_HOST'])) { // $_SERVER['HTTP_HOST'] не соответствует спецификациям. @@ -121,7 +128,7 @@ $_SERVER['HTTP_HOST'] = ''; } - $ssl = is_ssl(); + $ssl = isSSL(); $schema = ($ssl) ? 'https://' : 'http://'; $host = str_replace(':' . $_SERVER['SERVER_PORT'], '', $_SERVER['HTTP_HOST']); $port = ($_SERVER['SERVER_PORT'] == '80' || $_SERVER['SERVER_PORT'] == '443' || $ssl) @@ -136,10 +143,11 @@ if (defined('ACP')) $abs_path = dirname($abs_path); + define('ABS_PATH', rtrim(str_replace("\\", "/", $abs_path), '/') . '/'); } - set_host(); + setHost(); set_include_path (get_include_path() . '/' . BASE_DIR . '/lib'); @@ -153,11 +161,10 @@ ini_set ('url_rewriter.tags', ''); - // Переключение для нормальной работы с русскими буквами в некоторых функциях + //-- Переключение для нормальной работы с русскими буквами в некоторых функциях mb_internal_encoding("UTF-8"); - - // Вкл/Выкл отображения ошибок php + //-- Вкл/Выкл отображения ошибок php if (! PHP_DEBUGGING_FILE) { if (! PHP_DEBUGGING) @@ -172,10 +179,15 @@ } } + //-- Debug Class + require (BASE_DIR . '/class/class.debug.php'); + $Debug = new Debug; - /** - * Подкючаем необходимые файлы функций - */ + //-- Hooks Class + require (BASE_DIR . '/class/class.hooks.php'); + $Hooks = new Hooks; + + //-- Подкючаем необходимые файлы функций require_once (BASE_DIR . '/functions/func.breadcrumbs.php'); // Хлебные крошки require_once (BASE_DIR . '/functions/func.common.php'); // Основные функции require_once (BASE_DIR . '/functions/func.locale.php'); // Языковые функции @@ -196,44 +208,38 @@ require_once (BASE_DIR . '/functions/func.watermarks.php'); // Функции по работе с водными знаками - /** - * Создание папок и файлов - */ - foreach (array('cache', 'backup', 'session') as $dir) - { - write_htaccess_deny(BASE_DIR . '/' . $dir); - } + //-- Создание папок и файлов + foreach (array(ATTACH_DIR, 'cache', 'backup', 'logs', 'session', 'update') as $dir) + write_htaccess_deny(BASE_DIR . '/tmp/' . $dir); - foreach (array('attachments', 'combine', 'module', 'redactor', 'smarty', 'sql', 'tpl') as $dir) - { - write_htaccess_deny(BASE_DIR . '/cache/' . $dir); - } + foreach (array('combine', 'module', 'redactor', 'smarty', 'sql', 'templates', 'tpl') as $dir) + write_htaccess_deny(BASE_DIR . '/tmp/cache/' . $dir); global $AVE_DB; - // Класс для работы с MySQL (Global $AVE_DB) + //-- Класс для работы с MySQL (Global $AVE_DB) require_once (BASE_DIR . '/class/class.database.php'); - // Если не существует объекта по работе с БД + //-- Если не существует объекта по работе с БД if (! isset($AVE_DB)) { - // Подключаем конфигурационный файл с параметрами подключения - require_once (BASE_DIR . '/inc/db.config.php'); + //-- Подключаем конфигурационный файл с параметрами подключения + require_once (BASE_DIR . '/config/db.config.php'); - // Если параметры не указаны, прерываем работу + //-- Если параметры не указаны, прерываем работу if (! isset($config)) exit; - // Если константа префикса таблиц не задана, принудительно определяем ее на основании параметров в файле db.config.php + //-- Если константа префикса таблиц не задана, принудительно определяем ее на основании параметров в файле db.config.php if (! defined('PREFIX')) define('PREFIX', $config['dbpref']); - // Создаем объект для работы с БД + //-- Создаем объект для работы с БД try { $AVE_DB = AVE_DB::getInstance($config) - // Назначаем кодировку + //-- Назначаем кодировку ->setCharset('utf8') - // Назначаем БД + //-- Назначаем БД ->setDatabaseName($config['dbname']); } catch (AVE_DB_Exception $e) @@ -250,10 +256,10 @@ unset ($config); } - // Устанавливаем обновления системы + //-- Устанавливаем обновления системы if ($AVE_DB) { - $updaters = (glob(BASE_DIR . "/cache/*.update.php")); + $updaters = (glob(BASE_DIR . '/tmp/update/*.update.php')); if ($updaters) { @@ -261,9 +267,9 @@ foreach ($updaters as $ufile) { - @eval('?>' . @file_get_contents($ufile) . '' . @file_get_contents($ufile) . 'Query(" @@ -343,7 +353,7 @@ "); } - //Запоминаем язык браузера + //-- Запоминаем язык браузера $browlang = $_SERVER['HTTP_ACCEPT_LANGUAGE']; $browlang = explode('-', $browlang); $browlang = $browlang[0]; @@ -372,43 +382,31 @@ } } - + //-- Язык пользователя $_SESSION['user_language'] = (! empty($_SESSION['user_language']) ? $_SESSION['user_language'] :(isset($_SESSION['accept_langs'][$browlang]) ? $browlang : DEFAULT_LANGUAGE)); - define('DATE_FORMAT', get_settings('date_format')); define('TIME_FORMAT', get_settings('time_format')); - define('PAGE_NOT_FOUND_ID', intval(get_settings('page_not_found_id'))); + define('PAGE_NOT_FOUND_ID', (int)get_settings('page_not_found_id')); - - // Вывод данных документа без общего шаблона + //-- Вывод данных документа без общего шаблона if (isset($_REQUEST['onlycontent']) && 1 == $_REQUEST['onlycontent']) - { define('ONLYCONTENT', 1); - } - // Язык системы + //-- Язык системы set_locale(); - // Debug - require (BASE_DIR . '/class/class.debug.php'); - $Debug = new Debug; - - // Hooks - require (BASE_DIR . '/class/class.hooks.php'); - $Hooks = new Hooks; - - // Класс Шаблонов SMARTY + //-- Класс Шаблонов SMARTY require (BASE_DIR . '/class/class.template.php'); - // Класс пагинации + //-- Класс пагинации require (BASE_DIR . '/class/class.paginations.php'); - // Класс Модулей + //-- Класс Модулей require (BASE_DIR . '/class/class.modules.php'); $AVE_Module = new AVE_Module; ?> \ No newline at end of file diff --git a/inc/thumb.php b/inc/thumb.php index 6a43f13..2649084 100644 --- a/inc/thumb.php +++ b/inc/thumb.php @@ -224,7 +224,7 @@ { header($_SERVER['SERVER_PROTOCOL'] . ' 404 Not Found'); - $imageName = 'default.png'; + $imageName = 'noimage.png'; if (! file_exists("$imagePath/$imageName")) { diff --git a/index.php b/index.php index f788a98..a756426 100755 --- a/index.php +++ b/index.php @@ -15,15 +15,15 @@ define ('START_MEMORY', memory_get_usage()); define ('BASE_DIR', str_replace("\\", "/", dirname(__FILE__))); - // Проверяем уставлена ли CMS - if (! @filesize(BASE_DIR . '/inc/db.config.php')) + //-- Проверяем уставлена ли CMS + if (! @filesize(BASE_DIR . '/config/db.config.php')) { header ('Location:install/index.php'); exit; } - // Если в запросе пришел вызов thumbnail - // подключаем файл обработки thumbnail + //-- Если в запросе пришел вызов thumbnail + //-- подключаем файл обработки thumbnail if (! empty($_REQUEST['thumb'])) { require (BASE_DIR . '/inc/thumb.php'); @@ -32,41 +32,47 @@ ob_start(); - // Подключаем файл определения мобильных устройств - // далее пользуемся $MDetect + //-- Подключаем файл определения мобильных устройств + //-- далее пользуемся $MDetect require_once (BASE_DIR . '/lib/mobile_detect/Mobile_Detect.php'); $MDetect = new Mobile_Detect; - // Подключаем файл инициализации + //-- Подключаем файл инициализации require (BASE_DIR . '/inc/init.php'); unset ($GLOBALS['CMS_CONFIG']); - // Проверяем нет ли в запросе папки UPLOADS_DIR - // подключаем файл для работы thumbsnail + //-- Проверяем нет ли в запросе папки UPLOADS_DIR + //-- подключаем файл для работы thumbsnail if (strpos ($_SERVER['REQUEST_URI'], ABS_PATH . UPLOAD_DIR . '/') === 0) { require (BASE_DIR . '/inc/thumb.php'); exit; } - // Папка с шаблонами для Smarty + //-- Папка с шаблонами для Smarty $AVE_Template = new AVE_Template(BASE_DIR . '/templates/'); - // Подключаем ядро системы + //-- Подключаем ядро системы require (BASE_DIR . '/class/class.core.php'); $AVE_Core = new AVE_Core; - // Проверям на вызов внешних модулей и системных блоков - if (empty ($_REQUEST['module']) || empty ($_REQUEST['sysblock']) || empty ($_REQUEST['request'])) + //-- Проверям на вызов внешних модулей и системных блоков + if ( + empty ($_REQUEST['module']) + || + empty ($_REQUEST['sysblock']) + || + empty ($_REQUEST['request']) + ) $AVE_Core->coreUrlParse($_SERVER['REQUEST_URI']); $GLOBALS['page_id'] = array((isset($_REQUEST['id']) ? $_REQUEST['id'] : '') - => array('apage' => floatval(0))); + => array('page' => floatval(0))); - // Если пришел вызов на показ ревизии документа + //-- Если пришел вызов на показ ревизии документа if (! empty($_REQUEST['revission'])) { $res = $AVE_DB->Query(" @@ -86,7 +92,7 @@ $flds = get_document_fields((int)$_REQUEST['id'], $res); } - // Собираем страницу + //-- Собираем страницу $AVE_Core->coreSiteFetch(get_current_document_id()); $content = ob_get_clean(); @@ -98,20 +104,20 @@ else ob_start(); - eval ('?>' . $content . '' . $content . 'showAllQueries(); + //-- Вывод статистики загрузки и запросов SQL (только для администраторов) + if ( + ! defined('ONLYCONTENT') + && + UGROUP == 1 + && + defined('PROFILING') && PROFILING + ) + Debug::displayInfo(); ?> \ No newline at end of file diff --git a/install/data_base.sql b/install/data_base.sql index a17a672..4d5ee27 100755 --- a/install/data_base.sql +++ b/install/data_base.sql @@ -248,7 +248,10 @@ INSERT INTO `%%PRFX%%_documents` VALUES (2, 1, 0, 0, '404-not-found', '0', '404 - Документ не найден', 'Ошибка 404', 0, 0, 0, 1, '0', '', '', 'noindex,nofollow', '6', '0', '1', '0', 0, 0, 0, '', '', 'ru', '2', '');#inst# INSERT INTO `%%PRFX%%_navigation` VALUES - (1, 'main', 'Основное меню', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '1,2,3,4,5', '1');#inst# + (1,'main','Основное меню','
  • \n [tag:linkname]\n
  • ','','','
  • \n [tag:linkname]\n
  • ','','','
      \n[tag:content]\n
    ','','','','','','','','1,2,3,4,5','1');#inst# + +INSERT INTO `%%PRFX%%_navigation_items` VALUES + (1,1,1,'/','Главная','','_self','','','','',0,'1',0,'1');#inst# INSERT INTO `%%PRFX%%_rubric_fields` VALUES (1, 1, 0, 'header', 'Заголовок', 'single_line', 0, 1, '', '', '', '', ''), @@ -262,7 +265,7 @@ INSERT INTO `%%PRFX%%_rubric_permissions` VALUES (5, 1, 5, 'docread');#inst# INSERT INTO `%%PRFX%%_rubrics` VALUES - (1, 'Основные страницы', '', '0', '

    [tag:fld:header]

    [tag:fld:text]', 1, 1, 0, 1, '', '', '', '', '', '', '', '0', '', '0', '');#inst# + (1,'Основные страницы','','0','

    [tag:fld:header]

    \n[tag:fld:text]',1,1,0,1,'','','','','','','','0','','0',0);#inst# INSERT INTO `%%PRFX%%_settings` VALUES ( @@ -280,9 +283,9 @@ INSERT INTO `%%PRFX%%_settings` VALUES '%%EMAIL%%', '%%USERNAME%%', 'Здравствуйте %NAME%,\r\nВаша регистрация на сайте %HOST%. \r\n\r\nТеперь Вы можете войти на %HOST% со следующими данными:: \r\n\r\nПароль: %PASSWORD%\r\nE-Mail: %EMAIL%\r\n\r\n--------------------------------------------------\r\n%EMAILSIGNATURE%\r\n\r\n', - 'С уважением,\r\nслужба поддержки AVE.CMS\r\nsupport@ave-cms.ru | www.ave-cms.ru', + 'С уважением,\r\nслужба поддержки', '2', - '

    Ошибка...

    \r\n
    \r\nУ Вас нет прав на просмотр этого документа!.', + '

    Ошибка...

    \r\n

    \r\nУ Вас нет прав на просмотр этого документа!.\r\n

    ', '
      %s
    ', 'Первая «', '» Последняя', @@ -299,22 +302,22 @@ INSERT INTO `%%PRFX%%_settings` VALUES '0', '
  •  → 
  • ', '0', - '
  • %s
  • ', + '', '[name]', - '
  • %s
  • ', + '
  • %s
  • ', '1', '%d %B %Y', '%d %B %Y, %H:%M', 'RU', '0', '0', - '
    \n Содержимое скрыто. Пожалуйста, зарегистрируйтесь\n
    ' + '
    \n Содержимое скрыто.\n
    ' );#inst# INSERT INTO `%%PRFX%%_settings_lang` VALUES (1, 'ru', 'Русский', 'ru', '1', '1'), - (2, 'en', 'English', 'en', '0', '1'), - (3, 'ua', 'Українська', 'ua', '0', '1'), + (2, 'en', 'English', 'en', '0', '0'), + (3, 'ua', 'Українська', 'ua', '0', '0'), (4, 'de', 'Deutsch', 'de', '0', '0'), (5, 'it', 'Italian', 'it', '0', '0'), (6, 'fr', 'France', 'fr', '0', '0'), @@ -325,14 +328,13 @@ INSERT INTO `%%PRFX%%_settings_lang` VALUES (11, 'bg', 'Български', 'bg', '0', '0');#inst# INSERT INTO `%%PRFX%%_templates` VALUES - (1, 'Основной шаблон', '\n\n \n [tag:title] - [tag:sitename]\n\n \n\n \n \n \n\n \n\n \n \n\n [tag:rubheader]\n\n \n \n\n
    \n
    \n \n
    \n [tag:maincontent]\n
    \n
    \n
    \n\n \n \n \n \n \n', 1, 0);#inst# + (1,'Основной шаблон','\n\n \n \n\n \n \n \n\n \n\n \n\n \n \n \n \n \n \n\n [tag:rubheader]\n\n [tag:title] - [tag:sitename]\n \n \n \n
    \n \n
    \n\n \n
    \n
    \n
    \n [tag:maincontent]\n
    \n
    \n
    \n\n \n
    \n
    \n Создано при помощи [tag:version]\n
    \n
    \n\n \n \n \n \n \n \n\n [tag:rubfooter]\n \n',1,0);#inst# INSERT INTO `%%PRFX%%_user_groups` VALUES (1, 'Администраторы', '1', '0', '', 'alles'), (2, 'Анонимные пользователи', '1', '0', '', ''), (3, 'Модераторы', '1', '0', '', ''), - (4, 'Зарегистрированные', '1', '0', '', ''), - (5, 'Через логинзу', '1', '0', '', '');#inst# + (4, 'Зарегистрированные', '1', '0', '', '');#inst# INSERT INTO `%%PRFX%%_users` VALUES (1, '%%PASS%%', '%%EMAIL%%', '', '', '', '', '', '', '', '', '', '%%USERNAME%%', 1, '', '', '1', '', 'RU', '', '0', '0', '0', '0', '', '', '', '%%SALT%%', '', 0);#inst# diff --git a/install/index.php b/install/index.php index 11622ce..7ddbdb4 100644 --- a/install/index.php +++ b/install/index.php @@ -1,533 +1,528 @@ 0) + { + $cLastAlpha = strtolower(substr($str, -1)); + $size = intval($str); + switch($cLastAlpha) + { + case 't': + $size *= 1024; + case 'g': + $size *= 1024; + case 'm': + $size *= 1024; + case 'k': + $size *= 1024; + } + } + else { - array_push($error_is_required, $lang_i['error_is_writeable'] . $must_writeable . $lang_i['error_is_writeable_2'] ); + $size = 0; } + return $size; } -} -function clean_db ($name="", $prefix="", $mysql_connect) -{ - @mysqli_select_db($mysql_connect, $name); - $query = @mysqli_query($mysql_connect, "SHOW TABLES FROM " . $name); - - while ($row = @mysqli_fetch_array($query, MYSQL_NUM)) + /** + * Get GD version + * @return string + */ + function getGdVersion() { - if (preg_match("/^" . $prefix . "/", $row[0])) + if (function_exists('gd_info')) { - @mysqli_query($mysql_connect ,"DROP TABLE " . $row[0]); + $gd_info = @gd_info(); + return preg_replace('/[^0-9\.]/', '', $gd_info['GD Version']); } + + return NULL; } -} - -/** - * Convert size from 10M to bytes - * - * @param string $str e.g. 10M - * @return int - */ -function convertSizeToBytes($str) -{ - $str = trim($str); - if (strlen($str) > 0) + + /** + * Get PCRE version + * @return string + */ + function getPcreVersion() + { + defined('PCRE_VERSION') + ? list($version) = explode(' ', constant('PCRE_VERSION')) + : $version = NULL; + + return $version; + } + + /** + * Get MySQL version + * @return string + */ + function getMySQLVersion() { + $output = mysqli_get_client_info(); + preg_match('@[0-9]+\.[0-9]+\.[0-9]+@', $output, $version); + return $version[0]; + } + + function check_param($level, $text) { - $cLastAlpha = strtolower(substr($str, -1)); - $size = intval($str); - switch($cLastAlpha) + $level = intval($level); + + switch ($level) { - case 't': - $size *= 1024; - case 'g': - $size *= 1024; - case 'm': - $size *= 1024; - case 'k': - $size *= 1024; + //Параметр не соответствует. + case 2: + $img = 'ico_delete'; + break; + //Несоответствие, не влияющее на функционирование системы. + case 1: + $img = 'ico_ok'; + break; + //Параметр соответствует. + case 0: + $img = 'ico_ok_green'; + break; + //По умолчанию + default: + $img = 'ico_ok_noproblem'; + break; } + return $img; } - else + + + /** + * @subpackage install + */ + error_reporting(E_ERROR); + ini_set('display_errors', 7); + + global $config; + + ob_start(); + + define('SETUP', 1); + + define('BASE_DIR', str_replace("\\", "/", dirname(dirname(__FILE__)))); + + if (! is_writable(BASE_DIR . '/cache/smarty/')) + die('Cache folder is not writeable!'); + + include(BASE_DIR . '/config/db.config.php'); + include(BASE_DIR . '/inc/config.php'); + include(BASE_DIR . '/functions/func.common.php'); + include(BASE_DIR . '/functions/func.helpers.php'); + include(BASE_DIR . '/class/class.template.php'); + + $AVE_Template = new AVE_Template(BASE_DIR . '/install/tpl/'); + + $lang_file = BASE_DIR . '/install/lang/ru.txt'; + + $AVE_Template->config_load($lang_file); + + $ver = APP_NAME . ' v' . APP_VERSION; + + $db_connect = check_db_connect($config['dbhost'], $config['dbuser'], $config['dbpass'], $config['dbname']); + $check_installed = check_installed($config['dbpref']); + + if ((true === $db_connect) && $_REQUEST['step'] != 'finish' && check_installed($config['dbpref'])) { + echo '
    ' . $AVE_Template->get_config_vars('installed') . '
    '; + exit; + }; + + $error_is_required = array(); + + check_required(); + check_writable(); + + // include_once(BASE_DIR . '/inc/errors.php'); + + $count_error = sizeof((array) $error_is_required); + if (1 == $count_error) { - $size = 0; + $AVE_Template->assign('error_header', $AVE_Template->get_config_vars('erroro')); } - return $size; -} - -/** - * Get GD version - * @return string - */ -function getGdVersion() -{ - if (function_exists('gd_info')) + elseif ($count_error > 1) { - $gd_info = @gd_info(); - return preg_replace('/[^0-9\.]/', '', $gd_info['GD Version']); + $AVE_Template->assign('error_header', $AVE_Template->get_config_vars('erroro_more')); } - return NULL; -} - -/** - * Get PCRE version - * @return string - */ -function getPcreVersion() -{ - defined('PCRE_VERSION') - ? list($version) = explode(' ', constant('PCRE_VERSION')) - : $version = NULL; - - return $version; -} - -/** - * Get MySQL version - * @return string - */ -function getMySQLVersion() { - $output = mysqli_get_client_info(); - preg_match('@[0-9]+\.[0-9]+\.[0-9]+@', $output, $version); - return $version[0]; -} - -function check_param($level, $text) -{ - $level = intval($level); - - switch ($level) + if ($count_error > 0 && ! (isset($_REQUEST['force']) && 1 == $_REQUEST['force'])) { - //Параметр не соответствует. - case 2: - $img = 'ico_delete'; - break; - //Несоответствие, не влияющее на функционирование системы. - case 1: - $img = 'ico_ok'; - break; - //Параметр соответствует. - case 0: - $img = 'ico_ok_green'; - break; - //По умолчанию - default: - $img = 'ico_ok_noproblem'; - break; + $AVE_Template->assign('error_is_required', $error_is_required); + $AVE_Template->display('error.tpl'); + exit; } - return $img; -} + $_REQUEST['step'] = isset($_REQUEST['step']) ? $_REQUEST['step'] : ''; + + // Минимальные требования к системе + define('PHP_version', '5.6'); + define('MySQL_version', '5.0.0'); + define('GD_version', '2.0'); + define('PCRE_version', '7.0'); + define('JSON', $AVE_Template->get_config_vars('mess_on')); + define('MbString', $AVE_Template->get_config_vars('mess_on')); + define('SimpleXML', $AVE_Template->get_config_vars('mess_on')); + define('Iconv', $AVE_Template->get_config_vars('mess_on')); + define('XSLT', $AVE_Template->get_config_vars('mess_supported')); + define('Data_limit', '2'); // Mb + define('TIME_limit', '30'); // Sec + define('DISC_space', '30'); // Mb + define('RAM_space', '32M'); // Mb + define('SAFE_MODE', $AVE_Template->get_config_vars('mess_off')); + define('REGISTER_GLOBALS', $AVE_Template->get_config_vars('mess_off')); + define('MAGIC_QUOTES_GPC', $AVE_Template->get_config_vars('mess_off')); + + switch ($_REQUEST['step']) + { + //Начало + case '' : + + //Шаг 1 + case '1' : + $AVE_Template->display('step1.tpl'); + break; + + //Шаг 2 + case '2' : + $AVE_Template->display('step2.tpl'); + break; + + //Шаг 3 + case '3' : + $test['php_version'] = phpversion(); + $test['mysql_version'] = getMySQLVersion(); + $test['gd_version'] = getGdVersion(); + $test['pcre_version'] = getPcreVersion(); + $test['json'] = function_exists('json_encode') ? $AVE_Template->get_config_vars('mess_on') : $AVE_Template->get_config_vars('mess_off'); + $test['simplexml'] = function_exists('simplexml_load_string') ? $AVE_Template->get_config_vars('mess_on') : $AVE_Template->get_config_vars('mess_off'); + $test['mbstring'] = function_exists('mb_internal_encoding') ? $AVE_Template->get_config_vars('mess_on') : $AVE_Template->get_config_vars('mess_off'); + $test['iconv'] = function_exists('iconv') ? $AVE_Template->get_config_vars('mess_on') : $AVE_Template->get_config_vars('mess_off'); + $test['xslt'] = (function_exists('xslt_create') || function_exists('domxml_xslt_stylesheet') || (class_exists('DomDocument') && class_exists('XsltProcessor'))) ? XSLT : $AVE_Template->get_config_vars('mess_unsupported'); + $test['data_limit'] = ini_get('post_max_size') ? ini_get('post_max_size') : $AVE_Template->get_config_vars('mess_undefined'); + $test['time_limit'] = ini_get('max_execution_time') ? ini_get('max_execution_time') : $AVE_Template->get_config_vars('mess_undefined'); + $test['disk_space'] = round(@disk_free_space($_SERVER['DOCUMENT_ROOT']) / 1024 / 1024, 2); + $test['memmory_limit'] = ini_get('memory_limit') ? ini_get('memory_limit') : $AVE_Template->get_config_vars('mess_undefined'); + $test['s_m'] = (ini_get('safe_mode') == 1) ? $AVE_Template->get_config_vars('mess_on') : $AVE_Template->get_config_vars('mess_off'); + $test['r_g'] = (ini_get('register_globals') == 1) ? $AVE_Template->get_config_vars('mess_on') : $AVE_Template->get_config_vars('mess_off'); + $test['m_q'] = (ini_get('magic_quotes_gpc') == 1 || ini_get('magic_quotes_runtime') == 1 || ini_get('magic_quotes_sybase') == 1) ? $AVE_Template->get_config_vars('mess_on') : $AVE_Template->get_config_vars('mess_off'); + + $check['php_version'] = check_param(version_compare(phpversion(), PHP_version, ">=") ? 0 : 2, $test['php_version']); + $check['mysql_version'] = check_param(version_compare(getMySQLVersion(), MySQL_version, ">=") ? 0 : 2, $test['mysql_version']); + $check['gd_version'] = check_param(version_compare($test['gd_version'], GD_version, ">=") ? 0 : 2, $test['gd_version']); + $check['pcre_version'] = check_param(version_compare($test['pcre_version'], PCRE_version, ">=") ? 0 : 2, $test['pcre_version']); + $check['mbstring'] = check_param(function_exists('mb_internal_encoding') ? 0 : 2, $test['mbstring']); + $check['json'] = check_param(function_exists('json_encode') ? 0 : 2, $test['json']); + $check['simplexml'] = check_param(function_exists('simplexml_load_string') ? 0 : 2, $test['simplexml']); + $check['iconv'] = check_param(function_exists('iconv') ? 0 : 2, $test['iconv']); + $check['xslt'] = check_param(($test['xslt'] == XSLT) ? 0 : 2, $test['xslt']); + $check['data_limit'] = check_param(($test['data_limit'] != $AVE_Template->get_config_vars('mess_undefined') && version_compare($test['data_limit'], Data_limit, ">=")) ? 0 : 2, $test['data_limit']); + $check['time_limit'] = check_param(($test['time_limit'] != $AVE_Template->get_config_vars('mess_undefined') && $test['time_limit'] >= TIME_limit) ? 0 : 2, ($test['time_limit'] != $AVE_Template->get_config_vars('mess_undefined')) ? $test['time_limit'] . " " . $AVE_Template->get_config_vars('seconds') : $t_l); + $check['disk_space'] = check_param(($test['disk_space'] != $AVE_Template->get_config_vars('mess_undefined') && $test['disk_space'] >= DISC_space) ? 0 : 2, ($test['disk_space'] != $AVE_Template->get_config_vars('mess_undefined')) ? $test['disk_space'].$AVE_Template->get_config_vars('megabytes') : $test['disk_space']); + $check['memmory_limit'] = check_param(($test['memmory_limit'] != $AVE_Template->get_config_vars('mess_undefined') && convertSizeToBytes($test['memmory_limit']) >= convertSizeToBytes(RAM_space)) ? 0 : (($test['memmory_limit'] != $AVE_Template->get_config_vars('mess_undefined')) ? 2 : 1), $test['memmory_limit']); + $check['s_m'] = check_param(($test['s_m'] == SAFE_MODE) ? 0 : 1, $test['s_m']); + $check['r_g'] = check_param(($test['r_g'] == REGISTER_GLOBALS) ? 0 : 1, $test['r_g']); + $check['m_q'] = check_param(($test['m_q'] == MAGIC_QUOTES_GPC) ? 0 : 1, $test['m_q']); + + $AVE_Template->assign('check', $check); + $AVE_Template->assign('test', $test); + $AVE_Template->display('step3.tpl'); + break; + + //Шаг 4 + case '4' : + if (!empty($_POST['dbname']) && !empty($_POST['dbprefix'])) + { + $db_connect = check_db_connect($_POST['dbhost'], $_POST['dbuser'], $_POST['dbpass'], $_POST['dbname']); -/** - * @subpackage install - */ - error_reporting(E_ERROR); - ini_set('display_errors', 7); - -global $config; - -ob_start(); - -define('SETUP', 1); - -define('BASE_DIR', str_replace("\\", "/", dirname(dirname(__FILE__)))); - -if (!is_writable(BASE_DIR . '/cache/smarty/')) die('Cache folder is not writeable!'); - -include(BASE_DIR . '/inc/db.config.php'); -include(BASE_DIR . '/inc/config.php'); -include(BASE_DIR . '/functions/func.common.php'); -include(BASE_DIR . '/functions/func.helpers.php'); -include(BASE_DIR . '/class/class.template.php'); - -$AVE_Template = new AVE_Template(BASE_DIR . '/install/tpl/'); - -$lang_file = BASE_DIR . '/install/lang/ru.txt'; - -$AVE_Template->config_load($lang_file); - -$ver = APP_NAME . ' v' . APP_VERSION; - -$db_connect = check_db_connect($config['dbhost'], $config['dbuser'], $config['dbpass'], $config['dbname']); -$check_installed = check_installed($config['dbpref']); - -if ((true === $db_connect) && $_REQUEST['step'] != 'finish' && check_installed($config['dbpref'])) { - echo '
    ' . $AVE_Template->get_config_vars('installed') . '
    '; - exit; -}; - -$error_is_required = array(); - -check_required(); -check_writable(); - -// include_once(BASE_DIR . '/inc/errors.php'); - -$count_error = sizeof((array) $error_is_required); -if (1 == $count_error) -{ - $AVE_Template->assign('error_header', $AVE_Template->get_config_vars('erroro')); -} -elseif ($count_error > 1) -{ - $AVE_Template->assign('error_header', $AVE_Template->get_config_vars('erroro_more')); -} - -if ($count_error > 0 && ! (isset($_REQUEST['force']) && 1 == $_REQUEST['force'])) -{ - $AVE_Template->assign('error_is_required', $error_is_required); - $AVE_Template->display('error.tpl'); - exit; -} - -$_REQUEST['step'] = isset($_REQUEST['step']) ? $_REQUEST['step'] : ''; - -// Минимальные требования к системе -define('PHP_version', '5.5'); -define('MySQL_version', '5.0.0'); -define('GD_version', '2.0'); -define('PCRE_version', '7.0'); -define('JSON', $AVE_Template->get_config_vars('mess_on')); -define('MbString', $AVE_Template->get_config_vars('mess_on')); -define('SimpleXML', $AVE_Template->get_config_vars('mess_on')); -define('Iconv', $AVE_Template->get_config_vars('mess_on')); -define('XSLT', $AVE_Template->get_config_vars('mess_supported')); -define('Data_limit', '2'); // Mb -define('TIME_limit', '30'); // Sec -define('DISC_space', '30'); // Mb -define('RAM_space', '32M'); // Mb -define('SAFE_MODE', $AVE_Template->get_config_vars('mess_off')); -define('REGISTER_GLOBALS', $AVE_Template->get_config_vars('mess_off')); -define('MAGIC_QUOTES_GPC', $AVE_Template->get_config_vars('mess_off')); - -switch ($_REQUEST['step']) -{ - //Начало - case '' : - - //Шаг 1 - case '1' : - $AVE_Template->display('step1.tpl'); - break; - - //Шаг 2 - case '2' : - $AVE_Template->display('step2.tpl'); - break; - - //Шаг 3 - case '3' : - $test['php_version'] = phpversion(); - $test['mysql_version'] = getMySQLVersion(); - $test['gd_version'] = getGdVersion(); - $test['pcre_version'] = getPcreVersion(); - $test['json'] = function_exists('json_encode') ? $AVE_Template->get_config_vars('mess_on') : $AVE_Template->get_config_vars('mess_off'); - $test['simplexml'] = function_exists('simplexml_load_string') ? $AVE_Template->get_config_vars('mess_on') : $AVE_Template->get_config_vars('mess_off'); - $test['mbstring'] = function_exists('mb_internal_encoding') ? $AVE_Template->get_config_vars('mess_on') : $AVE_Template->get_config_vars('mess_off'); - $test['iconv'] = function_exists('iconv') ? $AVE_Template->get_config_vars('mess_on') : $AVE_Template->get_config_vars('mess_off'); - $test['xslt'] = (function_exists('xslt_create') || function_exists('domxml_xslt_stylesheet') || (class_exists('DomDocument') && class_exists('XsltProcessor'))) ? XSLT : $AVE_Template->get_config_vars('mess_unsupported'); - $test['data_limit'] = ini_get('post_max_size') ? ini_get('post_max_size') : $AVE_Template->get_config_vars('mess_undefined'); - $test['time_limit'] = ini_get('max_execution_time') ? ini_get('max_execution_time') : $AVE_Template->get_config_vars('mess_undefined'); - $test['disk_space'] = round(@disk_free_space($_SERVER['DOCUMENT_ROOT']) / 1024 / 1024, 2); - $test['memmory_limit'] = ini_get('memory_limit') ? ini_get('memory_limit') : $AVE_Template->get_config_vars('mess_undefined'); - $test['s_m'] = (ini_get('safe_mode') == 1) ? $AVE_Template->get_config_vars('mess_on') : $AVE_Template->get_config_vars('mess_off'); - $test['r_g'] = (ini_get('register_globals') == 1) ? $AVE_Template->get_config_vars('mess_on') : $AVE_Template->get_config_vars('mess_off'); - $test['m_q'] = (ini_get('magic_quotes_gpc') == 1 || ini_get('magic_quotes_runtime') == 1 || ini_get('magic_quotes_sybase') == 1) ? $AVE_Template->get_config_vars('mess_on') : $AVE_Template->get_config_vars('mess_off'); - - $check['php_version'] = check_param(version_compare(phpversion(), PHP_version, ">=") ? 0 : 2, $test['php_version']); - $check['mysql_version'] = check_param(version_compare(getMySQLVersion(), MySQL_version, ">=") ? 0 : 2, $test['mysql_version']); - $check['gd_version'] = check_param(version_compare($test['gd_version'], GD_version, ">=") ? 0 : 2, $test['gd_version']); - $check['pcre_version'] = check_param(version_compare($test['pcre_version'], PCRE_version, ">=") ? 0 : 2, $test['pcre_version']); - $check['mbstring'] = check_param(function_exists('mb_internal_encoding') ? 0 : 2, $test['mbstring']); - $check['json'] = check_param(function_exists('json_encode') ? 0 : 2, $test['json']); - $check['simplexml'] = check_param(function_exists('simplexml_load_string') ? 0 : 2, $test['simplexml']); - $check['iconv'] = check_param(function_exists('iconv') ? 0 : 2, $test['iconv']); - $check['xslt'] = check_param(($test['xslt'] == XSLT) ? 0 : 2, $test['xslt']); - $check['data_limit'] = check_param(($test['data_limit'] != $AVE_Template->get_config_vars('mess_undefined') && version_compare($test['data_limit'], Data_limit, ">=")) ? 0 : 2, $test['data_limit']); - $check['time_limit'] = check_param(($test['time_limit'] != $AVE_Template->get_config_vars('mess_undefined') && $test['time_limit'] >= TIME_limit) ? 0 : 2, ($test['time_limit'] != $AVE_Template->get_config_vars('mess_undefined')) ? $test['time_limit'] . " " . $AVE_Template->get_config_vars('seconds') : $t_l); - $check['disk_space'] = check_param(($test['disk_space'] != $AVE_Template->get_config_vars('mess_undefined') && $test['disk_space'] >= DISC_space) ? 0 : 2, ($test['disk_space'] != $AVE_Template->get_config_vars('mess_undefined')) ? $test['disk_space'].$AVE_Template->get_config_vars('megabytes') : $test['disk_space']); - $check['memmory_limit'] = check_param(($test['memmory_limit'] != $AVE_Template->get_config_vars('mess_undefined') && convertSizeToBytes($test['memmory_limit']) >= convertSizeToBytes(RAM_space)) ? 0 : (($test['memmory_limit'] != $AVE_Template->get_config_vars('mess_undefined')) ? 2 : 1), $test['memmory_limit']); - $check['s_m'] = check_param(($test['s_m'] == SAFE_MODE) ? 0 : 1, $test['s_m']); - $check['r_g'] = check_param(($test['r_g'] == REGISTER_GLOBALS) ? 0 : 1, $test['r_g']); - $check['m_q'] = check_param(($test['m_q'] == MAGIC_QUOTES_GPC) ? 0 : 1, $test['m_q']); - - $AVE_Template->assign('check', $check); - $AVE_Template->assign('test', $test); - $AVE_Template->display('step3.tpl'); - break; - - //Шаг 4 - case '4' : - if (!empty($_POST['dbname']) && !empty($_POST['dbprefix'])) - { - $db_connect = check_db_connect($_POST['dbhost'], $_POST['dbuser'], $_POST['dbpass'], $_POST['dbname']); - - if (true === $db_connect) { - $mysql_connect = @mysqli_connect($_POST['dbhost'], $_POST['dbuser'], $_POST['dbpass']); - @mysqli_select_db($mysql_connect, $_POST['dbname']); - } + if (true === $db_connect) { + $mysql_connect = @mysqli_connect($_POST['dbhost'], $_POST['dbuser'], $_POST['dbpass']); + @mysqli_select_db($mysql_connect, $_POST['dbname']); + } - // Очищаем бд (по префиксу) - if (isset($_REQUEST["dbclean"]) && $_REQUEST["dbclean"] == "1") { - clean_db($_POST['dbname'], $_POST['dbprefix'], $mysql_connect); - } + // Очищаем бд (по префиксу) + if (isset($_REQUEST["dbclean"]) && $_REQUEST["dbclean"] == "1") { + clean_db($_POST['dbname'], $_POST['dbprefix'], $mysql_connect); + } - // Создать новую БД - if(isset($_REQUEST['dbcreat'])){ + // Создать новую БД + if(isset($_REQUEST['dbcreat'])){ - $link = check_mysql_connect($_POST['dbhost'], $_POST['dbuser'], $_POST['dbpass']); + $link = check_mysql_connect($_POST['dbhost'], $_POST['dbuser'], $_POST['dbpass']); - if (false === $link) { - $AVE_Template->assign('warning', 'Ошибка соединения: ' . mysqli_error()); - } else { - $mysqli_connect = @mysqli_connect($_POST['dbhost'], $_POST['dbuser'], $_POST['dbpass']); - } + if (false === $link) { + $AVE_Template->assign('warning', 'Ошибка соединения: ' . mysqli_error()); + } else { + $mysqli_connect = @mysqli_connect($_POST['dbhost'], $_POST['dbuser'], $_POST['dbpass']); + } - if(false === $db_connect) { - @mysqli_query($mysqli_connect, "SET collation_server = 'utf8_general_ci'"); - @mysqli_query($mysqli_connect, "SET character_set_server = 'utf8'"); + if(false === $db_connect) { + @mysqli_query($mysqli_connect, "SET collation_server = 'utf8_general_ci'"); + @mysqli_query($mysqli_connect, "SET character_set_server = 'utf8'"); - $sql = 'CREATE DATABASE ' . $_POST['dbname']; + $sql = 'CREATE DATABASE ' . $_POST['dbname']; - if (false === check_mysql_query($mysqli_connect, $sql)) { - $AVE_Template->assign('warning', 'Ошибка при создании базы данных: ' . mysqli_error() . "\n"); + if (false === check_mysql_query($mysqli_connect, $sql)) { + $AVE_Template->assign('warning', 'Ошибка при создании базы данных: ' . mysqli_error() . "\n"); + } } } - } - $check_installed = check_installed($_POST['dbprefix']); + $check_installed = check_installed($_POST['dbprefix']); - $connect = check_db_connect($_POST['dbhost'], $_POST['dbuser'], $_POST['dbpass'], $_POST['dbname']); + $connect = check_db_connect($_POST['dbhost'], $_POST['dbuser'], $_POST['dbpass'], $_POST['dbname']); - if (true === $connect && false === $check_installed) - { - if (! @is_writeable(BASE_DIR . '/inc/db.config.php')) + if (true === $connect && false === $check_installed) { - $AVE_Template->assign('config_isnt_writeable', 1); - $AVE_Template->display('error.tpl'); - exit; - } + if (! @is_writeable(BASE_DIR . '/config/db.config.php')) + { + $AVE_Template->assign('config_isnt_writeable', 1); + $AVE_Template->display('error.tpl'); + exit; + } - $fp = @fopen(BASE_DIR . '/inc/db.config.php', 'w+'); - @fwrite($fp, "" - ); - @fclose($fp); - - $filename = BASE_DIR . '/install/structure_base.sql'; + $fp = @fopen(BASE_DIR . '/config/db.config.php', 'w+'); + @fwrite($fp, "" + ); + @fclose($fp); - $handle = fopen($filename, 'r'); - $db_structure = fread($handle, filesize($filename)); - fclose($handle); + $filename = BASE_DIR . '/install/structure_base.sql'; - $db_structure = str_replace('%%PRFX%%', $_POST['dbprefix'], $db_structure); + $handle = fopen($filename, 'r'); + $db_structure = fread($handle, filesize($filename)); + fclose($handle); - $mysql_connect = @mysqli_connect($_POST['dbhost'], $_POST['dbuser'], $_POST['dbpass'], $_POST['dbname']); - @mysqli_select_db($mysql_connect, $_POST['dbname']); + $db_structure = str_replace('%%PRFX%%', $_POST['dbprefix'], $db_structure); - $ar = explode('#inst#', $db_structure); + $mysql_connect = @mysqli_connect($_POST['dbhost'], $_POST['dbuser'], $_POST['dbpass'], $_POST['dbname']); + @mysqli_select_db($mysql_connect, $_POST['dbname']); - foreach ($ar as $in) + $ar = explode('#inst#', $db_structure); + + foreach ($ar as $in) + { + @mysqli_query($mysql_connect, "$in"); + } + + $AVE_Template->display('step5.tpl'); + exit; + } + elseif (true === $connect && true === $check_installed) { - @mysqli_query($mysql_connect, "$in"); + $AVE_Template->assign('installed', $AVE_Template->get_config_vars('database_installed')); + } + else + { + $AVE_Template->assign('warning', $AVE_Template->get_config_vars('database_not_connect')); } - $AVE_Template->display('step5.tpl'); - exit; - } - elseif (true === $connect && true === $check_installed) - { - $AVE_Template->assign('installed', $AVE_Template->get_config_vars('database_installed')); } else { - $AVE_Template->assign('warning', $AVE_Template->get_config_vars('database_not_connect')); + $dbpref = make_random_string(5, 'abcdefghijklmnopqrstuvwxyz0123456789'); + $AVE_Template->assign('dbpref', $dbpref); } - } - else - { - $dbpref = make_random_string(5, 'abcdefghijklmnopqrstuvwxyz0123456789'); - $AVE_Template->assign('dbpref', $dbpref); - } - - $AVE_Template->display('step4.tpl'); - break; + $AVE_Template->display('step4.tpl'); + break; - case '5' : - $_POST['email'] = chop($_POST['email']); - $_POST['username'] = chop($_POST['username']); + case '5' : + $_POST['email'] = chop($_POST['email']); + $_POST['username'] = chop($_POST['username']); - $regex_username = '/[^\w-]/'; - $regex_password = '/[^\x20-\xFF]/'; - $regex_email = '/^[\w.-]+@[a-z0-9.-]+\.(?:[a-z]{2}|com|org|net|edu|gov|mil|biz|info|mobi|name|aero|asia|jobs|museum)$/i'; + $regex_username = '/[^\w-]/'; + $regex_password = '/[^\x20-\xFF]/'; + $regex_email = '/^[\w.-]+@[a-z0-9.-]+\.(?:[a-z]{2}|com|org|net|edu|gov|mil|biz|info|mobi|name|aero|asia|jobs|museum)$/i'; - $errors = array(); - if ($_POST['email'] == '') array_push($errors, $AVE_Template->get_config_vars('noemail')); - if (! preg_match($regex_email, $_POST['email'])) array_push($errors, $AVE_Template->get_config_vars('email_no_specialchars')); - if (empty($_POST['pass']) || preg_match($regex_password, $_POST['pass'])) array_push($errors, $AVE_Template->get_config_vars('check_pass')); - if (strlen($_POST['pass']) < 5) array_push($errors, $AVE_Template->get_config_vars('pass_too_small')); - if (empty($_POST['username']) || preg_match($regex_username, $_POST['username'])) array_push($errors, $AVE_Template->get_config_vars('check_username')); + $errors = array(); + if ($_POST['email'] == '') array_push($errors, $AVE_Template->get_config_vars('noemail')); + if (! preg_match($regex_email, $_POST['email'])) array_push($errors, $AVE_Template->get_config_vars('email_no_specialchars')); + if (empty($_POST['pass']) || preg_match($regex_password, $_POST['pass'])) array_push($errors, $AVE_Template->get_config_vars('check_pass')); + if (strlen($_POST['pass']) < 5) array_push($errors, $AVE_Template->get_config_vars('pass_too_small')); + if (empty($_POST['username']) || preg_match($regex_username, $_POST['username'])) array_push($errors, $AVE_Template->get_config_vars('check_username')); - $AVE_Template->assign('errors', $errors); + $AVE_Template->assign('errors', $errors); - if (true === $db_connect && ! sizeof($errors)) - { - if (isset($_POST['demo']) && 1 == $_POST['demo']) + if (true === $db_connect && ! sizeof($errors)) { - $filename = BASE_DIR . '/install/data_demo.sql'; - } - else - { - $filename = BASE_DIR . '/install/data_base.sql'; - } + if (isset($_POST['demo']) && 1 == $_POST['demo']) + { + $filename = BASE_DIR . '/install/data_demo.sql'; + } + else + { + $filename = BASE_DIR . '/install/data_base.sql'; + } - $mysql_connect = @mysqli_connect($config['dbhost'], $config['dbuser'], $config['dbpass']); - @mysqli_select_db($mysql_connect, $config['dbname']); - - $handle = fopen($filename, 'r'); - $dbin = fread($handle, filesize($filename)); - fclose($handle); - - $salt = make_random_string(); - $hash = md5(md5($_POST['pass'] . $salt)); - - $dbin = str_replace('%%SITENAME%%', $ver, $dbin); - $dbin = str_replace('%%PRFX%%', $config['dbpref'], $dbin); - $dbin = str_replace('%%EMAIL%%', $_POST['email'], $dbin); - $dbin = str_replace('%%SALT%%', $salt, $dbin); - $dbin = str_replace('%%PASS%%', $hash, $dbin); - $dbin = str_replace('%%TIME%%', time(), $dbin); - $dbin = str_replace('%%FIRSTNAME%%', $_POST['firstname'], $dbin); - $dbin = str_replace('%%LASTNAME%%', $_POST['lastname'], $dbin); - $dbin = str_replace('%%USERNAME%%', $_POST['username'], $dbin); - $dbin = str_replace('%%PHONE%%', $_POST['fon'], $dbin); - $dbin = str_replace('%%FAX%%', $_POST['fax'], $dbin); - $dbin = str_replace('%%ZIP%%', $_POST['zip'], $dbin); - $dbin = str_replace('%%TOWN%%', $_POST['town'], $dbin); - $dbin = str_replace('%%STREET%%', $_POST['street'], $dbin); - $dbin = str_replace('%%HNR%%', $_POST['hnr'], $dbin); - - $ar = explode('#inst#', $dbin); - - foreach ($ar as $in) - { - @mysqli_query($mysql_connect, "SET NAMES 'utf8'"); - @mysqli_query($mysql_connect, "SET COLLATION_CONNECTION = 'utf8_general_ci'"); - @mysqli_query($mysql_connect, $in); - } -/* - $auth = base64_encode(serialize(array('id' => '1', 'hash'=>$hash))); - @setcookie('auth', $auth); -*/ - $AVE_Template->display('step6.tpl'); - exit; - } + $mysql_connect = @mysqli_connect($config['dbhost'], $config['dbuser'], $config['dbpass']); + @mysqli_select_db($mysql_connect, $config['dbname']); + + $handle = fopen($filename, 'r'); + $dbin = fread($handle, filesize($filename)); + fclose($handle); + + $salt = make_random_string(); + $hash = md5(md5($_POST['pass'] . $salt)); + + $dbin = str_replace('%%SITENAME%%', $ver, $dbin); + $dbin = str_replace('%%PRFX%%', $config['dbpref'], $dbin); + $dbin = str_replace('%%EMAIL%%', $_POST['email'], $dbin); + $dbin = str_replace('%%SALT%%', $salt, $dbin); + $dbin = str_replace('%%PASS%%', $hash, $dbin); + $dbin = str_replace('%%TIME%%', time(), $dbin); + $dbin = str_replace('%%FIRSTNAME%%', $_POST['firstname'], $dbin); + $dbin = str_replace('%%LASTNAME%%', $_POST['lastname'], $dbin); + $dbin = str_replace('%%USERNAME%%', $_POST['username'], $dbin); - $AVE_Template->display('step5.tpl'); - break; -} + $ar = explode('#inst#', $dbin); + foreach ($ar as $in) + { + @mysqli_query($mysql_connect, "SET NAMES 'utf8'"); + @mysqli_query($mysql_connect, "SET COLLATION_CONNECTION = 'utf8_general_ci'"); + @mysqli_query($mysql_connect, $in); + } + /* + $auth = base64_encode(serialize(array('id' => '1', 'hash'=>$hash))); + @setcookie('auth', $auth); + */ + $AVE_Template->display('step6.tpl'); + exit; + } + + $AVE_Template->display('step5.tpl'); + break; + } ?> \ No newline at end of file diff --git a/install/structure_base.sql b/install/structure_base.sql index 5403617..2ea4376 100755 --- a/install/structure_base.sql +++ b/install/structure_base.sql @@ -30,6 +30,7 @@ CREATE TABLE `%%PRFX%%_document_fields` ( PRIMARY KEY (`Id`), KEY `document_id` (`document_id`), KEY `field_value` (`field_value`), + KEY `field_number_value` (`field_number_value`), KEY `rubric_field_id` (`rubric_field_id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 PACK_KEYS=0;#inst# @@ -81,17 +82,17 @@ CREATE TABLE `%%PRFX%%_documents` ( `rubric_id` mediumint(5) unsigned NOT NULL DEFAULT '0', `rubric_tmpl_id` mediumint(5) unsigned NOT NULL DEFAULT '0', `document_parent` int(10) unsigned NOT NULL DEFAULT '0', - `document_alias` varchar(255) NOT NULL, + `document_alias` varchar(255) NOT NULL DEFAULT '', `document_alias_history` enum('0','1','2') NOT NULL DEFAULT '0', - `document_title` varchar(255) NOT NULL, - `document_breadcrum_title` varchar(255) NOT NULL, + `document_title` varchar(255) NOT NULL DEFAULT '', + `document_breadcrum_title` varchar(255) NOT NULL DEFAULT '', `document_published` int(10) unsigned NOT NULL DEFAULT '0', `document_expire` int(10) unsigned NOT NULL DEFAULT '0', `document_changed` int(10) unsigned NOT NULL DEFAULT '0', `document_author_id` mediumint(5) unsigned NOT NULL DEFAULT '1', `document_in_search` enum('1','0') NOT NULL DEFAULT '1', - `document_meta_keywords` text NOT NULL, - `document_meta_description` text NOT NULL, + `document_meta_keywords` text NOT NULL DEFAULT '', + `document_meta_description` text NOT NULL DEFAULT '', `document_meta_robots` enum('index,follow','index,nofollow','noindex,nofollow') NOT NULL DEFAULT 'index,follow', `document_sitemap_freq` tinyint(1) NOT NULL DEFAULT '3', `document_sitemap_pr` float NOT NULL DEFAULT '0.5', @@ -100,14 +101,15 @@ CREATE TABLE `%%PRFX%%_documents` ( `document_count_print` int(10) unsigned NOT NULL DEFAULT '0', `document_count_view` int(10) unsigned NOT NULL DEFAULT '0', `document_linked_navi_id` mediumint(5) unsigned NOT NULL DEFAULT '0', - `document_teaser` text NOT NULL, - `document_tags` text NOT NULL, - `document_lang` varchar(5) NOT NULL, + `document_teaser` text NOT NULL DEFAULT '', + `document_tags` text NOT NULL DEFAULT '', + `document_lang` varchar(5) NOT NULL DEFAULT '', `document_lang_group` int(10) NOT NULL DEFAULT '0', `document_property` text, PRIMARY KEY (`Id`), UNIQUE KEY `document_alias` (`document_alias`), KEY `rubric_id` (`rubric_id`), + KEY `document_parent` (`document_parent`), KEY `document_status` (`document_status`), KEY `document_published` (`document_published`), KEY `document_expire` (`document_expire`) @@ -152,6 +154,7 @@ CREATE TABLE `%%PRFX%%_module` ( CREATE TABLE `%%PRFX%%_modules_aliases` ( `id` tinyint(5) unsigned NOT NULL AUTO_INCREMENT, + `document_id` int(10) NOT NULL DEFAULT '0', `module_name` char(50) NOT NULL DEFAULT '', `module_action` varchar(255) NOT NULL DEFAULT '', `module_link` varchar(500) NOT NULL DEFAULT '', diff --git a/lib/debug/debug.css b/lib/debug/debug.css new file mode 100644 index 0000000..5e86d1e --- /dev/null +++ b/lib/debug/debug.css @@ -0,0 +1,48 @@ +/* == Debug Panel == */ +#debug-panel { + font-size: 12px; + opacity: 0.9; + position: fixed; + bottom: 0; + left: 0; + z-index: 2000; + width: 100%; +} +#debug-panel .debug-wrapper { + padding: 0px .875em; + background-color: #fff; + border: 1px solid rgba(0,0,0,0.2); + border-bottom: 0; + margin: 0px auto 0px auto; +} +#debug-panel .items { + padding: 10px; + height: 350px; + padding-top: 1em; + font-size: 12px; + color: #888; + font-family: Monaco, Menlo, Consolas, "Courier New", monospace +} +#debug-panel .debug-wrapper .legend { + background-color: #f9f9f9; + padding: .25em; + border: 1px solid rgba(0,0,0,0.2); + width: auto; + margin-top: -1.25em; +} +#debug-panel .debug-wrapper .legend span { + color: #999; + font-weight: 300 +} +#debug-panel a { + text-decoration: none; + color: rgba(0,0,0,0.5); + font-size: 12px; + margin: 0 .25em; +} +#debug-panel pre { + border: 0px; +} +#debugArrowMinimize { + float: right; +} \ No newline at end of file diff --git a/lib/debug/debug.js b/lib/debug/debug.js new file mode 100644 index 0000000..155958e --- /dev/null +++ b/lib/debug/debug.js @@ -0,0 +1,30 @@ +function appExpandTabs(act, key) { + var arrDebugTabs = ["General", "Params", "Globals", "Queries", "SqlTrace"]; + + keyTab = (key == null) + ? "General" + : key; + + for (var i = 0; i < arrDebugTabs.length; i++) { + if (act == "min" || arrDebugTabs[i] != keyTab) { + $("#content" + arrDebugTabs[i]).css("display", "none"); + $("#tab" + arrDebugTabs[i]).css("color", "#bbb") + } + } + if (act != "min") { + $("#content" + keyTab).css("display", ""); + $("#content" + keyTab).css({ + "overflow-y": "auto" + }); + $("#tab" + keyTab).css("color", "#222") + } + + $("#debug-panel").css("opacity", (act == "min") ? "0.9" : "1"); +}; + + +function appTabsHide() +{ + $('#debug-panel-legend span a').css("color", "#bbb"); + $("#debug-panel .items").hide(); +} \ No newline at end of file diff --git a/lib/debug/sql.php b/lib/debug/sql.php new file mode 100644 index 0000000..16b627f --- /dev/null +++ b/lib/debug/sql.php @@ -0,0 +1,1077 @@ +', '+', '-', '*', '/', '!', '^', '%', '|', '&', '#'); + + // For HTML syntax highlighting + // Styles applied to different token types + public static $quote_attributes = 'style="color: blue;"'; + public static $backtick_quote_attributes = 'style="color: purple;"'; + public static $reserved_attributes = 'style="font-weight:bold;"'; + public static $boundary_attributes = ''; + public static $number_attributes = 'style="color: green;"'; + public static $word_attributes = 'style="color: #333;"'; + public static $error_attributes = 'style="background-color: red;"'; + public static $comment_attributes = 'style="color: #aaa;"'; + public static $variable_attributes = 'style="color: orange;"'; + public static $pre_attributes = 'style="color: black; background-color: white;"'; + + // Boolean - whether or not the current environment is the CLI + // This affects the type of syntax highlighting + // If not defined, it will be determined automatically + public static $cli; + + // For CLI syntax highlighting + public static $cli_quote = "\x1b[34;1m"; + public static $cli_backtick_quote = "\x1b[35;1m"; + public static $cli_reserved = "\x1b[37m"; + public static $cli_boundary = ""; + public static $cli_number = "\x1b[32;1m"; + public static $cli_word = ""; + public static $cli_error = "\x1b[31;1;7m"; + public static $cli_comment = "\x1b[30;1m"; + public static $cli_functions = "\x1b[37m"; + public static $cli_variable = "\x1b[36;1m"; + + // The tab character to use when formatting SQL + public static $tab = ' '; + + // This flag tells us if queries need to be enclosed in
     tags
    +	public static $use_pre = true;
    +
    +	// This flag tells us if SqlFormatted has been initialized
    +	protected static $init;
    +
    +	// Regular expressions for tokenizing
    +	protected static $regex_boundaries;
    +	protected static $regex_reserved;
    +	protected static $regex_reserved_newline;
    +	protected static $regex_reserved_toplevel;
    +	protected static $regex_function;
    +
    +	// Cache variables
    +	// Only tokens shorter than this size will be cached.  Somewhere between 10 and 20 seems to work well for most cases.
    +	public static $max_cachekey_size = 15;
    +	protected static $token_cache = array();
    +	protected static $cache_hits = 0;
    +	protected static $cache_misses = 0;
    +
    +	/**
    +	 * Get stats about the token cache
    +	 * @return Array An array containing the keys 'hits', 'misses', 'entries', and 'size' in bytes
    +	 */
    +	public static function getCacheStats()
    +	{
    +		return array(
    +			'hits'=>self::$cache_hits,
    +			'misses'=>self::$cache_misses,
    +			'entries'=>count(self::$token_cache),
    +			'size'=>strlen(serialize(self::$token_cache))
    +		);
    +	}
    +
    +	/**
    +	 * Stuff that only needs to be done once.  Builds regular expressions and sorts the reserved words.
    +	 */
    +	protected static function init()
    +	{
    +		if (self::$init) return;
    +
    +		// Sort reserved word list from longest word to shortest, 3x faster than usort
    +		$reservedMap = array_combine(self::$reserved, array_map('strlen', self::$reserved));
    +		arsort($reservedMap);
    +		self::$reserved = array_keys($reservedMap);
    +
    +		// Set up regular expressions
    +		self::$regex_boundaries = '('.implode('|',array_map(array(__CLASS__, 'quote_regex'),self::$boundaries)).')';
    +		self::$regex_reserved = '('.implode('|',array_map(array(__CLASS__, 'quote_regex'),self::$reserved)).')';
    +		self::$regex_reserved_toplevel = str_replace(' ','\\s+','('.implode('|',array_map(array(__CLASS__, 'quote_regex'),self::$reserved_toplevel)).')');
    +		self::$regex_reserved_newline = str_replace(' ','\\s+','('.implode('|',array_map(array(__CLASS__, 'quote_regex'),self::$reserved_newline)).')');
    +
    +		self::$regex_function = '('.implode('|',array_map(array(__CLASS__, 'quote_regex'),self::$functions)).')';
    +
    +		self::$init = true;
    +	}
    +
    +	/**
    +	 * Return the next token and token type in a SQL string.
    +	 * Quoted strings, comments, reserved words, whitespace, and punctuation are all their own tokens.
    +	 *
    +	 * @param String $string   The SQL string
    +	 * @param array	 $previous The result of the previous getNextToken() call
    +	 *
    +	 * @return Array An associative array containing the type and value of the token.
    +	 */
    +	protected static function getNextToken($string, $previous = null)
    +	{
    +		// Whitespace
    +		if (preg_match('/^\s+/',$string,$matches)) {
    +			return array(
    +				self::TOKEN_VALUE => $matches[0],
    +				self::TOKEN_TYPE=>self::TOKEN_TYPE_WHITESPACE
    +			);
    +		}
    +
    +		// Comment
    +		if ($string[0] === '#' || (isset($string[1])&&($string[0]==='-'&&$string[1]==='-') || ($string[0]==='/'&&$string[1]==='*'))) {
    +			// Comment until end of line
    +			if ($string[0] === '-' || $string[0] === '#') {
    +				$last = strpos($string, "\n");
    +				$type = self::TOKEN_TYPE_COMMENT;
    +			} else { // Comment until closing comment tag
    +				$last = strpos($string, "*/", 2) + 2;
    +				$type = self::TOKEN_TYPE_BLOCK_COMMENT;
    +			}
    +
    +			if ($last === false) {
    +				$last = strlen($string);
    +			}
    +
    +			return array(
    +				self::TOKEN_VALUE => substr($string, 0, $last),
    +				self::TOKEN_TYPE  => $type
    +			);
    +		}
    +
    +		// Quoted String
    +		if ($string[0]==='"' || $string[0]==='\'' || $string[0]==='`' || $string[0]==='[') {
    +			$return = array(
    +				self::TOKEN_TYPE => (($string[0]==='`' || $string[0]==='[')? self::TOKEN_TYPE_BACKTICK_QUOTE : self::TOKEN_TYPE_QUOTE),
    +				self::TOKEN_VALUE => self::getQuotedString($string)
    +			);
    +
    +			return $return;
    +		}
    +
    +		// User-defined Variable
    +		if (($string[0] === '@' || $string[0] === ':') && isset($string[1])) {
    +			$ret = array(
    +				self::TOKEN_VALUE => null,
    +				self::TOKEN_TYPE => self::TOKEN_TYPE_VARIABLE
    +			);
    +
    +			// If the variable name is quoted
    +			if ($string[1]==='"' || $string[1]==='\'' || $string[1]==='`') {
    +				$ret[self::TOKEN_VALUE] = $string[0].self::getQuotedString(substr($string,1));
    +			}
    +			// Non-quoted variable name
    +			else {
    +				preg_match('/^('.$string[0].'[a-zA-Z0-9\._\$]+)/',$string,$matches);
    +				if ($matches) {
    +					$ret[self::TOKEN_VALUE] = $matches[1];
    +				}
    +			}
    +
    +			if($ret[self::TOKEN_VALUE] !== null) return $ret;
    +		}
    +
    +		// Number (decimal, binary, or hex)
    +		if (preg_match('/^([0-9]+(\.[0-9]+)?|0x[0-9a-fA-F]+|0b[01]+)($|\s|"\'`|'.self::$regex_boundaries.')/',$string,$matches)) {
    +			return array(
    +				self::TOKEN_VALUE => $matches[1],
    +				self::TOKEN_TYPE=>self::TOKEN_TYPE_NUMBER
    +			);
    +		}
    +
    +		// Boundary Character (punctuation and symbols)
    +		if (preg_match('/^('.self::$regex_boundaries.')/',$string,$matches)) {
    +			return array(
    +				self::TOKEN_VALUE => $matches[1],
    +				self::TOKEN_TYPE  => self::TOKEN_TYPE_BOUNDARY
    +			);
    +		}
    +
    +		// A reserved word cannot be preceded by a '.'
    +		// this makes it so in "mytable.from", "from" is not considered a reserved word
    +		if (!$previous || !isset($previous[self::TOKEN_VALUE]) || $previous[self::TOKEN_VALUE] !== '.') {
    +			$upper = strtoupper($string);
    +			// Top Level Reserved Word
    +			if (preg_match('/^('.self::$regex_reserved_toplevel.')($|\s|'.self::$regex_boundaries.')/', $upper,$matches)) {
    +				return array(
    +					self::TOKEN_TYPE=>self::TOKEN_TYPE_RESERVED_TOPLEVEL,
    +					self::TOKEN_VALUE=>substr($string,0,strlen($matches[1]))
    +				);
    +			}
    +			// Newline Reserved Word
    +			if (preg_match('/^('.self::$regex_reserved_newline.')($|\s|'.self::$regex_boundaries.')/', $upper,$matches)) {
    +				return array(
    +					self::TOKEN_TYPE=>self::TOKEN_TYPE_RESERVED_NEWLINE,
    +					self::TOKEN_VALUE=>substr($string,0,strlen($matches[1]))
    +				);
    +			}
    +			// Other Reserved Word
    +			if (preg_match('/^('.self::$regex_reserved.')($|\s|'.self::$regex_boundaries.')/', $upper,$matches)) {
    +				return array(
    +					self::TOKEN_TYPE=>self::TOKEN_TYPE_RESERVED,
    +					self::TOKEN_VALUE=>substr($string,0,strlen($matches[1]))
    +				);
    +			}
    +		}
    +
    +		// A function must be suceeded by '('
    +		// this makes it so "count(" is considered a function, but "count" alone is not
    +		$upper = strtoupper($string);
    +		// function
    +		if (preg_match('/^('.self::$regex_function.'[(]|\s|[)])/', $upper,$matches)) {
    +			return array(
    +				self::TOKEN_TYPE=>self::TOKEN_TYPE_RESERVED,
    +				self::TOKEN_VALUE=>substr($string,0,strlen($matches[1])-1)
    +			);
    +		}
    +
    +		// Non reserved word
    +		preg_match('/^(.*?)($|\s|["\'`]|'.self::$regex_boundaries.')/',$string,$matches);
    +
    +		return array(
    +			self::TOKEN_VALUE => $matches[1],
    +			self::TOKEN_TYPE  => self::TOKEN_TYPE_WORD
    +		);
    +	}
    +
    +	protected static function getQuotedString($string)
    +	{
    +		$ret = null;
    +
    +		// This checks for the following patterns:
    +		// 1. backtick quoted string using `` to escape
    +		// 2. square bracket quoted string (SQL Server) using ]] to escape
    +		// 3. double quoted string using "" or \" to escape
    +		// 4. single quoted string using '' or \' to escape
    +		if ( preg_match('/^(((`[^`]*($|`))+)|((\[[^\]]*($|\]))(\][^\]]*($|\]))*)|(("[^"\\\\]*(?:\\\\.[^"\\\\]*)*("|$))+)|((\'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*(\'|$))+))/s', $string, $matches)) {
    +			$ret = $matches[1];
    +		}
    +
    +		return $ret;
    +	}
    +
    +	/**
    +	 * Takes a SQL string and breaks it into tokens.
    +	 * Each token is an associative array with type and value.
    +	 *
    +	 * @param String $string The SQL string
    +	 *
    +	 * @return Array An array of tokens.
    +	 */
    +	protected static function tokenize($string)
    +	{
    +		self::init();
    +
    +		$tokens = array();
    +
    +		// Used for debugging if there is an error while tokenizing the string
    +		$original_length = strlen($string);
    +
    +		// Used to make sure the string keeps shrinking on each iteration
    +		$old_string_len = strlen($string) + 1;
    +
    +		$token = null;
    +
    +		$current_length = strlen($string);
    +
    +		// Keep processing the string until it is empty
    +		while ($current_length) {
    +			// If the string stopped shrinking, there was a problem
    +			if ($old_string_len <= $current_length) {
    +				$tokens[] = array(
    +					self::TOKEN_VALUE=>$string,
    +					self::TOKEN_TYPE=>self::TOKEN_TYPE_ERROR
    +				);
    +
    +				return $tokens;
    +			}
    +			$old_string_len =  $current_length;
    +
    +			// Determine if we can use caching
    +			if ($current_length >= self::$max_cachekey_size) {
    +				$cacheKey = substr($string,0,self::$max_cachekey_size);
    +			} else {
    +				$cacheKey = false;
    +			}
    +
    +			// See if the token is already cached
    +			if ($cacheKey && isset(self::$token_cache[$cacheKey])) {
    +				// Retrieve from cache
    +				$token = self::$token_cache[$cacheKey];
    +				$token_length = strlen($token[self::TOKEN_VALUE]);
    +				self::$cache_hits++;
    +			} else {
    +				// Get the next token and the token type
    +				$token = self::getNextToken($string, $token);
    +				$token_length = strlen($token[self::TOKEN_VALUE]);
    +				self::$cache_misses++;
    +
    +				// If the token is shorter than the max length, store it in cache
    +				if ($cacheKey && $token_length < self::$max_cachekey_size) {
    +					self::$token_cache[$cacheKey] = $token;
    +				}
    +			}
    +
    +			$tokens[] = $token;
    +
    +			// Advance the string
    +			$string = substr($string, $token_length);
    +
    +			$current_length -= $token_length;
    +		}
    +
    +		return $tokens;
    +	}
    +
    +	/**
    +	 * Format the whitespace in a SQL string to make it easier to read.
    +	 *
    +	 * @param String  $string	 The SQL string
    +	 * @param boolean $highlight If true, syntax highlighting will also be performed
    +	 *
    +	 * @return String The SQL string with HTML styles and formatting wrapped in a 
     tag
    +	 */
    +	public static function format($string, $highlight=true)
    +	{
    +		// This variable will be populated with formatted html
    +		$return = '';
    +
    +		// Use an actual tab while formatting and then switch out with self::$tab at the end
    +		$tab = "\t";
    +
    +		$indent_level = 0;
    +		$newline = false;
    +		$inline_parentheses = false;
    +		$increase_special_indent = false;
    +		$increase_block_indent = false;
    +		$indent_types = array();
    +		$added_newline = false;
    +		$inline_count = 0;
    +		$inline_indented = false;
    +		$clause_limit = false;
    +
    +		// Tokenize String
    +		$original_tokens = self::tokenize($string);
    +
    +		// Remove existing whitespace
    +		$tokens = array();
    +		foreach ($original_tokens as $i=>$token) {
    +			if ($token[self::TOKEN_TYPE] !== self::TOKEN_TYPE_WHITESPACE) {
    +				$token['i'] = $i;
    +				$tokens[] = $token;
    +			}
    +		}
    +
    +		// Format token by token
    +		foreach ($tokens as $i=>$token) {
    +			// Get highlighted token if doing syntax highlighting
    +			if ($highlight) {
    +				$highlighted = self::highlightToken($token);
    +			} else { // If returning raw text
    +				$highlighted = $token[self::TOKEN_VALUE];
    +			}
    +
    +			// If we are increasing the special indent level now
    +			if ($increase_special_indent) {
    +				$indent_level++;
    +				$increase_special_indent = false;
    +				array_unshift($indent_types,'special');
    +			}
    +			// If we are increasing the block indent level now
    +			if ($increase_block_indent) {
    +				$indent_level++;
    +				$increase_block_indent = false;
    +				array_unshift($indent_types,'block');
    +			}
    +
    +			// If we need a new line before the token
    +			if ($newline) {
    +				$return .= "\n" . str_repeat($tab, $indent_level);
    +				$newline = false;
    +				$added_newline = true;
    +			} else {
    +				$added_newline = false;
    +			}
    +
    +			// Display comments directly where they appear in the source
    +			if ($token[self::TOKEN_TYPE] === self::TOKEN_TYPE_COMMENT || $token[self::TOKEN_TYPE] === self::TOKEN_TYPE_BLOCK_COMMENT) {
    +				if ($token[self::TOKEN_TYPE] === self::TOKEN_TYPE_BLOCK_COMMENT) {
    +					$indent = str_repeat($tab,$indent_level);
    +					$return .= "\n" . $indent;
    +					$highlighted = str_replace("\n","\n".$indent,$highlighted);
    +				}
    +
    +				$return .= $highlighted;
    +				$newline = true;
    +				continue;
    +			}
    +
    +			if ($inline_parentheses) {
    +				// End of inline parentheses
    +				if ($token[self::TOKEN_VALUE] === ')') {
    +					$return = rtrim($return,' ');
    +
    +					if ($inline_indented) {
    +						array_shift($indent_types);
    +						$indent_level --;
    +						$return .= "\n" . str_repeat($tab, $indent_level);
    +					}
    +
    +					$inline_parentheses = false;
    +
    +					$return .= $highlighted . ' ';
    +					continue;
    +				}
    +
    +				if ($token[self::TOKEN_VALUE] === ',') {
    +					if ($inline_count >= 30) {
    +						$inline_count = 0;
    +						$newline = true;
    +					}
    +				}
    +
    +				$inline_count += strlen($token[self::TOKEN_VALUE]);
    +			}
    +
    +			// Opening parentheses increase the block indent level and start a new line
    +			if ($token[self::TOKEN_VALUE] === '(') {
    +				// First check if this should be an inline parentheses block
    +				// Examples are "NOW()", "COUNT(*)", "int(10)", key(`somecolumn`), DECIMAL(7,2)
    +				// Allow up to 3 non-whitespace tokens inside inline parentheses
    +				$length = 0;
    +				for ($j=1;$j<=250;$j++) {
    +					// Reached end of string
    +					if (!isset($tokens[$i+$j])) break;
    +
    +					$next = $tokens[$i+$j];
    +
    +					// Reached closing parentheses, able to inline it
    +					if ($next[self::TOKEN_VALUE] === ')') {
    +						$inline_parentheses = true;
    +						$inline_count = 0;
    +						$inline_indented = false;
    +						break;
    +					}
    +
    +					// Reached an invalid token for inline parentheses
    +					if ($next[self::TOKEN_VALUE]===';' || $next[self::TOKEN_VALUE]==='(') {
    +						break;
    +					}
    +
    +					// Reached an invalid token type for inline parentheses
    +					if ($next[self::TOKEN_TYPE]===self::TOKEN_TYPE_RESERVED_TOPLEVEL || $next[self::TOKEN_TYPE]===self::TOKEN_TYPE_RESERVED_NEWLINE || $next[self::TOKEN_TYPE]===self::TOKEN_TYPE_COMMENT || $next[self::TOKEN_TYPE]===self::TOKEN_TYPE_BLOCK_COMMENT) {
    +						break;
    +					}
    +
    +					$length += strlen($next[self::TOKEN_VALUE]);
    +				}
    +
    +				if ($inline_parentheses && $length > 30) {
    +					$increase_block_indent = true;
    +					$inline_indented = true;
    +					$newline = true;
    +				}
    +
    +				// Take out the preceding space unless there was whitespace there in the original query
    +				if (isset($original_tokens[$token['i']-1]) && $original_tokens[$token['i']-1][self::TOKEN_TYPE] !== self::TOKEN_TYPE_WHITESPACE) {
    +					$return = rtrim($return,' ');
    +				}
    +
    +				if (!$inline_parentheses) {
    +					$increase_block_indent = true;
    +					// Add a newline after the parentheses
    +					$newline = true;
    +				}
    +
    +			}
    +
    +			// Closing parentheses decrease the block indent level
    +			elseif ($token[self::TOKEN_VALUE] === ')') {
    +				// Remove whitespace before the closing parentheses
    +				$return = rtrim($return,' ');
    +
    +				$indent_level--;
    +
    +				// Reset indent level
    +				while ($j=array_shift($indent_types)) {
    +					if ($j==='special') {
    +						$indent_level--;
    +					} else {
    +						break;
    +					}
    +				}
    +
    +				if ($indent_level < 0) {
    +					// This is an error
    +					$indent_level = 0;
    +
    +					if ($highlight) {
    +						$return .= "\n".self::highlightError($token[self::TOKEN_VALUE]);
    +						continue;
    +					}
    +				}
    +
    +				// Add a newline before the closing parentheses (if not already added)
    +				if (!$added_newline) {
    +					$return .= "\n" . str_repeat($tab, $indent_level);
    +				}
    +			}
    +
    +			// Top level reserved words start a new line and increase the special indent level
    +			elseif ($token[self::TOKEN_TYPE] === self::TOKEN_TYPE_RESERVED_TOPLEVEL) {
    +				$increase_special_indent = true;
    +
    +				// If the last indent type was 'special', decrease the special indent for this round
    +				reset($indent_types);
    +				if (current($indent_types)==='special') {
    +					$indent_level--;
    +					array_shift($indent_types);
    +				}
    +
    +				// Add a newline after the top level reserved word
    +				$newline = true;
    +				// Add a newline before the top level reserved word (if not already added)
    +				if (!$added_newline) {
    +					$return .= "\n" . str_repeat($tab, $indent_level);
    +				}
    +				// If we already added a newline, redo the indentation since it may be different now
    +				else {
    +					$return = rtrim($return,$tab).str_repeat($tab, $indent_level);
    +				}
    +
    +				// If the token may have extra whitespace
    +				if (strpos($token[self::TOKEN_VALUE],' ')!==false || strpos($token[self::TOKEN_VALUE],"\n")!==false || strpos($token[self::TOKEN_VALUE],"\t")!==false) {
    +					$highlighted = preg_replace('/\s+/',' ',$highlighted);
    +				}
    +				//if SQL 'LIMIT' clause, start variable to reset newline
    +				if ($token[self::TOKEN_VALUE] === 'LIMIT' && !$inline_parentheses) {
    +					$clause_limit = true;
    +				}
    +			}
    +
    +			// Checks if we are out of the limit clause
    +			elseif ($clause_limit && $token[self::TOKEN_VALUE] !== "," && $token[self::TOKEN_TYPE] !== self::TOKEN_TYPE_NUMBER && $token[self::TOKEN_TYPE] !== self::TOKEN_TYPE_WHITESPACE) {
    +				$clause_limit = false;
    +			}
    +
    +			// Commas start a new line (unless within inline parentheses or SQL 'LIMIT' clause)
    +			elseif ($token[self::TOKEN_VALUE] === ',' && !$inline_parentheses) {
    +				//If the previous TOKEN_VALUE is 'LIMIT', resets new line
    +				if ($clause_limit === true) {
    +					$newline = false;
    +					$clause_limit = false;
    +				}
    +				// All other cases of commas
    +				else {
    +					$newline = true;
    +				}
    +			}
    +
    +			// Newline reserved words start a new line
    +			elseif ($token[self::TOKEN_TYPE] === self::TOKEN_TYPE_RESERVED_NEWLINE) {
    +				// Add a newline before the reserved word (if not already added)
    +				if (!$added_newline) {
    +					$return .= "\n" . str_repeat($tab, $indent_level);
    +				}
    +
    +				// If the token may have extra whitespace
    +				if (strpos($token[self::TOKEN_VALUE],' ')!==false || strpos($token[self::TOKEN_VALUE],"\n")!==false || strpos($token[self::TOKEN_VALUE],"\t")!==false) {
    +					$highlighted = preg_replace('/\s+/',' ',$highlighted);
    +				}
    +			}
    +
    +			// Multiple boundary characters in a row should not have spaces between them (not including parentheses)
    +			elseif ($token[self::TOKEN_TYPE] === self::TOKEN_TYPE_BOUNDARY) {
    +				if (isset($tokens[$i-1]) && $tokens[$i-1][self::TOKEN_TYPE] === self::TOKEN_TYPE_BOUNDARY) {
    +					if (isset($original_tokens[$token['i']-1]) && $original_tokens[$token['i']-1][self::TOKEN_TYPE] !== self::TOKEN_TYPE_WHITESPACE) {
    +						$return = rtrim($return,' ');
    +					}
    +				}
    +			}
    +
    +			// If the token shouldn't have a space before it
    +			if ($token[self::TOKEN_VALUE] === '.' || $token[self::TOKEN_VALUE] === ',' || $token[self::TOKEN_VALUE] === ';') {
    +				$return = rtrim($return, ' ');
    +			}
    +
    +			$return .= $highlighted.' ';
    +
    +			// If the token shouldn't have a space after it
    +			if ($token[self::TOKEN_VALUE] === '(' || $token[self::TOKEN_VALUE] === '.') {
    +				$return = rtrim($return,' ');
    +			}
    +
    +			// If this is the "-" of a negative number, it shouldn't have a space after it
    +			if($token[self::TOKEN_VALUE] === '-' && isset($tokens[$i+1]) && $tokens[$i+1][self::TOKEN_TYPE] === self::TOKEN_TYPE_NUMBER && isset($tokens[$i-1])) {
    +				$prev = $tokens[$i-1][self::TOKEN_TYPE];
    +				if($prev !== self::TOKEN_TYPE_QUOTE && $prev !== self::TOKEN_TYPE_BACKTICK_QUOTE && $prev !== self::TOKEN_TYPE_WORD && $prev !== self::TOKEN_TYPE_NUMBER) {
    +					$return = rtrim($return,' ');
    +				}
    +			}
    +		}
    +
    +		// If there are unmatched parentheses
    +		if ($highlight && array_search('block',$indent_types) !== false) {
    +			$return .= "\n".self::highlightError("WARNING: unclosed parentheses or section");
    +		}
    +
    +		// Replace tab characters with the configuration tab character
    +		$return = trim(str_replace("\t",self::$tab,$return));
    +
    +		if ($highlight) {
    +			$return = self::output($return);
    +		}
    +
    +		return $return;
    +	}
    +
    +	/**
    +	 * Add syntax highlighting to a SQL string
    +	 *
    +	 * @param String $string The SQL string
    +	 *
    +	 * @return String The SQL string with HTML styles applied
    +	 */
    +	public static function highlight($string)
    +	{
    +		$tokens = self::tokenize($string);
    +
    +		$return = '';
    +
    +		foreach ($tokens as $token) {
    +			$return .= self::highlightToken($token);
    +		}
    +
    +		return self::output($return);
    +	}
    +
    +	/**
    +	 * Split a SQL string into multiple queries.
    +	 * Uses ";" as a query delimiter.
    +	 *
    +	 * @param String $string The SQL string
    +	 *
    +	 * @return Array An array of individual query strings without trailing semicolons
    +	 */
    +	public static function splitQuery($string)
    +	{
    +		$queries = array();
    +		$current_query = '';
    +		$empty = true;
    +
    +		$tokens = self::tokenize($string);
    +
    +		foreach ($tokens as $token) {
    +			// If this is a query separator
    +			if ($token[self::TOKEN_VALUE] === ';') {
    +				if (!$empty) {
    +					$queries[] = $current_query.';';
    +				}
    +				$current_query = '';
    +				$empty = true;
    +				continue;
    +			}
    +
    +			// If this is a non-empty character
    +			if ($token[self::TOKEN_TYPE] !== self::TOKEN_TYPE_WHITESPACE && $token[self::TOKEN_TYPE] !== self::TOKEN_TYPE_COMMENT && $token[self::TOKEN_TYPE] !== self::TOKEN_TYPE_BLOCK_COMMENT) {
    +				$empty = false;
    +			}
    +
    +			$current_query .= $token[self::TOKEN_VALUE];
    +		}
    +
    +		if (!$empty) {
    +			$queries[] = trim($current_query);
    +		}
    +
    +		return $queries;
    +	}
    +
    +	/**
    +	 * Remove all comments from a SQL string
    +	 *
    +	 * @param String $string The SQL string
    +	 *
    +	 * @return String The SQL string without comments
    +	 */
    +	public static function removeComments($string)
    +	{
    +		$result = '';
    +
    +		$tokens = self::tokenize($string);
    +
    +		foreach ($tokens as $token) {
    +			// Skip comment tokens
    +			if ($token[self::TOKEN_TYPE] === self::TOKEN_TYPE_COMMENT || $token[self::TOKEN_TYPE] === self::TOKEN_TYPE_BLOCK_COMMENT) {
    +				continue;
    +			}
    +
    +			$result .= $token[self::TOKEN_VALUE];
    +		}
    +		$result = self::format( $result,false);
    +
    +		return $result;
    +	}
    +
    +	/**
    +	 * Compress a query by collapsing white space and removing comments
    +	 *
    +	 * @param String $string The SQL string
    +	 *
    +	 * @return String The SQL string without comments
    +	 */
    +	public static function compress($string)
    +	{
    +		$result = '';
    +
    +		$tokens = self::tokenize($string);
    +
    +		$whitespace = true;
    +		foreach ($tokens as $token) {
    +			// Skip comment tokens
    +			if ($token[self::TOKEN_TYPE] === self::TOKEN_TYPE_COMMENT || $token[self::TOKEN_TYPE] === self::TOKEN_TYPE_BLOCK_COMMENT) {
    +				continue;
    +			}
    +			// Remove extra whitespace in reserved words (e.g "OUTER	 JOIN" becomes "OUTER JOIN")
    +			elseif ($token[self::TOKEN_TYPE] === self::TOKEN_TYPE_RESERVED || $token[self::TOKEN_TYPE] === self::TOKEN_TYPE_RESERVED_NEWLINE || $token[self::TOKEN_TYPE] === self::TOKEN_TYPE_RESERVED_TOPLEVEL) {
    +				$token[self::TOKEN_VALUE] = preg_replace('/\s+/',' ',$token[self::TOKEN_VALUE]);
    +			}
    +
    +			if ($token[self::TOKEN_TYPE] === self::TOKEN_TYPE_WHITESPACE) {
    +				// If the last token was whitespace, don't add another one
    +				if ($whitespace) {
    +					continue;
    +				} else {
    +					$whitespace = true;
    +					// Convert all whitespace to a single space
    +					$token[self::TOKEN_VALUE] = ' ';
    +				}
    +			} else {
    +				$whitespace = false;
    +			}
    +
    +			$result .= $token[self::TOKEN_VALUE];
    +		}
    +
    +		return rtrim($result);
    +	}
    +
    +	/**
    +	 * Highlights a token depending on its type.
    +	 *
    +	 * @param Array $token An associative array containing type and value.
    +	 *
    +	 * @return String HTML code of the highlighted token.
    +	 */
    +	protected static function highlightToken($token)
    +	{
    +		$type = $token[self::TOKEN_TYPE];
    +
    +		if (self::is_cli()) {
    +			$token = $token[self::TOKEN_VALUE];
    +		} else {
    +			if (defined('ENT_IGNORE')) {
    +			  $token = htmlentities($token[self::TOKEN_VALUE],ENT_COMPAT | ENT_IGNORE ,'UTF-8');
    +			} else {
    +			  $token = htmlentities($token[self::TOKEN_VALUE],ENT_COMPAT,'UTF-8');
    +			}
    +		}
    +
    +		if ($type===self::TOKEN_TYPE_BOUNDARY) {
    +			return self::highlightBoundary($token);
    +		} elseif ($type===self::TOKEN_TYPE_WORD) {
    +			return self::highlightWord($token);
    +		} elseif ($type===self::TOKEN_TYPE_BACKTICK_QUOTE) {
    +			return self::highlightBacktickQuote($token);
    +		} elseif ($type===self::TOKEN_TYPE_QUOTE) {
    +			return self::highlightQuote($token);
    +		} elseif ($type===self::TOKEN_TYPE_RESERVED) {
    +			return self::highlightReservedWord($token);
    +		} elseif ($type===self::TOKEN_TYPE_RESERVED_TOPLEVEL) {
    +			return self::highlightReservedWord($token);
    +		} elseif ($type===self::TOKEN_TYPE_RESERVED_NEWLINE) {
    +			return self::highlightReservedWord($token);
    +		} elseif ($type===self::TOKEN_TYPE_NUMBER) {
    +			return self::highlightNumber($token);
    +		} elseif ($type===self::TOKEN_TYPE_VARIABLE) {
    +			return self::highlightVariable($token);
    +		} elseif ($type===self::TOKEN_TYPE_COMMENT || $type===self::TOKEN_TYPE_BLOCK_COMMENT) {
    +			return self::highlightComment($token);
    +		}
    +
    +		return $token;
    +	}
    +
    +	/**
    +	 * Highlights a quoted string
    +	 *
    +	 * @param String $value The token's value
    +	 *
    +	 * @return String HTML code of the highlighted token.
    +	 */
    +	protected static function highlightQuote($value)
    +	{
    +		if (self::is_cli()) {
    +			return self::$cli_quote . $value . "\x1b[0m";
    +		} else {
    +			return '' . $value . '';
    +		}
    +	}
    +
    +	/**
    +	 * Highlights a backtick quoted string
    +	 *
    +	 * @param String $value The token's value
    +	 *
    +	 * @return String HTML code of the highlighted token.
    +	 */
    +	protected static function highlightBacktickQuote($value)
    +	{
    +		if (self::is_cli()) {
    +			return self::$cli_backtick_quote . $value . "\x1b[0m";
    +		} else {
    +			return '' . $value . '';
    +		}
    +	}
    +
    +	/**
    +	 * Highlights a reserved word
    +	 *
    +	 * @param String $value The token's value
    +	 *
    +	 * @return String HTML code of the highlighted token.
    +	 */
    +	protected static function highlightReservedWord($value)
    +	{
    +		if (self::is_cli()) {
    +			return self::$cli_reserved . $value . "\x1b[0m";
    +		} else {
    +			return '' . $value . '';
    +		}
    +	}
    +
    +	/**
    +	 * Highlights a boundary token
    +	 *
    +	 * @param String $value The token's value
    +	 *
    +	 * @return String HTML code of the highlighted token.
    +	 */
    +	protected static function highlightBoundary($value)
    +	{
    +		if ($value==='(' || $value===')') return $value;
    +
    +		if (self::is_cli()) {
    +			return self::$cli_boundary . $value . "\x1b[0m";
    +		} else {
    +			return '' . $value . '';
    +		}
    +	}
    +
    +	/**
    +	 * Highlights a number
    +	 *
    +	 * @param String $value The token's value
    +	 *
    +	 * @return String HTML code of the highlighted token.
    +	 */
    +	protected static function highlightNumber($value)
    +	{
    +		if (self::is_cli()) {
    +			return self::$cli_number . $value . "\x1b[0m";
    +		} else {
    +			return '' . $value . '';
    +		}
    +	}
    +
    +	/**
    +	 * Highlights an error
    +	 *
    +	 * @param String $value The token's value
    +	 *
    +	 * @return String HTML code of the highlighted token.
    +	 */
    +	protected static function highlightError($value)
    +	{
    +		if (self::is_cli()) {
    +			return self::$cli_error . $value . "\x1b[0m";
    +		} else {
    +			return '' . $value . '';
    +		}
    +	}
    +
    +	/**
    +	 * Highlights a comment
    +	 *
    +	 * @param String $value The token's value
    +	 *
    +	 * @return String HTML code of the highlighted token.
    +	 */
    +	protected static function highlightComment($value)
    +	{
    +		if (self::is_cli()) {
    +			return self::$cli_comment . $value . "\x1b[0m";
    +		} else {
    +			return '' . $value . '';
    +		}
    +	}
    +
    +	/**
    +	 * Highlights a word token
    +	 *
    +	 * @param String $value The token's value
    +	 *
    +	 * @return String HTML code of the highlighted token.
    +	 */
    +	protected static function highlightWord($value)
    +	{
    +		if (self::is_cli()) {
    +			return self::$cli_word . $value . "\x1b[0m";
    +		} else {
    +			return '' . $value . '';
    +		}
    +	}
    +
    +	/**
    +	 * Highlights a variable token
    +	 *
    +	 * @param String $value The token's value
    +	 *
    +	 * @return String HTML code of the highlighted token.
    +	 */
    +	protected static function highlightVariable($value)
    +	{
    +		if (self::is_cli()) {
    +			return self::$cli_variable . $value . "\x1b[0m";
    +		} else {
    +			return '' . $value . '';
    +		}
    +	}
    +
    +	/**
    +	 * Helper function for building regular expressions for reserved words and boundary characters
    +	 *
    +	 * @param String $a The string to be quoted
    +	 *
    +	 * @return String The quoted string
    +	 */
    +	private static function quote_regex($a)
    +	{
    +		return preg_quote($a,'/');
    +	}
    +
    +	/**
    +	 * Helper function for building string output
    +	 *
    +	 * @param String $string The string to be quoted
    +	 *
    +	 * @return String The quoted string
    +	 */
    +	private static function output($string)
    +	{
    +		if (self::is_cli()) {
    +			return $string."\n";
    +		} else {
    +			$string=trim($string);
    +			if (!self::$use_pre) {
    +				return $string;
    +			}
    +
    +			return '
    ' . $string . '
    '; + } + } + + private static function is_cli() + { + if (isset(self::$cli)) return self::$cli; + else return php_sapi_name() === 'cli'; + } + +} \ No newline at end of file diff --git a/lib/redactor/codemirror/addon/comment/comment.js b/lib/redactor/codemirror/addon/comment/comment.js index 568e639..84c67ed 100644 --- a/lib/redactor/codemirror/addon/comment/comment.js +++ b/lib/redactor/codemirror/addon/comment/comment.js @@ -172,10 +172,6 @@ if (open == -1) return false var endLine = end == start ? startLine : self.getLine(end) var close = endLine.indexOf(endString, end == start ? open + startString.length : 0); - if (close == -1 && start != end) { - endLine = self.getLine(--end); - close = endLine.indexOf(endString); - } var insideStart = Pos(start, open + 1), insideEnd = Pos(end, close + 1) if (close == -1 || !/comment/.test(self.getTokenTypeAt(insideStart)) || diff --git a/lib/redactor/codemirror/addon/display/placeholder.js b/lib/redactor/codemirror/addon/display/placeholder.js index 2f8b1f8..65753eb 100644 --- a/lib/redactor/codemirror/addon/display/placeholder.js +++ b/lib/redactor/codemirror/addon/display/placeholder.js @@ -38,6 +38,7 @@ clearPlaceholder(cm); var elt = cm.state.placeholder = document.createElement("pre"); elt.style.cssText = "height: 0; overflow: visible"; + elt.style.direction = cm.getOption("direction"); elt.className = "CodeMirror-placeholder"; var placeHolder = cm.getOption("placeholder") if (typeof placeHolder == "string") placeHolder = document.createTextNode(placeHolder) diff --git a/lib/redactor/codemirror/addon/edit/closebrackets.js b/lib/redactor/codemirror/addon/edit/closebrackets.js index 7b07f7f..86b2fe1 100644 --- a/lib/redactor/codemirror/addon/edit/closebrackets.js +++ b/lib/redactor/codemirror/addon/edit/closebrackets.js @@ -129,11 +129,12 @@ else curType = "skip"; } else if (identical && cur.ch > 1 && triples.indexOf(ch) >= 0 && - cm.getRange(Pos(cur.line, cur.ch - 2), cur) == ch + ch && - (cur.ch <= 2 || cm.getRange(Pos(cur.line, cur.ch - 3), Pos(cur.line, cur.ch - 2)) != ch)) { + cm.getRange(Pos(cur.line, cur.ch - 2), cur) == ch + ch) { + if (cur.ch > 2 && /\bstring/.test(cm.getTokenTypeAt(Pos(cur.line, cur.ch - 2)))) return CodeMirror.Pass; curType = "addFour"; } else if (identical) { - if (!CodeMirror.isWordChar(next) && enteringString(cm, cur, ch)) curType = "both"; + var prev = cur.ch == 0 ? " " : cm.getRange(Pos(cur.line, cur.ch - 1), cur) + if (!CodeMirror.isWordChar(next) && prev != ch && !CodeMirror.isWordChar(prev)) curType = "both"; else return CodeMirror.Pass; } else if (opening && (cm.getLine(cur.line).length == cur.ch || isClosingBracket(next, pairs) || @@ -185,24 +186,9 @@ return str.length == 2 ? str : null; } - // Project the token type that will exists after the given char is - // typed, and use it to determine whether it would cause the start - // of a string token. - function enteringString(cm, pos, ch) { - var line = cm.getLine(pos.line); - var token = cm.getTokenAt(pos); - if (/\bstring2?\b/.test(token.type) || stringStartsAfter(cm, pos)) return false; - var stream = new CodeMirror.StringStream(line.slice(0, pos.ch) + ch + line.slice(pos.ch), 4); - stream.pos = stream.start = token.start; - for (;;) { - var type1 = cm.getMode().token(stream, token.state); - if (stream.pos >= pos.ch + 1) return /\bstring2?\b/.test(type1); - stream.start = stream.pos; - } - } - function stringStartsAfter(cm, pos) { var token = cm.getTokenAt(Pos(pos.line, pos.ch + 1)) - return /\bstring/.test(token.type) && token.start == pos.ch + return /\bstring/.test(token.type) && token.start == pos.ch && + (pos.ch == 0 || !/\bstring/.test(cm.getTokenTypeAt(pos))) } }); diff --git a/lib/redactor/codemirror/addon/edit/closetag.js b/lib/redactor/codemirror/addon/edit/closetag.js index a518da3..83f133a 100644 --- a/lib/redactor/codemirror/addon/edit/closetag.js +++ b/lib/redactor/codemirror/addon/edit/closetag.js @@ -53,13 +53,14 @@ function autoCloseGT(cm) { if (cm.getOption("disableInput")) return CodeMirror.Pass; var ranges = cm.listSelections(), replacements = []; + var opt = cm.getOption("autoCloseTags"); for (var i = 0; i < ranges.length; i++) { if (!ranges[i].empty()) return CodeMirror.Pass; var pos = ranges[i].head, tok = cm.getTokenAt(pos); var inner = CodeMirror.innerMode(cm.getMode(), tok.state), state = inner.state; if (inner.mode.name != "xml" || !state.tagName) return CodeMirror.Pass; - var opt = cm.getOption("autoCloseTags"), html = inner.mode.configuration == "html"; + var html = inner.mode.configuration == "html"; var dontCloseTags = (typeof opt == "object" && opt.dontCloseTags) || (html && htmlDontClose); var indentTags = (typeof opt == "object" && opt.indentTags) || (html && htmlIndent); @@ -81,13 +82,14 @@ newPos: indent ? CodeMirror.Pos(pos.line + 1, 0) : CodeMirror.Pos(pos.line, pos.ch + 1)}; } + var dontIndentOnAutoClose = (typeof opt == "object" && opt.dontIndentOnAutoClose); for (var i = ranges.length - 1; i >= 0; i--) { var info = replacements[i]; cm.replaceRange(info.text, ranges[i].head, ranges[i].anchor, "+insert"); var sel = cm.listSelections().slice(0); sel[i] = {head: info.newPos, anchor: info.newPos}; cm.setSelections(sel); - if (info.indent) { + if (!dontIndentOnAutoClose && info.indent) { cm.indentLine(info.newPos.line, null, true); cm.indentLine(info.newPos.line + 1, null, true); } @@ -97,6 +99,8 @@ function autoCloseCurrent(cm, typingSlash) { var ranges = cm.listSelections(), replacements = []; var head = typingSlash ? "/" : "") >= 0 - ? match[2].replace("x", " ") - : (parseInt(match[3], 10) + 1) + match[4]; - + var numbered = !(unorderedListRE.test(match[2]) || match[2].indexOf(">") >= 0); + var bullet = numbered ? (parseInt(match[3], 10) + 1) + match[4] : match[2].replace("x", " "); replacements[i] = "\n" + indent + bullet + after; + + if (numbered) incrementRemainingMarkdownListNumbers(cm, pos); } } cm.replaceSelections(replacements); }; + + // Auto-updating Markdown list numbers when a new item is added to the + // middle of a list + function incrementRemainingMarkdownListNumbers(cm, pos) { + var startLine = pos.line, lookAhead = 0, skipCount = 0; + var startItem = listRE.exec(cm.getLine(startLine)), startIndent = startItem[1]; + + do { + lookAhead += 1; + var nextLineNumber = startLine + lookAhead; + var nextLine = cm.getLine(nextLineNumber), nextItem = listRE.exec(nextLine); + + if (nextItem) { + var nextIndent = nextItem[1]; + var newNumber = (parseInt(startItem[3], 10) + lookAhead - skipCount); + var nextNumber = (parseInt(nextItem[3], 10)), itemNumber = nextNumber; + + if (startIndent === nextIndent && !isNaN(nextNumber)) { + if (newNumber === nextNumber) itemNumber = nextNumber + 1; + if (newNumber > nextNumber) itemNumber = newNumber + 1; + cm.replaceRange( + nextLine.replace(listRE, nextIndent + itemNumber + nextItem[4] + nextItem[5]), + { + line: nextLineNumber, ch: 0 + }, { + line: nextLineNumber, ch: nextLine.length + }); + } else { + if (startIndent.length > nextIndent.length) return; + // This doesn't run if the next line immediatley indents, as it is + // not clear of the users intention (new indented item or same level) + if ((startIndent.length < nextIndent.length) && (lookAhead === 1)) return; + skipCount += 1; + } + } + } while (nextItem); + } }); diff --git a/lib/redactor/codemirror/addon/edit/matchbrackets.js b/lib/redactor/codemirror/addon/edit/matchbrackets.js index 4d7a230..c9851bd 100644 --- a/lib/redactor/codemirror/addon/edit/matchbrackets.js +++ b/lib/redactor/codemirror/addon/edit/matchbrackets.js @@ -102,18 +102,23 @@ } } - var currentlyHighlighted = null; function doMatchBrackets(cm) { cm.operation(function() { - if (currentlyHighlighted) {currentlyHighlighted(); currentlyHighlighted = null;} - currentlyHighlighted = matchBrackets(cm, false, cm.state.matchBrackets); + if (cm.state.matchBrackets.currentlyHighlighted) { + cm.state.matchBrackets.currentlyHighlighted(); + cm.state.matchBrackets.currentlyHighlighted = null; + } + cm.state.matchBrackets.currentlyHighlighted = matchBrackets(cm, false, cm.state.matchBrackets); }); } CodeMirror.defineOption("matchBrackets", false, function(cm, val, old) { if (old && old != CodeMirror.Init) { cm.off("cursorActivity", doMatchBrackets); - if (currentlyHighlighted) {currentlyHighlighted(); currentlyHighlighted = null;} + if (cm.state.matchBrackets && cm.state.matchBrackets.currentlyHighlighted) { + cm.state.matchBrackets.currentlyHighlighted(); + cm.state.matchBrackets.currentlyHighlighted = null; + } } if (val) { cm.state.matchBrackets = typeof val == "object" ? val : {}; diff --git a/lib/redactor/codemirror/addon/fold/xml-fold.js b/lib/redactor/codemirror/addon/fold/xml-fold.js index 08e2149..3acf952 100644 --- a/lib/redactor/codemirror/addon/fold/xml-fold.js +++ b/lib/redactor/codemirror/addon/fold/xml-fold.js @@ -138,7 +138,7 @@ var iter = new Iter(cm, start.line, 0); for (;;) { var openTag = toNextTag(iter), end; - if (!openTag || iter.line != start.line || !(end = toTagEnd(iter))) return; + if (!openTag || !(end = toTagEnd(iter)) || iter.line != start.line) return; if (!openTag[1] && end != "selfClose") { var startPos = Pos(iter.line, iter.ch); var endPos = findMatchingClose(iter, openTag[2]); diff --git a/lib/redactor/codemirror/addon/hint/javascript-hint.js b/lib/redactor/codemirror/addon/hint/javascript-hint.js index d7088c1..f6ab2a2 100644 --- a/lib/redactor/codemirror/addon/hint/javascript-hint.js +++ b/lib/redactor/codemirror/addon/hint/javascript-hint.js @@ -32,7 +32,9 @@ // Find the token at the cursor var cur = editor.getCursor(), token = getToken(editor, cur); if (/\b(?:string|comment)\b/.test(token.type)) return; - token.state = CodeMirror.innerMode(editor.getMode(), token.state).state; + var innerMode = CodeMirror.innerMode(editor.getMode(), token.state); + if (innerMode.mode.helperType === "json") return; + token.state = innerMode.state; // If it's not a 'word-style' token, ignore the token. if (!/^[\w$_]*$/.test(token.string)) { @@ -92,8 +94,8 @@ var arrayProps = ("length concat join splice push pop shift unshift slice reverse sort indexOf " + "lastIndexOf every some filter forEach map reduce reduceRight ").split(" "); var funcProps = "prototype apply call bind".split(" "); - var javascriptKeywords = ("break case catch continue debugger default delete do else false finally for function " + - "if in instanceof new null return switch throw true try typeof var void while with").split(" "); + var javascriptKeywords = ("break case catch class const continue debugger default delete do else export extends false finally for function " + + "if in import instanceof new null return super switch this throw true try typeof var void while with yield").split(" "); var coffeescriptKeywords = ("and break catch class continue delete do else extends false finally for " + "if in instanceof isnt new no not null of off on or return switch then throw true try typeof until void while with yes").split(" "); diff --git a/lib/redactor/codemirror/addon/hint/show-hint.js b/lib/redactor/codemirror/addon/hint/show-hint.js index f72a0a9..81a63fc 100644 --- a/lib/redactor/codemirror/addon/hint/show-hint.js +++ b/lib/redactor/codemirror/addon/hint/show-hint.js @@ -121,7 +121,6 @@ var picked = (this.widget && this.widget.picked) || (first && this.options.completeSingle); if (this.widget) this.widget.close(); - if (data && this.data && isNewCompletion(this.data, data)) return; this.data = data; if (data && data.list.length) { @@ -135,11 +134,6 @@ } }; - function isNewCompletion(old, nw) { - var moved = CodeMirror.cmpPos(nw.from, old.from) - return moved > 0 && old.to.ch - old.from.ch != nw.to.ch - nw.from.ch - } - function parseOptions(cm, pos, options) { var editor = cm.options.hintOptions; var out = {}; @@ -403,12 +397,13 @@ }); CodeMirror.registerHelper("hint", "fromList", function(cm, options) { - var cur = cm.getCursor(), token = cm.getTokenAt(cur); - var to = CodeMirror.Pos(cur.line, token.end); - if (token.string && /\w/.test(token.string[token.string.length - 1])) { - var term = token.string, from = CodeMirror.Pos(cur.line, token.start); + var cur = cm.getCursor(), token = cm.getTokenAt(cur) + var term, from = CodeMirror.Pos(cur.line, token.start), to = cur + if (token.start < cur.ch && /\w/.test(token.string.charAt(cur.ch - token.start - 1))) { + term = token.string.substr(0, cur.ch - token.start) } else { - var term = "", from = to; + term = "" + from = cur } var found = []; for (var i = 0; i < options.words.length; i++) { diff --git a/lib/redactor/codemirror/addon/hint/sql-hint.js b/lib/redactor/codemirror/addon/hint/sql-hint.js index f5ec2ca..5d20eea 100644 --- a/lib/redactor/codemirror/addon/hint/sql-hint.js +++ b/lib/redactor/codemirror/addon/hint/sql-hint.js @@ -222,18 +222,20 @@ prevItem = separator[i]; } - var query = doc.getRange(validRange.start, validRange.end, false); - - for (var i = 0; i < query.length; i++) { - var lineText = query[i]; - eachWord(lineText, function(word) { - var wordUpperCase = word.toUpperCase(); - if (wordUpperCase === aliasUpperCase && getTable(previousWord)) - table = previousWord; - if (wordUpperCase !== CONS.ALIAS_KEYWORD) - previousWord = word; - }); - if (table) break; + if (validRange.start) { + var query = doc.getRange(validRange.start, validRange.end, false); + + for (var i = 0; i < query.length; i++) { + var lineText = query[i]; + eachWord(lineText, function(word) { + var wordUpperCase = word.toUpperCase(); + if (wordUpperCase === aliasUpperCase && getTable(previousWord)) + table = previousWord; + if (wordUpperCase !== CONS.ALIAS_KEYWORD) + previousWord = word; + }); + if (table) break; + } } return table; } @@ -273,8 +275,8 @@ if (search.charAt(0) == "." || search.charAt(0) == identifierQuote) { start = nameCompletion(cur, token, result, editor); } else { - addMatches(result, search, tables, function(w) {return w;}); addMatches(result, search, defaultTable, function(w) {return w;}); + addMatches(result, search, tables, function(w) {return w;}); if (!disableKeywords) addMatches(result, search, keywords, function(w) {return w.toUpperCase();}); } diff --git a/lib/redactor/codemirror/addon/lint/javascript-lint.js b/lib/redactor/codemirror/addon/lint/javascript-lint.js index c58f785..8266b7e 100644 --- a/lib/redactor/codemirror/addon/lint/javascript-lint.js +++ b/lib/redactor/codemirror/addon/lint/javascript-lint.js @@ -12,15 +12,6 @@ "use strict"; // declare global: JSHINT - var bogus = [ "Dangerous comment" ]; - - var warnings = [ [ "Expected '{'", - "Statement body should be inside '{ }' braces." ] ]; - - var errors = [ "Missing semicolon", "Extra comma", "Missing property name", - "Unmatched ", " and instead saw", " is not defined", - "Unclosed string", "Stopping, unable to continue" ]; - function validator(text, options) { if (!window.JSHINT) { if (window.console) { @@ -28,6 +19,8 @@ } return []; } + if (!options.indent) // JSHint error.character actually is a column index, this fixes underlining on lines using tabs for indentation + options.indent = 1; // JSHint default value is 4 JSHINT(text, options, options.globals); var errors = JSHINT.data().errors, result = []; if (errors) parseErrors(errors, result); @@ -36,105 +29,34 @@ CodeMirror.registerHelper("lint", "javascript", validator); - function cleanup(error) { - // All problems are warnings by default - fixWith(error, warnings, "warning", true); - fixWith(error, errors, "error"); - - return isBogus(error) ? null : error; - } - - function fixWith(error, fixes, severity, force) { - var description, fix, find, replace, found; - - description = error.description; - - for ( var i = 0; i < fixes.length; i++) { - fix = fixes[i]; - find = (typeof fix === "string" ? fix : fix[0]); - replace = (typeof fix === "string" ? null : fix[1]); - found = description.indexOf(find) !== -1; - - if (force || found) { - error.severity = severity; - } - if (found && replace) { - error.description = replace; - } - } - } - - function isBogus(error) { - var description = error.description; - for ( var i = 0; i < bogus.length; i++) { - if (description.indexOf(bogus[i]) !== -1) { - return true; - } - } - return false; - } - function parseErrors(errors, output) { for ( var i = 0; i < errors.length; i++) { var error = errors[i]; if (error) { - var linetabpositions, index; - - linetabpositions = []; - - // This next block is to fix a problem in jshint. Jshint - // replaces - // all tabs with spaces then performs some checks. The error - // positions (character/space) are then reported incorrectly, - // not taking the replacement step into account. Here we look - // at the evidence line and try to adjust the character position - // to the correct value. - if (error.evidence) { - // Tab positions are computed once per line and cached - var tabpositions = linetabpositions[error.line]; - if (!tabpositions) { - var evidence = error.evidence; - tabpositions = []; - // ugggh phantomjs does not like this - // forEachChar(evidence, function(item, index) { - Array.prototype.forEach.call(evidence, function(item, - index) { - if (item === '\t') { - // First col is 1 (not 0) to match error - // positions - tabpositions.push(index + 1); - } - }); - linetabpositions[error.line] = tabpositions; - } - if (tabpositions.length > 0) { - var pos = error.character; - tabpositions.forEach(function(tabposition) { - if (pos > tabposition) pos -= 1; - }); - error.character = pos; + if (error.line <= 0) { + if (window.console) { + window.console.warn("Cannot display JSHint error (invalid line " + error.line + ")", error); } + continue; } var start = error.character - 1, end = start + 1; if (error.evidence) { - index = error.evidence.substring(start).search(/.\b/); + var index = error.evidence.substring(start).search(/.\b/); if (index > -1) { end += index; } } // Convert to format expected by validation service - error.description = error.reason;// + "(jshint)"; - error.start = error.character; - error.end = end; - error = cleanup(error); - - if (error) - output.push({message: error.description, - severity: error.severity, - from: CodeMirror.Pos(error.line - 1, start), - to: CodeMirror.Pos(error.line - 1, end)}); + var hint = { + message: error.reason, + severity: error.code ? (error.code.startsWith('W') ? "warning" : "error") : "error", + from: CodeMirror.Pos(error.line - 1, start), + to: CodeMirror.Pos(error.line - 1, end) + }; + + output.push(hint); } } } diff --git a/lib/redactor/codemirror/addon/lint/lint.js b/lib/redactor/codemirror/addon/lint/lint.js index a9eb8fa..e00e77a 100644 --- a/lib/redactor/codemirror/addon/lint/lint.js +++ b/lib/redactor/codemirror/addon/lint/lint.js @@ -132,7 +132,7 @@ cm.off("change", abort) if (state.waitingFor != id) return if (arg2 && annotations instanceof CodeMirror) annotations = arg2 - updateLinting(cm, annotations) + cm.operation(function() {updateLinting(cm, annotations)}) }, passOptions, cm); } @@ -151,9 +151,9 @@ var annotations = getAnnotations(cm.getValue(), passOptions, cm); if (!annotations) return; if (annotations.then) annotations.then(function(issues) { - updateLinting(cm, issues); + cm.operation(function() {updateLinting(cm, issues)}) }); - else updateLinting(cm, annotations); + else cm.operation(function() {updateLinting(cm, annotations)}) } } diff --git a/lib/redactor/codemirror/addon/merge/merge.css b/lib/redactor/codemirror/addon/merge/merge.css index bda3d9f..dadd7f5 100644 --- a/lib/redactor/codemirror/addon/merge/merge.css +++ b/lib/redactor/codemirror/addon/merge/merge.css @@ -48,6 +48,12 @@ color: #555; line-height: 1; } +.CodeMirror-merge-scrolllock:after { + content: "\21db\00a0\00a0\21da"; +} +.CodeMirror-merge-scrolllock.CodeMirror-merge-scrolllock-enabled:after { + content: "\21db\21da"; +} .CodeMirror-merge-copybuttons-left, .CodeMirror-merge-copybuttons-right { position: absolute; diff --git a/lib/redactor/codemirror/addon/merge/merge.js b/lib/redactor/codemirror/addon/merge/merge.js index c94b27a..3a77f7a 100644 --- a/lib/redactor/codemirror/addon/merge/merge.js +++ b/lib/redactor/codemirror/addon/merge/merge.js @@ -211,7 +211,7 @@ function setScrollLock(dv, val, action) { dv.lockScroll = val; if (val && action != false) syncScroll(dv, DIFF_INSERT) && makeConnections(dv); - dv.lockButton.innerHTML = val ? "\u21db\u21da" : "\u21db  \u21da"; + (val ? CodeMirror.addClass : CodeMirror.rmClass)(dv.lockButton, "CodeMirror-merge-scrolllock-enabled"); } // Updating the marks for editor content @@ -738,6 +738,9 @@ mark.clear(); cm.removeLineClass(from, "wrap", "CodeMirror-merge-collapsed-line"); } + if (mark.explicitlyCleared) clear(); + CodeMirror.on(widget, "click", clear); + mark.on("clear", clear); CodeMirror.on(widget, "click", clear); return {mark: mark, clear: clear}; } diff --git a/lib/redactor/codemirror/addon/mode/multiplex.js b/lib/redactor/codemirror/addon/mode/multiplex.js index 3d8b34c..a084f70 100644 --- a/lib/redactor/codemirror/addon/mode/multiplex.js +++ b/lib/redactor/codemirror/addon/mode/multiplex.js @@ -50,7 +50,15 @@ CodeMirror.multiplexingMode = function(outer /*, others */) { if (found == stream.pos) { if (!other.parseDelimiters) stream.match(other.open); state.innerActive = other; - state.inner = CodeMirror.startState(other.mode, outer.indent ? outer.indent(state.outer, "") : 0); + + // Get the outer indent, making sure to handle CodeMirror.Pass + var outerIndent = 0; + if (outer.indent) { + var possibleOuterIndent = outer.indent(state.outer, ""); + if (possibleOuterIndent !== CodeMirror.Pass) outerIndent = possibleOuterIndent; + } + + state.inner = CodeMirror.startState(other.mode, outerIndent); return other.delimStyle && (other.delimStyle + " " + other.delimStyle + "-open"); } else if (found != -1 && found < cutOff) { cutOff = found; diff --git a/lib/redactor/codemirror/addon/search/match-highlighter.js b/lib/redactor/codemirror/addon/search/match-highlighter.js index 73ba0e0..260cdeb 100644 --- a/lib/redactor/codemirror/addon/search/match-highlighter.js +++ b/lib/redactor/codemirror/addon/search/match-highlighter.js @@ -90,7 +90,7 @@ var state = cm.state.matchHighlighter; cm.addOverlay(state.overlay = makeOverlay(query, hasBoundary, style)); if (state.options.annotateScrollbar && cm.showMatchesOnScrollbar) { - var searchFor = hasBoundary ? new RegExp("\\b" + query + "\\b") : query; + var searchFor = hasBoundary ? new RegExp("\\b" + query.replace(/[\\\[.+*?(){|^$]/g, "\\$&") + "\\b") : query; state.matchesonscroll = cm.showMatchesOnScrollbar(searchFor, false, {className: "CodeMirror-selection-highlight-scrollbar"}); } diff --git a/lib/redactor/codemirror/addon/search/searchcursor.js b/lib/redactor/codemirror/addon/search/searchcursor.js index eccd81a..e606c5e 100644 --- a/lib/redactor/codemirror/addon/search/searchcursor.js +++ b/lib/redactor/codemirror/addon/search/searchcursor.js @@ -19,8 +19,11 @@ + (regexp.multiline ? "m" : "") } - function ensureGlobal(regexp) { - return regexp.global ? regexp : new RegExp(regexp.source, regexpFlags(regexp) + "g") + function ensureFlags(regexp, flags) { + var current = regexpFlags(regexp), target = current + for (var i = 0; i < flags.length; i++) if (target.indexOf(flags.charAt(i)) == -1) + target += flags.charAt(i) + return current == target ? regexp : new RegExp(regexp.source, target) } function maybeMultiline(regexp) { @@ -28,7 +31,7 @@ } function searchRegexpForward(doc, regexp, start) { - regexp = ensureGlobal(regexp) + regexp = ensureFlags(regexp, "g") for (var line = start.line, ch = start.ch, last = doc.lastLine(); line <= last; line++, ch = 0) { regexp.lastIndex = ch var string = doc.getLine(line), match = regexp.exec(string) @@ -42,7 +45,7 @@ function searchRegexpForwardMultiline(doc, regexp, start) { if (!maybeMultiline(regexp)) return searchRegexpForward(doc, regexp, start) - regexp = ensureGlobal(regexp) + regexp = ensureFlags(regexp, "gm") var string, chunk = 1 for (var line = start.line, last = doc.lastLine(); line <= last;) { // This grows the search buffer in exponentially-sized chunks @@ -51,6 +54,7 @@ // searching for something that has tons of matches), but at the // same time, the amount of retries is limited. for (var i = 0; i < chunk; i++) { + if (line > last) break var curLine = doc.getLine(line++) string = string == null ? curLine : string + "\n" + curLine } @@ -81,7 +85,7 @@ } function searchRegexpBackward(doc, regexp, start) { - regexp = ensureGlobal(regexp) + regexp = ensureFlags(regexp, "g") for (var line = start.line, ch = start.ch, first = doc.firstLine(); line >= first; line--, ch = -1) { var string = doc.getLine(line) if (ch > -1) string = string.slice(0, ch) @@ -94,7 +98,7 @@ } function searchRegexpBackwardMultiline(doc, regexp, start) { - regexp = ensureGlobal(regexp) + regexp = ensureFlags(regexp, "gm") var string, chunk = 1 for (var line = start.line, first = doc.firstLine(); line >= first;) { for (var i = 0; i < chunk; i++) { @@ -159,7 +163,7 @@ for (var i = 1; i < lines.length - 1; i++) if (fold(doc.getLine(line + i)) != lines[i]) continue search var end = doc.getLine(line + lines.length - 1), endString = fold(end), lastLine = lines[lines.length - 1] - if (end.slice(0, lastLine.length) != lastLine) continue search + if (endString.slice(0, lastLine.length) != lastLine) continue search return {from: Pos(line, adjustPos(orig, string, cutFrom, fold) + ch), to: Pos(line + lines.length - 1, adjustPos(end, endString, lastLine.length, fold))} } @@ -213,7 +217,7 @@ return (reverse ? searchStringBackward : searchStringForward)(doc, query, pos, caseFold) } } else { - query = ensureGlobal(query) + query = ensureFlags(query, "gm") if (!options || options.multiline !== false) this.matches = function(reverse, pos) { return (reverse ? searchRegexpBackwardMultiline : searchRegexpForwardMultiline)(doc, query, pos) diff --git a/lib/redactor/codemirror/addon/tern/tern.js b/lib/redactor/codemirror/addon/tern/tern.js index a80dc7e..6276b53 100644 --- a/lib/redactor/codemirror/addon/tern/tern.js +++ b/lib/redactor/codemirror/addon/tern/tern.js @@ -614,7 +614,8 @@ var mouseOnTip = false, old = false; CodeMirror.on(tip, "mousemove", function() { mouseOnTip = true; }); CodeMirror.on(tip, "mouseout", function(e) { - if (!CodeMirror.contains(tip, e.relatedTarget || e.toElement)) { + var related = e.relatedTarget || e.toElement + if (!related || !CodeMirror.contains(tip, related)) { if (old) clear(); else mouseOnTip = false; } diff --git a/lib/redactor/codemirror/codemirror_connect.tpl b/lib/redactor/codemirror/codemirror_connect.tpl index 661c33d..958fdc7 100644 --- a/lib/redactor/codemirror/codemirror_connect.tpl +++ b/lib/redactor/codemirror/codemirror_connect.tpl @@ -16,6 +16,7 @@ + diff --git a/lib/redactor/codemirror/codemirror_editor.tpl b/lib/redactor/codemirror/codemirror_editor.tpl index 76c8785..2e3189f 100644 --- a/lib/redactor/codemirror/codemirror_editor.tpl +++ b/lib/redactor/codemirror/codemirror_editor.tpl @@ -50,7 +50,8 @@ editor{$conn_id} = CodeMirror.fromTextArea(document.getElementById('{$textarea_i enterMode: 'keep', tabMode: 'shift', autoCloseTags: true, - styleActiveLine: true + styleActiveLine: true, + smartyVersion : 2 {rdelim}); editor{$conn_id}.setSize('{$width|default:'100%'}', '{$height|default:'400px'}'); diff --git a/lib/redactor/codemirror/lib/codemirror.css b/lib/redactor/codemirror/lib/codemirror.css index 255de98..c7a8ae7 100644 --- a/lib/redactor/codemirror/lib/codemirror.css +++ b/lib/redactor/codemirror/lib/codemirror.css @@ -145,8 +145,8 @@ /* Default styles for common addons */ -div.CodeMirror span.CodeMirror-matchingbracket {color: #0f0;} -div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;} +div.CodeMirror span.CodeMirror-matchingbracket {color: #0b0;} +div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #a22;} .CodeMirror-matchingtag { background: rgba(255, 150, 0, .3); } .CodeMirror-activeline-background {background: #e8f2ff;} @@ -270,7 +270,7 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;} .CodeMirror-linewidget { position: relative; z-index: 2; - overflow: auto; + padding: 0.1px; /* Force widget margins to stay inside of the container */ } .CodeMirror-widget {} diff --git a/lib/redactor/codemirror/lib/codemirror.js b/lib/redactor/codemirror/lib/codemirror.js index b46428a..56f7a12 100644 --- a/lib/redactor/codemirror/lib/codemirror.js +++ b/lib/redactor/codemirror/lib/codemirror.js @@ -3274,8 +3274,10 @@ function updateHeightsInViewport(cm) { // Read and store the height of line widgets associated with the // given line. function updateWidgetHeight(line) { - if (line.widgets) { for (var i = 0; i < line.widgets.length; ++i) - { line.widgets[i].height = line.widgets[i].node.parentNode.offsetHeight } } + if (line.widgets) { for (var i = 0; i < line.widgets.length; ++i) { + var w = line.widgets[i], parent = w.node.parentNode + if (parent) { w.height = parent.offsetHeight } + } } } // Compute the lines that are visible in a given viewport (defaults @@ -4781,7 +4783,7 @@ function addChangeToHistory(doc, change, selAfter, opId) { if ((hist.lastOp == opId || hist.lastOrigin == change.origin && change.origin && - ((change.origin.charAt(0) == "+" && doc.cm && hist.lastModTime > time - doc.cm.options.historyEventDelay) || + ((change.origin.charAt(0) == "+" && hist.lastModTime > time - (doc.cm ? doc.cm.options.historyEventDelay : 500)) || change.origin.charAt(0) == "*")) && (cur = lastChangeEvent(hist, hist.lastOp == opId))) { // Merge this change into the last event @@ -5210,7 +5212,8 @@ function makeChangeInner(doc, change) { // Revert a change stored in a document's history. function makeChangeFromHistory(doc, type, allowSelectionOnly) { - if (doc.cm && doc.cm.state.suppressEdits && !allowSelectionOnly) { return } + var suppress = doc.cm && doc.cm.state.suppressEdits + if (suppress && !allowSelectionOnly) { return } var hist = doc.history, event, selAfter = doc.sel var source = type == "undo" ? hist.done : hist.undone, dest = type == "undo" ? hist.undone : hist.done @@ -5235,8 +5238,10 @@ function makeChangeFromHistory(doc, type, allowSelectionOnly) { return } selAfter = event - } - else { break } + } else if (suppress) { + source.push(event) + return + } else { break } } // Build up a reverse change object to add to the opposite history @@ -5712,7 +5717,7 @@ function addLineWidget(doc, handle, node, options) { } return true }) - signalLater(cm, "lineWidgetAdded", cm, widget, typeof handle == "number" ? handle : lineNo(handle)) + if (cm) { signalLater(cm, "lineWidgetAdded", cm, widget, typeof handle == "number" ? handle : lineNo(handle)) } return widget } @@ -6571,11 +6576,11 @@ function onResize(cm) { } var keyNames = { - 3: "Enter", 8: "Backspace", 9: "Tab", 13: "Enter", 16: "Shift", 17: "Ctrl", 18: "Alt", + 3: "Pause", 8: "Backspace", 9: "Tab", 13: "Enter", 16: "Shift", 17: "Ctrl", 18: "Alt", 19: "Pause", 20: "CapsLock", 27: "Esc", 32: "Space", 33: "PageUp", 34: "PageDown", 35: "End", 36: "Home", 37: "Left", 38: "Up", 39: "Right", 40: "Down", 44: "PrintScrn", 45: "Insert", 46: "Delete", 59: ";", 61: "=", 91: "Mod", 92: "Mod", 93: "Mod", - 106: "*", 107: "=", 109: "-", 110: ".", 111: "/", 127: "Delete", + 106: "*", 107: "=", 109: "-", 110: ".", 111: "/", 127: "Delete", 145: "ScrollLock", 173: "-", 186: ";", 187: "=", 188: ",", 189: "-", 190: ".", 191: "/", 192: "`", 219: "[", 220: "\\", 221: "]", 222: "'", 63232: "Up", 63233: "Down", 63234: "Left", 63235: "Right", 63272: "Delete", 63273: "Home", 63275: "End", 63276: "PageUp", 63277: "PageDown", 63302: "Insert" @@ -6722,6 +6727,9 @@ function keyName(event, noShift) { if (presto && event.keyCode == 34 && event["char"]) { return false } var name = keyNames[event.keyCode] if (name == null || event.altGraphKey) { return false } + // Ctrl-ScrollLock has keyCode 3, same as Ctrl-Pause, + // so we'll use event.code when available (Chrome 48+, FF 38+, Safari 10.1+) + if (event.keyCode == 3 && event.code) { name = event.code } return addModifierNames(name, event, noShift) } @@ -7061,18 +7069,26 @@ function lookupKeyForEditor(cm, name, handle) { // for bound mouse clicks. var stopSeq = new Delayed + function dispatchKey(cm, name, e, handle) { var seq = cm.state.keySeq if (seq) { if (isModifierKey(name)) { return "handled" } - stopSeq.set(50, function () { - if (cm.state.keySeq == seq) { - cm.state.keySeq = null - cm.display.input.reset() - } - }) - name = seq + " " + name + if (/\'$/.test(name)) + { cm.state.keySeq = null } + else + { stopSeq.set(50, function () { + if (cm.state.keySeq == seq) { + cm.state.keySeq = null + cm.display.input.reset() + } + }) } + if (dispatchKeyInner(cm, seq + " " + name, e, handle)) { return true } } + return dispatchKeyInner(cm, name, e, handle) +} + +function dispatchKeyInner(cm, name, e, handle) { var result = lookupKeyForEditor(cm, name, handle) if (result == "multi") @@ -7085,10 +7101,6 @@ function dispatchKey(cm, name, e, handle) { restartBlink(cm) } - if (seq && !result && /\'$/.test(name)) { - e_preventDefault(e) - return true - } return !!result } @@ -7300,8 +7312,8 @@ function leftButtonStartDrag(cm, event, pos, behavior) { var dragEnd = operation(cm, function (e) { if (webkit) { display.scroller.draggable = false } cm.state.draggingText = false - off(document, "mouseup", dragEnd) - off(document, "mousemove", mouseMove) + off(display.wrapper.ownerDocument, "mouseup", dragEnd) + off(display.wrapper.ownerDocument, "mousemove", mouseMove) off(display.scroller, "dragstart", dragStart) off(display.scroller, "drop", dragEnd) if (!moved) { @@ -7310,7 +7322,7 @@ function leftButtonStartDrag(cm, event, pos, behavior) { { extendSelection(cm.doc, pos, null, null, behavior.extend) } // Work around unexplainable focus problem in IE9 (#2127) and Chrome (#3081) if (webkit || ie && ie_version == 9) - { setTimeout(function () {document.body.focus(); display.input.focus()}, 20) } + { setTimeout(function () {display.wrapper.ownerDocument.body.focus(); display.input.focus()}, 20) } else { display.input.focus() } } @@ -7325,8 +7337,8 @@ function leftButtonStartDrag(cm, event, pos, behavior) { dragEnd.copy = !behavior.moveOnDrag // IE's approach to draggable if (display.scroller.dragDrop) { display.scroller.dragDrop() } - on(document, "mouseup", dragEnd) - on(document, "mousemove", mouseMove) + on(display.wrapper.ownerDocument, "mouseup", dragEnd) + on(display.wrapper.ownerDocument, "mousemove", mouseMove) on(display.scroller, "dragstart", dragStart) on(display.scroller, "drop", dragEnd) @@ -7458,8 +7470,8 @@ function leftButtonSelect(cm, event, start, behavior) { counter = Infinity e_preventDefault(e) display.input.focus() - off(document, "mousemove", move) - off(document, "mouseup", up) + off(display.wrapper.ownerDocument, "mousemove", move) + off(display.wrapper.ownerDocument, "mouseup", up) doc.history.lastSelOrigin = null } @@ -7469,8 +7481,8 @@ function leftButtonSelect(cm, event, start, behavior) { }) var up = operation(cm, done) cm.state.selectingText = up - on(document, "mousemove", move) - on(document, "mouseup", up) + on(display.wrapper.ownerDocument, "mousemove", move) + on(display.wrapper.ownerDocument, "mouseup", up) } // Used when mouse-selecting to adjust the anchor to the proper side @@ -7600,6 +7612,7 @@ function defineOptions(CodeMirror) { clearCaches(cm) regChange(cm) }, true) + option("lineSeparator", null, function (cm, val) { cm.doc.lineSep = val if (!val) { return } @@ -8006,7 +8019,7 @@ function applyTextInput(cm, inserted, deleted, sel, origin) { var paste = cm.state.pasteIncoming || origin == "paste" var textLines = splitLinesAuto(inserted), multiPaste = null - // When pasing N lines into N selections, insert one line per selection + // When pasting N lines into N selections, insert one line per selection if (paste && sel.ranges.length > 1) { if (lastCopied && lastCopied.text.join("\n") == inserted) { if (sel.ranges.length % lastCopied.text.length == 0) { @@ -9174,13 +9187,10 @@ TextareaInput.prototype.init = function (display) { var this$1 = this; var input = this, cm = this.cm + this.createField(display) + var te = this.textarea - // Wraps and hides input textarea - var div = this.wrapper = hiddenTextarea() - // The semihidden textarea that is focused when the editor is - // focused, and receives input. - var te = this.textarea = div.firstChild - display.wrapper.insertBefore(div, display.wrapper.firstChild) + display.wrapper.insertBefore(this.wrapper, display.wrapper.firstChild) // Needed to hide big blue blinking cursor on Mobile Safari (doesn't seem to work in iOS 8 anymore) if (ios) { te.style.width = "0px" } @@ -9247,6 +9257,14 @@ TextareaInput.prototype.init = function (display) { }) }; +TextareaInput.prototype.createField = function (_display) { + // Wraps and hides input textarea + this.wrapper = hiddenTextarea() + // The semihidden textarea that is focused when the editor is + // focused, and receives input. + this.textarea = this.wrapper.firstChild +}; + TextareaInput.prototype.prepareSelection = function () { // Redraw the selection and/or cursor var cm = this.cm, display = cm.display, doc = cm.doc @@ -9640,7 +9658,7 @@ CodeMirror.fromTextArea = fromTextArea addLegacyProps(CodeMirror) -CodeMirror.version = "5.31.0" +CodeMirror.version = "5.36.0" return CodeMirror; diff --git a/lib/redactor/codemirror/mode/clike/clike.js b/lib/redactor/codemirror/mode/clike/clike.js index d6d12c7..da7a6bf 100644 --- a/lib/redactor/codemirror/mode/clike/clike.js +++ b/lib/redactor/codemirror/mode/clike/clike.js @@ -374,7 +374,7 @@ CodeMirror.defineMode("clike", function(config, parserConfig) { blockKeywords: words("case do else for if switch while struct"), defKeywords: words("struct"), typeFirstDefinitions: true, - atoms: words("null true false"), + atoms: words("NULL true false"), hooks: {"#": cppHook, "*": pointerHook}, modeProps: {fold: ["brace", "include"]} }); @@ -390,7 +390,7 @@ CodeMirror.defineMode("clike", function(config, parserConfig) { blockKeywords: words("catch class do else finally for if struct switch try while"), defKeywords: words("class namespace struct enum union"), typeFirstDefinitions: true, - atoms: words("true false null"), + atoms: words("true false NULL"), dontIndentStatements: /^template$/, isIdentifierChar: /[\w\$_~\xa1-\uffff]/, hooks: { @@ -432,7 +432,7 @@ CodeMirror.defineMode("clike", function(config, parserConfig) { types: words("byte short int long float double boolean char void Boolean Byte Character Double Float " + "Integer Long Number Object Short String StringBuffer StringBuilder Void"), blockKeywords: words("catch class do else finally for if switch try while"), - defKeywords: words("class interface package enum @interface"), + defKeywords: words("class interface enum @interface"), typeFirstDefinitions: true, atoms: words("true false null"), number: /^(?:0x[a-f\d_]+|0b[01_]+|(?:[\d_]+\.?\d*|\.\d+)(?:e[-+]?[\d_]+)?)(u|ll?|l|f)?/i, @@ -489,6 +489,27 @@ CodeMirror.defineMode("clike", function(config, parserConfig) { return "string"; } + function tokenNestedComment(depth) { + return function (stream, state) { + var ch + while (ch = stream.next()) { + if (ch == "*" && stream.eat("/")) { + if (depth == 1) { + state.tokenize = null + break + } else { + state.tokenize = tokenNestedComment(depth - 1) + return state.tokenize(stream, state) + } + } else if (ch == "/" && stream.eat("*")) { + state.tokenize = tokenNestedComment(depth + 1) + return state.tokenize(stream, state) + } + } + return "comment" + } + } + def("text/x-scala", { name: "clike", keywords: words( @@ -544,6 +565,12 @@ CodeMirror.defineMode("clike", function(config, parserConfig) { } else { return false } + }, + + "/": function(stream, state) { + if (!stream.eat("*")) return false + state.tokenize = tokenNestedComment(1) + return state.tokenize(stream, state) } }, modeProps: {closeBrackets: {triples: '"'}} @@ -570,27 +597,29 @@ CodeMirror.defineMode("clike", function(config, parserConfig) { name: "clike", keywords: words( /*keywords*/ - "package as typealias class interface this super val " + - "var fun for is in This throw return " + + "package as typealias class interface this super val operator " + + "var fun for is in This throw return annotation " + "break continue object if else while do try when !in !is as? " + /*soft keywords*/ "file import where by get set abstract enum open inner override private public internal " + "protected catch finally out final vararg reified dynamic companion constructor init " + "sealed field property receiver param sparam lateinit data inline noinline tailrec " + - "external annotation crossinline const operator infix suspend" + "external annotation crossinline const operator infix suspend actual expect setparam" ), types: words( /* package java.lang */ "Boolean Byte Character CharSequence Class ClassLoader Cloneable Comparable " + "Compiler Double Exception Float Integer Long Math Number Object Package Pair Process " + "Runtime Runnable SecurityManager Short StackTraceElement StrictMath String " + - "StringBuffer System Thread ThreadGroup ThreadLocal Throwable Triple Void" + "StringBuffer System Thread ThreadGroup ThreadLocal Throwable Triple Void Annotation Any BooleanArray " + + "ByteArray Char CharArray DeprecationLevel DoubleArray Enum FloatArray Function Int IntArray Lazy " + + "LazyThreadSafetyMode LongArray Nothing ShortArray Unit" ), intendSwitch: false, indentStatements: false, multiLineStrings: true, - number: /^(?:0x[a-f\d_]+|0b[01_]+|(?:[\d_]+\.?\d*|\.\d+)(?:e[-+]?[\d_]+)?)(u|ll?|l|f)?/i, + number: /^(?:0x[a-f\d_]+|0b[01_]+|(?:[\d_]+(\.\d+)?|\.\d+)(?:e[-+]?[\d_]+)?)(u|ll?|l|f)?/i, blockKeywords: words("catch class do else finally for if where try while enum"), defKeywords: words("class val var object interface fun"), atoms: words("true false null this"), diff --git a/lib/redactor/codemirror/mode/clike/index.html b/lib/redactor/codemirror/mode/clike/index.html deleted file mode 100644 index 45c670a..0000000 --- a/lib/redactor/codemirror/mode/clike/index.html +++ /dev/null @@ -1,360 +0,0 @@ - - -CodeMirror: C-like mode - - - - - - - - - - - - -
    -

    C-like mode

    - -
    - -

    C++ example

    - -
    - -

    Objective-C example

    - -
    - -

    Java example

    - -
    - -

    Scala example

    - -
    - -

    Kotlin mode

    - -
    - -

    Ceylon mode

    - -
    - - - -

    Simple mode that tries to handle C-like languages as well as it - can. Takes two configuration parameters: keywords, an - object whose property names are the keywords in the language, - and useCPP, which determines whether C preprocessor - directives are recognized.

    - -

    MIME types defined: text/x-csrc - (C), text/x-c++src (C++), text/x-java - (Java), text/x-csharp (C#), - text/x-objectivec (Objective-C), - text/x-scala (Scala), text/x-vertex - x-shader/x-fragment (shader programs), - text/x-squirrel (Squirrel) and - text/x-ceylon (Ceylon)

    -
    diff --git a/lib/redactor/codemirror/mode/clike/scala.html b/lib/redactor/codemirror/mode/clike/scala.html deleted file mode 100644 index aa04cf0..0000000 --- a/lib/redactor/codemirror/mode/clike/scala.html +++ /dev/null @@ -1,767 +0,0 @@ - - -CodeMirror: Scala mode - - - - - - - - - - -
    -

    Scala mode

    -
    - -
    - - -
    diff --git a/lib/redactor/codemirror/mode/clike/test.js b/lib/redactor/codemirror/mode/clike/test.js deleted file mode 100644 index dad2e24..0000000 --- a/lib/redactor/codemirror/mode/clike/test.js +++ /dev/null @@ -1,59 +0,0 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -(function() { - var mode = CodeMirror.getMode({indentUnit: 2}, "text/x-c"); - function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); } - - MT("indent", - "[type void] [def foo]([type void*] [variable a], [type int] [variable b]) {", - " [type int] [variable c] [operator =] [variable b] [operator +]", - " [number 1];", - " [keyword return] [operator *][variable a];", - "}"); - - MT("indent_switch", - "[keyword switch] ([variable x]) {", - " [keyword case] [number 10]:", - " [keyword return] [number 20];", - " [keyword default]:", - " [variable printf]([string \"foo %c\"], [variable x]);", - "}"); - - MT("def", - "[type void] [def foo]() {}", - "[keyword struct] [def bar]{}", - "[type int] [type *][def baz]() {}"); - - MT("def_new_line", - "::[variable std]::[variable SomeTerribleType][operator <][variable T][operator >]", - "[def SomeLongMethodNameThatDoesntFitIntoOneLine]([keyword const] [variable MyType][operator &] [variable param]) {}") - - MT("double_block", - "[keyword for] (;;)", - " [keyword for] (;;)", - " [variable x][operator ++];", - "[keyword return];"); - - MT("preprocessor", - "[meta #define FOO 3]", - "[type int] [variable foo];", - "[meta #define BAR\\]", - "[meta 4]", - "[type unsigned] [type int] [variable bar] [operator =] [number 8];", - "[meta #include ][comment // comment]") - - - var mode_cpp = CodeMirror.getMode({indentUnit: 2}, "text/x-c++src"); - function MTCPP(name) { test.mode(name, mode_cpp, Array.prototype.slice.call(arguments, 1)); } - - MTCPP("cpp14_literal", - "[number 10'000];", - "[number 0b10'000];", - "[number 0x10'000];", - "[string '100000'];"); - - MTCPP("ctor_dtor", - "[def Foo::Foo]() {}", - "[def Foo::~Foo]() {}"); -})(); diff --git a/lib/redactor/codemirror/mode/css/css.js b/lib/redactor/codemirror/mode/css/css.js index 00e9b3d..f5f3a41 100644 --- a/lib/redactor/codemirror/mode/css/css.js +++ b/lib/redactor/codemirror/mode/css/css.js @@ -77,9 +77,9 @@ CodeMirror.defineMode("css", function(config, parserConfig) { return ret("qualifier", "qualifier"); } else if (/[:;{}\[\]\(\)]/.test(ch)) { return ret(null, ch); - } else if ((ch == "u" && stream.match(/rl(-prefix)?\(/)) || - (ch == "d" && stream.match("omain(")) || - (ch == "r" && stream.match("egexp("))) { + } else if (((ch == "u" || ch == "U") && stream.match(/rl(-prefix)?\(/i)) || + ((ch == "d" || ch == "D") && stream.match("omain(", true, true)) || + ((ch == "r" || ch == "R") && stream.match("egexp(", true, true))) { stream.backUp(1); state.tokenize = tokenParenthesized; return ret("property", "word"); @@ -162,16 +162,16 @@ CodeMirror.defineMode("css", function(config, parserConfig) { return pushContext(state, stream, "block"); } else if (type == "}" && state.context.prev) { return popContext(state); - } else if (supportsAtComponent && /@component/.test(type)) { + } else if (supportsAtComponent && /@component/i.test(type)) { return pushContext(state, stream, "atComponentBlock"); - } else if (/^@(-moz-)?document$/.test(type)) { + } else if (/^@(-moz-)?document$/i.test(type)) { return pushContext(state, stream, "documentTypes"); - } else if (/^@(media|supports|(-moz-)?document|import)$/.test(type)) { + } else if (/^@(media|supports|(-moz-)?document|import)$/i.test(type)) { return pushContext(state, stream, "atBlock"); - } else if (/^@(font-face|counter-style)/.test(type)) { + } else if (/^@(font-face|counter-style)/i.test(type)) { state.stateArg = type; return "restricted_atBlock_before"; - } else if (/^@(-(moz|ms|o|webkit)-)?keyframes$/.test(type)) { + } else if (/^@(-(moz|ms|o|webkit)-)?keyframes$/i.test(type)) { return "keyframes"; } else if (type && type.charAt(0) == "@") { return pushContext(state, stream, "at"); @@ -793,7 +793,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) { }, "@": function(stream) { if (stream.eat("{")) return [null, "interpolation"]; - if (stream.match(/^(charset|document|font-face|import|(-(moz|ms|o|webkit)-)?keyframes|media|namespace|page|supports)\b/, false)) return false; + if (stream.match(/^(charset|document|font-face|import|(-(moz|ms|o|webkit)-)?keyframes|media|namespace|page|supports)\b/i, false)) return false; stream.eatWhile(/[\w\\\-]/); if (stream.match(/^\s*:/, false)) return ["variable-2", "variable-definition"]; diff --git a/lib/redactor/codemirror/mode/css/gss.html b/lib/redactor/codemirror/mode/css/gss.html deleted file mode 100644 index 232fe8c..0000000 --- a/lib/redactor/codemirror/mode/css/gss.html +++ /dev/null @@ -1,103 +0,0 @@ - - -CodeMirror: Closure Stylesheets (GSS) mode - - - - - - - - - - - - -
    -

    Closure Stylesheets (GSS) mode

    -
    - - -

    A mode for Closure Stylesheets (GSS).

    -

    MIME type defined: text/x-gss.

    - -

    Parsing/Highlighting Tests: normal, verbose.

    - -
    diff --git a/lib/redactor/codemirror/mode/css/gss_test.js b/lib/redactor/codemirror/mode/css/gss_test.js deleted file mode 100644 index d56e592..0000000 --- a/lib/redactor/codemirror/mode/css/gss_test.js +++ /dev/null @@ -1,17 +0,0 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -(function() { - "use strict"; - - var mode = CodeMirror.getMode({indentUnit: 2}, "text/x-gss"); - function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1), "gss"); } - - MT("atComponent", - "[def @component] {", - "[tag foo] {", - " [property color]: [keyword black];", - "}", - "}"); - -})(); diff --git a/lib/redactor/codemirror/mode/css/index.html b/lib/redactor/codemirror/mode/css/index.html deleted file mode 100644 index 0d85311..0000000 --- a/lib/redactor/codemirror/mode/css/index.html +++ /dev/null @@ -1,75 +0,0 @@ - - -CodeMirror: CSS mode - - - - - - - - - - - - -
    -

    CSS mode

    -
    - - -

    MIME types defined: text/css, text/x-scss (demo), text/x-less (demo).

    - -

    Parsing/Highlighting Tests: normal, verbose.

    - -
    diff --git a/lib/redactor/codemirror/mode/css/less.html b/lib/redactor/codemirror/mode/css/less.html deleted file mode 100644 index adf7427..0000000 --- a/lib/redactor/codemirror/mode/css/less.html +++ /dev/null @@ -1,152 +0,0 @@ - - -CodeMirror: LESS mode - - - - - - - - - - -
    -

    LESS mode

    -
    - - -

    The LESS mode is a sub-mode of the CSS mode (defined in css.js).

    - -

    Parsing/Highlighting Tests: normal, verbose.

    -
    diff --git a/lib/redactor/codemirror/mode/css/less_test.js b/lib/redactor/codemirror/mode/css/less_test.js deleted file mode 100644 index dd82155..0000000 --- a/lib/redactor/codemirror/mode/css/less_test.js +++ /dev/null @@ -1,54 +0,0 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -(function() { - "use strict"; - - var mode = CodeMirror.getMode({indentUnit: 2}, "text/x-less"); - function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1), "less"); } - - MT("variable", - "[variable-2 @base]: [atom #f04615];", - "[qualifier .class] {", - " [property width]: [variable percentage]([number 0.5]); [comment // returns `50%`]", - " [property color]: [variable saturate]([variable-2 @base], [number 5%]);", - "}"); - - MT("amp", - "[qualifier .child], [qualifier .sibling] {", - " [qualifier .parent] [atom &] {", - " [property color]: [keyword black];", - " }", - " [atom &] + [atom &] {", - " [property color]: [keyword red];", - " }", - "}"); - - MT("mixin", - "[qualifier .mixin] ([variable dark]; [variable-2 @color]) {", - " [property color]: [atom darken]([variable-2 @color], [number 10%]);", - "}", - "[qualifier .mixin] ([variable light]; [variable-2 @color]) {", - " [property color]: [atom lighten]([variable-2 @color], [number 10%]);", - "}", - "[qualifier .mixin] ([variable-2 @_]; [variable-2 @color]) {", - " [property display]: [atom block];", - "}", - "[variable-2 @switch]: [variable light];", - "[qualifier .class] {", - " [qualifier .mixin]([variable-2 @switch]; [atom #888]);", - "}"); - - MT("nest", - "[qualifier .one] {", - " [def @media] ([property width]: [number 400px]) {", - " [property font-size]: [number 1.2em];", - " [def @media] [attribute print] [keyword and] [property color] {", - " [property color]: [keyword blue];", - " }", - " }", - "}"); - - - MT("interpolation", ".@{[variable foo]} { [property font-weight]: [atom bold]; }"); -})(); diff --git a/lib/redactor/codemirror/mode/css/scss.html b/lib/redactor/codemirror/mode/css/scss.html deleted file mode 100644 index f8e4d37..0000000 --- a/lib/redactor/codemirror/mode/css/scss.html +++ /dev/null @@ -1,157 +0,0 @@ - - -CodeMirror: SCSS mode - - - - - - - - - -
    -

    SCSS mode

    -
    - - -

    The SCSS mode is a sub-mode of the CSS mode (defined in css.js).

    - -

    Parsing/Highlighting Tests: normal, verbose.

    - -
    diff --git a/lib/redactor/codemirror/mode/css/scss_test.js b/lib/redactor/codemirror/mode/css/scss_test.js deleted file mode 100644 index 785921b..0000000 --- a/lib/redactor/codemirror/mode/css/scss_test.js +++ /dev/null @@ -1,110 +0,0 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -(function() { - var mode = CodeMirror.getMode({indentUnit: 2}, "text/x-scss"); - function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1), "scss"); } - - MT('url_with_quotation', - "[tag foo] { [property background]:[atom url]([string test.jpg]) }"); - - MT('url_with_double_quotes', - "[tag foo] { [property background]:[atom url]([string \"test.jpg\"]) }"); - - MT('url_with_single_quotes', - "[tag foo] { [property background]:[atom url]([string \'test.jpg\']) }"); - - MT('string', - "[def @import] [string \"compass/css3\"]"); - - MT('important_keyword', - "[tag foo] { [property background]:[atom url]([string \'test.jpg\']) [keyword !important] }"); - - MT('variable', - "[variable-2 $blue]:[atom #333]"); - - MT('variable_as_attribute', - "[tag foo] { [property color]:[variable-2 $blue] }"); - - MT('numbers', - "[tag foo] { [property padding]:[number 10px] [number 10] [number 10em] [number 8in] }"); - - MT('number_percentage', - "[tag foo] { [property width]:[number 80%] }"); - - MT('selector', - "[builtin #hello][qualifier .world]{}"); - - MT('singleline_comment', - "[comment // this is a comment]"); - - MT('multiline_comment', - "[comment /*foobar*/]"); - - MT('attribute_with_hyphen', - "[tag foo] { [property font-size]:[number 10px] }"); - - MT('string_after_attribute', - "[tag foo] { [property content]:[string \"::\"] }"); - - MT('directives', - "[def @include] [qualifier .mixin]"); - - MT('basic_structure', - "[tag p] { [property background]:[keyword red]; }"); - - MT('nested_structure', - "[tag p] { [tag a] { [property color]:[keyword red]; } }"); - - MT('mixin', - "[def @mixin] [tag table-base] {}"); - - MT('number_without_semicolon', - "[tag p] {[property width]:[number 12]}", - "[tag a] {[property color]:[keyword red];}"); - - MT('atom_in_nested_block', - "[tag p] { [tag a] { [property color]:[atom #000]; } }"); - - MT('interpolation_in_property', - "[tag foo] { #{[variable-2 $hello]}:[number 2]; }"); - - MT('interpolation_in_selector', - "[tag foo]#{[variable-2 $hello]} { [property color]:[atom #000]; }"); - - MT('interpolation_error', - "[tag foo]#{[variable foo]} { [property color]:[atom #000]; }"); - - MT("divide_operator", - "[tag foo] { [property width]:[number 4] [operator /] [number 2] }"); - - MT('nested_structure_with_id_selector', - "[tag p] { [builtin #hello] { [property color]:[keyword red]; } }"); - - MT('indent_mixin', - "[def @mixin] [tag container] (", - " [variable-2 $a]: [number 10],", - " [variable-2 $b]: [number 10])", - "{}"); - - MT('indent_nested', - "[tag foo] {", - " [tag bar] {", - " }", - "}"); - - MT('indent_parentheses', - "[tag foo] {", - " [property color]: [atom darken]([variable-2 $blue],", - " [number 9%]);", - "}"); - - MT('indent_vardef', - "[variable-2 $name]:", - " [string 'val'];", - "[tag tag] {", - " [tag inner] {", - " [property margin]: [number 3px];", - " }", - "}"); -})(); diff --git a/lib/redactor/codemirror/mode/css/test.js b/lib/redactor/codemirror/mode/css/test.js deleted file mode 100644 index 6fc6e33..0000000 --- a/lib/redactor/codemirror/mode/css/test.js +++ /dev/null @@ -1,206 +0,0 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -(function() { - var mode = CodeMirror.getMode({indentUnit: 2}, "css"); - function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); } - - // Error, because "foobarhello" is neither a known type or property, but - // property was expected (after "and"), and it should be in parentheses. - MT("atMediaUnknownType", - "[def @media] [attribute screen] [keyword and] [error foobarhello] { }"); - - // Soft error, because "foobarhello" is not a known property or type. - MT("atMediaUnknownProperty", - "[def @media] [attribute screen] [keyword and] ([error foobarhello]) { }"); - - // Make sure nesting works with media queries - MT("atMediaMaxWidthNested", - "[def @media] [attribute screen] [keyword and] ([property max-width]: [number 25px]) { [tag foo] { } }"); - - MT("atMediaFeatureValueKeyword", - "[def @media] ([property orientation]: [keyword landscape]) { }"); - - MT("atMediaUnknownFeatureValueKeyword", - "[def @media] ([property orientation]: [error upsidedown]) { }"); - - MT("tagSelector", - "[tag foo] { }"); - - MT("classSelector", - "[qualifier .foo-bar_hello] { }"); - - MT("idSelector", - "[builtin #foo] { [error #foo] }"); - - MT("tagSelectorUnclosed", - "[tag foo] { [property margin]: [number 0] } [tag bar] { }"); - - MT("tagStringNoQuotes", - "[tag foo] { [property font-family]: [variable hello] [variable world]; }"); - - MT("tagStringDouble", - "[tag foo] { [property font-family]: [string \"hello world\"]; }"); - - MT("tagStringSingle", - "[tag foo] { [property font-family]: [string 'hello world']; }"); - - MT("tagColorKeyword", - "[tag foo] {", - " [property color]: [keyword black];", - " [property color]: [keyword navy];", - " [property color]: [keyword yellow];", - "}"); - - MT("tagColorHex3", - "[tag foo] { [property background]: [atom #fff]; }"); - - MT("tagColorHex4", - "[tag foo] { [property background]: [atom #ffff]; }"); - - MT("tagColorHex6", - "[tag foo] { [property background]: [atom #ffffff]; }"); - - MT("tagColorHex8", - "[tag foo] { [property background]: [atom #ffffffff]; }"); - - MT("tagColorHex5Invalid", - "[tag foo] { [property background]: [atom&error #fffff]; }"); - - MT("tagColorHexInvalid", - "[tag foo] { [property background]: [atom&error #ffg]; }"); - - MT("tagNegativeNumber", - "[tag foo] { [property margin]: [number -5px]; }"); - - MT("tagPositiveNumber", - "[tag foo] { [property padding]: [number 5px]; }"); - - MT("tagVendor", - "[tag foo] { [meta -foo-][property box-sizing]: [meta -foo-][atom border-box]; }"); - - MT("tagBogusProperty", - "[tag foo] { [property&error barhelloworld]: [number 0]; }"); - - MT("tagTwoProperties", - "[tag foo] { [property margin]: [number 0]; [property padding]: [number 0]; }"); - - MT("tagTwoPropertiesURL", - "[tag foo] { [property background]: [atom url]([string //example.com/foo.png]); [property padding]: [number 0]; }"); - - MT("indent_tagSelector", - "[tag strong], [tag em] {", - " [property background]: [atom rgba](", - " [number 255], [number 255], [number 0], [number .2]", - " );", - "}"); - - MT("indent_atMedia", - "[def @media] {", - " [tag foo] {", - " [property color]:", - " [keyword yellow];", - " }", - "}"); - - MT("indent_comma", - "[tag foo] {", - " [property font-family]: [variable verdana],", - " [atom sans-serif];", - "}"); - - MT("indent_parentheses", - "[tag foo]:[variable-3 before] {", - " [property background]: [atom url](", - "[string blahblah]", - "[string etc]", - "[string ]) [keyword !important];", - "}"); - - MT("font_face", - "[def @font-face] {", - " [property font-family]: [string 'myfont'];", - " [error nonsense]: [string 'abc'];", - " [property src]: [atom url]([string http://blah]),", - " [atom url]([string http://foo]);", - "}"); - - MT("empty_url", - "[def @import] [atom url]() [attribute screen];"); - - MT("parens", - "[qualifier .foo] {", - " [property background-image]: [variable fade]([atom #000], [number 20%]);", - " [property border-image]: [atom linear-gradient](", - " [atom to] [atom bottom],", - " [variable fade]([atom #000], [number 20%]) [number 0%],", - " [variable fade]([atom #000], [number 20%]) [number 100%]", - " );", - "}"); - - MT("css_variable", - ":[variable-3 root] {", - " [variable-2 --main-color]: [atom #06c];", - "}", - "[tag h1][builtin #foo] {", - " [property color]: [atom var]([variable-2 --main-color]);", - "}"); - - MT("supports", - "[def @supports] ([keyword not] (([property text-align-last]: [atom justify]) [keyword or] ([meta -moz-][property text-align-last]: [atom justify])) {", - " [property text-align-last]: [atom justify];", - "}"); - - MT("document", - "[def @document] [tag url]([string http://blah]),", - " [tag url-prefix]([string https://]),", - " [tag domain]([string blah.com]),", - " [tag regexp]([string \".*blah.+\"]) {", - " [builtin #id] {", - " [property background-color]: [keyword white];", - " }", - " [tag foo] {", - " [property font-family]: [variable Verdana], [atom sans-serif];", - " }", - "}"); - - MT("document_url", - "[def @document] [tag url]([string http://blah]) { [qualifier .class] { } }"); - - MT("document_urlPrefix", - "[def @document] [tag url-prefix]([string https://]) { [builtin #id] { } }"); - - MT("document_domain", - "[def @document] [tag domain]([string blah.com]) { [tag foo] { } }"); - - MT("document_regexp", - "[def @document] [tag regexp]([string \".*blah.+\"]) { [builtin #id] { } }"); - - MT("counter-style", - "[def @counter-style] [variable binary] {", - " [property system]: [atom numeric];", - " [property symbols]: [number 0] [number 1];", - " [property suffix]: [string \".\"];", - " [property range]: [atom infinite];", - " [property speak-as]: [atom numeric];", - "}"); - - MT("counter-style-additive-symbols", - "[def @counter-style] [variable simple-roman] {", - " [property system]: [atom additive];", - " [property additive-symbols]: [number 10] [variable X], [number 5] [variable V], [number 1] [variable I];", - " [property range]: [number 1] [number 49];", - "}"); - - MT("counter-style-use", - "[tag ol][qualifier .roman] { [property list-style]: [variable simple-roman]; }"); - - MT("counter-style-symbols", - "[tag ol] { [property list-style]: [atom symbols]([atom cyclic] [string \"*\"] [string \"\\2020\"] [string \"\\2021\"] [string \"\\A7\"]); }"); - - MT("comment-does-not-disrupt", - "[def @font-face] [comment /* foo */] {", - " [property src]: [atom url]([string x]);", - " [property font-family]: [variable One];", - "}") -})(); diff --git a/lib/redactor/codemirror/mode/htmlembedded/htmlembedded.js b/lib/redactor/codemirror/mode/htmlembedded/htmlembedded.js index 464dc57..8099d37 100644 --- a/lib/redactor/codemirror/mode/htmlembedded/htmlembedded.js +++ b/lib/redactor/codemirror/mode/htmlembedded/htmlembedded.js @@ -14,7 +14,16 @@ "use strict"; CodeMirror.defineMode("htmlembedded", function(config, parserConfig) { + var closeComment = parserConfig.closeComment || "--%>" return CodeMirror.multiplexingMode(CodeMirror.getMode(config, "htmlmixed"), { + open: parserConfig.openComment || "<%--", + close: closeComment, + delimStyle: "comment", + mode: {token: function(stream) { + stream.skipTo(closeComment) || stream.skipToEnd() + return "comment" + }} + }, { open: parserConfig.open || parserConfig.scriptStartRegex || "<%", close: parserConfig.close || parserConfig.scriptEndRegex || "%>", mode: CodeMirror.getMode(config, parserConfig.scriptingModeSpec) diff --git a/lib/redactor/codemirror/mode/htmlembedded/index.html b/lib/redactor/codemirror/mode/htmlembedded/index.html deleted file mode 100644 index 9ed33cf..0000000 --- a/lib/redactor/codemirror/mode/htmlembedded/index.html +++ /dev/null @@ -1,60 +0,0 @@ - - -CodeMirror: Html Embedded Scripts mode - - - - - - - - - - - - - - -
    -

    Html Embedded Scripts mode

    -
    - - - -

    Mode for html embedded scripts like JSP and ASP.NET. Depends on multiplex and HtmlMixed which in turn depends on - JavaScript, CSS and XML.
    Other dependencies include those of the scripting language chosen.

    - -

    MIME types defined: application/x-aspx (ASP.NET), - application/x-ejs (Embedded Javascript), application/x-jsp (JavaServer Pages) - and application/x-erb

    -
    diff --git a/lib/redactor/codemirror/mode/htmlmixed/index.html b/lib/redactor/codemirror/mode/htmlmixed/index.html deleted file mode 100644 index e576c05..0000000 --- a/lib/redactor/codemirror/mode/htmlmixed/index.html +++ /dev/null @@ -1,100 +0,0 @@ - - -CodeMirror: HTML mixed mode - - - - - - - - - - - - - - -
    -

    HTML mixed mode

    -
    - - -

    The HTML mixed mode depends on the XML, JavaScript, and CSS modes.

    - -

    It takes an optional mode configuration - option, tags, which can be used to add custom - behavior for specific tags. When given, it should be an object - mapping tag names (for example script) to arrays or - three-element arrays. Those inner arrays indicate [attributeName, - valueRegexp, modeSpec] - specifications. For example, you could use ["type", /^foo$/, - "foo"] to map the attribute type="foo" to - the foo mode. When the first two fields are null - ([null, null, "mode"]), the given mode is used for - any such tag that doesn't match any of the previously given - attributes. For example:

    - -
    var myModeSpec = {
    -  name: "htmlmixed",
    -  tags: {
    -    style: [["type", /^text\/(x-)?scss$/, "text/x-scss"],
    -            [null, null, "css"]],
    -    custom: [[null, null, "customMode"]]
    -  }
    -}
    - -

    MIME types defined: text/html - (redefined, only takes effect if you load this parser after the - XML parser).

    - -
    diff --git a/lib/redactor/codemirror/mode/javascript/index.html b/lib/redactor/codemirror/mode/javascript/index.html deleted file mode 100644 index 592a133..0000000 --- a/lib/redactor/codemirror/mode/javascript/index.html +++ /dev/null @@ -1,114 +0,0 @@ - - -CodeMirror: JavaScript mode - - - - - - - - - - - - -
    -

    JavaScript mode

    - - -
    - - - -

    - JavaScript mode supports several configuration options: -

      -
    • json which will set the mode to expect JSON - data rather than a JavaScript program.
    • -
    • jsonld which will set the mode to expect - JSON-LD linked data rather - than a JavaScript program (demo).
    • -
    • typescript which will activate additional - syntax highlighting and some other things for TypeScript code - (demo).
    • -
    • statementIndent which (given a number) will - determine the amount of indentation to use for statements - continued on a new line.
    • -
    • wordCharacters, a regexp that indicates which - characters should be considered part of an identifier. - Defaults to /[\w$]/, which does not handle - non-ASCII identifiers. Can be set to something more elaborate - to improve Unicode support.
    • -
    -

    - -

    MIME types defined: text/javascript, application/json, application/ld+json, text/typescript, application/typescript.

    -
    diff --git a/lib/redactor/codemirror/mode/javascript/javascript.js b/lib/redactor/codemirror/mode/javascript/javascript.js index ca9fe8b..fe39eb1 100644 --- a/lib/redactor/codemirror/mode/javascript/javascript.js +++ b/lib/redactor/codemirror/mode/javascript/javascript.js @@ -26,7 +26,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c"), D = kw("keyword d"); var operator = kw("operator"), atom = {type: "atom", style: "atom"}; - var jsKeywords = { + return { "if": kw("if"), "while": A, "with": A, "else": B, "do": B, "try": B, "finally": B, "return": D, "break": D, "continue": D, "new": kw("new"), "delete": C, "void": C, "throw": C, "debugger": kw("debugger"), "var": kw("var"), "const": kw("var"), "let": kw("var"), @@ -38,35 +38,6 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { "yield": C, "export": kw("export"), "import": kw("import"), "extends": C, "await": C }; - - // Extend the 'normal' keywords with the TypeScript language extensions - if (isTS) { - var type = {type: "variable", style: "type"}; - var tsKeywords = { - // object-like things - "interface": kw("class"), - "implements": C, - "namespace": C, - "module": kw("module"), - "enum": kw("module"), - - // scope modifiers - "public": kw("modifier"), - "private": kw("modifier"), - "protected": kw("modifier"), - "abstract": kw("modifier"), - "readonly": kw("modifier"), - - // types - "string": type, "number": type, "boolean": type, "any": type - }; - - for (var attr in tsKeywords) { - jsKeywords[attr] = tsKeywords[attr]; - } - } - - return jsKeywords; }(); var isOperatorChar = /[+\-*&%=<>!?|~^@]/; @@ -155,7 +126,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { var kw = keywords[word] return ret(kw.type, kw.style, word) } - if (word == "async" && stream.match(/^\s*[\(\w]/, false)) + if (word == "async" && stream.match(/^(\s|\/\*.*?\*\/)*[\(\w]/, false)) return ret("async", "keyword", word) } return ret("variable", "variable", word) @@ -312,6 +283,10 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { } } + function isModifier(name) { + return name == "public" || name == "private" || name == "protected" || name == "abstract" || name == "readonly" + } + // Combinators var defaultVars = {name: "this", next: {name: "arguments"}}; @@ -368,13 +343,19 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { } if (type == "function") return cont(functiondef); if (type == "for") return cont(pushlex("form"), forspec, statement, poplex); + if (type == "class" || (isTS && value == "interface")) { cx.marked = "keyword"; return cont(pushlex("form"), className, poplex); } if (type == "variable") { - if (isTS && value == "type") { - cx.marked = "keyword" - return cont(typeexpr, expect("operator"), typeexpr, expect(";")); - } if (isTS && value == "declare") { + if (isTS && value == "declare") { cx.marked = "keyword" return cont(statement) + } else if (isTS && (value == "module" || value == "enum" || value == "type") && cx.stream.match(/^\s*\w/, false)) { + cx.marked = "keyword" + if (value == "enum") return cont(enumdef); + else if (value == "type") return cont(typeexpr, expect("operator"), typeexpr, expect(";")); + else return cont(pushlex("form"), pattern, expect("{"), pushlex("}"), block, poplex, poplex) + } else if (isTS && value == "namespace") { + cx.marked = "keyword" + return cont(pushlex("form"), expression, block, poplex) } else { return cont(pushlex("stat"), maybelabel); } @@ -385,25 +366,23 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { if (type == "default") return cont(expect(":")); if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"), statement, poplex, popcontext); - if (type == "class") return cont(pushlex("form"), className, poplex); if (type == "export") return cont(pushlex("stat"), afterExport, poplex); if (type == "import") return cont(pushlex("stat"), afterImport, poplex); - if (type == "module") return cont(pushlex("form"), pattern, expect("{"), pushlex("}"), block, poplex, poplex) if (type == "async") return cont(statement) if (value == "@") return cont(expression, statement) return pass(pushlex("stat"), expression, expect(";"), poplex); } - function expression(type) { - return expressionInner(type, false); + function expression(type, value) { + return expressionInner(type, value, false); } - function expressionNoComma(type) { - return expressionInner(type, true); + function expressionNoComma(type, value) { + return expressionInner(type, value, true); } function parenExpr(type) { if (type != "(") return pass() return cont(pushlex(")"), expression, expect(")"), poplex) } - function expressionInner(type, noComma) { + function expressionInner(type, value, noComma) { if (cx.state.fatArrowAt == cx.stream.start) { var body = noComma ? arrowBodyNoComma : arrowBody; if (type == "(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")"), poplex, expect("=>"), body, popcontext); @@ -413,7 +392,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { var maybeop = noComma ? maybeoperatorNoComma : maybeoperatorComma; if (atomicTypes.hasOwnProperty(type)) return cont(maybeop); if (type == "function") return cont(functiondef, maybeop); - if (type == "class") return cont(pushlex("form"), classExpression, poplex); + if (type == "class" || (isTS && value == "interface")) { cx.marked = "keyword"; return cont(pushlex("form"), classExpression, poplex); } if (type == "keyword c" || type == "async") return cont(noComma ? expressionNoComma : expression); if (type == "(") return cont(pushlex(")"), maybeexpression, expect(")"), poplex, maybeop); if (type == "operator" || type == "spread") return cont(noComma ? expressionNoComma : expression); @@ -421,6 +400,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { if (type == "{") return contCommasep(objprop, "}", null, maybeop); if (type == "quasi") return pass(quasi, maybeop); if (type == "new") return cont(maybeTarget(noComma)); + if (type == "import") return cont(expression); return cont(); } function maybeexpression(type) { @@ -438,6 +418,8 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { if (type == "=>") return cont(pushcontext, noComma ? arrowBodyNoComma : arrowBody, popcontext); if (type == "operator") { if (/\+\+|--/.test(value) || isTS && value == "!") return cont(me); + if (isTS && value == "<" && cx.stream.match(/^([^>]|<.*?>)*>\s*\(/, false)) + return cont(pushlex(">"), commasep(typeexpr, ">"), poplex, me); if (value == "?") return cont(expression, expect(":"), expr); return cont(expr); } @@ -509,10 +491,11 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { return cont(afterprop); } else if (type == "jsonld-keyword") { return cont(afterprop); - } else if (type == "modifier") { + } else if (isTS && isModifier(value)) { + cx.marked = "keyword" return cont(objprop) } else if (type == "[") { - return cont(expression, expect("]"), afterprop); + return cont(expression, maybetype, expect("]"), afterprop); } else if (type == "spread") { return cont(expressionNoComma, afterprop); } else if (value == "*") { @@ -564,15 +547,26 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { if (value == "?") return cont(maybetype); } } + function mayberettype(type) { + if (isTS && type == ":") { + if (cx.stream.match(/^\s*\w+\s+is\b/, false)) return cont(expression, isKW, typeexpr) + else return cont(typeexpr) + } + } + function isKW(_, value) { + if (value == "is") { + cx.marked = "keyword" + return cont() + } + } function typeexpr(type, value) { + if (value == "keyof" || value == "typeof") { + cx.marked = "keyword" + return cont(value == "keyof" ? typeexpr : expression) + } if (type == "variable" || value == "void") { - if (value == "keyof") { - cx.marked = "keyword" - return cont(typeexpr) - } else { - cx.marked = "type" - return cont(afterType) - } + cx.marked = "type" + return cont(afterType) } if (type == "string" || type == "number" || type == "atom") return cont(afterType); if (type == "[") return cont(pushlex("]"), commasep(typeexpr, "]", ","), poplex, afterType) @@ -600,18 +594,25 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { } function afterType(type, value) { if (value == "<") return cont(pushlex(">"), commasep(typeexpr, ">"), poplex, afterType) - if (value == "|" || type == ".") return cont(typeexpr) + if (value == "|" || type == "." || value == "&") return cont(typeexpr) if (type == "[") return cont(expect("]"), afterType) - if (value == "extends") return cont(typeexpr) + if (value == "extends" || value == "implements") { cx.marked = "keyword"; return cont(typeexpr) } } function maybeTypeArgs(_, value) { if (value == "<") return cont(pushlex(">"), commasep(typeexpr, ">"), poplex, afterType) } - function vardef() { + function typeparam() { + return pass(typeexpr, maybeTypeDefault) + } + function maybeTypeDefault(_, value) { + if (value == "=") return cont(typeexpr) + } + function vardef(_, value) { + if (value == "enum") {cx.marked = "keyword"; return cont(enumdef)} return pass(pattern, maybetype, maybeAssign, vardefCont); } function pattern(type, value) { - if (type == "modifier") return cont(pattern) + if (isTS && isModifier(value)) { cx.marked = "keyword"; return cont(pattern) } if (type == "variable") { register(value); return cont(); } if (type == "spread") return cont(pattern); if (type == "[") return contCommasep(pattern, "]"); @@ -636,7 +637,8 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { function maybeelse(type, value) { if (type == "keyword b" && value == "else") return cont(pushlex("form", "else"), statement, poplex); } - function forspec(type) { + function forspec(type, value) { + if (value == "await") return cont(forspec); if (type == "(") return cont(pushlex(")"), forspec1, expect(")"), poplex); } function forspec1(type) { @@ -660,12 +662,13 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { function functiondef(type, value) { if (value == "*") {cx.marked = "keyword"; return cont(functiondef);} if (type == "variable") {register(value); return cont(functiondef);} - if (type == "(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")"), poplex, maybetype, statement, popcontext); - if (isTS && value == "<") return cont(pushlex(">"), commasep(typeexpr, ">"), poplex, functiondef) + if (type == "(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")"), poplex, mayberettype, statement, popcontext); + if (isTS && value == "<") return cont(pushlex(">"), commasep(typeparam, ">"), poplex, functiondef) } function funarg(type, value) { if (value == "@") cont(expression, funarg) - if (type == "spread" || type == "modifier") return cont(funarg); + if (type == "spread") return cont(funarg); + if (isTS && isModifier(value)) { cx.marked = "keyword"; return cont(funarg); } return pass(pattern, maybetype, maybeAssign); } function classExpression(type, value) { @@ -677,15 +680,17 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { if (type == "variable") {register(value); return cont(classNameAfter);} } function classNameAfter(type, value) { - if (value == "<") return cont(pushlex(">"), commasep(typeexpr, ">"), poplex, classNameAfter) - if (value == "extends" || value == "implements" || (isTS && type == ",")) + if (value == "<") return cont(pushlex(">"), commasep(typeparam, ">"), poplex, classNameAfter) + if (value == "extends" || value == "implements" || (isTS && type == ",")) { + if (value == "implements") cx.marked = "keyword"; return cont(isTS ? typeexpr : expression, classNameAfter); + } if (type == "{") return cont(pushlex("}"), classBody, poplex); } function classBody(type, value) { - if (type == "modifier" || type == "async" || + if (type == "async" || (type == "variable" && - (value == "static" || value == "get" || value == "set") && + (value == "static" || value == "get" || value == "set" || (isTS && isModifier(value))) && cx.stream.match(/^\s+[\w$\xa1-\uffff]/, false))) { cx.marked = "keyword"; return cont(classBody); @@ -695,7 +700,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { return cont(isTS ? classfield : functiondef, classBody); } if (type == "[") - return cont(expression, expect("]"), isTS ? classfield : functiondef, classBody) + return cont(expression, maybetype, expect("]"), isTS ? classfield : functiondef, classBody) if (value == "*") { cx.marked = "keyword"; return cont(classBody); @@ -722,6 +727,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { } function afterImport(type) { if (type == "string") return cont(); + if (type == "(") return pass(expression); return pass(importSpec, maybeMoreImports, maybeFrom); } function importSpec(type, value) { @@ -743,6 +749,12 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { if (type == "]") return cont(); return pass(commasep(expressionNoComma, "]")); } + function enumdef() { + return pass(pushlex("form"), pattern, expect("{"), pushlex("}"), commasep(enummember, "}"), poplex, poplex) + } + function enummember() { + return pass(pattern, maybeAssign); + } function isContinuedStatement(state, textAfter) { return state.lastType == "operator" || state.lastType == "," || diff --git a/lib/redactor/codemirror/mode/javascript/json-ld.html b/lib/redactor/codemirror/mode/javascript/json-ld.html deleted file mode 100644 index 3a37f0b..0000000 --- a/lib/redactor/codemirror/mode/javascript/json-ld.html +++ /dev/null @@ -1,72 +0,0 @@ - - -CodeMirror: JSON-LD mode - - - - - - - - - - - - -
    -

    JSON-LD mode

    - - -
    - - - -

    This is a specialization of the JavaScript mode.

    -
    diff --git a/lib/redactor/codemirror/mode/javascript/test.js b/lib/redactor/codemirror/mode/javascript/test.js deleted file mode 100644 index 213bab0..0000000 --- a/lib/redactor/codemirror/mode/javascript/test.js +++ /dev/null @@ -1,408 +0,0 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -(function() { - var mode = CodeMirror.getMode({indentUnit: 2}, "javascript"); - function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); } - - MT("locals", - "[keyword function] [def foo]([def a], [def b]) { [keyword var] [def c] [operator =] [number 10]; [keyword return] [variable-2 a] [operator +] [variable-2 c] [operator +] [variable d]; }"); - - MT("comma-and-binop", - "[keyword function](){ [keyword var] [def x] [operator =] [number 1] [operator +] [number 2], [def y]; }"); - - MT("destructuring", - "([keyword function]([def a], [[[def b], [def c] ]]) {", - " [keyword let] {[def d], [property foo]: [def c][operator =][number 10], [def x]} [operator =] [variable foo]([variable-2 a]);", - " [[[variable-2 c], [variable y] ]] [operator =] [variable-2 c];", - "})();"); - - MT("destructure_trailing_comma", - "[keyword let] {[def a], [def b],} [operator =] [variable foo];", - "[keyword let] [def c];"); // Parser still in good state? - - MT("class_body", - "[keyword class] [def Foo] {", - " [property constructor]() {}", - " [property sayName]() {", - " [keyword return] [string-2 `foo${][variable foo][string-2 }oo`];", - " }", - "}"); - - MT("class", - "[keyword class] [def Point] [keyword extends] [variable SuperThing] {", - " [keyword get] [property prop]() { [keyword return] [number 24]; }", - " [property constructor]([def x], [def y]) {", - " [keyword super]([string 'something']);", - " [keyword this].[property x] [operator =] [variable-2 x];", - " }", - "}"); - - MT("anonymous_class_expression", - "[keyword const] [def Adder] [operator =] [keyword class] [keyword extends] [variable Arithmetic] {", - " [property add]([def a], [def b]) {}", - "};"); - - MT("named_class_expression", - "[keyword const] [def Subber] [operator =] [keyword class] [def Subtract] {", - " [property sub]([def a], [def b]) {}", - "};"); - - MT("class_async_method", - "[keyword class] [def Foo] {", - " [property sayName1]() {}", - " [keyword async] [property sayName2]() {}", - "}"); - - MT("import", - "[keyword function] [def foo]() {", - " [keyword import] [def $] [keyword from] [string 'jquery'];", - " [keyword import] { [def encrypt], [def decrypt] } [keyword from] [string 'crypto'];", - "}"); - - MT("import_trailing_comma", - "[keyword import] {[def foo], [def bar],} [keyword from] [string 'baz']") - - MT("const", - "[keyword function] [def f]() {", - " [keyword const] [[ [def a], [def b] ]] [operator =] [[ [number 1], [number 2] ]];", - "}"); - - MT("for/of", - "[keyword for]([keyword let] [def of] [keyword of] [variable something]) {}"); - - MT("generator", - "[keyword function*] [def repeat]([def n]) {", - " [keyword for]([keyword var] [def i] [operator =] [number 0]; [variable-2 i] [operator <] [variable-2 n]; [operator ++][variable-2 i])", - " [keyword yield] [variable-2 i];", - "}"); - - MT("quotedStringAddition", - "[keyword let] [def f] [operator =] [variable a] [operator +] [string 'fatarrow'] [operator +] [variable c];"); - - MT("quotedFatArrow", - "[keyword let] [def f] [operator =] [variable a] [operator +] [string '=>'] [operator +] [variable c];"); - - MT("fatArrow", - "[variable array].[property filter]([def a] [operator =>] [variable-2 a] [operator +] [number 1]);", - "[variable a];", // No longer in scope - "[keyword let] [def f] [operator =] ([[ [def a], [def b] ]], [def c]) [operator =>] [variable-2 a] [operator +] [variable-2 c];", - "[variable c];"); - - MT("spread", - "[keyword function] [def f]([def a], [meta ...][def b]) {", - " [variable something]([variable-2 a], [meta ...][variable-2 b]);", - "}"); - - MT("quasi", - "[variable re][string-2 `fofdlakj${][variable x] [operator +] ([variable re][string-2 `foo`]) [operator +] [number 1][string-2 }fdsa`] [operator +] [number 2]"); - - MT("quasi_no_function", - "[variable x] [operator =] [string-2 `fofdlakj${][variable x] [operator +] [string-2 `foo`] [operator +] [number 1][string-2 }fdsa`] [operator +] [number 2]"); - - MT("indent_statement", - "[keyword var] [def x] [operator =] [number 10]", - "[variable x] [operator +=] [variable y] [operator +]", - " [atom Infinity]", - "[keyword debugger];"); - - MT("indent_if", - "[keyword if] ([number 1])", - " [keyword break];", - "[keyword else] [keyword if] ([number 2])", - " [keyword continue];", - "[keyword else]", - " [number 10];", - "[keyword if] ([number 1]) {", - " [keyword break];", - "} [keyword else] [keyword if] ([number 2]) {", - " [keyword continue];", - "} [keyword else] {", - " [number 10];", - "}"); - - MT("indent_for", - "[keyword for] ([keyword var] [def i] [operator =] [number 0];", - " [variable i] [operator <] [number 100];", - " [variable i][operator ++])", - " [variable doSomething]([variable i]);", - "[keyword debugger];"); - - MT("indent_c_style", - "[keyword function] [def foo]()", - "{", - " [keyword debugger];", - "}"); - - MT("indent_else", - "[keyword for] (;;)", - " [keyword if] ([variable foo])", - " [keyword if] ([variable bar])", - " [number 1];", - " [keyword else]", - " [number 2];", - " [keyword else]", - " [number 3];"); - - MT("indent_funarg", - "[variable foo]([number 10000],", - " [keyword function]([def a]) {", - " [keyword debugger];", - "};"); - - MT("indent_below_if", - "[keyword for] (;;)", - " [keyword if] ([variable foo])", - " [number 1];", - "[number 2];"); - - MT("indent_semicolonless_if", - "[keyword function] [def foo]() {", - " [keyword if] ([variable x])", - " [variable foo]()", - "}") - - MT("indent_semicolonless_if_with_statement", - "[keyword function] [def foo]() {", - " [keyword if] ([variable x])", - " [variable foo]()", - " [variable bar]()", - "}") - - MT("multilinestring", - "[keyword var] [def x] [operator =] [string 'foo\\]", - "[string bar'];"); - - MT("scary_regexp", - "[string-2 /foo[[/]]bar/];"); - - MT("indent_strange_array", - "[keyword var] [def x] [operator =] [[", - " [number 1],,", - " [number 2],", - "]];", - "[number 10];"); - - MT("param_default", - "[keyword function] [def foo]([def x] [operator =] [string-2 `foo${][number 10][string-2 }bar`]) {", - " [keyword return] [variable-2 x];", - "}"); - - MT("new_target", - "[keyword function] [def F]([def target]) {", - " [keyword if] ([variable-2 target] [operator &&] [keyword new].[keyword target].[property name]) {", - " [keyword return] [keyword new]", - " .[keyword target];", - " }", - "}"); - - MT("async", - "[keyword async] [keyword function] [def foo]([def args]) { [keyword return] [atom true]; }"); - - MT("async_assignment", - "[keyword const] [def foo] [operator =] [keyword async] [keyword function] ([def args]) { [keyword return] [atom true]; };"); - - MT("async_object", - "[keyword let] [def obj] [operator =] { [property async]: [atom false] };"); - - // async be highlighet as keyword and foo as def, but it requires potentially expensive look-ahead. See #4173 - MT("async_object_function", - "[keyword let] [def obj] [operator =] { [property async] [property foo]([def args]) { [keyword return] [atom true]; } };"); - - MT("async_object_properties", - "[keyword let] [def obj] [operator =] {", - " [property prop1]: [keyword async] [keyword function] ([def args]) { [keyword return] [atom true]; },", - " [property prop2]: [keyword async] [keyword function] ([def args]) { [keyword return] [atom true]; },", - " [property prop3]: [keyword async] [keyword function] [def prop3]([def args]) { [keyword return] [atom true]; },", - "};"); - - MT("async_arrow", - "[keyword const] [def foo] [operator =] [keyword async] ([def args]) [operator =>] { [keyword return] [atom true]; };"); - - MT("async_jquery", - "[variable $].[property ajax]({", - " [property url]: [variable url],", - " [property async]: [atom true],", - " [property method]: [string 'GET']", - "});"); - - MT("async_variable", - "[keyword const] [def async] [operator =] {[property a]: [number 1]};", - "[keyword const] [def foo] [operator =] [string-2 `bar ${][variable async].[property a][string-2 }`];") - - MT("indent_switch", - "[keyword switch] ([variable x]) {", - " [keyword default]:", - " [keyword return] [number 2]", - "}") - - MT("regexp_corner_case", - "[operator +]{} [operator /] [atom undefined];", - "[[[meta ...][string-2 /\\//] ]];", - "[keyword void] [string-2 /\\//];", - "[keyword do] [string-2 /\\//]; [keyword while] ([number 0]);", - "[keyword if] ([number 0]) {} [keyword else] [string-2 /\\//];", - "[string-2 `${][variable async][operator ++][string-2 }//`];", - "[string-2 `${]{} [operator /] [string-2 /\\//}`];") - - MT("return_eol", - "[keyword return]", - "{} [string-2 /5/]") - - var ts_mode = CodeMirror.getMode({indentUnit: 2}, "application/typescript") - function TS(name) { - test.mode(name, ts_mode, Array.prototype.slice.call(arguments, 1)) - } - - TS("typescript_extend_type", - "[keyword class] [def Foo] [keyword extends] [type Some][operator <][type Type][operator >] {}") - - TS("typescript_arrow_type", - "[keyword let] [def x]: ([variable arg]: [type Type]) [operator =>] [type ReturnType]") - - TS("typescript_class", - "[keyword class] [def Foo] {", - " [keyword public] [keyword static] [property main]() {}", - " [keyword private] [property _foo]: [type string];", - "}") - - TS("typescript_literal_types", - "[keyword import] [keyword *] [keyword as] [def Sequelize] [keyword from] [string 'sequelize'];", - "[keyword interface] [def MyAttributes] {", - " [property truthy]: [string 'true'] [operator |] [number 1] [operator |] [atom true];", - " [property falsy]: [string 'false'] [operator |] [number 0] [operator |] [atom false];", - "}", - "[keyword interface] [def MyInstance] [keyword extends] [type Sequelize].[type Instance] [operator <] [type MyAttributes] [operator >] {", - " [property rawAttributes]: [type MyAttributes];", - " [property truthy]: [string 'true'] [operator |] [number 1] [operator |] [atom true];", - " [property falsy]: [string 'false'] [operator |] [number 0] [operator |] [atom false];", - "}") - - TS("typescript_extend_operators", - "[keyword export] [keyword interface] [def UserModel] [keyword extends]", - " [type Sequelize].[type Model] [operator <] [type UserInstance], [type UserAttributes] [operator >] {", - " [property findById]: (", - " [variable userId]: [type number]", - " ) [operator =>] [type Promise] [operator <] [type Array] [operator <] { [property id], [property name] } [operator >>];", - " [property updateById]: (", - " [variable userId]: [type number],", - " [variable isActive]: [type boolean]", - " ) [operator =>] [type Promise] [operator <] [type AccountHolderNotificationPreferenceInstance] [operator >];", - " }") - - TS("typescript_interface_with_const", - "[keyword const] [def hello]: {", - " [property prop1][operator ?]: [type string];", - " [property prop2][operator ?]: [type string];", - "} [operator =] {};") - - TS("typescript_double_extend", - "[keyword export] [keyword interface] [def UserAttributes] {", - " [property id][operator ?]: [type number];", - " [property createdAt][operator ?]: [type Date];", - "}", - "[keyword export] [keyword interface] [def UserInstance] [keyword extends] [type Sequelize].[type Instance][operator <][type UserAttributes][operator >], [type UserAttributes] {", - " [property id]: [type number];", - " [property createdAt]: [type Date];", - "}"); - - TS("typescript_index_signature", - "[keyword interface] [def A] {", - " [[ [variable prop]: [type string] ]]: [type any];", - " [property prop1]: [type any];", - "}"); - - TS("typescript_generic_class", - "[keyword class] [def Foo][operator <][type T][operator >] {", - " [property bar]() {}", - " [property foo](): [type Foo] {}", - "}") - - TS("typescript_type_when_keyword", - "[keyword export] [keyword type] [type AB] [operator =] [type A] [operator |] [type B];", - "[keyword type] [type Flags] [operator =] {", - " [property p1]: [type string];", - " [property p2]: [type boolean];", - "};") - - TS("typescript_type_when_not_keyword", - "[keyword class] [def HasType] {", - " [property type]: [type string];", - " [property constructor]([def type]: [type string]) {", - " [keyword this].[property type] [operator =] [variable-2 type];", - " }", - " [property setType]({ [def type] }: { [property type]: [type string]; }) {", - " [keyword this].[property type] [operator =] [variable-2 type];", - " }", - "}") - - TS("typescript_function_generics", - "[keyword function] [def a]() {}", - "[keyword function] [def b][operator <][type IA] [keyword extends] [type object], [type IB] [keyword extends] [type object][operator >]() {}", - "[keyword function] [def c]() {}") - - TS("typescript_complex_return_type", - "[keyword function] [def A]() {", - " [keyword return] [keyword this].[property property];", - "}", - "[keyword function] [def B](): [type Promise][operator <]{ [[ [variable key]: [type string] ]]: [type any] } [operator |] [atom null][operator >] {", - " [keyword return] [keyword this].[property property];", - "}") - - TS("typescript_complex_type_casting", - "[keyword const] [def giftpay] [operator =] [variable config].[property get]([string 'giftpay']) [keyword as] { [[ [variable platformUuid]: [type string] ]]: { [property version]: [type number]; [property apiCode]: [type string]; } };") - - TS("typescript_keyof", - "[keyword function] [def x][operator <][type T] [keyword extends] [keyword keyof] [type X][operator >]([def a]: [type T]) {", - " [keyword return]") - - TS("typescript_new_typeargs", - "[keyword let] [def x] [operator =] [keyword new] [variable Map][operator <][type string], [type Date][operator >]([string-2 `foo${][variable bar][string-2 }`])") - - TS("modifiers", - "[keyword class] [def Foo] {", - " [keyword public] [keyword abstract] [property bar]() {}", - " [property constructor]([keyword readonly] [keyword private] [def x]) {}", - "}") - - TS("arrow prop", - "({[property a]: [def p] [operator =>] [variable-2 p]})") - - var jsonld_mode = CodeMirror.getMode( - {indentUnit: 2}, - {name: "javascript", jsonld: true} - ); - function LD(name) { - test.mode(name, jsonld_mode, Array.prototype.slice.call(arguments, 1)); - } - - LD("json_ld_keywords", - '{', - ' [meta "@context"]: {', - ' [meta "@base"]: [string "http://example.com"],', - ' [meta "@vocab"]: [string "http://xmlns.com/foaf/0.1/"],', - ' [property "likesFlavor"]: {', - ' [meta "@container"]: [meta "@list"]', - ' [meta "@reverse"]: [string "@beFavoriteOf"]', - ' },', - ' [property "nick"]: { [meta "@container"]: [meta "@set"] },', - ' [property "nick"]: { [meta "@container"]: [meta "@index"] }', - ' },', - ' [meta "@graph"]: [[ {', - ' [meta "@id"]: [string "http://dbpedia.org/resource/John_Lennon"],', - ' [property "name"]: [string "John Lennon"],', - ' [property "modified"]: {', - ' [meta "@value"]: [string "2010-05-29T14:17:39+02:00"],', - ' [meta "@type"]: [string "http://www.w3.org/2001/XMLSchema#dateTime"]', - ' }', - ' } ]]', - '}'); - - LD("json_ld_fake", - '{', - ' [property "@fake"]: [string "@fake"],', - ' [property "@contextual"]: [string "@identifier"],', - ' [property "user@domain.com"]: [string "@graphical"],', - ' [property "@ID"]: [string "@@ID"]', - '}'); -})(); diff --git a/lib/redactor/codemirror/mode/javascript/typescript.html b/lib/redactor/codemirror/mode/javascript/typescript.html deleted file mode 100644 index 1f26d7f..0000000 --- a/lib/redactor/codemirror/mode/javascript/typescript.html +++ /dev/null @@ -1,61 +0,0 @@ - - -CodeMirror: TypeScript mode - - - - - - - - - -
    -

    TypeScript mode

    - - -
    - - - -

    This is a specialization of the JavaScript mode.

    -
    diff --git a/lib/redactor/codemirror/mode/livescript/index.html b/lib/redactor/codemirror/mode/livescript/index.html deleted file mode 100644 index f415479..0000000 --- a/lib/redactor/codemirror/mode/livescript/index.html +++ /dev/null @@ -1,459 +0,0 @@ - - -CodeMirror: LiveScript mode - - - - - - - - - - -
    -

    LiveScript mode

    -
    - - -

    MIME types defined: text/x-livescript.

    - -

    The LiveScript mode was written by Kenneth Bentley.

    - -
    diff --git a/lib/redactor/codemirror/mode/livescript/livescript.js b/lib/redactor/codemirror/mode/livescript/livescript.js deleted file mode 100644 index 1e363f8..0000000 --- a/lib/redactor/codemirror/mode/livescript/livescript.js +++ /dev/null @@ -1,280 +0,0 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -/** - * Link to the project's GitHub page: - * https://github.com/duralog/CodeMirror - */ - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror")); - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror"], mod); - else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { - "use strict"; - - CodeMirror.defineMode('livescript', function(){ - var tokenBase = function(stream, state) { - var next_rule = state.next || "start"; - if (next_rule) { - state.next = state.next; - var nr = Rules[next_rule]; - if (nr.splice) { - for (var i$ = 0; i$ < nr.length; ++i$) { - var r = nr[i$]; - if (r.regex && stream.match(r.regex)) { - state.next = r.next || state.next; - return r.token; - } - } - stream.next(); - return 'error'; - } - if (stream.match(r = Rules[next_rule])) { - if (r.regex && stream.match(r.regex)) { - state.next = r.next; - return r.token; - } else { - stream.next(); - return 'error'; - } - } - } - stream.next(); - return 'error'; - }; - var external = { - startState: function(){ - return { - next: 'start', - lastToken: {style: null, indent: 0, content: ""} - }; - }, - token: function(stream, state){ - while (stream.pos == stream.start) - var style = tokenBase(stream, state); - state.lastToken = { - style: style, - indent: stream.indentation(), - content: stream.current() - }; - return style.replace(/\./g, ' '); - }, - indent: function(state){ - var indentation = state.lastToken.indent; - if (state.lastToken.content.match(indenter)) { - indentation += 2; - } - return indentation; - } - }; - return external; - }); - - var identifier = '(?![\\d\\s])[$\\w\\xAA-\\uFFDC](?:(?!\\s)[$\\w\\xAA-\\uFFDC]|-[A-Za-z])*'; - var indenter = RegExp('(?:[({[=:]|[-~]>|\\b(?:e(?:lse|xport)|d(?:o|efault)|t(?:ry|hen)|finally|import(?:\\s*all)?|const|var|let|new|catch(?:\\s*' + identifier + ')?))\\s*$'); - var keywordend = '(?![$\\w]|-[A-Za-z]|\\s*:(?![:=]))'; - var stringfill = { - token: 'string', - regex: '.+' - }; - var Rules = { - start: [ - { - token: 'comment.doc', - regex: '/\\*', - next: 'comment' - }, { - token: 'comment', - regex: '#.*' - }, { - token: 'keyword', - regex: '(?:t(?:h(?:is|row|en)|ry|ypeof!?)|c(?:on(?:tinue|st)|a(?:se|tch)|lass)|i(?:n(?:stanceof)?|mp(?:ort(?:\\s+all)?|lements)|[fs])|d(?:e(?:fault|lete|bugger)|o)|f(?:or(?:\\s+own)?|inally|unction)|s(?:uper|witch)|e(?:lse|x(?:tends|port)|val)|a(?:nd|rguments)|n(?:ew|ot)|un(?:less|til)|w(?:hile|ith)|o[fr]|return|break|let|var|loop)' + keywordend - }, { - token: 'constant.language', - regex: '(?:true|false|yes|no|on|off|null|void|undefined)' + keywordend - }, { - token: 'invalid.illegal', - regex: '(?:p(?:ackage|r(?:ivate|otected)|ublic)|i(?:mplements|nterface)|enum|static|yield)' + keywordend - }, { - token: 'language.support.class', - regex: '(?:R(?:e(?:gExp|ferenceError)|angeError)|S(?:tring|yntaxError)|E(?:rror|valError)|Array|Boolean|Date|Function|Number|Object|TypeError|URIError)' + keywordend - }, { - token: 'language.support.function', - regex: '(?:is(?:NaN|Finite)|parse(?:Int|Float)|Math|JSON|(?:en|de)codeURI(?:Component)?)' + keywordend - }, { - token: 'variable.language', - regex: '(?:t(?:hat|il|o)|f(?:rom|allthrough)|it|by|e)' + keywordend - }, { - token: 'identifier', - regex: identifier + '\\s*:(?![:=])' - }, { - token: 'variable', - regex: identifier - }, { - token: 'keyword.operator', - regex: '(?:\\.{3}|\\s+\\?)' - }, { - token: 'keyword.variable', - regex: '(?:@+|::|\\.\\.)', - next: 'key' - }, { - token: 'keyword.operator', - regex: '\\.\\s*', - next: 'key' - }, { - token: 'string', - regex: '\\\\\\S[^\\s,;)}\\]]*' - }, { - token: 'string.doc', - regex: '\'\'\'', - next: 'qdoc' - }, { - token: 'string.doc', - regex: '"""', - next: 'qqdoc' - }, { - token: 'string', - regex: '\'', - next: 'qstring' - }, { - token: 'string', - regex: '"', - next: 'qqstring' - }, { - token: 'string', - regex: '`', - next: 'js' - }, { - token: 'string', - regex: '<\\[', - next: 'words' - }, { - token: 'string.regex', - regex: '//', - next: 'heregex' - }, { - token: 'string.regex', - regex: '\\/(?:[^[\\/\\n\\\\]*(?:(?:\\\\.|\\[[^\\]\\n\\\\]*(?:\\\\.[^\\]\\n\\\\]*)*\\])[^[\\/\\n\\\\]*)*)\\/[gimy$]{0,4}', - next: 'key' - }, { - token: 'constant.numeric', - regex: '(?:0x[\\da-fA-F][\\da-fA-F_]*|(?:[2-9]|[12]\\d|3[0-6])r[\\da-zA-Z][\\da-zA-Z_]*|(?:\\d[\\d_]*(?:\\.\\d[\\d_]*)?|\\.\\d[\\d_]*)(?:e[+-]?\\d[\\d_]*)?[\\w$]*)' - }, { - token: 'lparen', - regex: '[({[]' - }, { - token: 'rparen', - regex: '[)}\\]]', - next: 'key' - }, { - token: 'keyword.operator', - regex: '\\S+' - }, { - token: 'text', - regex: '\\s+' - } - ], - heregex: [ - { - token: 'string.regex', - regex: '.*?//[gimy$?]{0,4}', - next: 'start' - }, { - token: 'string.regex', - regex: '\\s*#{' - }, { - token: 'comment.regex', - regex: '\\s+(?:#.*)?' - }, { - token: 'string.regex', - regex: '\\S+' - } - ], - key: [ - { - token: 'keyword.operator', - regex: '[.?@!]+' - }, { - token: 'identifier', - regex: identifier, - next: 'start' - }, { - token: 'text', - regex: '', - next: 'start' - } - ], - comment: [ - { - token: 'comment.doc', - regex: '.*?\\*/', - next: 'start' - }, { - token: 'comment.doc', - regex: '.+' - } - ], - qdoc: [ - { - token: 'string', - regex: ".*?'''", - next: 'key' - }, stringfill - ], - qqdoc: [ - { - token: 'string', - regex: '.*?"""', - next: 'key' - }, stringfill - ], - qstring: [ - { - token: 'string', - regex: '[^\\\\\']*(?:\\\\.[^\\\\\']*)*\'', - next: 'key' - }, stringfill - ], - qqstring: [ - { - token: 'string', - regex: '[^\\\\"]*(?:\\\\.[^\\\\"]*)*"', - next: 'key' - }, stringfill - ], - js: [ - { - token: 'string', - regex: '[^\\\\`]*(?:\\\\.[^\\\\`]*)*`', - next: 'key' - }, stringfill - ], - words: [ - { - token: 'string', - regex: '.*?\\]>', - next: 'key' - }, stringfill - ] - }; - for (var idx in Rules) { - var r = Rules[idx]; - if (r.splice) { - for (var i = 0, len = r.length; i < len; ++i) { - var rr = r[i]; - if (typeof rr.regex === 'string') { - Rules[idx][i].regex = new RegExp('^' + rr.regex); - } - } - } else if (typeof rr.regex === 'string') { - Rules[idx].regex = new RegExp('^' + r.regex); - } - } - - CodeMirror.defineMIME('text/x-livescript', 'livescript'); - -}); diff --git a/lib/redactor/codemirror/mode/meta.js b/lib/redactor/codemirror/mode/meta.js new file mode 100644 index 0000000..615b6a5 --- /dev/null +++ b/lib/redactor/codemirror/mode/meta.js @@ -0,0 +1,217 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + CodeMirror.modeInfo = [ + {name: "APL", mime: "text/apl", mode: "apl", ext: ["dyalog", "apl"]}, + {name: "PGP", mimes: ["application/pgp", "application/pgp-encrypted", "application/pgp-keys", "application/pgp-signature"], mode: "asciiarmor", ext: ["asc", "pgp", "sig"]}, + {name: "ASN.1", mime: "text/x-ttcn-asn", mode: "asn.1", ext: ["asn", "asn1"]}, + {name: "Asterisk", mime: "text/x-asterisk", mode: "asterisk", file: /^extensions\.conf$/i}, + {name: "Brainfuck", mime: "text/x-brainfuck", mode: "brainfuck", ext: ["b", "bf"]}, + {name: "C", mime: "text/x-csrc", mode: "clike", ext: ["c", "h", "ino"]}, + {name: "C++", mime: "text/x-c++src", mode: "clike", ext: ["cpp", "c++", "cc", "cxx", "hpp", "h++", "hh", "hxx"], alias: ["cpp"]}, + {name: "Cobol", mime: "text/x-cobol", mode: "cobol", ext: ["cob", "cpy"]}, + {name: "C#", mime: "text/x-csharp", mode: "clike", ext: ["cs"], alias: ["csharp"]}, + {name: "Clojure", mime: "text/x-clojure", mode: "clojure", ext: ["clj", "cljc", "cljx"]}, + {name: "ClojureScript", mime: "text/x-clojurescript", mode: "clojure", ext: ["cljs"]}, + {name: "Closure Stylesheets (GSS)", mime: "text/x-gss", mode: "css", ext: ["gss"]}, + {name: "CMake", mime: "text/x-cmake", mode: "cmake", ext: ["cmake", "cmake.in"], file: /^CMakeLists.txt$/}, + {name: "CoffeeScript", mimes: ["application/vnd.coffeescript", "text/coffeescript", "text/x-coffeescript"], mode: "coffeescript", ext: ["coffee"], alias: ["coffee", "coffee-script"]}, + {name: "Common Lisp", mime: "text/x-common-lisp", mode: "commonlisp", ext: ["cl", "lisp", "el"], alias: ["lisp"]}, + {name: "Cypher", mime: "application/x-cypher-query", mode: "cypher", ext: ["cyp", "cypher"]}, + {name: "Cython", mime: "text/x-cython", mode: "python", ext: ["pyx", "pxd", "pxi"]}, + {name: "Crystal", mime: "text/x-crystal", mode: "crystal", ext: ["cr"]}, + {name: "CSS", mime: "text/css", mode: "css", ext: ["css"]}, + {name: "CQL", mime: "text/x-cassandra", mode: "sql", ext: ["cql"]}, + {name: "D", mime: "text/x-d", mode: "d", ext: ["d"]}, + {name: "Dart", mimes: ["application/dart", "text/x-dart"], mode: "dart", ext: ["dart"]}, + {name: "diff", mime: "text/x-diff", mode: "diff", ext: ["diff", "patch"]}, + {name: "Django", mime: "text/x-django", mode: "django"}, + {name: "Dockerfile", mime: "text/x-dockerfile", mode: "dockerfile", file: /^Dockerfile$/}, + {name: "DTD", mime: "application/xml-dtd", mode: "dtd", ext: ["dtd"]}, + {name: "Dylan", mime: "text/x-dylan", mode: "dylan", ext: ["dylan", "dyl", "intr"]}, + {name: "EBNF", mime: "text/x-ebnf", mode: "ebnf"}, + {name: "ECL", mime: "text/x-ecl", mode: "ecl", ext: ["ecl"]}, + {name: "edn", mime: "application/edn", mode: "clojure", ext: ["edn"]}, + {name: "Eiffel", mime: "text/x-eiffel", mode: "eiffel", ext: ["e"]}, + {name: "Elm", mime: "text/x-elm", mode: "elm", ext: ["elm"]}, + {name: "Embedded Javascript", mime: "application/x-ejs", mode: "htmlembedded", ext: ["ejs"]}, + {name: "Embedded Ruby", mime: "application/x-erb", mode: "htmlembedded", ext: ["erb"]}, + {name: "Erlang", mime: "text/x-erlang", mode: "erlang", ext: ["erl"]}, + {name: "Esper", mime: "text/x-esper", mode: "sql"}, + {name: "Factor", mime: "text/x-factor", mode: "factor", ext: ["factor"]}, + {name: "FCL", mime: "text/x-fcl", mode: "fcl"}, + {name: "Forth", mime: "text/x-forth", mode: "forth", ext: ["forth", "fth", "4th"]}, + {name: "Fortran", mime: "text/x-fortran", mode: "fortran", ext: ["f", "for", "f77", "f90"]}, + {name: "F#", mime: "text/x-fsharp", mode: "mllike", ext: ["fs"], alias: ["fsharp"]}, + {name: "Gas", mime: "text/x-gas", mode: "gas", ext: ["s"]}, + {name: "Gherkin", mime: "text/x-feature", mode: "gherkin", ext: ["feature"]}, + {name: "GitHub Flavored Markdown", mime: "text/x-gfm", mode: "gfm", file: /^(readme|contributing|history).md$/i}, + {name: "Go", mime: "text/x-go", mode: "go", ext: ["go"]}, + {name: "Groovy", mime: "text/x-groovy", mode: "groovy", ext: ["groovy", "gradle"], file: /^Jenkinsfile$/}, + {name: "HAML", mime: "text/x-haml", mode: "haml", ext: ["haml"]}, + {name: "Haskell", mime: "text/x-haskell", mode: "haskell", ext: ["hs"]}, + {name: "Haskell (Literate)", mime: "text/x-literate-haskell", mode: "haskell-literate", ext: ["lhs"]}, + {name: "Haxe", mime: "text/x-haxe", mode: "haxe", ext: ["hx"]}, + {name: "HXML", mime: "text/x-hxml", mode: "haxe", ext: ["hxml"]}, + {name: "ASP.NET", mime: "application/x-aspx", mode: "htmlembedded", ext: ["aspx"], alias: ["asp", "aspx"]}, + {name: "HTML", mime: "text/html", mode: "htmlmixed", ext: ["html", "htm", "handlebars", "hbs"], alias: ["xhtml"]}, + {name: "HTTP", mime: "message/http", mode: "http"}, + {name: "IDL", mime: "text/x-idl", mode: "idl", ext: ["pro"]}, + {name: "Pug", mime: "text/x-pug", mode: "pug", ext: ["jade", "pug"], alias: ["jade"]}, + {name: "Java", mime: "text/x-java", mode: "clike", ext: ["java"]}, + {name: "Java Server Pages", mime: "application/x-jsp", mode: "htmlembedded", ext: ["jsp"], alias: ["jsp"]}, + {name: "JavaScript", mimes: ["text/javascript", "text/ecmascript", "application/javascript", "application/x-javascript", "application/ecmascript"], + mode: "javascript", ext: ["js"], alias: ["ecmascript", "js", "node"]}, + {name: "JSON", mimes: ["application/json", "application/x-json"], mode: "javascript", ext: ["json", "map"], alias: ["json5"]}, + {name: "JSON-LD", mime: "application/ld+json", mode: "javascript", ext: ["jsonld"], alias: ["jsonld"]}, + {name: "JSX", mime: "text/jsx", mode: "jsx", ext: ["jsx"]}, + {name: "Jinja2", mime: "null", mode: "jinja2"}, + {name: "Julia", mime: "text/x-julia", mode: "julia", ext: ["jl"]}, + {name: "Kotlin", mime: "text/x-kotlin", mode: "clike", ext: ["kt"]}, + {name: "LESS", mime: "text/x-less", mode: "css", ext: ["less"]}, + {name: "LiveScript", mime: "text/x-livescript", mode: "livescript", ext: ["ls"], alias: ["ls"]}, + {name: "Lua", mime: "text/x-lua", mode: "lua", ext: ["lua"]}, + {name: "Markdown", mime: "text/x-markdown", mode: "markdown", ext: ["markdown", "md", "mkd"]}, + {name: "mIRC", mime: "text/mirc", mode: "mirc"}, + {name: "MariaDB SQL", mime: "text/x-mariadb", mode: "sql"}, + {name: "Mathematica", mime: "text/x-mathematica", mode: "mathematica", ext: ["m", "nb"]}, + {name: "Modelica", mime: "text/x-modelica", mode: "modelica", ext: ["mo"]}, + {name: "MUMPS", mime: "text/x-mumps", mode: "mumps", ext: ["mps"]}, + {name: "MS SQL", mime: "text/x-mssql", mode: "sql"}, + {name: "mbox", mime: "application/mbox", mode: "mbox", ext: ["mbox"]}, + {name: "MySQL", mime: "text/x-mysql", mode: "sql"}, + {name: "Nginx", mime: "text/x-nginx-conf", mode: "nginx", file: /nginx.*\.conf$/i}, + {name: "NSIS", mime: "text/x-nsis", mode: "nsis", ext: ["nsh", "nsi"]}, + {name: "NTriples", mimes: ["application/n-triples", "application/n-quads", "text/n-triples"], + mode: "ntriples", ext: ["nt", "nq"]}, + {name: "Objective-C", mime: "text/x-objectivec", mode: "clike", ext: ["m", "mm"], alias: ["objective-c", "objc"]}, + {name: "OCaml", mime: "text/x-ocaml", mode: "mllike", ext: ["ml", "mli", "mll", "mly"]}, + {name: "Octave", mime: "text/x-octave", mode: "octave", ext: ["m"]}, + {name: "Oz", mime: "text/x-oz", mode: "oz", ext: ["oz"]}, + {name: "Pascal", mime: "text/x-pascal", mode: "pascal", ext: ["p", "pas"]}, + {name: "PEG.js", mime: "null", mode: "pegjs", ext: ["jsonld"]}, + {name: "Perl", mime: "text/x-perl", mode: "perl", ext: ["pl", "pm"]}, + {name: "PHP", mimes: ["text/x-php", "application/x-httpd-php", "application/x-httpd-php-open"], mode: "php", ext: ["php", "php3", "php4", "php5", "php7", "phtml"]}, + {name: "Pig", mime: "text/x-pig", mode: "pig", ext: ["pig"]}, + {name: "Plain Text", mime: "text/plain", mode: "null", ext: ["txt", "text", "conf", "def", "list", "log"]}, + {name: "PLSQL", mime: "text/x-plsql", mode: "sql", ext: ["pls"]}, + {name: "PowerShell", mime: "application/x-powershell", mode: "powershell", ext: ["ps1", "psd1", "psm1"]}, + {name: "Properties files", mime: "text/x-properties", mode: "properties", ext: ["properties", "ini", "in"], alias: ["ini", "properties"]}, + {name: "ProtoBuf", mime: "text/x-protobuf", mode: "protobuf", ext: ["proto"]}, + {name: "Python", mime: "text/x-python", mode: "python", ext: ["BUILD", "bzl", "py", "pyw"], file: /^(BUCK|BUILD)$/}, + {name: "Puppet", mime: "text/x-puppet", mode: "puppet", ext: ["pp"]}, + {name: "Q", mime: "text/x-q", mode: "q", ext: ["q"]}, + {name: "R", mime: "text/x-rsrc", mode: "r", ext: ["r", "R"], alias: ["rscript"]}, + {name: "reStructuredText", mime: "text/x-rst", mode: "rst", ext: ["rst"], alias: ["rst"]}, + {name: "RPM Changes", mime: "text/x-rpm-changes", mode: "rpm"}, + {name: "RPM Spec", mime: "text/x-rpm-spec", mode: "rpm", ext: ["spec"]}, + {name: "Ruby", mime: "text/x-ruby", mode: "ruby", ext: ["rb"], alias: ["jruby", "macruby", "rake", "rb", "rbx"]}, + {name: "Rust", mime: "text/x-rustsrc", mode: "rust", ext: ["rs"]}, + {name: "SAS", mime: "text/x-sas", mode: "sas", ext: ["sas"]}, + {name: "Sass", mime: "text/x-sass", mode: "sass", ext: ["sass"]}, + {name: "Scala", mime: "text/x-scala", mode: "clike", ext: ["scala"]}, + {name: "Scheme", mime: "text/x-scheme", mode: "scheme", ext: ["scm", "ss"]}, + {name: "SCSS", mime: "text/x-scss", mode: "css", ext: ["scss"]}, + {name: "Shell", mimes: ["text/x-sh", "application/x-sh"], mode: "shell", ext: ["sh", "ksh", "bash"], alias: ["bash", "sh", "zsh"], file: /^PKGBUILD$/}, + {name: "Sieve", mime: "application/sieve", mode: "sieve", ext: ["siv", "sieve"]}, + {name: "Slim", mimes: ["text/x-slim", "application/x-slim"], mode: "slim", ext: ["slim"]}, + {name: "Smalltalk", mime: "text/x-stsrc", mode: "smalltalk", ext: ["st"]}, + {name: "Smarty", mime: "text/x-smarty", mode: "smarty", ext: ["tpl"]}, + {name: "Solr", mime: "text/x-solr", mode: "solr"}, + {name: "SML", mime: "text/x-sml", mode: "mllike", ext: ["sml", "sig", "fun", "smackspec"]}, + {name: "Soy", mime: "text/x-soy", mode: "soy", ext: ["soy"], alias: ["closure template"]}, + {name: "SPARQL", mime: "application/sparql-query", mode: "sparql", ext: ["rq", "sparql"], alias: ["sparul"]}, + {name: "Spreadsheet", mime: "text/x-spreadsheet", mode: "spreadsheet", alias: ["excel", "formula"]}, + {name: "SQL", mime: "text/x-sql", mode: "sql", ext: ["sql"]}, + {name: "SQLite", mime: "text/x-sqlite", mode: "sql"}, + {name: "Squirrel", mime: "text/x-squirrel", mode: "clike", ext: ["nut"]}, + {name: "Stylus", mime: "text/x-styl", mode: "stylus", ext: ["styl"]}, + {name: "Swift", mime: "text/x-swift", mode: "swift", ext: ["swift"]}, + {name: "sTeX", mime: "text/x-stex", mode: "stex"}, + {name: "LaTeX", mime: "text/x-latex", mode: "stex", ext: ["text", "ltx", "tex"], alias: ["tex"]}, + {name: "SystemVerilog", mime: "text/x-systemverilog", mode: "verilog", ext: ["v", "sv", "svh"]}, + {name: "Tcl", mime: "text/x-tcl", mode: "tcl", ext: ["tcl"]}, + {name: "Textile", mime: "text/x-textile", mode: "textile", ext: ["textile"]}, + {name: "TiddlyWiki ", mime: "text/x-tiddlywiki", mode: "tiddlywiki"}, + {name: "Tiki wiki", mime: "text/tiki", mode: "tiki"}, + {name: "TOML", mime: "text/x-toml", mode: "toml", ext: ["toml"]}, + {name: "Tornado", mime: "text/x-tornado", mode: "tornado"}, + {name: "troff", mime: "text/troff", mode: "troff", ext: ["1", "2", "3", "4", "5", "6", "7", "8", "9"]}, + {name: "TTCN", mime: "text/x-ttcn", mode: "ttcn", ext: ["ttcn", "ttcn3", "ttcnpp"]}, + {name: "TTCN_CFG", mime: "text/x-ttcn-cfg", mode: "ttcn-cfg", ext: ["cfg"]}, + {name: "Turtle", mime: "text/turtle", mode: "turtle", ext: ["ttl"]}, + {name: "TypeScript", mime: "application/typescript", mode: "javascript", ext: ["ts"], alias: ["ts"]}, + {name: "TypeScript-JSX", mime: "text/typescript-jsx", mode: "jsx", ext: ["tsx"], alias: ["tsx"]}, + {name: "Twig", mime: "text/x-twig", mode: "twig"}, + {name: "Web IDL", mime: "text/x-webidl", mode: "webidl", ext: ["webidl"]}, + {name: "VB.NET", mime: "text/x-vb", mode: "vb", ext: ["vb"]}, + {name: "VBScript", mime: "text/vbscript", mode: "vbscript", ext: ["vbs"]}, + {name: "Velocity", mime: "text/velocity", mode: "velocity", ext: ["vtl"]}, + {name: "Verilog", mime: "text/x-verilog", mode: "verilog", ext: ["v"]}, + {name: "VHDL", mime: "text/x-vhdl", mode: "vhdl", ext: ["vhd", "vhdl"]}, + {name: "Vue.js Component", mimes: ["script/x-vue", "text/x-vue"], mode: "vue", ext: ["vue"]}, + {name: "XML", mimes: ["application/xml", "text/xml"], mode: "xml", ext: ["xml", "xsl", "xsd", "svg"], alias: ["rss", "wsdl", "xsd"]}, + {name: "XQuery", mime: "application/xquery", mode: "xquery", ext: ["xy", "xquery"]}, + {name: "Yacas", mime: "text/x-yacas", mode: "yacas", ext: ["ys"]}, + {name: "YAML", mimes: ["text/x-yaml", "text/yaml"], mode: "yaml", ext: ["yaml", "yml"], alias: ["yml"]}, + {name: "Z80", mime: "text/x-z80", mode: "z80", ext: ["z80"]}, + {name: "mscgen", mime: "text/x-mscgen", mode: "mscgen", ext: ["mscgen", "mscin", "msc"]}, + {name: "xu", mime: "text/x-xu", mode: "mscgen", ext: ["xu"]}, + {name: "msgenny", mime: "text/x-msgenny", mode: "mscgen", ext: ["msgenny"]} + ]; + // Ensure all modes have a mime property for backwards compatibility + for (var i = 0; i < CodeMirror.modeInfo.length; i++) { + var info = CodeMirror.modeInfo[i]; + if (info.mimes) info.mime = info.mimes[0]; + } + + CodeMirror.findModeByMIME = function(mime) { + mime = mime.toLowerCase(); + for (var i = 0; i < CodeMirror.modeInfo.length; i++) { + var info = CodeMirror.modeInfo[i]; + if (info.mime == mime) return info; + if (info.mimes) for (var j = 0; j < info.mimes.length; j++) + if (info.mimes[j] == mime) return info; + } + if (/\+xml$/.test(mime)) return CodeMirror.findModeByMIME("application/xml") + if (/\+json$/.test(mime)) return CodeMirror.findModeByMIME("application/json") + }; + + CodeMirror.findModeByExtension = function(ext) { + for (var i = 0; i < CodeMirror.modeInfo.length; i++) { + var info = CodeMirror.modeInfo[i]; + if (info.ext) for (var j = 0; j < info.ext.length; j++) + if (info.ext[j] == ext) return info; + } + }; + + CodeMirror.findModeByFileName = function(filename) { + for (var i = 0; i < CodeMirror.modeInfo.length; i++) { + var info = CodeMirror.modeInfo[i]; + if (info.file && info.file.test(filename)) return info; + } + var dot = filename.lastIndexOf("."); + var ext = dot > -1 && filename.substring(dot + 1, filename.length); + if (ext) return CodeMirror.findModeByExtension(ext); + }; + + CodeMirror.findModeByName = function(name) { + name = name.toLowerCase(); + for (var i = 0; i < CodeMirror.modeInfo.length; i++) { + var info = CodeMirror.modeInfo[i]; + if (info.name.toLowerCase() == name) return info; + if (info.alias) for (var j = 0; j < info.alias.length; j++) + if (info.alias[j].toLowerCase() == name) return info; + } + }; +}); diff --git a/lib/redactor/codemirror/mode/php/index.html b/lib/redactor/codemirror/mode/php/index.html deleted file mode 100644 index adf6b1b..0000000 --- a/lib/redactor/codemirror/mode/php/index.html +++ /dev/null @@ -1,64 +0,0 @@ - - -CodeMirror: PHP mode - - - - - - - - - - - - - - - -
    -

    PHP mode

    -
    - - - -

    Simple HTML/PHP mode based on - the C-like mode. Depends on XML, - JavaScript, CSS, HTMLMixed, and C-like modes.

    - -

    MIME types defined: application/x-httpd-php (HTML with PHP code), text/x-php (plain, non-wrapped PHP code).

    -
    diff --git a/lib/redactor/codemirror/mode/php/test.js b/lib/redactor/codemirror/mode/php/test.js deleted file mode 100644 index e2ecefc..0000000 --- a/lib/redactor/codemirror/mode/php/test.js +++ /dev/null @@ -1,154 +0,0 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -(function() { - var mode = CodeMirror.getMode({indentUnit: 2}, "php"); - function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); } - - MT('simple_test', - '[meta ]'); - - MT('variable_interpolation_non_alphanumeric', - '[meta $/$\\$}$\\\"$:$;$?$|$[[$]]$+$=aaa"]', - '[meta ?>]'); - - MT('variable_interpolation_digits', - '[meta ]'); - - MT('variable_interpolation_simple_syntax_1', - '[meta ]'); - - MT('variable_interpolation_simple_syntax_2', - '[meta ]'); - - MT('variable_interpolation_simple_syntax_3', - '[meta [variable aaaaa][string .aaaaaa"];', - '[keyword echo] [string "aaa][variable-2 $aaaa][string ->][variable-2 $aaaaa][string .aaaaaa"];', - '[keyword echo] [string "aaa][variable-2 $aaaa]->[variable aaaaa][string [[2]].aaaaaa"];', - '[keyword echo] [string "aaa][variable-2 $aaaa]->[variable aaaaa][string ->aaaa2.aaaaaa"];', - '[meta ?>]'); - - MT('variable_interpolation_escaping', - '[meta aaa.aaa"];', - '[keyword echo] [string "aaa\\$aaaa[[2]]aaa.aaa"];', - '[keyword echo] [string "aaa\\$aaaa[[asd]]aaa.aaa"];', - '[keyword echo] [string "aaa{\\$aaaa->aaa.aaa"];', - '[keyword echo] [string "aaa{\\$aaaa[[2]]aaa.aaa"];', - '[keyword echo] [string "aaa{\\aaaaa[[asd]]aaa.aaa"];', - '[keyword echo] [string "aaa\\${aaaa->aaa.aaa"];', - '[keyword echo] [string "aaa\\${aaaa[[2]]aaa.aaa"];', - '[keyword echo] [string "aaa\\${aaaa[[asd]]aaa.aaa"];', - '[meta ?>]'); - - MT('variable_interpolation_complex_syntax_1', - '[meta aaa.aaa"];', - '[keyword echo] [string "aaa][variable-2 $]{[variable-2 $aaaa]}[string ->aaa.aaa"];', - '[keyword echo] [string "aaa][variable-2 $]{[variable-2 $aaaa][[',' [number 42]',']]}[string ->aaa.aaa"];', - '[keyword echo] [string "aaa][variable-2 $]{[variable aaaa][meta ?>]aaaaaa'); - - MT('variable_interpolation_complex_syntax_2', - '[meta } $aaaaaa.aaa"];', - '[keyword echo] [string "][variable-2 $]{[variable aaa][comment /*}?>*/][[',' [string "aaa][variable-2 $aaa][string {}][variable-2 $]{[variable aaa]}[string "]',']]}[string ->aaa.aaa"];', - '[keyword echo] [string "][variable-2 $]{[variable aaa][comment /*} } $aaa } */]}[string ->aaa.aaa"];'); - - - function build_recursive_monsters(nt, t, n){ - var monsters = [t]; - for (var i = 1; i <= n; ++i) - monsters[i] = nt.join(monsters[i - 1]); - return monsters; - } - - var m1 = build_recursive_monsters( - ['[string "][variable-2 $]{[variable aaa] [operator +] ', '}[string "]'], - '[comment /* }?>} */] [string "aaa][variable-2 $aaa][string .aaa"]', - 10 - ); - - MT('variable_interpolation_complex_syntax_3_1', - '[meta ]'); - - var m2 = build_recursive_monsters( - ['[string "a][variable-2 $]{[variable aaa] [operator +] ', ' [operator +] ', '}[string .a"]'], - '[comment /* }?>{{ */] [string "a?>}{{aa][variable-2 $aaa][string .a}a?>a"]', - 5 - ); - - MT('variable_interpolation_complex_syntax_3_2', - '[meta ]'); - - function build_recursive_monsters_2(mf1, mf2, nt, t, n){ - var monsters = [t]; - for (var i = 1; i <= n; ++i) - monsters[i] = nt[0] + mf1[i - 1] + nt[1] + mf2[i - 1] + nt[2] + monsters[i - 1] + nt[3]; - return monsters; - } - - var m3 = build_recursive_monsters_2( - m1, - m2, - ['[string "a][variable-2 $]{[variable aaa] [operator +] ', ' [operator +] ', ' [operator +] ', '}[string .a"]'], - '[comment /* }?>{{ */] [string "a?>}{{aa][variable-2 $aaa][string .a}a?>a"]', - 4 - ); - - MT('variable_interpolation_complex_syntax_3_3', - '[meta ]'); - - MT("variable_interpolation_heredoc", - "[meta - -CodeMirror: Smarty mode - - - - - - - - - - -
    -

    Smarty mode

    -
    - -

    Mode for Smarty version 2 or 3, which allows for custom delimiter tags.

    - -

    Several configuration parameters are supported:

    - -
      -
    • leftDelimiter and rightDelimiter, - which should be strings that determine where the Smarty syntax - starts and ends.
    • -
    • version, which should be 2 or 3.
    • -
    • baseMode, which can be a mode spec - like "text/html" to set a different background mode.
    • -
    - -

    MIME types defined: text/x-smarty

    - -

    Smarty 2, custom delimiters

    - -
    - -

    Smarty 3

    - - - - - -
    diff --git a/lib/redactor/codemirror/mode/smartymixed/smartymixed.js b/lib/redactor/codemirror/mode/smartymixed/smartymixed.js new file mode 100644 index 0000000..89e5a55 --- /dev/null +++ b/lib/redactor/codemirror/mode/smartymixed/smartymixed.js @@ -0,0 +1,173 @@ +/** +* @file smartymixed.js +* @brief Smarty Mixed Codemirror mode (Smarty + Mixed HTML) +* @author Ruslan Osmanov +* @version 3.0 +* @date 05.07.2013 +*/ +CodeMirror.defineMode("smartymixed", function(config) { + var settings, regs, helpers, parsers, + htmlMixedMode = CodeMirror.getMode(config, "htmlmixed"), + smartyMode = CodeMirror.getMode(config, "smarty"), + + settings = { + rightDelimiter: '}', + leftDelimiter: '{' + }; + + if (config.hasOwnProperty("leftDelimiter")) { + settings.leftDelimiter = config.leftDelimiter; + } + if (config.hasOwnProperty("rightDelimiter")) { + settings.rightDelimiter = config.rightDelimiter; + } + + regs = { + smartyComment: new RegExp("^" + settings.leftDelimiter + "\\*"), + literalOpen: new RegExp(settings.leftDelimiter + "literal" + settings.rightDelimiter), + literalClose: new RegExp(settings.leftDelimiter + "\/literal" + settings.rightDelimiter), + hasLeftDelimeter: new RegExp(".*" + settings.leftDelimiter), + htmlHasLeftDelimeter: new RegExp("[^<>]*" + settings.leftDelimiter) + }; + + helpers = { + chain: function(stream, state, parser) { + state.tokenize = parser; + return parser(stream, state); + }, + + cleanChain: function(stream, state, parser) { + state.tokenize = null; + state.localState = null; + state.localMode = null; + return (typeof parser == "string") ? (parser ? parser : null) : parser(stream, state); + }, + + maybeBackup: function(stream, pat, style) { + var cur = stream.current(); + var close = cur.search(pat), + m; + if (close > - 1) stream.backUp(cur.length - close); + else if (m = cur.match(/<\/?$/)) { + stream.backUp(cur.length); + if (!stream.match(pat, false)) stream.match(cur[0]); + } + return style; + } + }; + + parsers = { + html: function(stream, state) { + if (!state.inLiteral && stream.match(regs.htmlHasLeftDelimeter, false) && state.htmlMixedState.htmlState.tagName === null) { + state.tokenize = parsers.smarty; + state.localMode = smartyMode; + state.localState = smartyMode.startState(htmlMixedMode.indent(state.htmlMixedState, "")); + return helpers.maybeBackup(stream, settings.leftDelimiter, smartyMode.token(stream, state.localState)); + } else if (!state.inLiteral && stream.match(settings.leftDelimiter, false)) { + state.tokenize = parsers.smarty; + state.localMode = smartyMode; + state.localState = smartyMode.startState(htmlMixedMode.indent(state.htmlMixedState, "")); + return helpers.maybeBackup(stream, settings.leftDelimiter, smartyMode.token(stream, state.localState)); + } + return htmlMixedMode.token(stream, state.htmlMixedState); + }, + + smarty: function(stream, state) { + if (stream.match(settings.leftDelimiter, false)) { + if (stream.match(regs.smartyComment, false)) { + return helpers.chain(stream, state, parsers.inBlock("comment", "*" + settings.rightDelimiter)); + } + } else if (stream.match(settings.rightDelimiter, false)) { + stream.eat(settings.rightDelimiter); + state.tokenize = parsers.html; + state.localMode = htmlMixedMode; + state.localState = state.htmlMixedState; + return "tag"; + } + + return helpers.maybeBackup(stream, settings.rightDelimiter, smartyMode.token(stream, state.localState)); + }, + + inBlock: function(style, terminator) { + return function(stream, state) { + while (!stream.eol()) { + if (stream.match(terminator)) { + helpers.cleanChain(stream, state, ""); + break; + } + stream.next(); + } + return style; + }; + } + }; + + return { + startState: function() { + var state = htmlMixedMode.startState(); + return { + token: parsers.html, + localMode: null, + localState: null, + htmlMixedState: state, + tokenize: null, + inLiteral: false + }; + }, + + copyState: function(state) { + var local = null, tok = (state.tokenize || state.token); + if (state.localState) { + local = CodeMirror.copyState((tok != parsers.html ? smartyMode : htmlMixedMode), state.localState); + } + return { + token: state.token, + tokenize: state.tokenize, + localMode: state.localMode, + localState: local, + htmlMixedState: CodeMirror.copyState(htmlMixedMode, state.htmlMixedState), + inLiteral: state.inLiteral + }; + }, + + token: function(stream, state) { + if (stream.match(settings.leftDelimiter, false)) { + if (!state.inLiteral && stream.match(regs.literalOpen, true)) { + state.inLiteral = true; + return "keyword"; + } else if (state.inLiteral && stream.match(regs.literalClose, true)) { + state.inLiteral = false; + return "keyword"; + } + } + if (state.inLiteral && state.localState != state.htmlMixedState) { + state.tokenize = parsers.html; + state.localMode = htmlMixedMode; + state.localState = state.htmlMixedState; + } + + var style = (state.tokenize || state.token)(stream, state); + return style; + }, + + indent: function(state, textAfter) { + if (state.localMode == smartyMode + || (state.inLiteral && !state.localMode) + || regs.hasLeftDelimeter.test(textAfter)) { + return CodeMirror.Pass; + } + return htmlMixedMode.indent(state.htmlMixedState, textAfter); + }, + + innerMode: function(state) { + return { + state: state.localState || state.htmlMixedState, + mode: state.localMode || htmlMixedMode + }; + } + }; +}, +"htmlmixed"); + +CodeMirror.defineMIME("text/x-smarty", "smartymixed"); +// vim: et ts=2 sts=2 sw=2 \ No newline at end of file diff --git a/lib/redactor/codemirror/mode/sql/index.html b/lib/redactor/codemirror/mode/sql/index.html deleted file mode 100644 index b434f0f..0000000 --- a/lib/redactor/codemirror/mode/sql/index.html +++ /dev/null @@ -1,88 +0,0 @@ - - -CodeMirror: SQL Mode for CodeMirror - - - - - - - - - - - - -
    -

    SQL Mode for CodeMirror

    -
    - -
    -

    MIME types defined: - text/x-sql, - text/x-mysql, - text/x-mariadb, - text/x-cassandra, - text/x-plsql, - text/x-mssql, - text/x-hive, - text/x-pgsql, - text/x-gql, - text/x-gpsql. - text/x-esper. -

    - - -
    diff --git a/lib/redactor/codemirror/mode/sql/sql.js b/lib/redactor/codemirror/mode/sql/sql.js index da416f2..2010b1c 100644 --- a/lib/redactor/codemirror/mode/sql/sql.js +++ b/lib/redactor/codemirror/mode/sql/sql.js @@ -21,7 +21,8 @@ CodeMirror.defineMode("sql", function(config, parserConfig) { operatorChars = parserConfig.operatorChars || /^[*+\-%<>!=&|~^]/, support = parserConfig.support || {}, hooks = parserConfig.hooks || {}, - dateSQL = parserConfig.dateSQL || {"date" : true, "time" : true, "timestamp" : true}; + dateSQL = parserConfig.dateSQL || {"date" : true, "time" : true, "timestamp" : true}, + backslashStringEscapes = parserConfig.backslashStringEscapes !== false function tokenBase(stream, state) { var ch = stream.next(); @@ -125,7 +126,7 @@ CodeMirror.defineMode("sql", function(config, parserConfig) { state.tokenize = tokenBase; break; } - escaped = !escaped && ch == "\\"; + escaped = backslashStringEscapes && !escaped && ch == "\\"; } return "string"; }; @@ -292,6 +293,7 @@ CodeMirror.defineMode("sql", function(config, parserConfig) { builtin: set("bigint numeric bit smallint decimal smallmoney int tinyint money float real char varchar text nchar nvarchar ntext binary varbinary image cursor timestamp hierarchyid uniqueidentifier sql_variant xml table "), atoms: set("false true null unknown"), operatorChars: /^[*+\-%<>!=]/, + backslashStringEscapes: false, dateSQL: set("date datetimeoffset datetime2 smalldatetime datetime time"), hooks: { "@": hookVar @@ -400,7 +402,7 @@ CodeMirror.defineMode("sql", function(config, parserConfig) { name: "sql", client: set("source"), // https://www.postgresql.org/docs/10/static/sql-keywords-appendix.html - keywords: set(sqlKeywords + "a abort abs absent absolute access according action ada add admin after aggregate all allocate also always analyse analyze any are array array_agg array_max_cardinality asensitive assertion assignment asymmetric at atomic attribute attributes authorization avg backward base64 before begin begin_frame begin_partition bernoulli binary bit_length blob blocked bom both breadth c cache call called cardinality cascade cascaded case cast catalog catalog_name ceil ceiling chain characteristics characters character_length character_set_catalog character_set_name character_set_schema char_length check checkpoint class class_origin clob close cluster coalesce cobol collate collation collation_catalog collation_name collation_schema collect column columns column_name command_function command_function_code comment comments commit committed concurrently condition condition_number configuration conflict connect connection connection_name constraint constraints constraint_catalog constraint_name constraint_schema constructor contains content continue control conversion convert copy corr corresponding cost covar_pop covar_samp cross csv cube cume_dist current current_catalog current_date current_default_transform_group current_path current_role current_row current_schema current_time current_timestamp current_transform_group_for_type current_user cursor cursor_name cycle data database datalink datetime_interval_code datetime_interval_precision day db deallocate dec declare default defaults deferrable deferred defined definer degree delimiter delimiters dense_rank depth deref derived describe descriptor deterministic diagnostics dictionary disable discard disconnect dispatch dlnewcopy dlpreviouscopy dlurlcomplete dlurlcompleteonly dlurlcompletewrite dlurlpath dlurlpathonly dlurlpathwrite dlurlscheme dlurlserver dlvalue do document domain dynamic dynamic_function dynamic_function_code each element else empty enable encoding encrypted end end-exec end_frame end_partition enforced enum equals escape event every except exception exclude excluding exclusive exec execute exists exp explain expression extension external extract false family fetch file filter final first first_value flag float floor following for force foreign fortran forward found frame_row free freeze fs full function functions fusion g general generated get global go goto grant granted greatest grouping groups handler header hex hierarchy hold hour id identity if ignore ilike immediate immediately immutable implementation implicit import including increment indent index indexes indicator inherit inherits initially inline inner inout input insensitive instance instantiable instead integrity intersect intersection invoker isnull isolation k key key_member key_type label lag language large last last_value lateral lead leading leakproof least left length level library like_regex link listen ln load local localtime localtimestamp location locator lock locked logged lower m map mapping match matched materialized max maxvalue max_cardinality member merge message_length message_octet_length message_text method min minute minvalue mod mode modifies module month more move multiset mumps name names namespace national natural nchar nclob nesting new next nfc nfd nfkc nfkd nil no none normalize normalized nothing notify notnull nowait nth_value ntile null nullable nullif nulls number object occurrences_regex octets octet_length of off offset oids old only open operator option options ordering ordinality others out outer output over overlaps overlay overriding owned owner p pad parallel parameter parameter_mode parameter_name parameter_ordinal_position parameter_specific_catalog parameter_specific_name parameter_specific_schema parser partial partition pascal passing passthrough password percent percentile_cont percentile_disc percent_rank period permission placing plans pli policy portion position position_regex power precedes preceding prepare prepared preserve primary prior privileges procedural procedure program public quote range rank read reads reassign recheck recovery recursive ref references referencing refresh regr_avgx regr_avgy regr_count regr_intercept regr_r2 regr_slope regr_sxx regr_sxy regr_syy reindex relative release rename repeatable replace replica requiring reset respect restart restore restrict restricted result return returned_cardinality returned_length returned_octet_length returned_sqlstate returning returns revoke right role rollback rollup routine routine_catalog routine_name routine_schema row rows row_count row_number rule savepoint scale schema schema_name scope scope_catalog scope_name scope_schema scroll search second section security selective self sensitive sequence sequences serializable server server_name session session_user setof sets share show similar simple size skip snapshot some source space specific specifictype specific_name sql sqlcode sqlerror sqlexception sqlstate sqlwarning sqrt stable standalone start state statement static statistics stddev_pop stddev_samp stdin stdout storage strict strip structure style subclass_origin submultiset substring substring_regex succeeds sum symmetric sysid system system_time system_user t tables tablesample tablespace table_name temp template temporary then ties timezone_hour timezone_minute to token top_level_count trailing transaction transactions_committed transactions_rolled_back transaction_active transform transforms translate translate_regex translation treat trigger trigger_catalog trigger_name trigger_schema trim trim_array true truncate trusted type types uescape unbounded uncommitted under unencrypted unique unknown unlink unlisten unlogged unnamed unnest until untyped upper uri usage user user_defined_type_catalog user_defined_type_code user_defined_type_name user_defined_type_schema using vacuum valid validate validator value value_of varbinary variadic var_pop var_samp verbose version versioning view views volatile when whenever whitespace width_bucket window within work wrapper write xmlagg xmlattributes xmlbinary xmlcast xmlcomment xmlconcat xmldeclaration xmldocument xmlelement xmlexists xmlforest xmliterate xmlnamespaces xmlparse xmlpi xmlquery xmlroot xmlschema xmlserialize xmltable xmltext xmlvalidate year yes loop repeat attach path depends detach zone"), + keywords: set(sqlKeywords + "a abort abs absent absolute access according action ada add admin after aggregate all allocate also always analyse analyze any are array array_agg array_max_cardinality asensitive assertion assignment asymmetric at atomic attribute attributes authorization avg backward base64 before begin begin_frame begin_partition bernoulli binary bit_length blob blocked bom both breadth c cache call called cardinality cascade cascaded case cast catalog catalog_name ceil ceiling chain characteristics characters character_length character_set_catalog character_set_name character_set_schema char_length check checkpoint class class_origin clob close cluster coalesce cobol collate collation collation_catalog collation_name collation_schema collect column columns column_name command_function command_function_code comment comments commit committed concurrently condition condition_number configuration conflict connect connection connection_name constraint constraints constraint_catalog constraint_name constraint_schema constructor contains content continue control conversion convert copy corr corresponding cost covar_pop covar_samp cross csv cube cume_dist current current_catalog current_date current_default_transform_group current_path current_role current_row current_schema current_time current_timestamp current_transform_group_for_type current_user cursor cursor_name cycle data database datalink datetime_interval_code datetime_interval_precision day db deallocate dec declare default defaults deferrable deferred defined definer degree delimiter delimiters dense_rank depth deref derived describe descriptor deterministic diagnostics dictionary disable discard disconnect dispatch dlnewcopy dlpreviouscopy dlurlcomplete dlurlcompleteonly dlurlcompletewrite dlurlpath dlurlpathonly dlurlpathwrite dlurlscheme dlurlserver dlvalue do document domain dynamic dynamic_function dynamic_function_code each element else empty enable encoding encrypted end end-exec end_frame end_partition enforced enum equals escape event every except exception exclude excluding exclusive exec execute exists exp explain expression extension external extract false family fetch file filter final first first_value flag float floor following for force foreign fortran forward found frame_row free freeze fs full function functions fusion g general generated get global go goto grant granted greatest grouping groups handler header hex hierarchy hold hour id identity if ignore ilike immediate immediately immutable implementation implicit import including increment indent index indexes indicator inherit inherits initially inline inner inout input insensitive instance instantiable instead integrity intersect intersection invoker isnull isolation k key key_member key_type label lag language large last last_value lateral lc_collate lc_ctype lead leading leakproof least left length level library like_regex link listen ln load local localtime localtimestamp location locator lock locked logged lower m map mapping match matched materialized max maxvalue max_cardinality member merge message_length message_octet_length message_text method min minute minvalue mod mode modifies module month more move multiset mumps name names namespace national natural nchar nclob nesting new next nfc nfd nfkc nfkd nil no none normalize normalized nothing notify notnull nowait nth_value ntile null nullable nullif nulls number object occurrences_regex octets octet_length of off offset oids old only open operator option options ordering ordinality others out outer output over overlaps overlay overriding owned owner p pad parallel parameter parameter_mode parameter_name parameter_ordinal_position parameter_specific_catalog parameter_specific_name parameter_specific_schema parser partial partition pascal passing passthrough password percent percentile_cont percentile_disc percent_rank period permission placing plans pli policy portion position position_regex power precedes preceding prepare prepared preserve primary prior privileges procedural procedure program public quote range rank read reads reassign recheck recovery recursive ref references referencing refresh regr_avgx regr_avgy regr_count regr_intercept regr_r2 regr_slope regr_sxx regr_sxy regr_syy reindex relative release rename repeatable replace replica requiring reset respect restart restore restrict restricted result return returned_cardinality returned_length returned_octet_length returned_sqlstate returning returns revoke right role rollback rollup routine routine_catalog routine_name routine_schema row rows row_count row_number rule savepoint scale schema schema_name scope scope_catalog scope_name scope_schema scroll search second section security selective self sensitive sequence sequences serializable server server_name session session_user setof sets share show similar simple size skip snapshot some source space specific specifictype specific_name sql sqlcode sqlerror sqlexception sqlstate sqlwarning sqrt stable standalone start state statement static statistics stddev_pop stddev_samp stdin stdout storage strict strip structure style subclass_origin submultiset substring substring_regex succeeds sum symmetric sysid system system_time system_user t tables tablesample tablespace table_name temp template temporary then ties timezone_hour timezone_minute to token top_level_count trailing transaction transactions_committed transactions_rolled_back transaction_active transform transforms translate translate_regex translation treat trigger trigger_catalog trigger_name trigger_schema trim trim_array true truncate trusted type types uescape unbounded uncommitted under unencrypted unique unknown unlink unlisten unlogged unnamed unnest until untyped upper uri usage user user_defined_type_catalog user_defined_type_code user_defined_type_name user_defined_type_schema using vacuum valid validate validator value value_of varbinary variadic var_pop var_samp verbose version versioning view views volatile when whenever whitespace width_bucket window within work wrapper write xmlagg xmlattributes xmlbinary xmlcast xmlcomment xmlconcat xmldeclaration xmldocument xmlelement xmlexists xmlforest xmliterate xmlnamespaces xmlparse xmlpi xmlquery xmlroot xmlschema xmlserialize xmltable xmltext xmlvalidate year yes loop repeat attach path depends detach zone"), // https://www.postgresql.org/docs/10/static/datatype.html builtin: set("bigint int8 bigserial serial8 bit varying varbit boolean bool box bytea character char varchar cidr circle date double precision float8 inet integer int int4 interval json jsonb line lseg macaddr macaddr8 money numeric decimal path pg_lsn point polygon real float4 smallint int2 smallserial serial2 serial serial4 text time without zone with timetz timestamp timestamptz tsquery tsvector txid_snapshot uuid xml"), atoms: set("false true null unknown"), diff --git a/lib/redactor/codemirror/mode/xml/index.html b/lib/redactor/codemirror/mode/xml/index.html deleted file mode 100644 index c56b8b6..0000000 --- a/lib/redactor/codemirror/mode/xml/index.html +++ /dev/null @@ -1,61 +0,0 @@ - - -CodeMirror: XML mode - - - - - - - - - -
    -

    XML mode

    -
    - -

    The XML mode supports these configuration parameters:

    -
    -
    htmlMode (boolean)
    -
    This switches the mode to parse HTML instead of XML. This - means attributes do not have to be quoted, and some elements - (such as br) do not require a closing tag.
    -
    matchClosing (boolean)
    -
    Controls whether the mode checks that close tags match the - corresponding opening tag, and highlights mismatches as errors. - Defaults to true.
    -
    alignCDATA (boolean)
    -
    Setting this to true will force the opening tag of CDATA - blocks to not be indented.
    -
    - -

    MIME types defined: application/xml, text/html.

    -
    diff --git a/lib/redactor/codemirror/mode/xml/test.js b/lib/redactor/codemirror/mode/xml/test.js deleted file mode 100644 index f48156b..0000000 --- a/lib/redactor/codemirror/mode/xml/test.js +++ /dev/null @@ -1,51 +0,0 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -(function() { - var mode = CodeMirror.getMode({indentUnit: 2}, "xml"), mname = "xml"; - function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1), mname); } - - MT("matching", - "[tag&bracket <][tag top][tag&bracket >]", - " text", - " [tag&bracket <][tag inner][tag&bracket />]", - "[tag&bracket ]"); - - MT("nonmatching", - "[tag&bracket <][tag top][tag&bracket >]", - " [tag&bracket <][tag inner][tag&bracket />]", - " [tag&bracket ]"); - - MT("doctype", - "[meta ]", - "[tag&bracket <][tag top][tag&bracket />]"); - - MT("cdata", - "[tag&bracket <][tag top][tag&bracket >]", - " [atom ]", - "[tag&bracket ]"); - - // HTML tests - mode = CodeMirror.getMode({indentUnit: 2}, "text/html"); - - MT("selfclose", - "[tag&bracket <][tag html][tag&bracket >]", - " [tag&bracket <][tag link] [attribute rel]=[string stylesheet] [attribute href]=[string \"/foobar\"][tag&bracket >]", - "[tag&bracket ]"); - - MT("list", - "[tag&bracket <][tag ol][tag&bracket >]", - " [tag&bracket <][tag li][tag&bracket >]one", - " [tag&bracket <][tag li][tag&bracket >]two", - "[tag&bracket ]"); - - MT("valueless", - "[tag&bracket <][tag input] [attribute type]=[string checkbox] [attribute checked][tag&bracket />]"); - - MT("pThenArticle", - "[tag&bracket <][tag p][tag&bracket >]", - " foo", - "[tag&bracket <][tag article][tag&bracket >]bar"); - -})(); diff --git a/lib/redactor/codemirror/mode/xml/xml.js b/lib/redactor/codemirror/mode/xml/xml.js index f987a3a..0f1c9b1 100644 --- a/lib/redactor/codemirror/mode/xml/xml.js +++ b/lib/redactor/codemirror/mode/xml/xml.js @@ -52,6 +52,7 @@ var xmlConfig = { doNotIndent: {}, allowUnquoted: false, allowMissing: false, + allowMissingTagName: false, caseFold: false } @@ -226,6 +227,9 @@ CodeMirror.defineMode("xml", function(editorConf, config_) { state.tagName = stream.current(); setStyle = "tag"; return attrState; + } else if (config.allowMissingTagName && type == "endTag") { + setStyle = "tag bracket"; + return attrState(type, stream, state); } else { setStyle = "error"; return tagNameState; @@ -244,6 +248,9 @@ CodeMirror.defineMode("xml", function(editorConf, config_) { setStyle = "tag error"; return closeStateErr; } + } else if (config.allowMissingTagName && type == "endTag") { + setStyle = "tag bracket"; + return closeState(type, stream, state); } else { setStyle = "error"; return closeStateErr; diff --git a/lib/redactor/codemirror/theme/lucario.css b/lib/redactor/codemirror/theme/lucario.css new file mode 100644 index 0000000..17a1551 --- /dev/null +++ b/lib/redactor/codemirror/theme/lucario.css @@ -0,0 +1,37 @@ +/* + Name: lucario + Author: Raphael Amorim + + Original Lucario color scheme (https://github.com/raphamorim/lucario) +*/ + +.cm-s-lucario.CodeMirror, .cm-s-lucario .CodeMirror-gutters { + background-color: #2b3e50 !important; + color: #f8f8f2 !important; + border: none; +} +.cm-s-lucario .CodeMirror-gutters { color: #2b3e50; } +.cm-s-lucario .CodeMirror-cursor { border-left: solid thin #E6C845; } +.cm-s-lucario .CodeMirror-linenumber { color: #f8f8f2; } +.cm-s-lucario .CodeMirror-selected { background: #243443; } +.cm-s-lucario .CodeMirror-line::selection, .cm-s-lucario .CodeMirror-line > span::selection, .cm-s-lucario .CodeMirror-line > span > span::selection { background: #243443; } +.cm-s-lucario .CodeMirror-line::-moz-selection, .cm-s-lucario .CodeMirror-line > span::-moz-selection, .cm-s-lucario .CodeMirror-line > span > span::-moz-selection { background: #243443; } +.cm-s-lucario span.cm-comment { color: #5c98cd; } +.cm-s-lucario span.cm-string, .cm-s-lucario span.cm-string-2 { color: #E6DB74; } +.cm-s-lucario span.cm-number { color: #ca94ff; } +.cm-s-lucario span.cm-variable { color: #f8f8f2; } +.cm-s-lucario span.cm-variable-2 { color: #f8f8f2; } +.cm-s-lucario span.cm-def { color: #72C05D; } +.cm-s-lucario span.cm-operator { color: #66D9EF; } +.cm-s-lucario span.cm-keyword { color: #ff6541; } +.cm-s-lucario span.cm-atom { color: #bd93f9; } +.cm-s-lucario span.cm-meta { color: #f8f8f2; } +.cm-s-lucario span.cm-tag { color: #ff6541; } +.cm-s-lucario span.cm-attribute { color: #66D9EF; } +.cm-s-lucario span.cm-qualifier { color: #72C05D; } +.cm-s-lucario span.cm-property { color: #f8f8f2; } +.cm-s-lucario span.cm-builtin { color: #72C05D; } +.cm-s-lucario span.cm-variable-3, .cm-s-lucario span.cm-type { color: #ffb86c; } + +.cm-s-lucario .CodeMirror-activeline-background { background: #243443; } +.cm-s-lucario .CodeMirror-matchingbracket { text-decoration: underline; color: white !important; } diff --git a/lib/redactor/codemirror/theme/oceanic-next.css b/lib/redactor/codemirror/theme/oceanic-next.css new file mode 100644 index 0000000..296277b --- /dev/null +++ b/lib/redactor/codemirror/theme/oceanic-next.css @@ -0,0 +1,44 @@ +/* + + Name: oceanic-next + Author: Filype Pereira (https://github.com/fpereira1) + + Original oceanic-next color scheme by Dmitri Voronianski (https://github.com/voronianski/oceanic-next-color-scheme) + +*/ + +.cm-s-oceanic-next.CodeMirror { background: #304148; color: #f8f8f2; } +.cm-s-oceanic-next div.CodeMirror-selected { background: rgba(101, 115, 126, 0.33); } +.cm-s-oceanic-next .CodeMirror-line::selection, .cm-s-oceanic-next .CodeMirror-line > span::selection, .cm-s-oceanic-next .CodeMirror-line > span > span::selection { background: rgba(101, 115, 126, 0.33); } +.cm-s-oceanic-next .CodeMirror-line::-moz-selection, .cm-s-oceanic-next .CodeMirror-line > span::-moz-selection, .cm-s-oceanic-next .CodeMirror-line > span > span::-moz-selection { background: rgba(101, 115, 126, 0.33); } +.cm-s-oceanic-next .CodeMirror-gutters { background: #304148; border-right: 10px; } +.cm-s-oceanic-next .CodeMirror-guttermarker { color: white; } +.cm-s-oceanic-next .CodeMirror-guttermarker-subtle { color: #d0d0d0; } +.cm-s-oceanic-next .CodeMirror-linenumber { color: #d0d0d0; } +.cm-s-oceanic-next .CodeMirror-cursor { border-left: 1px solid #f8f8f0; } + +.cm-s-oceanic-next span.cm-comment { color: #65737E; } +.cm-s-oceanic-next span.cm-atom { color: #C594C5; } +.cm-s-oceanic-next span.cm-number { color: #F99157; } + +.cm-s-oceanic-next span.cm-property { color: #99C794; } +.cm-s-oceanic-next span.cm-attribute, +.cm-s-oceanic-next span.cm-keyword { color: #C594C5; } +.cm-s-oceanic-next span.cm-builtin { color: #66d9ef; } +.cm-s-oceanic-next span.cm-string { color: #99C794; } + +.cm-s-oceanic-next span.cm-variable, +.cm-s-oceanic-next span.cm-variable-2, +.cm-s-oceanic-next span.cm-variable-3 { color: #f8f8f2; } +.cm-s-oceanic-next span.cm-def { color: #6699CC; } +.cm-s-oceanic-next span.cm-bracket { color: #5FB3B3; } +.cm-s-oceanic-next span.cm-tag { color: #C594C5; } +.cm-s-oceanic-next span.cm-header { color: #C594C5; } +.cm-s-oceanic-next span.cm-link { color: #C594C5; } +.cm-s-oceanic-next span.cm-error { background: #C594C5; color: #f8f8f0; } + +.cm-s-oceanic-next .CodeMirror-activeline-background { background: rgba(101, 115, 126, 0.33); } +.cm-s-oceanic-next .CodeMirror-matchingbracket { + text-decoration: underline; + color: white !important; +} diff --git a/lib/redactor/codemirror/theme/shadowfox.css b/lib/redactor/codemirror/theme/shadowfox.css new file mode 100644 index 0000000..32d59b1 --- /dev/null +++ b/lib/redactor/codemirror/theme/shadowfox.css @@ -0,0 +1,52 @@ +/* + + Name: shadowfox + Author: overdodactyl (http://github.com/overdodactyl) + + Original shadowfox color scheme by Firefox + +*/ + +.cm-s-shadowfox.CodeMirror { background: #2a2a2e; color: #b1b1b3; } +.cm-s-shadowfox div.CodeMirror-selected { background: #353B48; } +.cm-s-shadowfox .CodeMirror-line::selection, .cm-s-shadowfox .CodeMirror-line > span::selection, .cm-s-shadowfox .CodeMirror-line > span > span::selection { background: #353B48; } +.cm-s-shadowfox .CodeMirror-line::-moz-selection, .cm-s-shadowfox .CodeMirror-line > span::-moz-selection, .cm-s-shadowfox .CodeMirror-line > span > span::-moz-selection { background: #353B48; } +.cm-s-shadowfox .CodeMirror-gutters { background: #0c0c0d ; border-right: 1px solid #0c0c0d; } +.cm-s-shadowfox .CodeMirror-guttermarker { color: #555; } +.cm-s-shadowfox .CodeMirror-linenumber { color: #939393; } +.cm-s-shadowfox .CodeMirror-cursor { border-left: 1px solid #fff; } + +.cm-s-shadowfox span.cm-comment { color: #939393; } +.cm-s-shadowfox span.cm-atom { color: #FF7DE9; } +.cm-s-shadowfox span.cm-quote { color: #FF7DE9; } +.cm-s-shadowfox span.cm-builtin { color: #FF7DE9; } +.cm-s-shadowfox span.cm-attribute { color: #FF7DE9; } +.cm-s-shadowfox span.cm-keyword { color: #FF7DE9; } +.cm-s-shadowfox span.cm-error { color: #FF7DE9; } + +.cm-s-shadowfox span.cm-number { color: #6B89FF; } +.cm-s-shadowfox span.cm-string { color: #6B89FF; } +.cm-s-shadowfox span.cm-string-2 { color: #6B89FF; } + +.cm-s-shadowfox span.cm-meta { color: #939393; } +.cm-s-shadowfox span.cm-hr { color: #939393; } + +.cm-s-shadowfox span.cm-header { color: #75BFFF; } +.cm-s-shadowfox span.cm-qualifier { color: #75BFFF; } +.cm-s-shadowfox span.cm-variable-2 { color: #75BFFF; } + +.cm-s-shadowfox span.cm-property { color: #86DE74; } + +.cm-s-shadowfox span.cm-def { color: #75BFFF; } +.cm-s-shadowfox span.cm-bracket { color: #75BFFF; } +.cm-s-shadowfox span.cm-tag { color: #75BFFF; } +.cm-s-shadowfox span.cm-link:visited { color: #75BFFF; } + +.cm-s-shadowfox span.cm-variable { color: #B98EFF; } +.cm-s-shadowfox span.cm-variable-3 { color: #d7d7db; } +.cm-s-shadowfox span.cm-link { color: #737373; } +.cm-s-shadowfox span.cm-operator { color: #b1b1b3; } +.cm-s-shadowfox span.cm-special { color: #d7d7db; } + +.cm-s-shadowfox .CodeMirror-activeline-background { background: rgba(185, 215, 253, .15) } +.cm-s-shadowfox .CodeMirror-matchingbracket { outline: solid 1px rgba(255, 255, 255, .25); color: white !important; } diff --git a/lib/redactor/codemirror/theme/solarized.css b/lib/redactor/codemirror/theme/solarized.css index d95f6c1..fcd1d70 100644 --- a/lib/redactor/codemirror/theme/solarized.css +++ b/lib/redactor/codemirror/theme/solarized.css @@ -87,7 +87,6 @@ http://ethanschoonover.com/solarized/img/solarized-palette.png text-decoration: underline; text-decoration-style: dotted; } -.cm-s-solarized .cm-strong { color: #eee; } .cm-s-solarized .cm-error, .cm-s-solarized .cm-invalidchar { color: #586e75; diff --git a/lib/redactor/elfinder/php/connector.php b/lib/redactor/elfinder/php/connector.php index ebeb560..d76550a 100644 --- a/lib/redactor/elfinder/php/connector.php +++ b/lib/redactor/elfinder/php/connector.php @@ -1,16 +1,19 @@ run(); - +$connector->run(); \ No newline at end of file diff --git a/robots.txt b/robots.txt index 3117a78..536fa08 100644 --- a/robots.txt +++ b/robots.txt @@ -1,18 +1,18 @@ User-Agent: * Disallow: /admin/ -Disallow: /backup/ -Disallow: /cache/ Disallow: /class/ +Disallow: /config/ Disallow: /fields/ Disallow: /functions/ Disallow: /inc/ Disallow: /lib/ #Disallow: /modules/ -Disallow: /session/ Disallow: /*?sysblock Disallow: /*?request +Disallow: /*?module Disallow: /*index.php?module #Disallow: /templates/ +Disallow: /tmp/ # #Sitemap: http://site.com/sitemap.xml #Host: site.com \ No newline at end of file diff --git a/backup/.htaccess b/tmp/.htaccess similarity index 100% rename from backup/.htaccess rename to tmp/.htaccess diff --git a/cache/.htaccess b/tmp/attachments/.htaccess similarity index 100% rename from cache/.htaccess rename to tmp/attachments/.htaccess diff --git a/cache/attachments/.htaccess b/tmp/backup/.htaccess similarity index 100% rename from cache/attachments/.htaccess rename to tmp/backup/.htaccess diff --git a/cache/combine/.htaccess b/tmp/cache/.htaccess similarity index 100% rename from cache/combine/.htaccess rename to tmp/cache/.htaccess diff --git a/cache/module/.htaccess b/tmp/cache/combine/.htaccess similarity index 100% rename from cache/module/.htaccess rename to tmp/cache/combine/.htaccess diff --git a/cache/redactor/.htaccess b/tmp/cache/module/.htaccess similarity index 100% rename from cache/redactor/.htaccess rename to tmp/cache/module/.htaccess diff --git a/cache/smarty/.htaccess b/tmp/cache/redactor/.htaccess similarity index 100% rename from cache/smarty/.htaccess rename to tmp/cache/redactor/.htaccess diff --git a/cache/redactor/log.txt b/tmp/cache/redactor/log.txt similarity index 100% rename from cache/redactor/log.txt rename to tmp/cache/redactor/log.txt diff --git a/cache/sql/.htaccess b/tmp/cache/smarty/.htaccess similarity index 100% rename from cache/sql/.htaccess rename to tmp/cache/smarty/.htaccess diff --git a/cache/tpl/.htaccess b/tmp/cache/sql/.htaccess similarity index 100% rename from cache/tpl/.htaccess rename to tmp/cache/sql/.htaccess diff --git a/session/.htaccess b/tmp/cache/templates/.htaccess similarity index 100% rename from session/.htaccess rename to tmp/cache/templates/.htaccess diff --git a/tmp/cache/tpl/.htaccess b/tmp/cache/tpl/.htaccess new file mode 100644 index 0000000..14249c5 --- /dev/null +++ b/tmp/cache/tpl/.htaccess @@ -0,0 +1 @@ +Deny from all \ No newline at end of file diff --git a/tmp/logs/.htaccess b/tmp/logs/.htaccess new file mode 100644 index 0000000..14249c5 --- /dev/null +++ b/tmp/logs/.htaccess @@ -0,0 +1 @@ +Deny from all \ No newline at end of file diff --git a/tmp/session/.htaccess b/tmp/session/.htaccess new file mode 100644 index 0000000..14249c5 --- /dev/null +++ b/tmp/session/.htaccess @@ -0,0 +1 @@ +Deny from all \ No newline at end of file diff --git a/tmp/update/.htaccess b/tmp/update/.htaccess new file mode 100644 index 0000000..14249c5 --- /dev/null +++ b/tmp/update/.htaccess @@ -0,0 +1 @@ +Deny from all \ No newline at end of file diff --git a/uploads/images/noimage.gif b/uploads/images/noimage.gif deleted file mode 100644 index 36ced75..0000000 Binary files a/uploads/images/noimage.gif and /dev/null differ diff --git a/uploads/images/noimage.png b/uploads/images/noimage.png new file mode 100644 index 0000000..79eb521 Binary files /dev/null and b/uploads/images/noimage.png differ