Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Mahmood Reza Sajjadi 2014-02-13 15:17:40 +03:30
commit f70b40f112
152 changed files with 4719 additions and 4683 deletions

8
.gitignore vendored
View File

@ -1,4 +1,3 @@
src/.idea/workspace.xml
src/mibew/install/package
src/absent_*
src/release*
@ -15,3 +14,10 @@ src/mibew/plugins/*
src/mibew/locales/*
!src/mibew/locales/en/
!src/mibew/locales/names/
# Do not index composer files
src/composer.phar
src/composer.lock
# Do not index third-party libraries
src/mibew/vendor

View File

@ -1 +0,0 @@
messenger

View File

@ -1,31 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectCodeStyleSettingsManager">
<option name="PER_PROJECT_SETTINGS">
<value>
<option name="OTHER_INDENT_OPTIONS">
<value>
<option name="INDENT_SIZE" value="4" />
<option name="CONTINUATION_INDENT_SIZE" value="8" />
<option name="TAB_SIZE" value="4" />
<option name="USE_TAB_CHARACTER" value="true" />
<option name="SMART_TABS" value="false" />
<option name="LABEL_INDENT_SIZE" value="0" />
<option name="LABEL_INDENT_ABSOLUTE" value="false" />
<option name="USE_RELATIVE_INDENTS" value="false" />
</value>
</option>
<XML>
<option name="XML_LEGACY_SETTINGS_IMPORTED" value="true" />
</XML>
<codeStyleSettings language="PHP">
<indentOptions>
<option name="USE_TAB_CHARACTER" value="true" />
</indentOptions>
</codeStyleSettings>
</value>
</option>
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
</component>
</project>

View File

@ -1,13 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding" useUTFGuessing="true" native2AsciiForPropertiesFiles="false">
<file url="file://$PROJECT_DIR$" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/mibew/locales/be/properties" charset="windows-1251" />
<file url="file://$PROJECT_DIR$/mibew/locales/bg/properties" charset="windows-1251" />
<file url="file://$PROJECT_DIR$/mibew/locales/ca/properties" charset="ISO-8859-1" />
<file url="file://$PROJECT_DIR$/mibew/locales/ru/properties" charset="windows-1251" />
<file url="file://$PROJECT_DIR$/mibew/locales/sp/properties" charset="ISO-8859-1" />
<file url="file://$PROJECT_DIR$/mibew/locales/ua/properties" charset="windows-1251" />
</component>
</project>

View File

@ -1,11 +0,0 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0" is_locked="false">
<option name="myName" value="Project Default" />
<option name="myLocal" value="false" />
<inspection_tool class="SpellCheckingInspection" enabled="false" level="TYPO" enabled_by_default="false">
<option name="processCode" value="true" />
<option name="processLiterals" value="true" />
<option name="processComments" value="true" />
</inspection_tool>
</profile>
</component>

View File

@ -1,7 +0,0 @@
<component name="InspectionProjectProfileManager">
<settings>
<option name="PROJECT_PROFILE" value="Project Default" />
<option name="USE_PROJECT_PROFILE" value="true" />
<version value="1.0" />
</settings>
</component>

View File

@ -1,15 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module-library">
<library name="PHP">
<CLASSES />
<SOURCES />
</library>
</orderEntry>
</component>
</module>

View File

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectResources">
<default-html-doctype>http://www.w3.org/1999/xhtml</default-html-doctype>
</component>
<component name="ProjectRootManager" version="2" />
</project>

View File

@ -1,9 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/messenger.iml" filepath="$PROJECT_DIR$/.idea/messenger.iml" />
</modules>
</component>
</project>

View File

@ -1,80 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CodeStyleSettingsManager">
<option name="PER_PROJECT_SETTINGS">
<value>
<ADDITIONAL_INDENT_OPTIONS fileType="js">
<option name="INDENT_SIZE" value="4" />
<option name="CONTINUATION_INDENT_SIZE" value="8" />
<option name="TAB_SIZE" value="4" />
<option name="USE_TAB_CHARACTER" value="false" />
<option name="SMART_TABS" value="false" />
<option name="LABEL_INDENT_SIZE" value="0" />
<option name="LABEL_INDENT_ABSOLUTE" value="false" />
<option name="USE_RELATIVE_INDENTS" value="false" />
</ADDITIONAL_INDENT_OPTIONS>
<ADDITIONAL_INDENT_OPTIONS fileType="jsp">
<option name="INDENT_SIZE" value="4" />
<option name="CONTINUATION_INDENT_SIZE" value="8" />
<option name="TAB_SIZE" value="4" />
<option name="USE_TAB_CHARACTER" value="false" />
<option name="SMART_TABS" value="false" />
<option name="LABEL_INDENT_SIZE" value="0" />
<option name="LABEL_INDENT_ABSOLUTE" value="false" />
<option name="USE_RELATIVE_INDENTS" value="false" />
</ADDITIONAL_INDENT_OPTIONS>
<ADDITIONAL_INDENT_OPTIONS fileType="php">
<option name="INDENT_SIZE" value="4" />
<option name="CONTINUATION_INDENT_SIZE" value="8" />
<option name="TAB_SIZE" value="4" />
<option name="USE_TAB_CHARACTER" value="false" />
<option name="SMART_TABS" value="false" />
<option name="LABEL_INDENT_SIZE" value="0" />
<option name="LABEL_INDENT_ABSOLUTE" value="false" />
<option name="USE_RELATIVE_INDENTS" value="false" />
</ADDITIONAL_INDENT_OPTIONS>
<ADDITIONAL_INDENT_OPTIONS fileType="sass">
<option name="INDENT_SIZE" value="2" />
<option name="CONTINUATION_INDENT_SIZE" value="8" />
<option name="TAB_SIZE" value="4" />
<option name="USE_TAB_CHARACTER" value="false" />
<option name="SMART_TABS" value="false" />
<option name="LABEL_INDENT_SIZE" value="0" />
<option name="LABEL_INDENT_ABSOLUTE" value="false" />
<option name="USE_RELATIVE_INDENTS" value="false" />
</ADDITIONAL_INDENT_OPTIONS>
<ADDITIONAL_INDENT_OPTIONS fileType="sql">
<option name="INDENT_SIZE" value="2" />
<option name="CONTINUATION_INDENT_SIZE" value="8" />
<option name="TAB_SIZE" value="4" />
<option name="USE_TAB_CHARACTER" value="false" />
<option name="SMART_TABS" value="false" />
<option name="LABEL_INDENT_SIZE" value="0" />
<option name="LABEL_INDENT_ABSOLUTE" value="false" />
<option name="USE_RELATIVE_INDENTS" value="false" />
</ADDITIONAL_INDENT_OPTIONS>
<ADDITIONAL_INDENT_OPTIONS fileType="xml">
<option name="INDENT_SIZE" value="4" />
<option name="CONTINUATION_INDENT_SIZE" value="8" />
<option name="TAB_SIZE" value="4" />
<option name="USE_TAB_CHARACTER" value="false" />
<option name="SMART_TABS" value="false" />
<option name="LABEL_INDENT_SIZE" value="0" />
<option name="LABEL_INDENT_ABSOLUTE" value="false" />
<option name="USE_RELATIVE_INDENTS" value="false" />
</ADDITIONAL_INDENT_OPTIONS>
<ADDITIONAL_INDENT_OPTIONS fileType="yml">
<option name="INDENT_SIZE" value="2" />
<option name="CONTINUATION_INDENT_SIZE" value="8" />
<option name="TAB_SIZE" value="4" />
<option name="USE_TAB_CHARACTER" value="false" />
<option name="SMART_TABS" value="false" />
<option name="LABEL_INDENT_SIZE" value="0" />
<option name="LABEL_INDENT_ABSOLUTE" value="false" />
<option name="USE_RELATIVE_INDENTS" value="false" />
</ADDITIONAL_INDENT_OPTIONS>
</value>
</option>
</component>
</project>

View File

@ -1,5 +0,0 @@
<component name="DependencyValidationManager">
<state>
<option name="SKIP_IMPORT_STATEMENTS" value="false" />
</state>
</component>

View File

@ -1,7 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$/../.." vcs="Git" />
</component>
</project>

View File

@ -5,11 +5,12 @@
<property name="closure.c" value="/opt/closure/compiler.jar" />
<property name="handlebars" value="handlebars" />
<property name="dialogs_styles_path" value="${mibew_path}/styles/dialogs" />
<property name="pages_styles_path" value="${mibew_path}/styles/pages" />
<property name="js_path" value="${mibew_path}/js" />
<!-- Compile Handlebars templates for dialogs styles -->
<target name="styles_handlebars" description="Compile Handlebars templates for dialogs styles">
<target name="dialogs_handlebars" description="Compile Handlebars templates for dialogs styles">
<echo>Flatten templates directory structure</echo>
<!-- Use system 'mkdir' instead of ant 'mkdir' task because it do not
@ -98,6 +99,73 @@
<echo>Done</echo>
</target>
<!-- Compile Handlebars templates for pages styles -->
<target name="pages_handlebars" description="Compile Handlebars templates for pages styles">
<!-- Compile applications templates -->
<apply executable="${handlebars}">
<arg value="-f"/>
<targetfile />
<dirset dir=".">
<include name="${pages_styles_path}/*/templates_src/client_side/*" />
</dirset>
<mapper
type="regexp"
from="^(.*)/templates_src/client_side/(.*)$$"
to="\1/templates_compiled/client_side/\2_app_tmp.tpl.js"
/>
</apply>
<!-- Use closule compiler instead of handlebars minifyer (-m flag)
because of handlebars does not insert line breaks.
Very long lines are cutted by ant and this brings problems -->
<apply executable="java">
<arg value="-jar" />
<arg value="${closure.c}" />
<arg value="--js" />
<srcfile />
<arg value="--js_output_file" />
<targetfile />
<fileset dir=".">
<include name="${pages_styles_path}/*/templates_compiled/client_side/*_app_tmp.tpl.js" />
</fileset>
<mapper type="glob" from="*_app_tmp.tpl.js" to="*_app_tmp.c.tpl.js" />
</apply>
<!-- Add license info. Use move because of it is the best way to append
some info to files -->
<move todir="${pages_styles_path}" overwrite="true">
<fileset dir="${pages_styles_path}">
<include name="*/templates_compiled/client_side/*_tmp.c.tpl.js" />
</fileset>
<!--<mapper type="glob" from="*/templates_compiled/client_side/*_tmp.c.tpl.js" to="*.tpl.js"/>-->
<mapper type="glob" from="*_tmp.c.tpl.js" to="*.tpl.js"/>
<filterchain>
<!-- Add header -->
<concatfilter prepend="tools/compiled_templates_header.txt" />
<!-- Skip empty lines -->
<linecontainsregexp negate="true">
<regexp pattern="^\s+$$" />
</linecontainsregexp>
</filterchain>
</move>
<!-- Remove all temporary files. -->
<delete>
<fileset dir="${pages_styles_path}">
<include name="*/templates_compiled/client_side/*_tmp.tpl.js" />
</fileset>
</delete>
<echo>Done</echo>
</target>
<!-- Compile Handlebars templates for all styles (both dialogs and pages) -->
<target name="styles_handlebars" depends="pages_handlebars,dialogs_handlebars" description="Compile Handlebars templates for all styles">
<echo>Handlebars templates from all styles are built.</echo>
</target>
<!-- Compile and concatenate JavaScript files for dialog styles -->
<target name="styles_js" description="Compile JavaScript files for all dialogs styles">
@ -156,7 +224,7 @@
<!-- Build all stuff related to dialogs styles -->
<target name="styles_all" depends="styles_handlebars,styles_js" description="Run styles_handlebars and styles_js targets">
<echo>Dialogs styles built.</echo>
<echo>Styles built.</echo>
</target>
@ -192,7 +260,7 @@
<!-- Build JavaScript application -->
<target name="app_js" depends="core_handlebars">
<target name="app_js">
<echo>Build "${app_name}" JavaScript application</echo>
<!-- Remove old application file -->
@ -200,9 +268,6 @@
<!-- Append application files to the result file -->
<concat destfile="${js_path}/compiled/${app_name}_app.js" eol="lf">
<!-- Append templates -->
<filelist dir="${js_path}/templates/compiled" files="${app_name}_app.tpl.js" />
<!-- Append application static initialization code -->
<filelist dir="${js_path}/compiled/${app_name}" files="init.js" />
@ -353,74 +418,6 @@
</target>
<!-- Compile Handlebars templates of the Core -->
<target name="core_handlebars" description="Compile Handlebars templates of the Core">
<echo>Compile Handlebars templates of the Core</echo>
<!-- Compile applications templates -->
<apply executable="${handlebars}">
<arg value="-f"/>
<targetfile />
<dirset dir=".">
<include name="${js_path}/templates/source/*" />
</dirset>
<mapper type="regexp" from="^(.*)/source/(.*)$$" to="\1/compiled/\2_app_tmp.tpl.js" />
</apply>
<!-- Build misc files -->
<apply executable="${handlebars}">
<arg value="-f"/>
<targetfile />
<fileset dir=".">
<include name="${js_path}/templates/source/*.handlebars" />
</fileset>
<mapper type="regexp" from="^(.*)/source/(.*)\.handlebars$$" to="\1/compiled/\2_tmp.tpl.js" />
</apply>
<!-- Use closule compiler instead of handlebars minifyer (-m flag)
because of handlebars not insert line breaks.
Very long lines are cutted by ant and this brings problems -->
<apply executable="java">
<arg value="-jar" />
<arg value="${closure.c}" />
<arg value="--js" />
<srcfile />
<arg value="--js_output_file" />
<targetfile />
<fileset dir=".">
<include name="${js_path}/templates/compiled/*_app_tmp.tpl.js" />
</fileset>
<mapper type="glob" from="*_app_tmp.tpl.js" to="*_app_tmp.c.tpl.js" />
</apply>
<!-- Add license info. Use move because of it is the best way to append
some info to files -->
<move todir="${js_path}/templates/compiled" overwrite="true">
<fileset dir="${js_path}/templates/compiled">
<include name="*_tmp.c.tpl.js" />
</fileset>
<mapper type="glob" from="*_tmp.c.tpl.js" to="*.tpl.js"/>
<filterchain>
<!-- Add header -->
<concatfilter prepend="tools/compiled_templates_header.txt" />
<!-- Skip empty lines -->
<linecontainsregexp negate="true">
<regexp pattern="^\s+$$" />
</linecontainsregexp>
</filterchain>
</move>
<!-- Remove all temporary files. -->
<delete>
<fileset dir="${js_path}/templates/compiled">
<include name="*_tmp.tpl.js" />
</fileset>
</delete>
<echo>Done</echo>
</target>
<!-- Build all project -->
<target name="all" depends="chat_app_js,thread_log_app_js,users_app_js,styles_all" description="Build everything">
<echo>Mibew Messenger built.</echo>

8
src/composer.json Normal file
View File

@ -0,0 +1,8 @@
{
"require": {
"xamin/handlebars.php": "dev-master#5b188ce19e9b07170238c82bd34051a31bdeebbf"
},
"config": {
"vendor-dir": "mibew/vendor"
}
}

View File

@ -33,7 +33,8 @@ if ($referer && isset($_SESSION['threadid'])) {
$msg = getstring2_(
"chat.client.visited.page",
array($referer),
$thread->locale
$thread->locale,
true
);
$thread->postMessage(Thread::KIND_FOR_AGENT, $msg);
}

View File

@ -34,6 +34,9 @@ require_once(MIBEW_FS_ROOT.'/libs/config.php');
*/
define('MIBEW_CONFIG_WEB_ROOT', $mibewroot);
// Initialize external dependencies
require_once(MIBEW_FS_ROOT . '/vendor/autoload.php');
// Try to get actual base URL of the Mibew
$requestUri = $_SERVER["REQUEST_URI"];
if (!preg_match('/^(.*)\\/install(\\/[^\\/\\\\]*)?$/', $requestUri, $matches)) {
@ -55,8 +58,9 @@ require_once(MIBEW_FS_ROOT.'/libs/common/misc.php');
require_once(MIBEW_FS_ROOT.'/libs/common/response.php');
require_once(MIBEW_FS_ROOT.'/libs/common/string.php');
require_once(MIBEW_FS_ROOT.'/libs/classes/Mibew/Style/StyleInterface.php');
require_once(MIBEW_FS_ROOT.'/libs/classes/Mibew/Style/Style.php');
require_once(MIBEW_FS_ROOT.'/libs/classes/Mibew/Style/AbstractStyle.php');
require_once(MIBEW_FS_ROOT.'/libs/classes/Mibew/Style/PageStyle.php');
require_once(MIBEW_FS_ROOT.'/libs/classes/Mibew/Handlebars/HelpersSet.php');
// Include database structure
require_once(MIBEW_FS_ROOT.'/install/dbinfo.php');

View File

@ -1,13 +1,3 @@
/*
Copyright 2005-2013 the original author or authors.
Licensed under the Apache License, Version 2.0 (the "License").
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
*/
(function(){var k=Handlebars.template,l=Handlebars.templates=Handlebars.templates||{};l.default_control=k(function(a,b,e,h,f){this.compilerInfo=[4,">= 1.0.0"];e=this.merge(e,a.helpers);f=f||{};h=this.escapeExpression;a="<strong>";(e=e.title)?e=e.call(b,{hash:{},data:f}):(e=b.title,e="function"===typeof e?e.apply(b):e);return a+=h(e)+"</strong>"});l.message=k(function(a,b,e,h,f){this.compilerInfo=[4,">= 1.0.0"];e=this.merge(e,a.helpers);f=f||{};var c,g=this.escapeExpression,j=e.helperMissing;a={hash:{},
data:f};a="<span>"+(g((c=e.formatTime||b.formatTime,c?c.call(b,b.created,a):j.call(b,"formatTime",b.created,a)))+"</span>\n");if((c=e["if"].call(b,b.name,{hash:{},inverse:this.noop,fn:this.program(1,function(a,c){var b,d;b="<span class='n";(d=e.kindName)?d=d.call(a,{hash:{},data:c}):(d=a.kindName,d="function"===typeof d?d.apply(a):d);b+=g(d)+"'>";(d=e.name)?d=d.call(a,{hash:{},data:c}):(d=a.name,d="function"===typeof d?d.apply(a):d);return b+=g(d)+"</span>: "},f),data:f}))||0===c)a+=c;a+="\n<span class='m";
(c=e.kindName)?c=c.call(b,{hash:{},data:f}):(c=b.kindName,c="function"===typeof c?c.apply(b):c);a+=g(c)+"'>";if((c=e["if"].call(b,b.allowFormatting,{hash:{},inverse:this.program(5,function(a,b){var c,d;d={hash:{},data:b};return g((c=e.apply||a.apply,c?c.call(a,a.message,"urlReplace, nl2br",d):j.call(a,"apply",a.message,"urlReplace, nl2br",d)))},f),fn:this.program(3,function(a,c){var b,d;d={hash:{},data:c};return g((b=e.apply||a.apply,b?b.call(a,a.message,"urlReplace, nl2br, allowTags",d):j.call(a,
"apply",a.message,"urlReplace, nl2br, allowTags",d)))},f),data:f}))||0===c)a+=c;return a+="</span><br/>"})})();
/*
Copyright 2005-2013 the original author or authors.
Licensed under the Apache License, Version 2.0 (the "License").

View File

@ -1,37 +1,3 @@
/*
Copyright 2005-2013 the original author or authors.
Licensed under the Apache License, Version 2.0 (the "License").
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
*/
(function(){var l=Handlebars.template,m=Handlebars.templates=Handlebars.templates||{};m.agent=l(function(c,b,e,a,d){this.compilerInfo=[4,">= 1.0.0"];e=this.merge(e,c.helpers);d=d||{};var f=e.helperMissing,h=this.escapeExpression;c='<span class="agent-status-';if((a=e["if"].call(b,b.away,{hash:{},inverse:this.program(3,function(){return"online"},d),fn:this.program(1,function(){return"away"},d),data:d}))||0===a)c+=a;c+=' inline-block" title="';if((a=e["if"].call(b,b.away,{hash:{},inverse:this.program(7,
function(a,c){var b,g;g={hash:{},data:c};return h((b=e.L10n||a.L10n,b?b.call(a,"pending.status.online",g):f.call(a,"L10n","pending.status.online",g)))},d),fn:this.program(5,function(a,c){var b,g;g={hash:{},data:c};return h((b=e.L10n||a.L10n,b?b.call(a,"pending.status.away",g):f.call(a,"L10n","pending.status.away",g)))},d),data:d}))||0===a)c+=a;c+='"></span>';(a=e.name)?a=a.call(b,{hash:{},data:d}):(a=b.name,a="function"===typeof a?a.apply(b):a);c+=h(a);if((a=e.unless.call(b,b.isLast,{hash:{},inverse:this.noop,
fn:this.program(9,function(){return","},d),data:d}))||0===a)c+=a;return c});m.no_threads=l(function(c,b,e,a,d){this.compilerInfo=[4,">= 1.0.0"];e=this.merge(e,c.helpers);d=d||{};var f;c=e.helperMissing;a=this.escapeExpression;d={hash:{},data:d};return b='<td class="no-threads" colspan="8">'+(a((f=e.L10n||b.L10n,f?f.call(b,"clients.no_clients",d):c.call(b,"L10n","clients.no_clients",d)))+"</td>")});m.no_visitors=l(function(c,b,e,a,d){this.compilerInfo=[4,">= 1.0.0"];e=this.merge(e,c.helpers);d=d||
{};var f;c=e.helperMissing;a=this.escapeExpression;d={hash:{},data:d};return b='<td class="no-visitors" colspan="9">'+(a((f=e.L10n||b.L10n,f?f.call(b,"visitors.no_visitors",d):c.call(b,"L10n","visitors.no_visitors",d)))+"</td>")});m.queued_thread=l(function(c,b,e,a,d){this.compilerInfo=[4,">= 1.0.0"];e=this.merge(e,c.helpers);d=d||{};var f=e.helperMissing,h=this.escapeExpression;c='<td class="visitor">\n <div><a href="javascript:void(0);" class="user-name open-dialog" title="';if((a=e["if"].call(b,
b.canOpen,{hash:{},inverse:this.program(3,function(a,c){var b,g;g={hash:{},data:c};return h((b=e.L10n||a.L10n,b?b.call(a,"pending.table.view",g):f.call(a,"L10n","pending.table.view",g)))},d),fn:this.program(1,function(a,c){var b,g;g={hash:{},data:c};return h((b=e.L10n||a.L10n,b?b.call(a,"pending.table.speak",g):f.call(a,"L10n","pending.table.speak",g)))},d),data:d}))||0===a)c+=a;c+='">';if((a=e["if"].call(b,b.ban,{hash:{},inverse:this.noop,fn:this.program(5,function(a,c){var b,g;b={hash:{},data:c};
return b=""+(h((g=e.L10n||a.L10n,g?g.call(a,"chat.client.spam.prefix",b):f.call(a,"L10n","chat.client.spam.prefix",b)))+"&nbsp;")},d),data:d}))||0===a)c+=a;(a=e.userName)?a=a.call(b,{hash:{},data:d}):(a=b.userName,a="function"===typeof a?a.apply(b):a);c+=h(a)+"</a></div>\n ";if((a=e["if"].call(b,b.firstMessage,{hash:{},inverse:this.noop,fn:this.program(7,function(a,b){var c,g;c='<div class="first-message"><a href="javascript:void(0);" title="';(g=e.firstMessage)?g=g.call(a,{hash:{},data:b}):(g=
a.firstMessage,g="function"===typeof g?g.apply(a):g);c+=h(g)+'">';(g=e.firstMessagePreview)?g=g.call(a,{hash:{},data:b}):(g=a.firstMessagePreview,g="function"===typeof g?g.apply(a):g);return c+=h(g)+"</a></div>"},d),data:d}))||0===a)c+=a;c+='\n</td>\n<td class="visitor">\n <div class="default-thread-controls inline-block">\n ';if((a=e["if"].call(b,b.canOpen,{hash:{},inverse:this.noop,fn:this.program(9,function(a,c){var b,g;b={hash:{},data:c};return b='\n <div class="control open-dialog open-control inline-block" title="'+
(h((g=e.L10n||a.L10n,g?g.call(a,"pending.table.speak",b):f.call(a,"L10n","pending.table.speak",b)))+'"></div>\n ')},d),data:d}))||0===a)c+=a;c+="\n ";if((a=e["if"].call(b,b.canView,{hash:{},inverse:this.noop,fn:this.program(11,function(a,b){var c,g;c={hash:{},data:b};return c='\n <div class="control view-control inline-block" title="'+(h((g=e.L10n||a.L10n,g?g.call(a,"pending.table.view",c):f.call(a,"L10n","pending.table.view",c)))+'"></div>\n ')},d),data:d}))||0===
a)c+=a;c+="\n ";if((a=e["if"].call(b,b.tracked,{hash:{},inverse:this.noop,fn:this.program(13,function(a,c){var b,g;b={hash:{},data:c};return b='\n <div class="control track-control inline-block" title="'+(h((g=e.L10n||a.L10n,g?g.call(a,"pending.table.tracked",b):f.call(a,"L10n","pending.table.tracked",b)))+'"></div>\n ')},d),data:d}))||0===a)c+=a;c+="\n ";if((a=e["if"].call(b,b.canBan,{hash:{},inverse:this.noop,fn:this.program(15,function(a,b){var c,g;c={hash:{},data:b};
return c='\n <div class="control ban-control inline-block" title="'+(h((g=e.L10n||a.L10n,g?g.call(a,"pending.table.ban",c):f.call(a,"L10n","pending.table.ban",c)))+'"></div>\n ')},d),data:d}))||0===a)c+=a;c+='\n </div>\n <div class="thread-controls inline-block"></div>\n</td>\n<td class="visitor">';if((a=e["if"].call(b,b.userIp,{hash:{},inverse:this.program(19,function(a,c){var b;(b=e.remote)?b=b.call(a,{hash:{},data:c}):(b=a.remote,b="function"===typeof b?b.apply(a):b);return h(b)},
d),fn:this.program(17,function(a,b){var c,g;c='<a href="javascript:void(0);" class="geo-link" title="GeoLocation">';(g=e.remote)?g=g.call(a,{hash:{},data:b}):(g=a.remote,g="function"===typeof g?g.apply(a):g);return c+=h(g)+"</a>"},d),data:d}))||0===a)c+=a;c+='</td>\n<td class="visitor">';(a=e.stateDesc)?a=a.call(b,{hash:{},data:d}):(a=b.stateDesc,a="function"===typeof a?a.apply(b):a);c+=h(a)+'</td>\n<td class="visitor">';(a=e.agentName)?a=a.call(b,{hash:{},data:d}):(a=b.agentName,a="function"===typeof a?
a.apply(b):a);c+=h(a)+'</td>\n<td class="visitor"><span class="timesince" data-timestamp="';(a=e.totalTime)?a=a.call(b,{hash:{},data:d}):(a=b.totalTime,a="function"===typeof a?a.apply(b):a);c+=h(a)+'"></span></td>\n<td class="visitor">';if((a=e.unless.call(b,b.chatting,{hash:{},inverse:this.program(23,function(){return"-"},d),fn:this.program(21,function(a,b){var c,g;c='<span class="timesince" data-timestamp="';(g=e.waitingTime)?g=g.call(a,{hash:{},data:b}):(g=a.waitingTime,g="function"===typeof g?
g.apply(a):g);return c+=h(g)+'"></span>'},d),data:d}))||0===a)c+=a;c+='</td>\n<td class="visitor">';if((a=e["if"].call(b,b.ban,{hash:{},inverse:this.program(27,function(a,b){var c;(c=e.userAgent)?c=c.call(a,{hash:{},data:b}):(c=a.userAgent,c="function"===typeof c?c.apply(a):c);return h(c)},d),fn:this.program(25,function(a){var c;return h((c=(c=a.ban,null==c||!1===c?c:c.reason),"function"===typeof c?c.apply(a):c))},d),data:d}))||0===a)c+=a;return c+"</td>"});m.status_panel=l(function(c,b,e,a,d){this.compilerInfo=
[4,">= 1.0.0"];e=this.merge(e,c.helpers);d=d||{};var f,h=e.helperMissing,j=this.escapeExpression;c='<div id="connstatus">';(a=e.message)?a=a.call(b,{hash:{},data:d}):(a=b.message,a="function"===typeof a?a.apply(b):a);c+=j(a);if((f=e["if"].call(b,(a=b.agent,null==a||!1===a?a:a.away),{hash:{},inverse:this.program(3,function(a,c){var b,d;d={hash:{},data:c};return j((b=e.L10n||a.L10n,b?b.call(a,"pending.status.online",d):h.call(a,"L10n","pending.status.online",d)))},d),fn:this.program(1,function(a,c){var b,
d;d={hash:{},data:c};return j((b=e.L10n||a.L10n,b?b.call(a,"pending.status.away",d):h.call(a,"L10n","pending.status.away",d)))},d),data:d}))||0===f)c+=f;c+='</div><div id="connlinks"><a href="javascript:void(0);" id="change-status">';if((f=e["if"].call(b,(a=b.agent,null==a||!1===a?a:a.away),{hash:{},inverse:this.program(7,function(a,c){var b,d;d={hash:{},data:c};return j((b=e.L10n||a.L10n,b?b.call(a,"pending.status.setaway",d):h.call(a,"L10n","pending.status.setaway",d)))},d),fn:this.program(5,function(a,
c){var b,d;d={hash:{},data:c};return j((b=e.L10n||a.L10n,b?b.call(a,"pending.status.setonline",d):h.call(a,"L10n","pending.status.setonline",d)))},d),data:d}))||0===f)c+=f;return c+"</a></div>"});m.threads_collection=l(function(c,b,e,a,d){this.compilerInfo=[4,">= 1.0.0"];e=this.merge(e,c.helpers);d=d||{};var f,h=e.helperMissing,j=this.escapeExpression;a={hash:{},data:d};c='<table class="awaiting" border="0">\n<thead>\n<tr>\n <th class="first">'+(j((f=e.L10n||b.L10n,f?f.call(b,"pending.table.head.name",
a):h.call(b,"L10n","pending.table.head.name",a)))+"</th>\n <th>");a={hash:{},data:d};c+=j((f=e.L10n||b.L10n,f?f.call(b,"pending.table.head.actions",a):h.call(b,"L10n","pending.table.head.actions",a)))+"</th>\n <th>";a={hash:{},data:d};c+=j((f=e.L10n||b.L10n,f?f.call(b,"pending.table.head.contactid",a):h.call(b,"L10n","pending.table.head.contactid",a)))+"</th>\n <th>";a={hash:{},data:d};c+=j((f=e.L10n||b.L10n,f?f.call(b,"pending.table.head.state",a):h.call(b,"L10n","pending.table.head.state",
a)))+"</th>\n <th>";a={hash:{},data:d};c+=j((f=e.L10n||b.L10n,f?f.call(b,"pending.table.head.operator",a):h.call(b,"L10n","pending.table.head.operator",a)))+"</th>\n <th>";a={hash:{},data:d};c+=j((f=e.L10n||b.L10n,f?f.call(b,"pending.table.head.total",a):h.call(b,"L10n","pending.table.head.total",a)))+"</th>\n <th>";a={hash:{},data:d};c+=j((f=e.L10n||b.L10n,f?f.call(b,"pending.table.head.waittime",a):h.call(b,"L10n","pending.table.head.waittime",a)))+"</th>\n <th>";a={hash:{},data:d};
return c+=j((f=e.L10n||b.L10n,f?f.call(b,"pending.table.head.etc",a):h.call(b,"L10n","pending.table.head.etc",a)))+'</th>\n</tr>\n</thead>\n<tbody id="threads-container">\n\n</tbody>\n</table>'});m.visitor=l(function(c,b,e,a,d){function f(){return"-"}this.compilerInfo=[4,">= 1.0.0"];e=this.merge(e,c.helpers);d=d||{};var h,j=e.helperMissing,k=this.escapeExpression;c='<td class="visitor">\n ';if((a=e.unless.call(b,b.invitationInfo,{hash:{},inverse:this.program(3,function(a,c){var b;(b=e.userName)?
b=b.call(a,{hash:{},data:c}):(b=a.userName,b="function"===typeof b?b.apply(a):b);return k(b)},d),fn:this.program(1,function(a,b){var c,d;c={hash:{},data:b};c='<a href="javascript:void(0);" class="invite-link" title="'+(k((d=e.L10n||a.L10n,d?d.call(a,"pending.table.invite",c):j.call(a,"L10n","pending.table.invite",c)))+'">');(d=e.userName)?d=d.call(a,{hash:{},data:b}):(d=a.userName,d="function"===typeof d?d.apply(a):d);return c+=k(d)+"</a>"},d),data:d}))||0===a)c+=a;h={hash:{},data:d};c=c+'\n</td>\n<td class="visitor">\n <div class="default-visitor-controls inline-block">\n <div class="control track-control inline-block" title="'+
(k((a=e.L10n||b.L10n,a?a.call(b,"pending.table.tracked",h):j.call(b,"L10n","pending.table.tracked",h)))+'"></div>\n </div>\n <div class="visitor-controls inline-block"></div>\n</td>\n<td class="visitor">');if((a=e["if"].call(b,b.userIp,{hash:{},inverse:this.program(7,function(a,c){var b;(b=e.remote)?b=b.call(a,{hash:{},data:c}):(b=a.remote,b="function"===typeof b?b.apply(a):b);return k(b)},d),fn:this.program(5,function(a,b){var c,d;c='<a href="javascript:void(0);" class="geo-link" title="GeoLocation">';
(d=e.remote)?d=d.call(a,{hash:{},data:b}):(d=a.remote,d="function"===typeof d?d.apply(a):d);return c+=k(d)+"</a>"},d),data:d}))||0===a)c+=a;c+='</td>\n<td class="visitor"><span class="timesince" data-timestamp="';(a=e.firstTime)?a=a.call(b,{hash:{},data:d}):(a=b.firstTime,a="function"===typeof a?a.apply(b):a);c+=k(a)+'"></span></td>\n<td class="visitor"><span class="timesince" data-timestamp="';(a=e.lastTime)?a=a.call(b,{hash:{},data:d}):(a=b.lastTime,a="function"===typeof a?a.apply(b):a);c+=k(a)+
'"></span></td>\n<td class="visitor">';if((a=e["if"].call(b,b.invitationInfo,{hash:{},inverse:this.program(11,f,d),fn:this.program(9,function(a){var b;return k((b=(b=a.invitationInfo,null==b||!1===b?b:b.agentName),"function"===typeof b?b.apply(a):b))},d),data:d}))||0===a)c+=a;c+='</td>\n<td class="visitor">';if((a=e["if"].call(b,b.invitationInfo,{hash:{},inverse:this.program(11,f,d),fn:this.program(13,function(a){var b;return a=""+('<span class="timesince" data-timestamp="'+k((b=(b=a.invitationInfo,
null==b||!1===b?b:b.time),"function"===typeof b?b.apply(a):b))+'"></span>')},d),data:d}))||0===a)c+=a;c+='</td>\n<td class="visitor">';(a=e.invitations)?a=a.call(b,{hash:{},data:d}):(a=b.invitations,a="function"===typeof a?a.apply(b):a);c+=k(a)+" / ";(a=e.chats)?a=a.call(b,{hash:{},data:d}):(a=b.chats,a="function"===typeof a?a.apply(b):a);c+=k(a)+'</td>\n<td class="visitor">';(a=e.userAgent)?a=a.call(b,{hash:{},data:d}):(a=b.userAgent,a="function"===typeof a?a.apply(b):a);return c+=k(a)+"</td>"});
m.visitors_collection=l(function(c,b,e,a,d){this.compilerInfo=[4,">= 1.0.0"];e=this.merge(e,c.helpers);d=d||{};var f,h=e.helperMissing,j=this.escapeExpression;a={hash:{},data:d};c='<table id="visitorslist" class="awaiting" border="0">\n<thead>\n<tr>\n <th class="first">'+(j((f=e.L10n||b.L10n,f?f.call(b,"visitors.table.head.name",a):h.call(b,"L10n","visitors.table.head.name",a)))+"</th>\n <th>");a={hash:{},data:d};c+=j((f=e.L10n||b.L10n,f?f.call(b,"visitors.table.head.actions",a):h.call(b,"L10n",
"visitors.table.head.actions",a)))+"</th>\n <th>";a={hash:{},data:d};c+=j((f=e.L10n||b.L10n,f?f.call(b,"visitors.table.head.contactid",a):h.call(b,"L10n","visitors.table.head.contactid",a)))+"</th>\n <th>";a={hash:{},data:d};c+=j((f=e.L10n||b.L10n,f?f.call(b,"visitors.table.head.firsttimeonsite",a):h.call(b,"L10n","visitors.table.head.firsttimeonsite",a)))+"</th>\n <th>";a={hash:{},data:d};c+=j((f=e.L10n||b.L10n,f?f.call(b,"visitors.table.head.lasttimeonsite",a):h.call(b,"L10n","visitors.table.head.lasttimeonsite",
a)))+"</th>\n <th>";a={hash:{},data:d};c+=j((f=e.L10n||b.L10n,f?f.call(b,"visitors.table.head.invited.by",a):h.call(b,"L10n","visitors.table.head.invited.by",a)))+"</th>\n <th>";a={hash:{},data:d};c+=j((f=e.L10n||b.L10n,f?f.call(b,"visitors.table.head.invitationtime",a):h.call(b,"L10n","visitors.table.head.invitationtime",a)))+"</th>\n <th>";a={hash:{},data:d};c+=j((f=e.L10n||b.L10n,f?f.call(b,"visitors.table.head.invitations",a):h.call(b,"L10n","visitors.table.head.invitations",a)))+"</th>\n <th>";
a={hash:{},data:d};return c+=j((f=e.L10n||b.L10n,f?f.call(b,"visitors.table.head.etc",a):h.call(b,"L10n","visitors.table.head.etc",a)))+'</th>\n</tr>\n</thead>\n<tbody id="visitors-container">\n</tbody>\n</table>'})})();
/*
Copyright 2005-2013 the original author or authors.
Licensed under the Apache License, Version 2.0 (the "License").

View File

@ -1,34 +0,0 @@
/*
Copyright 2005-2013 the original author or authors.
Licensed under the Apache License, Version 2.0 (the "License").
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
*/
(function(){var l=Handlebars.template,m=Handlebars.templates=Handlebars.templates||{};m.agent=l(function(c,b,e,a,d){this.compilerInfo=[4,">= 1.0.0"];e=this.merge(e,c.helpers);d=d||{};var f=e.helperMissing,h=this.escapeExpression;c='<span class="agent-status-';if((a=e["if"].call(b,b.away,{hash:{},inverse:this.program(3,function(){return"online"},d),fn:this.program(1,function(){return"away"},d),data:d}))||0===a)c+=a;c+=' inline-block" title="';if((a=e["if"].call(b,b.away,{hash:{},inverse:this.program(7,
function(a,c){var b,g;g={hash:{},data:c};return h((b=e.L10n||a.L10n,b?b.call(a,"pending.status.online",g):f.call(a,"L10n","pending.status.online",g)))},d),fn:this.program(5,function(a,c){var b,g;g={hash:{},data:c};return h((b=e.L10n||a.L10n,b?b.call(a,"pending.status.away",g):f.call(a,"L10n","pending.status.away",g)))},d),data:d}))||0===a)c+=a;c+='"></span>';(a=e.name)?a=a.call(b,{hash:{},data:d}):(a=b.name,a="function"===typeof a?a.apply(b):a);c+=h(a);if((a=e.unless.call(b,b.isLast,{hash:{},inverse:this.noop,
fn:this.program(9,function(){return","},d),data:d}))||0===a)c+=a;return c});m.no_threads=l(function(c,b,e,a,d){this.compilerInfo=[4,">= 1.0.0"];e=this.merge(e,c.helpers);d=d||{};var f;c=e.helperMissing;a=this.escapeExpression;d={hash:{},data:d};return b='<td class="no-threads" colspan="8">'+(a((f=e.L10n||b.L10n,f?f.call(b,"clients.no_clients",d):c.call(b,"L10n","clients.no_clients",d)))+"</td>")});m.no_visitors=l(function(c,b,e,a,d){this.compilerInfo=[4,">= 1.0.0"];e=this.merge(e,c.helpers);d=d||
{};var f;c=e.helperMissing;a=this.escapeExpression;d={hash:{},data:d};return b='<td class="no-visitors" colspan="9">'+(a((f=e.L10n||b.L10n,f?f.call(b,"visitors.no_visitors",d):c.call(b,"L10n","visitors.no_visitors",d)))+"</td>")});m.queued_thread=l(function(c,b,e,a,d){this.compilerInfo=[4,">= 1.0.0"];e=this.merge(e,c.helpers);d=d||{};var f=e.helperMissing,h=this.escapeExpression;c='<td class="visitor">\n <div><a href="javascript:void(0);" class="user-name open-dialog" title="';if((a=e["if"].call(b,
b.canOpen,{hash:{},inverse:this.program(3,function(a,c){var b,g;g={hash:{},data:c};return h((b=e.L10n||a.L10n,b?b.call(a,"pending.table.view",g):f.call(a,"L10n","pending.table.view",g)))},d),fn:this.program(1,function(a,c){var b,g;g={hash:{},data:c};return h((b=e.L10n||a.L10n,b?b.call(a,"pending.table.speak",g):f.call(a,"L10n","pending.table.speak",g)))},d),data:d}))||0===a)c+=a;c+='">';if((a=e["if"].call(b,b.ban,{hash:{},inverse:this.noop,fn:this.program(5,function(a,c){var b,g;b={hash:{},data:c};
return b=""+(h((g=e.L10n||a.L10n,g?g.call(a,"chat.client.spam.prefix",b):f.call(a,"L10n","chat.client.spam.prefix",b)))+"&nbsp;")},d),data:d}))||0===a)c+=a;(a=e.userName)?a=a.call(b,{hash:{},data:d}):(a=b.userName,a="function"===typeof a?a.apply(b):a);c+=h(a)+"</a></div>\n ";if((a=e["if"].call(b,b.firstMessage,{hash:{},inverse:this.noop,fn:this.program(7,function(a,b){var c,g;c='<div class="first-message"><a href="javascript:void(0);" title="';(g=e.firstMessage)?g=g.call(a,{hash:{},data:b}):(g=
a.firstMessage,g="function"===typeof g?g.apply(a):g);c+=h(g)+'">';(g=e.firstMessagePreview)?g=g.call(a,{hash:{},data:b}):(g=a.firstMessagePreview,g="function"===typeof g?g.apply(a):g);return c+=h(g)+"</a></div>"},d),data:d}))||0===a)c+=a;c+='\n</td>\n<td class="visitor">\n <div class="default-thread-controls inline-block">\n ';if((a=e["if"].call(b,b.canOpen,{hash:{},inverse:this.noop,fn:this.program(9,function(a,c){var b,g;b={hash:{},data:c};return b='\n <div class="control open-dialog open-control inline-block" title="'+
(h((g=e.L10n||a.L10n,g?g.call(a,"pending.table.speak",b):f.call(a,"L10n","pending.table.speak",b)))+'"></div>\n ')},d),data:d}))||0===a)c+=a;c+="\n ";if((a=e["if"].call(b,b.canView,{hash:{},inverse:this.noop,fn:this.program(11,function(a,b){var c,g;c={hash:{},data:b};return c='\n <div class="control view-control inline-block" title="'+(h((g=e.L10n||a.L10n,g?g.call(a,"pending.table.view",c):f.call(a,"L10n","pending.table.view",c)))+'"></div>\n ')},d),data:d}))||0===
a)c+=a;c+="\n ";if((a=e["if"].call(b,b.tracked,{hash:{},inverse:this.noop,fn:this.program(13,function(a,c){var b,g;b={hash:{},data:c};return b='\n <div class="control track-control inline-block" title="'+(h((g=e.L10n||a.L10n,g?g.call(a,"pending.table.tracked",b):f.call(a,"L10n","pending.table.tracked",b)))+'"></div>\n ')},d),data:d}))||0===a)c+=a;c+="\n ";if((a=e["if"].call(b,b.canBan,{hash:{},inverse:this.noop,fn:this.program(15,function(a,b){var c,g;c={hash:{},data:b};
return c='\n <div class="control ban-control inline-block" title="'+(h((g=e.L10n||a.L10n,g?g.call(a,"pending.table.ban",c):f.call(a,"L10n","pending.table.ban",c)))+'"></div>\n ')},d),data:d}))||0===a)c+=a;c+='\n </div>\n <div class="thread-controls inline-block"></div>\n</td>\n<td class="visitor">';if((a=e["if"].call(b,b.userIp,{hash:{},inverse:this.program(19,function(a,c){var b;(b=e.remote)?b=b.call(a,{hash:{},data:c}):(b=a.remote,b="function"===typeof b?b.apply(a):b);return h(b)},
d),fn:this.program(17,function(a,b){var c,g;c='<a href="javascript:void(0);" class="geo-link" title="GeoLocation">';(g=e.remote)?g=g.call(a,{hash:{},data:b}):(g=a.remote,g="function"===typeof g?g.apply(a):g);return c+=h(g)+"</a>"},d),data:d}))||0===a)c+=a;c+='</td>\n<td class="visitor">';(a=e.stateDesc)?a=a.call(b,{hash:{},data:d}):(a=b.stateDesc,a="function"===typeof a?a.apply(b):a);c+=h(a)+'</td>\n<td class="visitor">';(a=e.agentName)?a=a.call(b,{hash:{},data:d}):(a=b.agentName,a="function"===typeof a?
a.apply(b):a);c+=h(a)+'</td>\n<td class="visitor"><span class="timesince" data-timestamp="';(a=e.totalTime)?a=a.call(b,{hash:{},data:d}):(a=b.totalTime,a="function"===typeof a?a.apply(b):a);c+=h(a)+'"></span></td>\n<td class="visitor">';if((a=e.unless.call(b,b.chatting,{hash:{},inverse:this.program(23,function(){return"-"},d),fn:this.program(21,function(a,b){var c,g;c='<span class="timesince" data-timestamp="';(g=e.waitingTime)?g=g.call(a,{hash:{},data:b}):(g=a.waitingTime,g="function"===typeof g?
g.apply(a):g);return c+=h(g)+'"></span>'},d),data:d}))||0===a)c+=a;c+='</td>\n<td class="visitor">';if((a=e["if"].call(b,b.ban,{hash:{},inverse:this.program(27,function(a,b){var c;(c=e.userAgent)?c=c.call(a,{hash:{},data:b}):(c=a.userAgent,c="function"===typeof c?c.apply(a):c);return h(c)},d),fn:this.program(25,function(a){var c;return h((c=(c=a.ban,null==c||!1===c?c:c.reason),"function"===typeof c?c.apply(a):c))},d),data:d}))||0===a)c+=a;return c+"</td>"});m.status_panel=l(function(c,b,e,a,d){this.compilerInfo=
[4,">= 1.0.0"];e=this.merge(e,c.helpers);d=d||{};var f,h=e.helperMissing,j=this.escapeExpression;c='<div id="connstatus">';(a=e.message)?a=a.call(b,{hash:{},data:d}):(a=b.message,a="function"===typeof a?a.apply(b):a);c+=j(a);if((f=e["if"].call(b,(a=b.agent,null==a||!1===a?a:a.away),{hash:{},inverse:this.program(3,function(a,c){var b,d;d={hash:{},data:c};return j((b=e.L10n||a.L10n,b?b.call(a,"pending.status.online",d):h.call(a,"L10n","pending.status.online",d)))},d),fn:this.program(1,function(a,c){var b,
d;d={hash:{},data:c};return j((b=e.L10n||a.L10n,b?b.call(a,"pending.status.away",d):h.call(a,"L10n","pending.status.away",d)))},d),data:d}))||0===f)c+=f;c+='</div><div id="connlinks"><a href="javascript:void(0);" id="change-status">';if((f=e["if"].call(b,(a=b.agent,null==a||!1===a?a:a.away),{hash:{},inverse:this.program(7,function(a,c){var b,d;d={hash:{},data:c};return j((b=e.L10n||a.L10n,b?b.call(a,"pending.status.setaway",d):h.call(a,"L10n","pending.status.setaway",d)))},d),fn:this.program(5,function(a,
c){var b,d;d={hash:{},data:c};return j((b=e.L10n||a.L10n,b?b.call(a,"pending.status.setonline",d):h.call(a,"L10n","pending.status.setonline",d)))},d),data:d}))||0===f)c+=f;return c+"</a></div>"});m.threads_collection=l(function(c,b,e,a,d){this.compilerInfo=[4,">= 1.0.0"];e=this.merge(e,c.helpers);d=d||{};var f,h=e.helperMissing,j=this.escapeExpression;a={hash:{},data:d};c='<table class="awaiting" border="0">\n<thead>\n<tr>\n <th class="first">'+(j((f=e.L10n||b.L10n,f?f.call(b,"pending.table.head.name",
a):h.call(b,"L10n","pending.table.head.name",a)))+"</th>\n <th>");a={hash:{},data:d};c+=j((f=e.L10n||b.L10n,f?f.call(b,"pending.table.head.actions",a):h.call(b,"L10n","pending.table.head.actions",a)))+"</th>\n <th>";a={hash:{},data:d};c+=j((f=e.L10n||b.L10n,f?f.call(b,"pending.table.head.contactid",a):h.call(b,"L10n","pending.table.head.contactid",a)))+"</th>\n <th>";a={hash:{},data:d};c+=j((f=e.L10n||b.L10n,f?f.call(b,"pending.table.head.state",a):h.call(b,"L10n","pending.table.head.state",
a)))+"</th>\n <th>";a={hash:{},data:d};c+=j((f=e.L10n||b.L10n,f?f.call(b,"pending.table.head.operator",a):h.call(b,"L10n","pending.table.head.operator",a)))+"</th>\n <th>";a={hash:{},data:d};c+=j((f=e.L10n||b.L10n,f?f.call(b,"pending.table.head.total",a):h.call(b,"L10n","pending.table.head.total",a)))+"</th>\n <th>";a={hash:{},data:d};c+=j((f=e.L10n||b.L10n,f?f.call(b,"pending.table.head.waittime",a):h.call(b,"L10n","pending.table.head.waittime",a)))+"</th>\n <th>";a={hash:{},data:d};
return c+=j((f=e.L10n||b.L10n,f?f.call(b,"pending.table.head.etc",a):h.call(b,"L10n","pending.table.head.etc",a)))+'</th>\n</tr>\n</thead>\n<tbody id="threads-container">\n\n</tbody>\n</table>'});m.visitor=l(function(c,b,e,a,d){function f(){return"-"}this.compilerInfo=[4,">= 1.0.0"];e=this.merge(e,c.helpers);d=d||{};var h,j=e.helperMissing,k=this.escapeExpression;c='<td class="visitor">\n ';if((a=e.unless.call(b,b.invitationInfo,{hash:{},inverse:this.program(3,function(a,c){var b;(b=e.userName)?
b=b.call(a,{hash:{},data:c}):(b=a.userName,b="function"===typeof b?b.apply(a):b);return k(b)},d),fn:this.program(1,function(a,b){var c,d;c={hash:{},data:b};c='<a href="javascript:void(0);" class="invite-link" title="'+(k((d=e.L10n||a.L10n,d?d.call(a,"pending.table.invite",c):j.call(a,"L10n","pending.table.invite",c)))+'">');(d=e.userName)?d=d.call(a,{hash:{},data:b}):(d=a.userName,d="function"===typeof d?d.apply(a):d);return c+=k(d)+"</a>"},d),data:d}))||0===a)c+=a;h={hash:{},data:d};c=c+'\n</td>\n<td class="visitor">\n <div class="default-visitor-controls inline-block">\n <div class="control track-control inline-block" title="'+
(k((a=e.L10n||b.L10n,a?a.call(b,"pending.table.tracked",h):j.call(b,"L10n","pending.table.tracked",h)))+'"></div>\n </div>\n <div class="visitor-controls inline-block"></div>\n</td>\n<td class="visitor">');if((a=e["if"].call(b,b.userIp,{hash:{},inverse:this.program(7,function(a,c){var b;(b=e.remote)?b=b.call(a,{hash:{},data:c}):(b=a.remote,b="function"===typeof b?b.apply(a):b);return k(b)},d),fn:this.program(5,function(a,b){var c,d;c='<a href="javascript:void(0);" class="geo-link" title="GeoLocation">';
(d=e.remote)?d=d.call(a,{hash:{},data:b}):(d=a.remote,d="function"===typeof d?d.apply(a):d);return c+=k(d)+"</a>"},d),data:d}))||0===a)c+=a;c+='</td>\n<td class="visitor"><span class="timesince" data-timestamp="';(a=e.firstTime)?a=a.call(b,{hash:{},data:d}):(a=b.firstTime,a="function"===typeof a?a.apply(b):a);c+=k(a)+'"></span></td>\n<td class="visitor"><span class="timesince" data-timestamp="';(a=e.lastTime)?a=a.call(b,{hash:{},data:d}):(a=b.lastTime,a="function"===typeof a?a.apply(b):a);c+=k(a)+
'"></span></td>\n<td class="visitor">';if((a=e["if"].call(b,b.invitationInfo,{hash:{},inverse:this.program(11,f,d),fn:this.program(9,function(a){var b;return k((b=(b=a.invitationInfo,null==b||!1===b?b:b.agentName),"function"===typeof b?b.apply(a):b))},d),data:d}))||0===a)c+=a;c+='</td>\n<td class="visitor">';if((a=e["if"].call(b,b.invitationInfo,{hash:{},inverse:this.program(11,f,d),fn:this.program(13,function(a){var b;return a=""+('<span class="timesince" data-timestamp="'+k((b=(b=a.invitationInfo,
null==b||!1===b?b:b.time),"function"===typeof b?b.apply(a):b))+'"></span>')},d),data:d}))||0===a)c+=a;c+='</td>\n<td class="visitor">';(a=e.invitations)?a=a.call(b,{hash:{},data:d}):(a=b.invitations,a="function"===typeof a?a.apply(b):a);c+=k(a)+" / ";(a=e.chats)?a=a.call(b,{hash:{},data:d}):(a=b.chats,a="function"===typeof a?a.apply(b):a);c+=k(a)+'</td>\n<td class="visitor">';(a=e.userAgent)?a=a.call(b,{hash:{},data:d}):(a=b.userAgent,a="function"===typeof a?a.apply(b):a);return c+=k(a)+"</td>"});
m.visitors_collection=l(function(c,b,e,a,d){this.compilerInfo=[4,">= 1.0.0"];e=this.merge(e,c.helpers);d=d||{};var f,h=e.helperMissing,j=this.escapeExpression;a={hash:{},data:d};c='<table id="visitorslist" class="awaiting" border="0">\n<thead>\n<tr>\n <th class="first">'+(j((f=e.L10n||b.L10n,f?f.call(b,"visitors.table.head.name",a):h.call(b,"L10n","visitors.table.head.name",a)))+"</th>\n <th>");a={hash:{},data:d};c+=j((f=e.L10n||b.L10n,f?f.call(b,"visitors.table.head.actions",a):h.call(b,"L10n",
"visitors.table.head.actions",a)))+"</th>\n <th>";a={hash:{},data:d};c+=j((f=e.L10n||b.L10n,f?f.call(b,"visitors.table.head.contactid",a):h.call(b,"L10n","visitors.table.head.contactid",a)))+"</th>\n <th>";a={hash:{},data:d};c+=j((f=e.L10n||b.L10n,f?f.call(b,"visitors.table.head.firsttimeonsite",a):h.call(b,"L10n","visitors.table.head.firsttimeonsite",a)))+"</th>\n <th>";a={hash:{},data:d};c+=j((f=e.L10n||b.L10n,f?f.call(b,"visitors.table.head.lasttimeonsite",a):h.call(b,"L10n","visitors.table.head.lasttimeonsite",
a)))+"</th>\n <th>";a={hash:{},data:d};c+=j((f=e.L10n||b.L10n,f?f.call(b,"visitors.table.head.invited.by",a):h.call(b,"L10n","visitors.table.head.invited.by",a)))+"</th>\n <th>";a={hash:{},data:d};c+=j((f=e.L10n||b.L10n,f?f.call(b,"visitors.table.head.invitationtime",a):h.call(b,"L10n","visitors.table.head.invitationtime",a)))+"</th>\n <th>";a={hash:{},data:d};c+=j((f=e.L10n||b.L10n,f?f.call(b,"visitors.table.head.invitations",a):h.call(b,"L10n","visitors.table.head.invitations",a)))+"</th>\n <th>";
a={hash:{},data:d};return c+=j((f=e.L10n||b.L10n,f?f.call(b,"visitors.table.head.etc",a):h.call(b,"L10n","visitors.table.head.etc",a)))+'</th>\n</tr>\n</thead>\n<tbody id="visitors-container">\n</tbody>\n</table>'})})();

View File

@ -723,14 +723,15 @@ function chat_start_for_user(
Thread::KIND_FOR_AGENT,
getstring2(
'chat.visitor.invitation.accepted',
array($operator_name)
array($operator_name),
true
)
);
} else {
if ($referrer) {
$thread->postMessage(
Thread::KIND_FOR_AGENT,
getstring2('chat.came.from', array($referrer))
getstring2('chat.came.from', array($referrer), true)
);
}
if ($requested_operator && !$requested_operator_online) {
@ -738,11 +739,12 @@ function chat_start_for_user(
Thread::KIND_INFO,
getstring2(
'chat.requested_operator.offline',
array(get_operator_name($requested_operator))
array(get_operator_name($requested_operator)),
true
)
);
} else {
$thread->postMessage(Thread::KIND_INFO, getstring('chat.wait'));
$thread->postMessage(Thread::KIND_INFO, getstring('chat.wait', true));
}
}
@ -750,7 +752,7 @@ function chat_start_for_user(
if ($info) {
$thread->postMessage(
Thread::KIND_FOR_AGENT,
getstring2('chat.visitor.info', array($info))
getstring2('chat.visitor.info', array($info), true)
);
}

View File

@ -0,0 +1,573 @@
<?php
/*
* Copyright 2005-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
namespace Mibew\Handlebars;
/**
* Set of helpers to for server side templates
*/
class HelpersSet
{
/**
* Contains an instance of helpers set.
*
* @var \Mibew\Handlebars\HelpersSet
*/
protected static $instance = null;
/**
* Storage for overridable blocks' content.
*
* This storage is used by "block" helper and "override" helper.
*
* @var array
*/
protected $blocksStorage = array();
/**
* Returns a set of handlebars helpers.
*
* @return array Helpers list that can be passed to
* \Handlebars\Helpers::__construct();
*/
public static function getHelpers()
{
if (!self::$instance) {
self::$instance = new self();
}
return self::$instance->helpersList();
}
/**
* A helper for string localization.
*
* Example of usage:
* <code>
* {{l10n "localization.string" arg1 arg2 arg3}}
* </code>
* where:
* - "localization.string" is localization constant.
* - arg* are arguments that will be passed to getlocal2 function. There
* can be arbitrary number of such arguments.
*/
public function localizationHelper($template, $context, $args, $source)
{
// Check if there is at least one argument
$parsed_arguments = $template->parseArguments($args);
if (empty($parsed_arguments)) {
return '';
}
$text = $context->get(array_shift($parsed_arguments));
// We need to escape extra arguments passed to the helper. Thus we need
// to get escape function and its arguments from the template engine.
$escape_func = $template->getEngine()->getEscape();
$escape_args = $template->getEngine()->getEscapeArgs();
// Check if there are any other arguments passed into helper and escape
// them.
$local_args = array();
foreach ($parsed_arguments as $parsed_argument) {
// Get locale argument string and add it to escape function
// arguments.
array_unshift($escape_args, $context->get($parsed_argument));
// Escape locale argument's value
$local_args[] = call_user_func_array(
$escape_func,
array_values($escape_args)
);
// Remove locale argument's value from escape function argument
array_shift($escape_args);
}
if (empty($local_args)) {
$result = getlocal($text);
} else {
$result = getlocal2($text, $local_args);
}
return new \Handlebars\SafeString($result);
}
/**
* Conditional helper that checks if two values are equal or not.
*
* Example of usage:
* <code>
* {{#ifEqual first second}}
* The first argument is equal to the second one.
* {{else}}
* The arguments are not equal.
* {{/ifEqual}}
* </code>
*/
public function ifEqualHelper($template, $context, $args, $source)
{
$parsed_args = $template->parseArguments($args);
if (empty($parsed_args) || count($parsed_args) < 2) {
return '';
}
$condition = ($context->get($parsed_args[0]) == $context->get($parsed_args[1]));
if ($condition) {
$template->setStopToken('else');
$buffer = $template->render($context);
$template->setStopToken(false);
} else {
$template->setStopToken('else');
$template->discard();
$template->setStopToken(false);
$buffer = $template->render($context);
}
return $buffer;
}
/**
* Conditional helper that checks if at least one argumet can be treated as
* "true" value.
*
* Example of usage:
* <code>
* {{#ifAny first second third}}
* At least one of argument can be threated as "true".
* {{else}}
* All values are "falsy"
* {{/ifAny}}
* </code>
*/
public function ifAnyHelper($template, $context, $args, $source)
{
$parsed_args = $template->parseArguments($args);
if (empty($parsed_args)) {
return '';
}
$condition = false;
foreach ($parsed_args as $parsed_arg) {
$value = $context->get($parsed_arg);
if ($value instanceof \Handlebars\String) {
// We need to get internal string. Casting any object of
// \Handlebars\String will have positive result even for those
// with empty internal strings.
$value = $value->getString();
}
if ($value) {
$condition = true;
break;
}
}
if ($condition) {
$template->setStopToken('else');
$buffer = $template->render($context);
$template->setStopToken(false);
} else {
$template->setStopToken('else');
$template->discard();
$template->setStopToken(false);
$buffer = $template->render($context);
}
return $buffer;
}
/**
* A helper for templates inheritance.
*
* Example of usage:
* <code>
* {{#extends "parentTemplateName"}}
* {{#override "blockName"}}
* Overridden first block
* {{/override}}
*
* {{#override "anotherBlockName"}}
* Overridden second block
* {{/override}}
* {{/extends}}
* </code>
*/
public function extendsHelper($template, $context, $args, $source)
{
// Get name of the parent template
$parsed_args = $template->parseArguments($args);
if (empty($parsed_args)) {
return '';
}
$parent_template = $context->get(array_shift($parsed_args));
// Render content inside "extends" block to override blocks
$template->render($context);
// We need to another instance of \Handlebars\Template to render parent
// template. It can be got from Handlebars engine, so get the latter.
$handlebars = $template->getEngine();
// Render the parent template
return $handlebars->render($parent_template, $context);
}
/**
* A helper for defining default content of a block.
*
* Example of usage:
* <code>
* {{#block "blockName"}}
* Default content for the block
* {{/block}}
* </code>
*/
public function blockHelper($template, $context, $args, $source)
{
// Get block name
$parsed_args = $template->parseArguments($args);
if (empty($parsed_args)) {
return '';
}
$block_name = $context->get(array_shift($parsed_args));
// If the block is not overridden render and show the default value
if (!isset($this->blocksStorage[$block_name])) {
return $template->render($context);
}
// Show overridden content
return $this->blocksStorage[$block_name];
}
/**
* A helper for overriding content of a block.
*
* Example of usage:
* <code>
* {{#extends "parentTemplateName"}}
* {{#override "blockName"}}
* Overridden first block
* {{/override}}
*
* {{#override "anotherBlockName"}}
* Overridden second block
* {{/override}}
* {{/extends}}
* </code>
*/
public function overrideHelper($template, $context, $args, $source)
{
// Get block name
$parsed_args = $template->parseArguments($args);
if (empty($parsed_args)) {
return '';
}
$block_name = $context->get(array_shift($parsed_args));
// We need to provide unlimited inheritence level. Rendering is started
// from the deepest level template. If the content is in the block
// storage it is related with the deepest level template. Thus we do not
// need to override it.
if (!isset($this->blocksStorage[$block_name])) {
$this->blocksStorage[$block_name] = $template->render($context);
}
}
/**
* Conditional helper that checks if block overridden or not.
*
* Example of usage:
* <code>
* {{#ifOverridden "blockName"}}
* The block was overridden
* {{else}}
* The block was not overridden
* {{/ifOverriden}}
* </code>
*/
public function ifOverriddenHelper($template, $context, $args, $source)
{
// Get block name
$parsed_args = $template->parseArguments($args);
if (empty($parsed_args)) {
return '';
}
$block_name = $context->get(array_shift($parsed_args));
// Check condition and render blocks
if (isset($this->blocksStorage[$block_name])) {
$template->setStopToken('else');
$buffer = $template->render($context);
$template->setStopToken(false);
} else {
$template->setStopToken('else');
$template->discard();
$template->setStopToken(false);
$buffer = $template->render($context);
}
return $buffer;
}
/**
* Conditional helper that checks if block overridden or not.
*
* Example of usage:
* <code>
* {{#unlessOverridden "blockName"}}
* The block was not overridden
* {{else}}
* The block was overridden
* {{/unlessOverriden}}
* </code>
*/
public function unlessOverriddenHelper($template, $context, $args, $source)
{
// Get block name
$parsed_args = $template->parseArguments($args);
if (empty($parsed_args)) {
return '';
}
$block_name = $context->get(array_shift($parsed_args));
// Check condition and render blocks
if (!isset($this->blocksStorage[$block_name])) {
$template->setStopToken('else');
$buffer = $template->render($context);
$template->setStopToken(false);
} else {
$template->setStopToken('else');
$template->discard();
$template->setStopToken(false);
$buffer = $template->render($context);
}
return $buffer;
}
/**
* Generates markup with hidden input tag for CSRF token.
*
* Example of usage:
* <code>
* {{csrfTokenInput}}
* </code>
*/
public function csrfTokenInputHelper()
{
return new \Handlebars\SafeString(get_csrf_token_input());
}
/**
* Generates CSRF taken formated prepared to insert in URLs.
*
* Example of usage:
* <code>
* {{csrfTokenInUrl}}
* </code>
*/
public function csrfTokenInUrlHelper()
{
return new \Handlebars\SafeString(get_csrf_token_in_url());
}
/**
* Generates pagination block.
*
* Example of usage:
* <code>
* {{generatePagination stylePath paginationInfo bottom}}
* </code>
* where:
* - "stylePath" is expression for path to current style.
* - "paginationInfo" is 'info' key from the result of setup_pagination
* function.
* - "bottom": optional argument that indicate if pagination block shoud
* be generated for a page bottom or not. If specified and equal to
* string "false" then boolean false will be passed into
* generate_pagination. In all other cases boolean true will be used.
*/
public function generatePaginationHelper($template, $context, $args, $source)
{
$parsed_args = $template->parseArguments($args);
if (empty($parsed_args) || count($parsed_args) < 2) {
return '';
}
$stylePath = $context->get($parsed_args[0]);
$pagination_info = $context->get($parsed_args[1]);
$bottom = empty($parsed_args[2]) ? true : $context->get($parsed_args[2]);
$pagination = generate_pagination(
$stylePath,
$pagination_info,
($bottom === "false") ? false : true
);
return new \Handlebars\SafeString($pagination);
}
/**
* Escapes special characters to use result as a valid JavaScript string
* enclosed with single quotes (') or duouble quotes (").
*
* Example of usage:
* <code>
* var a = "{{#jsString}}some string to escape{{/jsString}}";
* </code>
*/
public function jsStringHelper($template, $context, $args, $source)
{
return str_replace("\n", "\\n", addslashes($template->render($context)));
}
/**
* Helper for repeating content.
*
* Example of usage:
* <code>
* {{#repeat times}}content to repeat{{/repeat}}
* </code>
*/
public function repeatHelper($template, $context, $args, $source)
{
$parsed_args = $template->parseArguments($args);
if (empty($parsed_args)) {
return '';
}
$times = intval($context->get($parsed_args[0]));
$string = $template->render($context);
return str_repeat($string, $times);
}
/**
* Helper for replacing substrings.
*
* Example of usage:
* <code>
* {{#replace search replacement}}target content{{/replace}}
* </code>
*/
public function replaceHelper($template, $context, $args, $source)
{
$parsed_args = $template->parseArguments($args);
if (empty($parsed_args) || count($parsed_args) < 2) {
return '';
}
$search = $context->get($parsed_args[0]);
$replacement = $context->get($parsed_args[1]);
$subject = $template->render($context);
return str_replace($search, $replacement, $subject);
}
/**
* Format date using internal format.
*
* Example of usage:
* <code>
* {{formatDate unixTimestamp}}
* </code>
*/
public function formatDateHelper($template, $context, $args, $source)
{
$parsed_args = $template->parseArguments($args);
if (empty($parsed_args)) {
return '';
}
$timestamp = intval($context->get($parsed_args[0]));
return date_to_text($timestamp);
}
/**
* Format date difference using internal format.
*
* Example of usage:
* <code>
* {{formatDateDiff seconds}}
* </code>
*/
public function formatDateDiffHelper($template, $context, $args, $source)
{
$parsed_args = $template->parseArguments($args);
if (empty($parsed_args)) {
return '';
}
$seconds = intval($context->get($parsed_args[0]));
return date_diff_to_text($seconds);
}
/**
* Cut string if it exceeds specified length.
*
* Example of usage:
* <code>
* {{cutString string length}}
* </code>
*/
public function cutStringHelper($template, $context, $args, $source)
{
$parsed_args = $template->parseArguments($args);
if (empty($parsed_args) || count($parsed_args) < 2) {
return '';
}
$string = $context->get($parsed_args[0]);
$length = intval($context->get($parsed_args[1]));
return substr($string, 0, $length);
}
/**
* Actually builds helpers list.
*
* @return array List of helpers
*/
protected function helpersList()
{
return array(
'l10n' => array($this, 'localizationHelper'),
'extends' => array($this, 'extendsHelper'),
'block' => array($this, 'blockHelper'),
'override' => array($this, 'overrideHelper'),
'ifOverridden' => array($this, 'ifOverriddenHelper'),
'unlessOverridden' => array($this, 'unlessOverriddenHelper'),
'ifEqual' => array($this, 'ifEqualHelper'),
'ifAny' => array($this, 'ifAnyHelper'),
'generatePagination' => array($this, 'generatePaginationHelper'),
'jsString' => array($this, 'jsStringHelper'),
'repeat' => array($this, 'repeatHelper'),
'replace' => array($this, 'replaceHelper'),
'formatDate' => array($this, 'formatDateHelper'),
'formatDateDiff' => array($this, 'formatDateDiffHelper'),
'cutString' => array($this, 'cutStringHelper'),
'csrfTokenInput' => array($this, 'csrfTokenInputHelper'),
'csrfTokenInUrl' => array($this, 'csrfTokenInUrlHelper'),
);
}
}

View File

@ -533,7 +533,7 @@ class ThreadProcessor extends ClientSideProcessor
if ($email) {
$thread->postMessage(
Thread::KIND_FOR_AGENT,
getstring2('chat.visitor.email', array($email))
getstring2('chat.visitor.email', array($email), true)
);
}
@ -647,19 +647,19 @@ class ThreadProcessor extends ClientSideProcessor
if ($referrer) {
$thread->postMessage(
Thread::KIND_FOR_AGENT,
getstring2('chat.came.from', array($referrer))
getstring2('chat.came.from', array($referrer), true)
);
}
if ($email) {
$thread->postMessage(
Thread::KIND_FOR_AGENT,
getstring2('chat.visitor.email', array($email))
getstring2('chat.visitor.email', array($email), true)
);
}
if ($info) {
$thread->postMessage(
Thread::KIND_FOR_AGENT,
getstring2('chat.visitor.info', array($info))
getstring2('chat.visitor.info', array($info), true)
);
}
$thread->postMessage(Thread::KIND_USER, $message, array('name' => $name));

View File

@ -19,12 +19,44 @@ namespace Mibew\Style;
// Import namespaces and classes of the core
use Mibew\Settings;
use Mibew\Handlebars\HelpersSet;
/**
* Represents a style for operator pages
*/
class PageStyle extends AbstractStyle implements StyleInterface
{
/**
* Template engine for chat templates.
*
* @var \Handlebars\Handlebars
*/
protected $templateEngine;
/**
* Object constructor
*
* @param string $style_name Name of the style
*/
public function __construct($style_name)
{
parent::__construct($style_name);
$templates_loader = new \Handlebars\Loader\FilesystemLoader(
MIBEW_FS_ROOT . '/' . $this->filesPath() . '/templates_src/server_side/'
);
$this->templateEngine = new \Handlebars\Handlebars(array(
'loader' => $templates_loader,
'partials_loader' => $templates_loader,
'helpers' => new \Handlebars\Helpers(HelpersSet::getHelpers())
));
// Use custom function to escape strings
$this->templateEngine->setEscape('safe_htmlspecialchars');
$this->templateEngine->setEscapeArgs(array());
}
/**
* Builds base path for style files. This path is relative Mibew root and
* does not contain neither leading nor trailing slash.
@ -49,20 +81,18 @@ class PageStyle extends AbstractStyle implements StyleInterface
// Prepare to output html
start_html_output();
// Build full view name. Remove '\' and '/' characters form the
// specified view name
$full_view_name = MIBEW_FS_ROOT . '/' . $this->filesPath() . '/views/'
. str_replace("/\\", '', $template_name) . '.php';
// $page variable is used in included views files, so we need to create
// it as an alias of $data argument.
$page = $data;
// Add template root value to page variables
$page['stylepath'] = MIBEW_WEB_ROOT . '/' . $this->filesPath();
// Pass additional variables to template
$page['mibewRoot'] = MIBEW_WEB_ROOT;
$page['mibewVersion'] = MIBEW_VERSION;
$page['currentLocale'] = CURRENT_LOCALE;
$page['rtl'] = (getlocal("localedirection") == 'rtl');
$page['stylePath'] = MIBEW_WEB_ROOT . '/' . $this->filesPath();
// Load and execute the view
require($full_view_name);
echo($this->templateEngine->render($template_name, $page));
}
/**

View File

@ -364,7 +364,7 @@ class Thread
// Send message
$thread->postMessage(
self::KIND_EVENTS,
getstring_("chat.status.user.reopenedthread", $thread->locale)
getstring_("chat.status.user.reopenedthread", $thread->locale, true)
);
return $thread;
@ -602,7 +602,8 @@ class Thread
// Send message to user
$message_to_post = getstring_(
"chat.status.operator.dead",
$this->locale
$this->locale,
true
);
$this->postMessage(
self::KIND_CONN,
@ -626,7 +627,8 @@ class Thread
// And send a message to operator
$message_to_post = getstring_(
"chat.status.user.dead",
$this->locale
$this->locale,
true
);
$this->postMessage(
self::KIND_FOR_AGENT,
@ -708,13 +710,15 @@ class Thread
$message_to_post = getstring2_(
"chat.status.operator.changed",
array($operator_name, $this->agentName),
$this->locale
$this->locale,
true
);
} else {
$message_to_post = getstring2_(
"chat.status.operator.returned",
array($operator_name),
$this->locale
$this->locale,
true
);
}
@ -867,7 +871,8 @@ class Thread
getstring2_(
"chat.status.user.left",
array($this->userName),
$this->locale
$this->locale,
true
)
);
} else {
@ -876,7 +881,8 @@ class Thread
self::KIND_FOR_AGENT,
getstring_(
"chat.visitor.invitation.canceled",
$this->locale
$this->locale,
true
)
);
} else {
@ -885,7 +891,8 @@ class Thread
getstring2_(
"chat.status.operator.left",
array($this->agentName),
$this->locale
$this->locale,
true
)
);
}
@ -942,20 +949,23 @@ class Thread
$message = getstring2_(
"chat.status.operator.changed",
array($operator_name, $this->agentName),
$this->locale
$this->locale,
true
);
} else {
$message = getstring2_(
"chat.status.operator.returned",
array($operator_name),
$this->locale
$this->locale,
true
);
}
} else {
$message = getstring2_(
"chat.status.operator.joined",
array($operator_name),
$this->locale
$this->locale,
true
);
}
} elseif ($this->state == self::STATE_CHATTING) {
@ -965,7 +975,8 @@ class Thread
$message = getstring2_(
"chat.status.operator.changed",
array($operator_name, $this->agentName),
$this->locale
$this->locale,
true
);
}
} else {
@ -1015,7 +1026,8 @@ class Thread
$message = getstring2_(
"chat.status.user.changedname",
array($old_name, $new_name),
$this->locale
$this->locale,
true
);
$this->postMessage(self::KIND_EVENTS, $message);
}

View File

@ -33,20 +33,18 @@ function csrf_check_token()
}
}
/* print csrf token as a hidden field */
function print_csrf_token_input()
function get_csrf_token_input()
{
set_csrf_token();
echo "<input name='csrf_token' type='hidden' value='" . $_SESSION['csrf_token'] . "' />";
return '<input name="csrf_token" type="hidden" value="' . $_SESSION['csrf_token'] . '" />';
}
/* print csrf token in url format */
function print_csrf_token_in_url()
function get_csrf_token_in_url()
{
set_csrf_token();
echo "&amp;csrf_token=" . $_SESSION['csrf_token'];
return "&amp;csrf_token=" . $_SESSION['csrf_token'];
}
/* set csrf token */

View File

@ -287,7 +287,7 @@ function getoutputenc()
: MIBEW_ENCODING;
}
function getstring_($text, $locale)
function getstring_($text, $locale, $raw = false)
{
global $messages;
if (!isset($messages[$locale])) {
@ -296,53 +296,66 @@ function getstring_($text, $locale)
$localized = $messages[$locale];
if (isset($localized[$text])) {
return $localized[$text];
return $raw
? $localized[$text]
: sanitize_string($localized[$text], 'low', 'moderate');
}
if ($locale != 'en') {
return getstring_($text, 'en');
return getstring_($text, 'en', $raw);
}
return "!" . $text;
return "!" . ($raw ? $text : sanitize_string($text, 'low', 'moderate'));
}
function getstring($text)
function getstring($text, $raw = false)
{
return getstring_($text, CURRENT_LOCALE);
return getstring_($text, CURRENT_LOCALE, $raw);
}
function getlocal($text)
function getlocal($text, $raw = false)
{
return myiconv(MIBEW_ENCODING, getoutputenc(), getstring_($text, CURRENT_LOCALE));
return getlocal_($text, CURRENT_LOCALE, $raw);
}
function getlocal_($text, $locale)
function getlocal_($text, $locale, $raw = false)
{
return myiconv(MIBEW_ENCODING, getoutputenc(), getstring_($text, $locale));
$string = myiconv(
MIBEW_ENCODING,
getoutputenc(),
getstring_($text, $locale, true)
);
return $raw ? $string : sanitize_string($string, 'low', 'moderate');
}
function getstring2_($text, $params, $locale)
function getstring2_($text, $params, $locale, $raw = false)
{
$string = getstring_($text, $locale);
$string = getstring_($text, $locale, true);
for ($i = 0; $i < count($params); $i++) {
$string = str_replace("{" . $i . "}", $params[$i], $string);
}
return $string;
return $raw ? $string : sanitize_string($string, 'low', 'moderate');
}
function getstring2($text, $params)
function getstring2($text, $params, $raw = false)
{
return getstring2_($text, $params, CURRENT_LOCALE);
return getstring2_($text, $params, CURRENT_LOCALE, $raw);
}
function getlocal2($text, $params)
function getlocal2($text, $params, $raw = false)
{
$string = myiconv(MIBEW_ENCODING, getoutputenc(), getstring_($text, CURRENT_LOCALE));
$string = myiconv(
MIBEW_ENCODING,
getoutputenc(),
getstring_($text, CURRENT_LOCALE, true)
);
for ($i = 0; $i < count($params); $i++) {
$string = str_replace("{" . $i . "}", $params[$i], $string);
}
return $string;
return $raw ? $string : sanitize_string($string, 'low', 'moderate');
}
/* prepares for Javascript string */
@ -354,7 +367,7 @@ function get_local_for_js($text, $params)
$string = str_replace("{" . $i . "}", $params[$i], $string);
}
return $string;
return sanitize_string($string, 'low', 'moderate');
}
function locale_load_id_list($name)

View File

@ -54,3 +54,116 @@ function escape_with_cdata($text)
{
return "<![CDATA[" . str_replace("]]>", "]]>]]&gt;<![CDATA[", $text) . "]]>";
}
/**
* Simple HTML sanitation.
*
* Includes some code from the PHP StripAttributes Class For XML and HTML.
*
* @param string $string Target string
* @param string $tags_level Sanitation level for tags. Available values are
* "high", "moderate" and "low".
* @param string $attr_level Sanitation level for attributes. Available values
* are "high", "moderate" and "low".
* @return string Sanitized string with stripped dangerous tags and attributes.
*
* @author David (semlabs.co.uk)
* @copyright (c) 2009, David (semlabs.co.uk)
* @license MIT
* @link http://semlabs.co.uk/journal/php-strip-attributes-class-for-xml-and-html
*/
function sanitize_string($string, $tags_level = 'high', $attr_level = 'high')
{
$sanitize_tags = array(
'high' => '',
'moderate' => '<span><em><strong><b><i><br>',
'low' => '<span><em><strong><b><i><br><p><ul><ol><li><a><font><style>',
);
$sanitize_attributes = array(
'high' => array(),
'moderate' => array('class', 'style', 'href', 'rel', 'id'),
'low' => false,
);
$tags_level = array_key_exists($tags_level, $sanitize_tags) ? $tags_level : 'high';
$string = strip_tags($string, $sanitize_tags[$tags_level]);
$attr_level = array_key_exists($attr_level, $sanitize_attributes) ? $attr_level : 'high';
if ($sanitize_attributes[$attr_level]) {
preg_match_all("/<([^ !\/\>\n]+)([^>]*)>/i", $string, $elements);
foreach ($elements[1] as $key => $element) {
if ($elements[2][$key]) {
$new_attributes = '';
preg_match_all(
"/([^ =]+)\s*=\s*[\"|']{0,1}([^\"']*)[\"|']{0,1}/i",
$elements[2][$key],
$attributes
);
if ($attributes[1]) {
foreach ($attributes[1] as $attr_key => $attr) {
if (in_array($attributes[1][$attr_key], $sanitize_attributes[$attr_level])) {
$new_attributes .= ' ' . $attributes[1][$attr_key]
. '="' . $attributes[2][$attr_key] . '"';
}
}
}
$replacement = '<' . $elements[1][$key] . $new_attributes . '>';
$string = preg_replace(
'/' . sanitize_reg_escape($elements[0][$key]) . '/',
$replacement,
$string
);
}
}
}
return $string;
}
/**
* Remove dangerous characters from regular expression.
*
* @param string $string Target regular expression
* @return string Sanitized reqular expression
*/
function sanitize_reg_escape($string)
{
$conversions = array(
"^" => "\^",
"[" => "\[",
"." => "\.",
"$" => "\$",
"{" => "\{",
"*" => "\*",
"(" => "\(",
"\\" => "\\\\",
"/" => "\/",
"+" => "\+",
")" => "\)",
"|" => "\|",
"?" => "\?",
"<" => "\<",
">" => "\>",
);
return strtr($string, $conversions);
}
/**
* Wrapper for htmlspecialchars with single quotes conversion enabled by default
*
* @param string $string Target string
* @return string Escaped string
*/
function safe_htmlspecialchars($string)
{
$string = preg_replace('/[\x00-\x08\x10-\x1f]/', '', $string);
return htmlspecialchars($string, ENT_QUOTES);
}

View File

@ -47,6 +47,9 @@ require_once(MIBEW_FS_ROOT . '/libs/common/constants.php');
require_once(MIBEW_FS_ROOT . '/libs/common/autoload.php');
spl_autoload_register('class_autoload');
// Initialize external dependencies
require_once(MIBEW_FS_ROOT . '/vendor/autoload.php');
// Include common libs
require_once(MIBEW_FS_ROOT . '/libs/common/configurations.php');
require_once(MIBEW_FS_ROOT . '/libs/common/verification.php');

View File

@ -121,12 +121,13 @@ function invitation_invite($visitor_id, $operator)
Thread::KIND_FOR_AGENT,
getlocal2(
'chat.visitor.invitation.sent',
array($operator_name, $last_visited_page)
array($operator_name, $last_visited_page),
true
)
);
$thread->postMessage(
Thread::KIND_AGENT,
getlocal("invitation.message"),
getlocal("invitation.message", true),
array(
'name' => $operator_name,
'operator_id' => $operator['operatorid'],
@ -200,7 +201,7 @@ function invitation_reject($visitor_id)
if ($thread) {
$thread->postMessage(
Thread::KIND_FOR_AGENT,
getlocal('chat.visitor.invitation.rejected')
getlocal('chat.visitor.invitation.rejected', true)
);
}
@ -270,7 +271,7 @@ function invitation_close_old()
$thread = Thread::createFromDbInfo($thread_info);
$thread->postMessage(
Thread::KIND_FOR_AGENT,
getstring_('chat.visitor.invitation.ignored', $thread->locale)
getstring_('chat.visitor.invitation.ignored', $thread->locale, true)
);
unset($thread);
}

View File

@ -761,6 +761,10 @@ function prepare_menu($operator, $has_right = true)
$result = array();
$result['operator'] = to_page(get_operator_name($operator));
$result['goOnlineLink'] = getlocal2(
"menu.goonline",
array(MIBEW_WEB_ROOT . "/operator/users.php?nomenu")
);
if ($has_right) {
$result['showban'] = Settings::get('enableban') == "1";
$result['showstat'] = Settings::get('enablestatistics') == "1";

View File

@ -25,6 +25,7 @@ $page = array();
$page['title'] = getlocal("license.title");
$page['no_right_menu'] = true;
$page['fixedwrap'] = true;
$page['show_small_login'] = false;
$page_style = new PageStyle(PageStyle::currentStyle());
$page_style->render('license', $page);

View File

@ -167,7 +167,7 @@ form.field.groupname.description=Name to identify the group.
form.field.groupname=Name
form.field.groupparent=Parent group
form.field.groupparent.description=Groups can be organized in a hierarchical structure
form.field.groupparent.root=&lt;none&gt;
form.field.groupparent.root=-none-
form.field.groupweight=Weight
form.field.groupweight.description=Groups with lower weight display higher in groups list. Group weight is a positive integer value.
form.field.login.description=Login can consist of small Latin letters and underscore.

View File

@ -71,14 +71,15 @@ foreach ($messages as $msg) {
$history .= message_to_text($msg);
}
$subject = getstring("mail.user.history.subject");
$subject = getstring("mail.user.history.subject", true);
$body = getstring2(
"mail.user.history.body",
array($thread->userName,
$history,
Settings::get('title'),
Settings::get('hosturl')
)
),
true
);
mibew_mail($email, $mibew_mailbox, $subject, $body);

View File

@ -123,7 +123,7 @@ if (isset($_POST['address'])) {
$thread_id = verify_param('thread', "/^\d{1,9}$/");
$thread = Thread::load($thread_id);
if ($thread) {
$page['thread'] = to_page($thread->userName);
$page['thread'] = htmlspecialchars(to_page($thread->userName));
$page['threadid'] = $thread_id;
$page['formaddress'] = to_page($thread->remote);
$page['formdays'] = 15;

View File

@ -57,6 +57,11 @@ $blocked_list = $db->query(
array('return_rows' => Database::RETURN_ALL_ROWS)
);
foreach ($blocked_list as &$item) {
$item['comment'] = to_page($item['comment']);
}
unset($item);
$page['title'] = getlocal("page_bans.title");
$page['menuid'] = "blocked";

View File

@ -92,8 +92,14 @@ if (isset($_GET['act']) && $_GET['act'] == 'delete') {
// Get messages and setup pagination
$messages = load_canned_messages($lang, $group_id);
$pagination = setup_pagination($messages);
$canned_messages = load_canned_messages($lang, $group_id);
foreach ($canned_messages as &$message) {
$message['vctitle'] = to_page($message['vctitle']);
$message['vcvalue'] = to_page($message['vcvalue']);
}
unset($message);
$pagination = setup_pagination($canned_messages);
$page['pagination'] = $pagination['info'];
$page['pagination.items'] = $pagination['items'];

View File

@ -71,7 +71,7 @@ if (isset($_POST['message']) && isset($_POST['title'])) {
}
$page['saved'] = true;
$page = array_merge($page, prepare_menu($operator, false));
$page_style->render('cannededit', $page);
$page_style->render('canned_edit', $page);
exit;
}
}
@ -84,4 +84,4 @@ $page['title'] = empty($string_id) ? getlocal("cannednew.title") : getlocal("can
$page = array_merge($page, prepare_menu($operator, false));
$page_style->render('cannededit', $page);
$page_style->render('canned_edit', $page);

View File

@ -121,4 +121,4 @@ $page['menuid'] = "getcode";
$page = array_merge($page, prepare_menu($operator));
$page_style = new PageStyle(PageStyle::currentStyle());
$page_style->render('gen_button', $page);
$page_style->render('get_code', $page);

View File

@ -27,10 +27,12 @@ $operator = check_login();
csrf_check_token();
$group_id = verify_param("gid", "/^\d{1,9}$/");
$page = array('groupid' => $group_id);
$page['operators'] = get_operators_list();
$page['errors'] = array();
$page = array(
'groupid' => $group_id,
'errors' => array(),
);
$operators = get_operators_list();
$group = group_by_id($group_id);
if (!$group) {
@ -38,7 +40,7 @@ if (!$group) {
} elseif (isset($_POST['gid'])) {
$new_members = array();
foreach ($page['operators'] as $op) {
foreach ($operators as $op) {
if (verify_param("op" . $op['operatorid'], "/^on$/", "") == "on") {
$new_members[] = $op['operatorid'];
}
@ -52,8 +54,18 @@ if (!$group) {
$page['formop'] = array();
$page['currentgroup'] = $group ? to_page(htmlspecialchars($group['vclocalname'])) : "";
$checked_operators = array();
foreach (get_group_members($group_id) as $rel) {
$page['formop'][] = $rel['operatorid'];
$checked_operators[] = $rel['operatorid'];
}
$page['operators'] = array();
foreach ($operators as $op) {
$op['vclocalename'] = to_page($op['vclocalename']);
$op['vclogin'] = to_page($op['vclogin']);
$op['checked'] = in_array($op['operatorid'], $checked_operators);
$page['operators'][] = $op;
}
$page['stored'] = isset($_GET['stored']);
@ -65,4 +77,4 @@ $page = array_merge($page, prepare_menu($operator));
$page['tabs'] = setup_group_settings_tabs($group_id, 1);
$page_style = new PageStyle(PageStyle::currentStyle());
$page_style->render('groupmembers', $page);
$page_style->render('group_members', $page);

View File

@ -27,6 +27,10 @@ require_once(MIBEW_FS_ROOT . '/libs/groups.php');
$operator = check_login();
csrf_check_token();
$page = array(
'errors' => array(),
);
if (isset($_GET['act']) && $_GET['act'] == 'del') {
$group_id = isset($_GET['gid']) ? $_GET['gid'] : "";
@ -49,10 +53,22 @@ if (isset($_GET['act']) && $_GET['act'] == 'del') {
}
}
$page = array();
$sort['by'] = verify_param("sortby", "/^(name|lastseen|weight)$/", "name");
$sort['desc'] = (verify_param("sortdirection", "/^(desc|asc)$/", "desc") == "desc");
$page['groups'] = get_sorted_groups($sort);
// Load and prepare groups
$groups = get_sorted_groups($sort);
foreach ($groups as &$group) {
$group['vclocalname'] = to_page($group['vclocalname']);
$group['vclocaldescription'] = to_page($group['vclocaldescription']);
$group['isOnline'] = group_is_online($group);
$group['isAway'] = group_is_away($group);
$group['lastTimeOnline'] = time() - ($group['ilastseen'] ? $group['ilastseen'] : time());
$group['inumofagents'] = to_page($group['inumofagents']);
}
unset($group);
$page['groups'] = $groups;
$page['formsortby'] = $sort['by'];
$page['formsortdirection'] = $sort['desc'] ? 'desc' : 'asc';
$page['canmodify'] = is_capable(CAN_ADMINISTRATE, $operator);

View File

@ -54,7 +54,6 @@ if ($query !== false) {
foreach ($groups as $group) {
$group_name[$group['groupid']] = $group['vclocalname'];
}
$page['groupName'] = $group_name;
$values = array(
':query' => "%{$query}%",
@ -119,7 +118,24 @@ if ($query !== false) {
);
foreach ($threads_list as $item) {
$page['pagination.items'][] = Thread::createFromDbInfo($item);
$thread = Thread::createFromDbInfo($item);
$group_name_set = ($thread->groupId
&& $thread->groupId != 0
&& isset($group_name[$thread->groupId]));
$page['pagination.items'][] = array(
'threadId' => $thread->id,
'userName' => to_page($thread->userName),
'userAddress' => get_user_addr(to_page($thread->remote)),
'agentName' => to_page($thread->agentName),
'messageCount' => to_page($thread->messageCount),
'groupName' => ($group_name_set
? to_page($group_name[$thread->groupId])
: false),
'chatTime' => $thread->modified - $thread->created,
'chatCreated' => $thread->created,
);
}
} else {
$page['pagination'] = false;
@ -136,8 +152,10 @@ $page['formtype'] = $search_type;
$page['forminsystemmessages'] = $search_in_system_messages;
$page['title'] = getlocal("page_analysis.search.title");
$page['menuid'] = "history";
$page['canSearchInSystemMessages'] = ($search_type != 'all')
&& ($search_type != 'message');
$page = array_merge($page, prepare_menu($operator));
$page_style = new PageStyle(PageStyle::currentStyle());
$page_style->render('thread_search', $page);
$page_style->render('history', $page);

View File

@ -38,6 +38,7 @@ $page = array(
'newFeatures' => Settings::get('featuresversion') != FEATURES_VERSION,
'featuresPage' => MIBEW_WEB_ROOT . "/operator/features.php",
'isOnline' => $is_online,
'warnOffline' => true,
'title' => getlocal("topMenu.admin"),
'menuid' => "main",
);
@ -45,4 +46,4 @@ $page = array(
$page = array_merge($page, prepare_menu($operator));
$page_style = new PageStyle(PageStyle::currentStyle());
$page_style->render('menu', $page);
$page_style->render('index', $page);

View File

@ -167,10 +167,11 @@ $page['canchangelogin'] = is_capable(CAN_ADMINISTRATE, $operator);
$page['needChangePassword'] = check_password_hash($operator['vclogin'], '', $operator['vcpassword']);
$page['title'] = getlocal("page_agent.title");
$page['menuid'] = ($op_id == $operator['operatorid']) ? "profile" : "operators";
$page['requirePassword'] = (!$op_id || $page['needChangePassword']);
$page = array_merge($page, prepare_menu($operator));
$page['tabs'] = setup_operator_settings_tabs($op_id, 0);
$page_style = new PageStyle(PageStyle::currentStyle());
$page_style->render('agent', $page);
$page_style->render('operator', $page);

View File

@ -104,7 +104,22 @@ $list_options['sort'] = $sort;
if (in_isolation($operator)) {
$list_options['isolated_operator_id'] = $operator['operatorid'];
}
$page['allowedAgents'] = get_operators_list($list_options);
$operators_list = get_operators_list($list_options);
// Prepare operator to render in template
foreach ($operators_list as &$item) {
$item['vclogin'] = to_page($item['vclogin']);
$item['vclocalename'] = to_page($item['vclocalename']);
$item['vccommonname'] = to_page($item['vccommonname']);
$item['isAvailable'] = operator_is_available($item);
$item['isAway'] = operator_is_away($item);
$item['lastTimeOnline'] = time() - $item['time'];
$item['isDisabled'] = operator_is_disabled($item);
}
unset($item);
$page['allowedAgents'] = $operators_list;
$page['canmodify'] = is_capable(CAN_ADMINISTRATE, $operator);
$page['availableOrders'] = array(
array('id' => 'login', 'name' => getlocal('page_agents.login')),
@ -125,4 +140,4 @@ setlocale(LC_TIME, getstring("time.locale"));
$page = array_merge($page, prepare_menu($operator));
$page_style = new PageStyle(PageStyle::currentStyle());
$page_style->render('agents', $page);
$page_style->render('operators', $page);

View File

@ -29,11 +29,14 @@ csrf_check_token();
$operator_in_isolation = in_isolation($operator);
$op_id = verify_param("op", "/^\d{1,9}$/");
$page = array('opid' => $op_id);
$page['groups'] = $operator_in_isolation
$page = array(
'opid' => $op_id,
'errors' => array()
);
$groups = $operator_in_isolation
? get_all_groups_for_operator($operator)
: get_all_groups();
$page['errors'] = array();
$can_modify = is_capable(CAN_ADMINISTRATE, $operator);
@ -49,7 +52,7 @@ if (!$op) {
if (count($page['errors']) == 0) {
$new_groups = array();
foreach ($page['groups'] as $group) {
foreach ($groups as $group) {
if (verify_param("group" . $group['groupid'], "/^on$/", "") == "on") {
$new_groups[] = $group['groupid'];
}
@ -61,21 +64,30 @@ if (!$op) {
}
}
$page['formgroup'] = array();
$page['currentop'] = $op
? to_page(get_operator_name($op)) . " (" . $op['vclogin'] . ")"
: getlocal("not_found");
$page['canmodify'] = $can_modify ? "1" : "";
$checked_groups = array();
if ($op) {
foreach (get_operator_group_ids($op_id) as $rel) {
$page['formgroup'][] = $rel['groupid'];
$checked_groups[] = $rel['groupid'];
}
}
$page['groups'] = array();
foreach ($groups as $group) {
$group['vclocalname'] = to_page($group['vclocalname']);
$group['vclocaldescription'] = to_page($group['vclocaldescription']);
$group['checked'] = in_array($group['groupid'], $checked_groups);
$page['groups'][] = $group;
}
$page['stored'] = isset($_GET['stored']);
$page['title'] = getlocal("operator.groups.title");
$page['menuid'] = ($page['operatorid'] == $op_id) ? "profile" : "operators";
$page['menuid'] = ($operator['operatorid'] == $op_id) ? "profile" : "operators";
$page = array_merge($page, prepare_menu($operator));

View File

@ -64,18 +64,23 @@ if (!$op) {
}
}
$page['permissionsList'] = get_permission_list();
$page['formpermissions'] = array("");
$page['currentop'] = $op ? to_page(get_operator_name($op)) . " (" . $op['vclogin'] . ")" : getlocal("not_found");
$checked_permissions = array();
if ($op) {
foreach (permission_ids() as $perm => $id) {
if (is_capable($perm, $op)) {
$page['formpermissions'][] = $id;
$checked_permissions[] = $id;
}
}
}
$page['permissionsList'] = array();
foreach(get_permission_list() as $perm) {
$perm['checked'] = in_array($perm['id'], $checked_permissions);
$page['permissionsList'][] = $perm;
}
$page['stored'] = isset($_GET['stored']);
$page['title'] = getlocal("permissions.title");
$page['menuid'] = ($operator['operatorid'] == $op_id) ? "profile" : "operators";

View File

@ -66,7 +66,8 @@ if (isset($_GET['nextGroup'])) {
getstring2_(
"chat.status.operator.redirect",
array(get_operator_name($operator)),
$thread->locale
$thread->locale,
true
)
);
} else {
@ -110,7 +111,8 @@ if (isset($_GET['nextGroup'])) {
getstring2_(
"chat.status.operator.redirect",
array(get_operator_name($operator)),
$thread->locale
$thread->locale,
true
)
);
} else {

View File

@ -44,8 +44,13 @@ $page['showbydate'] = ($statistics_type == 'bydate');
$page['showbyagent'] = ($statistics_type == 'byagent');
$page['showbypage'] = ($statistics_type == 'bypage');
$page['cron_path'] = cron_get_uri(Settings::get('cron_key'));
$page['last_cron_run'] = Settings::get('_last_cron_run');
$page['pageDescription'] = getlocal2(
"statistics.description.full",
array(
date_to_text(Settings::get('_last_cron_run')),
cron_get_uri(Settings::get('cron_key')),
)
);
$page['show_invitations_info'] = (bool) Settings::get('enabletracking');
@ -159,6 +164,15 @@ if ($statistics_type == 'bydate') {
),
array('return_rows' => Database::RETURN_ALL_ROWS)
);
// We need to pass operator name through "to_page" function because we
// cannot do it in a template.
// TODO: Remove this block when "to_page" function will be removed.
foreach ($page['reportByAgent'] as &$row) {
$row['name'] = to_page($row['name']);
}
unset($row);
$active_tab = 1;
} elseif ($statistics_type == 'bypage') {
$page['reportByPage'] = $db->query(

View File

@ -40,14 +40,19 @@ if (isset($_GET['threadid'])) {
$group = group_by_id($thread->groupId);
$thread_info = array(
'thread' => $thread,
'groupName' => get_group_name($group),
'userName' => to_page($thread->userName),
'userAddress' => get_user_addr(to_page($thread->remote)),
'userAgentVersion' => get_user_agent_version(to_page($thread->userAgent)),
'agentName' => to_page($thread->agentName),
'chatTime' => ($thread->modified - $thread->created),
'chatStarted' => $thread->created,
'groupName' => to_page(get_group_name($group)),
);
$page['thread_info'] = $thread_info;
$page['threadInfo'] = $thread_info;
// Build messages list
$last_id = -1;
$messages = $thread_info['thread']->getMessages(false, $last_id);
$messages = $thread->getMessages(false, $last_id);
$page['threadMessages'] = json_encode($messages);
}

View File

@ -63,6 +63,7 @@ foreach ($path as $k => $v) {
}
$page['title'] = getlocal("tracked.path");
$page['show_small_login'] = false;
$page_style = new PageStyle(PageStyle::currentStyle());
$page_style->render('tracked', $page);

View File

@ -43,8 +43,8 @@ $lang2 = $messages[$target];
$page = array(
'lang1' => $source,
'lang2' => $target,
'title1' => isset($lang1["localeid"]) ? $lang1["localeid"] : $source,
'title2' => isset($lang2["localeid"]) ? $lang2["localeid"] : $target,
'title1' => to_page(isset($lang1["localeid"]) ? $lang1["localeid"] : $source),
'title2' => to_page(isset($lang2["localeid"]) ? $lang2["localeid"] : $target),
'errors' => array(),
);
@ -117,6 +117,9 @@ foreach ($all_keys as $key) {
'id' => $key,
'l1' => $t_source,
'l2' => $value,
'idToPage' => to_page($key),
'l1ToPage' => to_page($t_source),
'l2ToPage' => to_page($value),
);
}
}
@ -163,4 +166,4 @@ $page['menuid'] = "translate";
$page = array_merge($page, prepare_menu($operator));
$page_style->render('translatelist', $page);
$page_style->render('translate_list', $page);

View File

@ -71,11 +71,19 @@ $page['pagination'] = $pagination['info'];
$page['pagination.items'] = $pagination['items'];
foreach ($page['pagination.items'] as $key => $item) {
$page['pagination.items'][$key] = Thread::createFromDbInfo($item);
$thread = Thread::createFromDbInfo($item);
$page['pagination.items'][$key] = array(
'threadId' => to_page($thread->id),
'userName' => to_page($thread->userName),
'userAddress' => get_user_addr(to_page($thread->remote)),
'agentName' => to_page($thread->agentName),
'chatTime' => ($thread->modified - $thread->created),
'chatCreated' => $thread->created,
);
}
$page['title'] = getlocal("page.analysis.userhistory.title");
$page['menuid'] = "history";
$page_style = new PageStyle(PageStyle::currentStyle());
$page_style->render('userhistory', $page);
$page_style->render('user_history', $page);

View File

@ -35,7 +35,7 @@ notify_operator_alive($operator['operatorid'], $status);
$_SESSION[SESSION_PREFIX . "operatorgroups"] = get_operator_groups_list($operator['operatorid']);
$page = array();
$page['havemenu'] = isset($_GET['nomenu']) ? "0" : "1";
$page['havemenu'] = !isset($_GET['nomenu']);
$page['showpopup'] = (Settings::get('enablepopupnotification') == '1') ? "1" : "0";
$page['frequency'] = Settings::get('updatefrequency_operator');
$page['istatus'] = $status;
@ -68,4 +68,4 @@ $page = array_merge($page, get_plugins_data('users'));
$page = array_merge($page, prepare_menu($operator));
$page_style->render('pending_users', $page);
$page_style->render('users', $page);

View File

@ -800,10 +800,13 @@ table.awaiting .no-threads, table.awaiting .no-visitors {
}
.dashitem {
width:33%;
margin: 0px 2em 5em 0px;
padding: 5px 2em 5em;
width:32%;
vertical-align: top;
display: inline-block;
}
.dashitem-content {
padding: 5px 2em 5em;
}
.dashitem:hover {

View File

@ -18,3 +18,8 @@
display: inline;
zoom: 1;
}
.dashitem {
display: inline;
zoom: 1;
}

View File

@ -0,0 +1,34 @@
/*
Copyright 2005-2013 the original author or authors.
Licensed under the Apache License, Version 2.0 (the "License").
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
*/
(function(){var k=Handlebars.template,l=Handlebars.templates=Handlebars.templates||{};l.visitor=k(function(b,c,e,a,d){function f(){return"-"}this.compilerInfo=[4,">= 1.0.0"];e=this.merge(e,b.helpers);d=d||{};var g,h=e.helperMissing,j=this.escapeExpression;b='<td class="visitor">\n ';if((a=e.unless.call(c,c.invitationInfo,{hash:{},inverse:this.program(3,function(a,b){var c;(c=e.userName)?c=c.call(a,{hash:{},data:b}):(c=a.userName,c="function"===typeof c?c.apply(a):c);return j(c)},d),fn:this.program(1,
function(a,b){var c,d;c={hash:{},data:b};c='<a href="javascript:void(0);" class="invite-link" title="'+(j((d=e.L10n||a.L10n,d?d.call(a,"pending.table.invite",c):h.call(a,"L10n","pending.table.invite",c)))+'">');(d=e.userName)?d=d.call(a,{hash:{},data:b}):(d=a.userName,d="function"===typeof d?d.apply(a):d);return c+=j(d)+"</a>"},d),data:d}))||0===a)b+=a;g={hash:{},data:d};b=b+'\n</td>\n<td class="visitor">\n <div class="default-visitor-controls inline-block">\n <div class="control track-control inline-block" title="'+
(j((a=e.L10n||c.L10n,a?a.call(c,"pending.table.tracked",g):h.call(c,"L10n","pending.table.tracked",g)))+'"></div>\n </div>\n <div class="visitor-controls inline-block"></div>\n</td>\n<td class="visitor">');if((a=e["if"].call(c,c.userIp,{hash:{},inverse:this.program(7,function(a,c){var b;(b=e.remote)?b=b.call(a,{hash:{},data:c}):(b=a.remote,b="function"===typeof b?b.apply(a):b);return j(b)},d),fn:this.program(5,function(a,b){var c,d;c='<a href="javascript:void(0);" class="geo-link" title="GeoLocation">';
(d=e.remote)?d=d.call(a,{hash:{},data:b}):(d=a.remote,d="function"===typeof d?d.apply(a):d);return c+=j(d)+"</a>"},d),data:d}))||0===a)b+=a;b+='</td>\n<td class="visitor"><span class="timesince" data-timestamp="';(a=e.firstTime)?a=a.call(c,{hash:{},data:d}):(a=c.firstTime,a="function"===typeof a?a.apply(c):a);b+=j(a)+'"></span></td>\n<td class="visitor"><span class="timesince" data-timestamp="';(a=e.lastTime)?a=a.call(c,{hash:{},data:d}):(a=c.lastTime,a="function"===typeof a?a.apply(c):a);b+=j(a)+
'"></span></td>\n<td class="visitor">';if((a=e["if"].call(c,c.invitationInfo,{hash:{},inverse:this.program(11,f,d),fn:this.program(9,function(a){var b;return j((b=(b=a.invitationInfo,null==b||!1===b?b:b.agentName),"function"===typeof b?b.apply(a):b))},d),data:d}))||0===a)b+=a;b+='</td>\n<td class="visitor">';if((a=e["if"].call(c,c.invitationInfo,{hash:{},inverse:this.program(11,f,d),fn:this.program(13,function(a){var b;return a=""+('<span class="timesince" data-timestamp="'+j((b=(b=a.invitationInfo,
null==b||!1===b?b:b.time),"function"===typeof b?b.apply(a):b))+'"></span>')},d),data:d}))||0===a)b+=a;b+='</td>\n<td class="visitor">';(a=e.invitations)?a=a.call(c,{hash:{},data:d}):(a=c.invitations,a="function"===typeof a?a.apply(c):a);b+=j(a)+" / ";(a=e.chats)?a=a.call(c,{hash:{},data:d}):(a=c.chats,a="function"===typeof a?a.apply(c):a);b+=j(a)+'</td>\n<td class="visitor">';(a=e.userAgent)?a=a.call(c,{hash:{},data:d}):(a=c.userAgent,a="function"===typeof a?a.apply(c):a);return b+=j(a)+"</td>"});
l.queued_thread=k(function(b,c,e,a,d){this.compilerInfo=[4,">= 1.0.0"];e=this.merge(e,b.helpers);d=d||{};var f=e.helperMissing,g=this.escapeExpression;b='<td class="visitor">\n <div><a href="javascript:void(0);" class="user-name open-dialog" title="';if((a=e["if"].call(c,c.canOpen,{hash:{},inverse:this.program(3,function(a,b){var c,d;d={hash:{},data:b};return g((c=e.L10n||a.L10n,c?c.call(a,"pending.table.view",d):f.call(a,"L10n","pending.table.view",d)))},d),fn:this.program(1,function(a,b){var c,
d;d={hash:{},data:b};return g((c=e.L10n||a.L10n,c?c.call(a,"pending.table.speak",d):f.call(a,"L10n","pending.table.speak",d)))},d),data:d}))||0===a)b+=a;b+='">';if((a=e["if"].call(c,c.ban,{hash:{},inverse:this.noop,fn:this.program(5,function(a,b){var c,d;c={hash:{},data:b};return c=""+(g((d=e.L10n||a.L10n,d?d.call(a,"chat.client.spam.prefix",c):f.call(a,"L10n","chat.client.spam.prefix",c)))+"&nbsp;")},d),data:d}))||0===a)b+=a;(a=e.userName)?a=a.call(c,{hash:{},data:d}):(a=c.userName,a="function"===
typeof a?a.apply(c):a);b+=g(a)+"</a></div>\n ";if((a=e["if"].call(c,c.firstMessage,{hash:{},inverse:this.noop,fn:this.program(7,function(a,b){var c,d;c='<div class="first-message"><a href="javascript:void(0);" title="';(d=e.firstMessage)?d=d.call(a,{hash:{},data:b}):(d=a.firstMessage,d="function"===typeof d?d.apply(a):d);c+=g(d)+'">';(d=e.firstMessagePreview)?d=d.call(a,{hash:{},data:b}):(d=a.firstMessagePreview,d="function"===typeof d?d.apply(a):d);return c+=g(d)+"</a></div>"},d),data:d}))||0===
a)b+=a;b+='\n</td>\n<td class="visitor">\n <div class="default-thread-controls inline-block">\n ';if((a=e["if"].call(c,c.canOpen,{hash:{},inverse:this.noop,fn:this.program(9,function(a,b){var c,d;c={hash:{},data:b};return c='\n <div class="control open-dialog open-control inline-block" title="'+(g((d=e.L10n||a.L10n,d?d.call(a,"pending.table.speak",c):f.call(a,"L10n","pending.table.speak",c)))+'"></div>\n ')},d),data:d}))||0===a)b+=a;b+="\n ";if((a=e["if"].call(c,
c.canView,{hash:{},inverse:this.noop,fn:this.program(11,function(a,b){var c,d;c={hash:{},data:b};return c='\n <div class="control view-control inline-block" title="'+(g((d=e.L10n||a.L10n,d?d.call(a,"pending.table.view",c):f.call(a,"L10n","pending.table.view",c)))+'"></div>\n ')},d),data:d}))||0===a)b+=a;b+="\n ";if((a=e["if"].call(c,c.tracked,{hash:{},inverse:this.noop,fn:this.program(13,function(a,b){var c,d;c={hash:{},data:b};return c='\n <div class="control track-control inline-block" title="'+
(g((d=e.L10n||a.L10n,d?d.call(a,"pending.table.tracked",c):f.call(a,"L10n","pending.table.tracked",c)))+'"></div>\n ')},d),data:d}))||0===a)b+=a;b+="\n ";if((a=e["if"].call(c,c.canBan,{hash:{},inverse:this.noop,fn:this.program(15,function(a,b){var c,d;c={hash:{},data:b};return c='\n <div class="control ban-control inline-block" title="'+(g((d=e.L10n||a.L10n,d?d.call(a,"pending.table.ban",c):f.call(a,"L10n","pending.table.ban",c)))+'"></div>\n ')},d),data:d}))||0===
a)b+=a;b+='\n </div>\n <div class="thread-controls inline-block"></div>\n</td>\n<td class="visitor">';if((a=e["if"].call(c,c.userIp,{hash:{},inverse:this.program(19,function(a,b){var c;(c=e.remote)?c=c.call(a,{hash:{},data:b}):(c=a.remote,c="function"===typeof c?c.apply(a):c);return g(c)},d),fn:this.program(17,function(a,c){var b,d;b='<a href="javascript:void(0);" class="geo-link" title="GeoLocation">';(d=e.remote)?d=d.call(a,{hash:{},data:c}):(d=a.remote,d="function"===typeof d?d.apply(a):
d);return b+=g(d)+"</a>"},d),data:d}))||0===a)b+=a;b+='</td>\n<td class="visitor">';(a=e.stateDesc)?a=a.call(c,{hash:{},data:d}):(a=c.stateDesc,a="function"===typeof a?a.apply(c):a);b+=g(a)+'</td>\n<td class="visitor">';(a=e.agentName)?a=a.call(c,{hash:{},data:d}):(a=c.agentName,a="function"===typeof a?a.apply(c):a);b+=g(a)+'</td>\n<td class="visitor"><span class="timesince" data-timestamp="';(a=e.totalTime)?a=a.call(c,{hash:{},data:d}):(a=c.totalTime,a="function"===typeof a?a.apply(c):a);b+=g(a)+
'"></span></td>\n<td class="visitor">';if((a=e.unless.call(c,c.chatting,{hash:{},inverse:this.program(23,function(){return"-"},d),fn:this.program(21,function(a,c){var b,d;b='<span class="timesince" data-timestamp="';(d=e.waitingTime)?d=d.call(a,{hash:{},data:c}):(d=a.waitingTime,d="function"===typeof d?d.apply(a):d);return b+=g(d)+'"></span>'},d),data:d}))||0===a)b+=a;b+='</td>\n<td class="visitor">';if((a=e["if"].call(c,c.ban,{hash:{},inverse:this.program(27,function(a,c){var b;(b=e.userAgent)?b=
b.call(a,{hash:{},data:c}):(b=a.userAgent,b="function"===typeof b?b.apply(a):b);return g(b)},d),fn:this.program(25,function(a){var b;return g((b=(b=a.ban,null==b||!1===b?b:b.reason),"function"===typeof b?b.apply(a):b))},d),data:d}))||0===a)b+=a;return b+"</td>"});l.no_visitors=k(function(b,c,e,a,d){this.compilerInfo=[4,">= 1.0.0"];e=this.merge(e,b.helpers);d=d||{};var f;b=e.helperMissing;a=this.escapeExpression;d={hash:{},data:d};return c='<td class="no-visitors" colspan="9">'+(a((f=e.L10n||c.L10n,
f?f.call(c,"visitors.no_visitors",d):b.call(c,"L10n","visitors.no_visitors",d)))+"</td>")});l.no_threads=k(function(b,c,e,a,d){this.compilerInfo=[4,">= 1.0.0"];e=this.merge(e,b.helpers);d=d||{};var f;b=e.helperMissing;a=this.escapeExpression;d={hash:{},data:d};return c='<td class="no-threads" colspan="8">'+(a((f=e.L10n||c.L10n,f?f.call(c,"clients.no_clients",d):b.call(c,"L10n","clients.no_clients",d)))+"</td>")});l.status_panel=k(function(b,c,e,a,d){this.compilerInfo=[4,">= 1.0.0"];e=this.merge(e,
b.helpers);d=d||{};var f,g=e.helperMissing,h=this.escapeExpression;b='<div id="connstatus">';(a=e.message)?a=a.call(c,{hash:{},data:d}):(a=c.message,a="function"===typeof a?a.apply(c):a);b+=h(a);if((f=e["if"].call(c,(a=c.agent,null==a||!1===a?a:a.away),{hash:{},inverse:this.program(3,function(a,b){var c,d;d={hash:{},data:b};return h((c=e.L10n||a.L10n,c?c.call(a,"pending.status.online",d):g.call(a,"L10n","pending.status.online",d)))},d),fn:this.program(1,function(a,b){var c,d;d={hash:{},data:b};return h((c=
e.L10n||a.L10n,c?c.call(a,"pending.status.away",d):g.call(a,"L10n","pending.status.away",d)))},d),data:d}))||0===f)b+=f;b+='</div><div id="connlinks"><a href="javascript:void(0);" id="change-status">';if((f=e["if"].call(c,(a=c.agent,null==a||!1===a?a:a.away),{hash:{},inverse:this.program(7,function(a,b){var c,d;d={hash:{},data:b};return h((c=e.L10n||a.L10n,c?c.call(a,"pending.status.setaway",d):g.call(a,"L10n","pending.status.setaway",d)))},d),fn:this.program(5,function(a,b){var c,d;d={hash:{},data:b};
return h((c=e.L10n||a.L10n,c?c.call(a,"pending.status.setonline",d):g.call(a,"L10n","pending.status.setonline",d)))},d),data:d}))||0===f)b+=f;return b+"</a></div>"});l.threads_collection=k(function(b,c,e,a,d){this.compilerInfo=[4,">= 1.0.0"];e=this.merge(e,b.helpers);d=d||{};var f,g=e.helperMissing,h=this.escapeExpression;a={hash:{},data:d};b='<table class="awaiting" border="0">\n<thead>\n<tr>\n <th class="first">'+(h((f=e.L10n||c.L10n,f?f.call(c,"pending.table.head.name",a):g.call(c,"L10n","pending.table.head.name",
a)))+"</th>\n <th>");a={hash:{},data:d};b+=h((f=e.L10n||c.L10n,f?f.call(c,"pending.table.head.actions",a):g.call(c,"L10n","pending.table.head.actions",a)))+"</th>\n <th>";a={hash:{},data:d};b+=h((f=e.L10n||c.L10n,f?f.call(c,"pending.table.head.contactid",a):g.call(c,"L10n","pending.table.head.contactid",a)))+"</th>\n <th>";a={hash:{},data:d};b+=h((f=e.L10n||c.L10n,f?f.call(c,"pending.table.head.state",a):g.call(c,"L10n","pending.table.head.state",a)))+"</th>\n <th>";a={hash:{},data:d};
b+=h((f=e.L10n||c.L10n,f?f.call(c,"pending.table.head.operator",a):g.call(c,"L10n","pending.table.head.operator",a)))+"</th>\n <th>";a={hash:{},data:d};b+=h((f=e.L10n||c.L10n,f?f.call(c,"pending.table.head.total",a):g.call(c,"L10n","pending.table.head.total",a)))+"</th>\n <th>";a={hash:{},data:d};b+=h((f=e.L10n||c.L10n,f?f.call(c,"pending.table.head.waittime",a):g.call(c,"L10n","pending.table.head.waittime",a)))+"</th>\n <th>";a={hash:{},data:d};return b+=h((f=e.L10n||c.L10n,f?f.call(c,"pending.table.head.etc",
a):g.call(c,"L10n","pending.table.head.etc",a)))+'</th>\n</tr>\n</thead>\n<tbody id="threads-container">\n\n</tbody>\n</table>'});l.visitors_collection=k(function(b,c,e,a,d){this.compilerInfo=[4,">= 1.0.0"];e=this.merge(e,b.helpers);d=d||{};var f,g=e.helperMissing,h=this.escapeExpression;a={hash:{},data:d};b='<table id="visitorslist" class="awaiting" border="0">\n<thead>\n<tr>\n <th class="first">'+(h((f=e.L10n||c.L10n,f?f.call(c,"visitors.table.head.name",a):g.call(c,"L10n","visitors.table.head.name",
a)))+"</th>\n <th>");a={hash:{},data:d};b+=h((f=e.L10n||c.L10n,f?f.call(c,"visitors.table.head.actions",a):g.call(c,"L10n","visitors.table.head.actions",a)))+"</th>\n <th>";a={hash:{},data:d};b+=h((f=e.L10n||c.L10n,f?f.call(c,"visitors.table.head.contactid",a):g.call(c,"L10n","visitors.table.head.contactid",a)))+"</th>\n <th>";a={hash:{},data:d};b+=h((f=e.L10n||c.L10n,f?f.call(c,"visitors.table.head.firsttimeonsite",a):g.call(c,"L10n","visitors.table.head.firsttimeonsite",a)))+"</th>\n <th>";
a={hash:{},data:d};b+=h((f=e.L10n||c.L10n,f?f.call(c,"visitors.table.head.lasttimeonsite",a):g.call(c,"L10n","visitors.table.head.lasttimeonsite",a)))+"</th>\n <th>";a={hash:{},data:d};b+=h((f=e.L10n||c.L10n,f?f.call(c,"visitors.table.head.invited.by",a):g.call(c,"L10n","visitors.table.head.invited.by",a)))+"</th>\n <th>";a={hash:{},data:d};b+=h((f=e.L10n||c.L10n,f?f.call(c,"visitors.table.head.invitationtime",a):g.call(c,"L10n","visitors.table.head.invitationtime",a)))+"</th>\n <th>";a=
{hash:{},data:d};b+=h((f=e.L10n||c.L10n,f?f.call(c,"visitors.table.head.invitations",a):g.call(c,"L10n","visitors.table.head.invitations",a)))+"</th>\n <th>";a={hash:{},data:d};return b+=h((f=e.L10n||c.L10n,f?f.call(c,"visitors.table.head.etc",a):g.call(c,"L10n","visitors.table.head.etc",a)))+'</th>\n</tr>\n</thead>\n<tbody id="visitors-container">\n</tbody>\n</table>'});l.agent=k(function(b,c,e,a,d){this.compilerInfo=[4,">= 1.0.0"];e=this.merge(e,b.helpers);d=d||{};var f=e.helperMissing,g=this.escapeExpression;
b='<span class="agent-status-';if((a=e["if"].call(c,c.away,{hash:{},inverse:this.program(3,function(){return"online"},d),fn:this.program(1,function(){return"away"},d),data:d}))||0===a)b+=a;b+=' inline-block" title="';if((a=e["if"].call(c,c.away,{hash:{},inverse:this.program(7,function(a,b){var c,d;d={hash:{},data:b};return g((c=e.L10n||a.L10n,c?c.call(a,"pending.status.online",d):f.call(a,"L10n","pending.status.online",d)))},d),fn:this.program(5,function(a,b){var c,d;d={hash:{},data:b};return g((c=
e.L10n||a.L10n,c?c.call(a,"pending.status.away",d):f.call(a,"L10n","pending.status.away",d)))},d),data:d}))||0===a)b+=a;b+='"></span>';(a=e.name)?a=a.call(c,{hash:{},data:d}):(a=c.name,a="function"===typeof a?a.apply(c):a);b+=g(a);if((a=e.unless.call(c,c.isLast,{hash:{},inverse:this.noop,fn:this.program(9,function(){return","},d),data:d}))||0===a)b+=a;return b})})();

View File

@ -0,0 +1,13 @@
{{#if errors}}
<div class="errinfo">
<img src="{{stylePath}}/images/icon_err.gif" width="40" height="40" border="0" alt="" class="left"/>
{{l10n "errors.header"}}
{{#each errors}}
{{l10n "errors.prefix"}}
{{{this}}}
{{l10n "errors.suffix"}}
{{/each}}
{{l10n "errors.footer"}}
</div>
<br clear="all"/>
{{/if}}

View File

@ -0,0 +1,14 @@
<div id="sidebar">
<ul>
<li>
<h2><b>{{l10n "lang.choose"}}</b></h2>
<ul class="locales">
{{#each localeLinks}}
<li {{#ifEqual @key ../currentLocale}} class="active"{{/ifEqual}}>
<a href="?locale={{@key}}">{{this}}</a>
</li>
{{/each}}
</ul>
</li>
</ul>
</div>

View File

@ -0,0 +1,51 @@
<div id="sidebar">
<ul>
{{#if warnOffline}}
{{#unless isOnline}}
<li id="offwarn">
<img src="{{stylePath}}/images/dash/warn.gif" alt="" width="24" height="24"/>
<p>{{{goOnlineLink}}}</p>
</li>
{{/unless}}
{{/if}}
{{#if operator}}
<li>
<h2>{{l10n "right.main"}}</h2>
<ul class="submenu">
<li{{#ifEqual menuid "main"}} class="active"{{/ifEqual}}><a href="{{mibewRoot}}/operator/index.php">{{l10n "topMenu.main"}}</a></li>
<li{{#ifEqual menuid "users"}} class="active"{{/ifEqual}}><a href="{{mibewRoot}}/operator/users.php">{{l10n "topMenu.users"}}</a> <span class="small">(<a class="inner" href="{{mibewRoot}}/operator/users.php?nomenu">{{l10n "topMenu.users.nomenu"}}</a>)</span></li>
<li{{#ifEqual menuid "history"}} class="active"{{/ifEqual}}><a href="{{mibewRoot}}/operator/history.php">{{l10n "page_analysis.search.title"}}</a></li>
{{#if showstat}}
<li{{#ifEqual menuid "statistics"}} class="active"{{/ifEqual}}><a href="{{mibewRoot}}/operator/statistics.php">{{l10n "statistics.title"}}</a></li>
{{/if}}
{{#if showban}}
<li{{#ifEqual menuid "blocked"}} class="active"{{/ifEqual}}><a href="{{mibewRoot}}/operator/blocked.php">{{l10n "menu.blocked"}}</a></li>
{{/if}}
</ul>
</li>
<li>
<h2>{{l10n "right.administration"}}</h2>
<ul class="submenu">
<li{{#ifEqual menuid "canned"}} class="active"{{/ifEqual}}><a href="{{mibewRoot}}/operator/canned.php">{{l10n "menu.canned"}}</a></li>
{{#if showadmin}}
<li{{#ifEqual menuid "getcode"}} class="active"{{/ifEqual}}><a href="{{mibewRoot}}/operator/getcode.php">{{l10n "leftMenu.client_gen_button"}}</a></li>
<li{{#ifEqual menuid "operators"}} class="active"{{/ifEqual}}><a href="{{mibewRoot}}/operator/operators.php">{{l10n "leftMenu.client_agents"}}</a></li>
<li{{#ifEqual menuid "groups"}} class="active"{{/ifEqual}}><a href="{{mibewRoot}}/operator/groups.php">{{l10n "menu.groups"}}</a></li>
<li{{#ifEqual menuid "settings"}} class="active"{{/ifEqual}}><a href="{{mibewRoot}}/operator/settings.php">{{l10n "leftMenu.client_settings"}}</a></li>
<li{{#ifEqual menuid "translate"}} class="active"{{/ifEqual}}><a href="{{mibewRoot}}/operator/translate.php">{{l10n "menu.translate"}}</a></li>
<li{{#ifEqual menuid "updates"}} class="active"{{/ifEqual}}><a href="{{mibewRoot}}/operator/updates.php">{{l10n "menu.updates"}}</a></li>
{{/if}}
{{#if currentopid}}
<li{{#ifEqual menuid "profile"}} class="active"{{/ifEqual}}><a href="{{mibewRoot}}/operator/operator.php?op={{currentopid}}">{{l10n "menu.profile"}}</a></li>
{{/if}}
</ul>
</li>
<li>
<h2>{{l10n "right.other"}}</h2>
<ul class="submenu">
<li><a href="{{mibewRoot}}/operator/logout.php">{{l10n "topMenu.logoff"}}</a></li>
</ul>
</li>
{{/if}}
</ul>
</div>

View File

@ -0,0 +1,11 @@
{{#if tabs}}
<ul class="tabs">
{{#each tabs}}
{{#if this}}
<li><a href="{{this}}">{{@key}}</a></li>
{{else}}
<li class="active"><a href="#">{{@key}}</a></li>
{{/if}}
{{/each}}
</ul>
{{/if}}

View File

@ -0,0 +1,84 @@
{{#extends "layout"}}
{{#override "menu"}}{{> _menu}}{{/override}}
{{#override "content"}}
{{l10n "page_avatar.intro"}}
<br />
<br />
{{> _errors}}
<form name="avatarForm" method="post" action="{{mibewRoot}}/operator/avatar.php" enctype="multipart/form-data">
{{csrfTokenInput}}
<input type="hidden" name="op" value="{{opid}}"/>
<div>
{{> _tabs}}
<div class="mform">
<div class="formtop">
<div class="formtopi"></div>
</div>
<div class="forminner">
<p><b>{{currentop}}&lrm;</b></p>
<div class="fieldForm">
{{#if avatar}}
<div class="field">
<div class="flabel">{{l10n "form.field.avatar.current"}}</div>
<div class="fvalue">
<img src="{{avatar}}" alt="cannot load avatar"/><br/>
{{#if canmodify}}
<a class="formauth" href="{{mibewRoot}}/operator/avatar.php?op={{opid}}&amp;delete=true">
{{l10n "page_agent.clear_avatar"}}
</a>
{{/if}}
</div>
<div class="fdescr"> &mdash; {{l10n "form.field.avatar.current.description"}}</div>
<br clear="all"/>
</div>
{{else}}
{{#unless canmodify}}
<div class="field">
<div class="fvaluenodesc">
No avatar
</div>
</div>
{{/unless}}
{{/if}}
{{#if canmodify}}
<div class="field">
<label for="avatarFile" class="flabel">
{{l10n "form.field.avatar.upload"}}<span class="required">*</span>
</label>
<div class="fvalue">
<input id="avatarFile" type="file" name="avatarFile" size="40" value="{{formavatarFile}}" class="formauth"/>
</div>
<label for="avatarFile" class="fdescr"> &mdash; {{l10n "form.field.avatar.upload.description"}}</label>
<br clear="all"/>
</div>
<div class="fbutton">
<input type="image" name="save" value="" src="{{mibewRoot}}{{l10n "image.button.save"}}" alt="{{l10n "button.save"}}"/>
</div>
{{/if}}
</div>
</div>
<div class="formbottom">
<div class="formbottomi"></div>
</div>
</div>
</div>
<div class="asterisk">
{{l10n "common.asterisk_explanation"}}
</div>
</form>
{{/override}}
{{/extends}}

View File

@ -0,0 +1,85 @@
{{#extends "layout"}}
{{#override "content"}}
{{#if saved}}
{{l10n "page_ban.sent" address}}
<script type="text/javascript"><!--
if(window.opener && window.opener.location) {
window.opener.location.reload();
}
setTimeout( (function() { window.close(); }), 1500 );
//--></script>
{{else}}
{{l10n "page_ban.intro"}}
<br/>
<br/>
{{> _errors}}
{{#if thread}}
{{l10n "page_ban.thread" thread}}<br/>
<br/>
{{/if}}
<form name="banForm" method="post" action="{{mibewRoot}}/operator/ban.php">
{{csrfTokenInput}}
<input type="hidden" name="banId" value="{{banId}}"/>
{{#if threadid}}
<input type="hidden" name="threadid" value="{{threadid}}"/>
{{/if}}
<div class="mform">
<div class="formtop">
<div class="formtopi"></div>
</div>
<div class="forminner">
<div class="fieldForm">
<div class="field">
<label for="address" class="flabel">{{l10n "form.field.address"}}<span class="required">*</span></label>
<div class="fvalue">
<input id="address" type="text" name="address" size="40" value="{{formaddress}}" class="formauth"/>
</div>
<label for="address" class="fdescr"> &mdash; {{l10n "form.field.address.description"}}</label>
<br clear="all"/>
</div>
<div class="field">
<label for="days" class="flabel">{{l10n "form.field.ban_days"}}<span class="required">*</span></label>
<div class="fvalue">
<input id="days" type="text" name="days" size="4" value="{{formdays}}" class="formauth"/>
</div>
<label for="days" class="fdescr"> &mdash; {{l10n "form.field.ban_days.description"}}</label>
<br clear="all"/>
</div>
<div class="field">
<label for="comment" class="flabel">{{l10n "form.field.ban_comment"}}<span class="required">*</span></label>
<div class="fvalue">
<input id="comment" type="text" name="comment" size="40" value="{{formcomment}}" class="formauth"/>
</div>
<label for="comment" class="fdescr"> &mdash; {{l10n "form.field.ban_comment.description"}}</label>
<br clear="all"/>
</div>
<div class="fbutton">
<input type="image" name="save" value="" src="{{mibewRoot}}{{l10n "image.button.save"}}" alt="{{l10n "button.save"}}"/>
</div>
</div>
</div>
<div class="formbottom">
<div class="formbottomi"></div>
</div>
</div>
<div class="asterisk">
{{l10n "common.asterisk_explanation"}}
</div>
</form>
{{/if}}
{{/override}}
{{/extends}}

View File

@ -0,0 +1,81 @@
{{#extends "layout"}}
{{#override "menu"}}{{> _menu}}{{/override}}
{{#override "header"}}
<script type="text/javascript" language="javascript" src="{{mibewRoot}}/js/libs/jquery.min.js"></script>
<script type="text/javascript" language="javascript"><!--
(function($) {
$(document).ready(function(){
var confirmMessage = "{{#jsString}}{{l10n 'page_bans.confirm' '{addr}'}}{{/jsString}}";
$('a.removelink').click(function(){
var addr = $.trim($("#t" + this.id).text());
return confirm(confirmMessage.replace("{addr}", addr));
});
});
})(jQuery);
//--></script>
{{/override}}
{{#override "content"}}
{{l10n "page_ban.intro"}}
<br />
<br />
{{> _errors}}
<div class="tabletool">
<img src="{{stylePath}}/images/buttons/createban.gif" border="0" alt=""/>
<a href="{{mibewRoot}}/operator/ban.php" title="{{l10n "page_bans.add"}}"
onclick="this.newWindow = window.open('{{mibewRoot}}/operator/ban.php', '', 'toolbar=0,scrollbars=1,location=0,status=1,menubar=0,width=640,height=480,resizable=1');this.newWindow.focus();this.newWindow.opener=window;return false;">{{l10n "page_bans.add"}}</a>
</div>
<br clear="all"/>
<table class="list">
<thead>
<tr class="header">
<th>{{l10n "form.field.address"}}</th>
<th>{{l10n "page_bans.to"}}</th>
<th>{{l10n "form.field.ban_comment"}}</th>
<th>{{l10n "page_bans.edit"}}</th>
</tr>
</thead>
<tbody>
{{#each [pagination.items]}}
<tr>
<td class="notlast">
<a href="{{../mibewRoot}}/operator/history.php?q={{address}}&type=visitor" class="man" id="ti{{banid}}">
{{address}}
</a>
</td>
<td class="notlast">{{formatDate till}}</td>
<td>{{cutString comment "30"}}</td>
<td>
<a class="removelink" id="i{{banid}}" href="{{../mibewRoot}}/operator/blocked.php?act=del&amp;id={{banid}}{{csrfTokenInUrl}}">
{{l10n "remove.item"}}
</a>,
<a href="{{../mibewRoot}}/operator/ban.php?id={{banid}}"
onclick="this.newWindow = window.open('{{../mibewRoot}}/operator/ban.php?id={{banid}}', '', 'toolbar=0,scrollbars=1,location=0,status=1,menubar=0,width=640,height=480,resizable=1');this.newWindow.focus();this.newWindow.opener=window;return false;">{{l10n "edit.item"}}</a>
</td>
</tr>
{{else}}
<tr>
<td colspan="4">
{{l10n "tag.pagination.no_items.elements"}}
</td>
</tr>
{{/each}}
</tbody>
</table>
{{#if pagination}}
<br />
{{generatePagination stylePath pagination}}
{{/if}}
{{/override}}
{{/extends}}

View File

@ -0,0 +1,93 @@
{{#extends "layout"}}
{{#override "menu"}}{{> _menu}}{{/override}}
{{#override "content"}}
{{l10n "canned.descr"}}
<br />
<br />
{{> _errors}}
<form name="cannedForm" method="get" action="{{mibewRoot}}/operator/canned.php">
<div class="mform">
<div class="formtop">
<div class="formtopi"></div>
</div>
<div class="forminner">
<div class="packedFormField">
{{l10n "canned.locale"}}<br/>
<select name="lang" onchange="this.form.submit();">
{{#each locales}}
<option value="{{id}}"{{#ifEqual id ../formlang}} selected="selected"{{/ifEqual}}>{{name}}</option>
{{/each}}
</select>
</div>
<div class="packedFormField">
{{l10n "canned.group"}}<br/>
<select name="group" onchange="this.form.submit();">
{{#each groups}}
<option value="{{groupid}}"{{#ifEqual groupid ../formgroup}} selected="selected"{{/ifEqual}}>{{#repeat level}}&nbsp;&nbsp;{{/repeat}}{{vclocalname}}</option>
{{/each}}
</select>
</div>
<br clear="all"/>
</div>
<div class="formbottom">
<div class="formbottomi"></div>
</div>
</div>
</form>
<br/>
<div class="tabletool">
<img src="{{stylePath}}/images/buttons/createban.gif" border="0" alt=""/>
<a href="{{mibewRoot}}/operator/cannededit.php?lang={{formlang}}&amp;group={{formgroup}}" target="_blank"
onclick="this.newWindow = window.open('{{mibewRoot}}/operator/cannededit.php?lang={{formlang}}&amp;group={{formgroup}}', '', 'toolbar=0,scrollbars=1,location=0,status=1,menubar=0,width=640,height=480,resizable=1');this.newWindow.focus();this.newWindow.opener=window;return false;">
{{l10n "canned.add"}}
</a>
</div>
<br clear="all"/>
<table class="translate">
<thead>
<tr class="header">
<th>{{l10n "canned.message_title"}}</th>
<th>{{l10n "cannededit.message"}}</th>
<th>{{l10n "canned.actions"}}</th>
</tr>
</thead>
<tbody>
{{#each [pagination.items]}}
<tr>
<td>
{{#replace "\n" ""}}{{vctitle}}{{/replace}}
</td>
<td>
{{#replace "\n" "<br/>"}}{{vcvalue}}{{/replace}}
</td>
<td>
<a href="{{../mibewRoot}}/operator/cannededit.php?key={{id}}" target="_blank"
onclick="this.newWindow = window.open('{{../mibewRoot}}/operator/cannededit.php?key={{id}}', '', 'toolbar=0,scrollbars=1,location=0,status=1,menubar=0,width=640,height=480,resizable=1');this.newWindow.focus();this.newWindow.opener=window;return false;">{{l10n "canned.actions.edit"}}</a>,
<a href="{{../mibewRoot}}/operator/canned.php?act=delete&amp;key={{id}}&amp;lang={{../formlang}}&amp;group={{../formgroup}}{{csrfTokenInUrl}}">{{l10n "canned.actions.del"}}</a>
</td>
</tr>
{{else}}
<tr>
<td colspan="3">{{l10n "tag.pagination.no_items.elements"}}</td>
</tr>
{{/each}}
</tbody>
</table>
{{#if pagination}}
<br />
{{generatePagination stylePath pagination}}
{{/if}}
{{/override}}
{{/extends}}

View File

@ -0,0 +1,67 @@
{{#extends "layout"}}
{{#override "content"}}
{{#if saved}}
{{l10n "cannededit.done"}}
<script type="text/javascript"><!--
if(window.opener && window.opener.location) {
window.opener.location.reload();
}
setTimeout( (function() { window.close(); }), 1500 );
//--></script>
{{else}}
{{#if key}}
{{l10n "cannededit.descr"}}
{{else}}
{{l10n "cannednew.descr"}}
{{/if}}
<br/>
<br/>
{{> _errors}}
<form name="cannedForm" method="post" action="{{mibewRoot}}/operator/cannededit.php">
{{csrfTokenInput}}
<input type="hidden" name="key" value="{{key}}"/>
{{#unless key}}
<input type="hidden" name="lang" value="{{locale}}"/>
<input type="hidden" name="group" value="{{groupid}}"/>
{{/unless}}
<div class="mform">
<div class="formtop">
<div class="formtopi"></div>
</div>
<div class="forminner">
<div class="fieldForm">
<div class="field">
<label for="titlefield" class="flabel">{{l10n "canned.message_title"}}</label>
<div class="fvaluenodesc">
<input id="titlefield" type="text" name="title" class="wide" maxlength="100" value="{{formtitle}}"/>
</div>
</div>
<div class="field">
<label for="message" class="flabel">{{l10n "cannededit.message"}}</label>
<div class="fvaluenodesc">
<textarea id="message" name="message" cols="20" rows="5" class="wide">{{formmessage}}</textarea>
</div>
</div>
<div class="fbutton">
<input type="image" name="save" value="" src="{{mibewRoot}}{{l10n "image.button.save"}}" alt="{{l10n "button.save"}}"/>
</div>
</div>
</div>
<div class="formbottom">
<div class="formbottomi"></div>
</div>
</div>
</form>
{{/if}}
{{/override}}
{{/extends}}

View File

@ -0,0 +1,67 @@
{{#extends "layout"}}
{{#override "content"}}
<div id="confirmpane">
<div class="mform">
<div class="formtop">
<div class="formtopi"></div>
</div>
<div class="forminner">
{{l10n "confirm.take.message" user agent}}
<br/>
<br/>
<br/>
<div>
<table class="nicebutton">
<tr>
<td>
<a href="{{link}}">
<img src="{{stylePath}}/images/submit.gif" width="40" height="35" border="0" alt="" />
</a>
</td>
<td class="submit">
<a href="{{link}}">
{{l10n "confirm.take.yes"}}
</a>
</td>
<td>
<a href="{{link}}">
<img src="{{stylePath}}/images/submitrest.gif" width="10" height="35" border="0" alt="" />
</a>
</td>
</tr>
</table>
<table class="nicebutton">
<tr>
<td>
<a href="javascript:window.close();">
<img src="{{stylePath}}/images/submit.gif" width="40" height="35" border="0" alt="" />
</a>
</td>
<td class="submit">
<a href="javascript:window.close();">
{{l10n "confirm.take.no"}}
</a>
</td>
<td>
<a href="javascript:window.close();">
<img src="{{stylePath}}/images/submitrest.gif" width="10" height="35" border="0" alt="" />
</a>
</td>
</tr>
</table>
<br clear="all"/>
</div>
</div>
<div class="formbottom">
<div class="formbottomi"></div>
</div>
</div>
</div>
{{/override}}
{{/extends}}

View File

@ -0,0 +1,188 @@
{{#extends "layout"}}
{{#override "menu"}}{{> _menu}}{{/override}}
{{#override "header"}}
<script type="text/javascript" language="javascript" src="{{mibewRoot}}/js/libs/jquery.min.js"></script>
<script type="text/javascript" language="javascript" src="{{stylePath}}/js/features.js"></script>
{{/override}}
{{#override "content"}}
{{l10n "page_settings.intro"}}
<br />
<br />
{{> _errors}}
{{#if stored}}
<div id="formmessage">{{l10n "features.saved"}}</div>
{{/if}}
<form name="features" method="post" action="{{mibewRoot}}/operator/features.php">
{{csrfTokenInput}}
<input type="hidden" name="sent" value="true"/>
<div>
{{> _tabs}}
<div class="mform">
<div class="formtop">
<div class="formtopi"></div>
</div>
<div class="forminner">
<div class="fieldForm">
<div class="field">
<label for="usercanchangename" class="flabel">{{l10n "settings.usercanchangename"}}</label>
<div class="fvalue">
<input id="usercanchangename" type="checkbox" name="usercanchangename" value="on"{{#if formusercanchangename}} checked="checked"{{/if}}{{#unless canmodify}} disabled="disabled"{{/unless}}/>
</div>
<label for="usercanchangename" class="fdescr"> &mdash; {{l10n "settings.usercanchangename.description"}}</label>
<br clear="all"/>
</div>
<div class="field">
<label for="enablessl" class="flabel">{{l10n "settings.enablessl"}}</label>
<div class="fvalue">
<input id="enablessl" type="checkbox" name="enablessl" value="on"{{#if formenablessl}} checked="checked"{{/if}}{{#unless canmodify}} disabled="disabled"{{/unless}}/>
</div>
<label for="enablessl" class="fdescr"> &mdash; {{l10n "settings.enablessl.description"}}</label>
<br clear="all"/>
<div class="subfield underssl">
<label for="forcessl" class="flabel">{{l10n "settings.forcessl"}}</label>
<div class="fvalue">
<input id="forcessl" type="checkbox" name="forcessl" value="on"{{#if formforcessl}} checked="checked"{{/if}}{{#unless canmodify}} disabled="disabled"{{/unless}}/>
</div>
<label for="forcessl" class="fdescr"> &mdash; {{l10n "settings.forcessl.description"}}</label>
<br clear="all"/>
</div>
</div>
<div class="field">
<label for="enablegroups" class="flabel">{{l10n "settings.enablegroups"}}</label>
<div class="fvalue">
<input id="enablegroups" type="checkbox" name="enablegroups" value="on"{{#if formenablegroups}} checked="checked"{{/if}}{{#unless canmodify}} disabled="disabled"{{/unless}}/>
</div>
<label for="enablegroups" class="fdescr"> &mdash; {{l10n "settings.enablegroups.description"}}</label>
<br clear="all"/>
<div class="subfield undergroups">
<label for="enablegroupsisolation" class="flabel">{{l10n "settings.enablegroupsisolation"}}</label>
<div class="fvalue">
<input id="enablegroupsisolation" type="checkbox" name="enablegroupsisolation" value="on"{{#if formenablegroupsisolation}} checked="checked"{{/if}}{{#unless canmodify}} disabled="disabled"{{/unless}}/>
</div>
<label for="enablegroupsisolation" class="fdescr"> &mdash; {{l10n "settings.enablegroupsisolation.description"}}</label>
<br clear="all"/>
</div>
</div>
<div class="field">
<label for="enablestatistics" class="flabel">{{l10n "settings.enablestatistics"}}</label>
<div class="fvalue">
<input id="enablestatistics" type="checkbox" name="enablestatistics" value="on"{{#if formenablestatistics}} checked="checked"{{/if}}{{#unless canmodify}} disabled="disabled"{{/unless}}/>
</div>
<label for="enablestatistics" class="fdescr"> &mdash; {{l10n "settings.enablestatistics.description"}}</label>
<br clear="all"/>
</div>
<div class="field">
<label for="enabletracking" class="flabel">{{l10n "settings.enabletracking"}}</label>
<div class="fvalue">
<input id="enabletracking" type="checkbox" name="enabletracking" value="on"{{#if formenabletracking}} checked="checked"{{/if}}{{#unless canmodify}} disabled="disabled"{{/unless}}/>
</div>
<label for="enabletracking" class="fdescr"> &mdash; {{l10n "settings.enabletracking.description"}}</label>
<br clear="all"/>
</div>
<div class="field">
<label for="enableban" class="flabel">{{l10n "settings.enableban"}}</label>
<div class="fvalue">
<input id="enableban" type="checkbox" name="enableban" value="on"{{#if formenableban}} checked="checked"{{/if}}{{#unless canmodify}} disabled="disabled"{{/unless}}/>
</div>
<label for="enableban" class="fdescr"> &mdash; {{l10n "settings.enableban.description"}}</label>
<br clear="all"/>
</div>
<div class="field">
<label for="enablepresurvey" class="flabel">{{l10n "settings.enablepresurvey"}}</label>
<div class="fvalue">
<input id="enablepresurvey" type="checkbox" name="enablepresurvey" value="on"{{#if formenablepresurvey}} checked="checked"{{/if}}{{#unless canmodify}} disabled="disabled"{{/unless}}/>
</div>
<label for="enablepresurvey" class="fdescr"> &mdash; {{l10n "settings.enablepresurvey.description"}}</label>
<br clear="all"/>
<div class="subfield undersurvey">
<label for="surveyaskmail" class="flabel">{{l10n "settings.survey.askmail"}}</label>
<div class="fvalue">
<input id="surveyaskmail" type="checkbox" name="surveyaskmail" value="on"{{#if formsurveyaskmail}} checked="checked"{{/if}}{{#unless canmodify}} disabled="disabled"{{/unless}}/>
</div>
<label for="surveyaskmail" class="fdescr"> &mdash; {{l10n "settings.survey.askmail.description"}}</label>
<br clear="all"/>
</div>
<div class="subfield undersurvey">
<label for="surveyaskgroup" class="flabel">{{l10n "settings.survey.askgroup"}}</label>
<div class="fvalue">
<input id="surveyaskgroup" type="checkbox" name="surveyaskgroup" value="on"{{#if formsurveyaskgroup}} checked="checked"{{/if}}{{#unless canmodify}} disabled="disabled"{{/unless}}/>
</div>
<label for="surveyaskgroup" class="fdescr"> &mdash; {{l10n "settings.survey.askgroup.description"}}</label>
<br clear="all"/>
</div>
<div class="subfield undersurvey">
<label for="surveyaskmessage" class="flabel">{{l10n "settings.survey.askmessage"}}</label>
<div class="fvalue">
<input id="surveyaskmessage" type="checkbox" name="surveyaskmessage" value="on"{{#if formsurveyaskmessage}} checked="checked"{{/if}}{{#unless canmodify}} disabled="disabled"{{/unless}}/>
</div>
<label for="surveyaskmessage" class="fdescr"> &mdash; {{l10n "settings.survey.askmessage.description"}}</label>
<br clear="all"/>
</div>
</div>
<div class="field">
<label for="enablepopupnotification" class="flabel">{{l10n "settings.popup_notification"}}</label>
<div class="fvalue">
<input id="enablepopupnotification" type="checkbox" name="enablepopupnotification" value="on"{{#if formenablepopupnotification}} checked="checked"{{/if}}{{#unless canmodify}} disabled="disabled"{{/unless}}/>
</div>
<label for="enablepopupnotification" class="fdescr"> &mdash; {{l10n "settings.popup_notification.description"}}</label>
<br clear="all"/>
</div>
<div class="field">
<label for="showonlineoperators" class="flabel">{{l10n "settings.show_online_operators"}}</label>
<div class="fvalue">
<input id="showonlineoperators" type="checkbox" name="showonlineoperators" value="on"{{#if formshowonlineoperators}} checked="checked"{{/if}}{{#unless canmodify}} disabled="disabled"{{/unless}}/>
</div>
<label for="showonlineoperators" class="fdescr"> &mdash; {{l10n "settings.show_online_operators.description"}}</label>
<br clear="all"/>
</div>
<div class="field">
<label for="enablecaptcha" class="flabel">{{l10n "settings.leavemessage_captcha"}}</label>
<div class="fvalue">
<input id="enablecaptcha" type="checkbox" name="enablecaptcha" value="on"{{#if formenablecaptcha}} checked="checked"{{/if}}{{#unless canmodify}} disabled="disabled"{{/unless}}/>
</div>
<label for="enablecaptcha" class="fdescr"> &mdash; {{l10n "settings.leavemessage_captcha.description"}}</label>
<br clear="all"/>
</div>
{{#if canmodify}}
<div class="fbutton">
<input type="image" name="save" value="" src="{{mibewRoot}}{{l10n "image.button.save"}}" alt="{{l10n "button.save"}}"/>
</div>
{{/if}}
</div>
</div>
<div class="formbottom">
<div class="formbottomi"></div>
</div>
</div>
</div>
</form>
{{/override}}
{{/extends}}

View File

@ -0,0 +1,144 @@
{{#extends "layout"}}
{{#override "menu"}}{{> _menu}}{{/override}}
{{#override "content"}}
{{l10n "page.gen_button.intro"}}
<br />
<br />
{{> _errors}}
<form name="buttonCodeForm" method="get" action="{{mibewRoot}}/operator/getcode.php">
<div class="mform">
<div class="formtop">
<div class="formtopi"></div>
</div>
<div class="forminner">
<div class="fieldForm">
<div class="fieldinrow">
<label for="lang" class="flabel">{{l10n "page.gen_button.choose_locale"}}</label>
<div class="fvaluenodesc">
<select id="lang" name="lang" onchange="this.form.submit();">
{{#each availableLocales}}
<option value="{{this}}"{{#ifEqual this ../formlang}} selected="selected"{{/ifEqual}}>{{this}}</option>
{{/each}}
</select>
</div>
</div>
<div class="fieldinrow">
<label for="style" class="flabel">{{l10n "page.gen_button.choose_style"}}</label>
<div class="fvaluenodesc">
<select id="style" name="style" onchange="this.form.submit();">
{{#each availableChatStyles}}
"<option value="{{@key}}"{{#ifEqual @key ../formstyle}} selected="selected"{{/ifEqual}}>{{this}}</option>
{{/each}}
</select>
</div>
</div>
<br clear="all"/>
<div class="fieldinrow">
<label for="codetype" class="flabel">{{l10n "page.gen_button.choose_type"}}</label>
<div class="fvaluenodesc">
<select id="codetype" name="codetype" onchange="this.form.submit();">
{{#each availableCodeTypes}}
<option value="{{@key}}"{{#ifEqual @key ../formcodetype}} selected="selected"{{/ifEqual}}>{{this}}</option>
{{/each}}
</select>
</div>
</div>
<br clear="all"/>
{{#unless operator_code}}
<div class="fieldinrow">
<label for="i" class="flabel">{{l10n "page.gen_button.choose_image"}}</label>
<div class="fvaluenodesc">
<select id="i" name="i" onchange="this.form.submit();">
{{#each availableImages}}
<option value="{{this}}"{{#ifEqual this ../formimage}} selected="selected"{{/ifEqual}}>{{this}}</option>
{{/each}}
</select>
</div>
</div>
{{#if enabletracking}}
<div class="fieldinrow">
<label for="invitationstyle" class="flabel">{{l10n "page.gen_button.choose_invitationstyle"}}</label>
<div class="fvaluenodesc">
<select id="invitationstyle" name="invitationstyle" onchange="this.form.submit();">
{{#each availableInvitationStyles}}
<option value="{{@key}}"{{#ifEqual @key ../forminvitationstyle}} selected="selected"{{/ifEqual}}>{{this}}</option>
{{/each}}
</select>
</div>
</div>
{{/if}}
<br clear="all"/>
{{/unless}}
<div class="fieldinrow">
<label for="group" class="flabel">{{l10n "page.gen_button.choose_group"}}</label>
<div class="fvaluenodesc">
<select id="group" name="group" onchange="this.form.submit();">
{{#each groups}}
<option value="{{groupid}}"{{#ifEqual groupid ../formgroup}} selected="selected"{{/ifEqual}}>{{#repeat level}}&nbsp;&nbsp;{{/repeat}}{{vclocalname}}</option>
{{/each}}
</select>
</div>
</div>
<br clear="all"/>
<div class="fieldinrow">
<label for="hostname" class="flabel">{{l10n "page.gen_button.include_site_name"}}</label>
<div class="fvaluenodesc">
<input id="hostname" type="checkbox" name="hostname" value="on"{{#if formhostname}} checked="checked"{{/if}} onchange="this.form.submit();"/>
</div>
</div>
{{#if formhostname}}
<div class="fieldinrow">
<label for="secure" class="flabel">{{l10n "page.gen_button.secure_links"}}</label>
<div class="fvaluenodesc">
<input id="secure" type="checkbox" name="secure" value="on"{{#if formsecure}} checked="checked"{{/if}} onchange="this.form.submit();"/>
</div>
</div>
{{/if}}
<br clear="all"/>
<div class="field">
<label for="modsecurity" class="flabel">{{l10n "page.gen_button.modsecurity"}}</label>
<div class="fvaluenodesc">
<input id="modsecurity" type="checkbox" name="modsecurity" value="on"{{#if formmodsecurity}} checked="checked"{{/if}} onchange="this.form.submit();"/>
</div>
</div>
<div class="field">
<label for="buttonCode" class="flabel">{{l10n "page.gen_button.code"}}</label>
<div class="fvaluewithta" dir="ltr">
<textarea id="buttonCode" cols="44" rows="15">{{buttonCode}}</textarea>
</div>
<label for="buttonCode" class="fdescr">{{l10n "page.gen_button.code.description"}}</label>
<br clear="all"/>
</div>
<div class="field">
<div class="flabel">{{l10n "page.gen_button.sample"}}</div>
<div class="fvaluenodesc">
{{{buttonCode}}}
</div>
</div>
</div>
</div>
<div class="formbottom">
<div class="formbottomi"></div>
</div>
</div>
</form>
{{/override}}
{{/extends}}

View File

@ -0,0 +1,164 @@
{{#extends "layout"}}
{{#override "menu"}}{{> _menu}}{{/override}}
{{#override "header"}}
<script type="text/javascript" language="javascript" src="{{mibewRoot}}/js/libs/jquery.min.js"></script>
<script type="text/javascript" language="javascript" src="{{stylePath}}/js/group.js"></script>
{{/override}}
{{#override "content"}}
{{#if grid}}
{{l10n "page.group.intro"}}
{{else}}
{{l10n "page.group.create_new"}}
{{/if}}
<br />
<br />
{{> _errors}}
{{#if stored}}
<div id="formmessage">{{l10n "data.saved"}}</div>
{{/if}}
<form name="groupForm" method="post" action="{{mibewRoot}}/operator/group.php">
{{csrfTokenInput}}
<input type="hidden" name="gid" value="{{grid}}"/>
<div>
{{> _tabs}}
<div class="mform">
<div class="formtop">
<div class="formtopi"></div>
</div>
<div class="forminner">
<div class="fieldForm">
<div class="field">
<label for="name" class="flabel">{{l10n "form.field.groupname"}}<span class="required">*</span></label>
<div class="fvalue">
<input id="name" type="text" name="name" size="40" value="{{formname}}" class="formauth"/>
</div>
<label for="name" class="fdescr"> &mdash; {{l10n "form.field.groupname.description"}}</label>
<br clear="all"/>
</div>
<div class="field">
<label for="description" class="flabel">{{l10n "form.field.groupdesc"}}</label>
<div class="fvalue">
<input id="description" type="text" name="description" size="40" value="{{formdescription}}" class="formauth"/>
</div>
<label for="description" class="fdescr"> &mdash; {{l10n "form.field.groupdesc.description"}}</label>
<br clear="all"/>
</div>
<div class="field">
<label for="commonname" class="flabel">{{l10n "form.field.groupcommonname"}}</label>
<div class="fvalue">
<input id="commonname" type="text" name="commonname" size="40" value="{{formcommonname}}" class="formauth"/>
</div>
<label for="commonname" class="fdescr"> &mdash; {{l10n "form.field.groupcommonname.description"}}</label>
<br clear="all"/>
</div>
<div class="field">
<label for="commondescription" class="flabel">{{l10n "form.field.groupcommondesc"}}</label>
<div class="fvalue">
<input id="commondescription" type="text" name="commondescription" size="40" value="{{formcommondescription}}" class="formauth"/>
</div>
<label for="commondescription" class="fdescr"> &mdash; {{l10n "form.field.groupcommondesc.description"}}</label>
<br clear="all"/>
</div>
<div class="field">
<label for="email" class="flabel">{{l10n "form.field.mail"}}</label>
<div class="fvalue">
<input id="email" type="text" name="email" size="40" value="{{formemail}}" class="formauth"/>
</div>
<label for="email" class="fdescr"> &mdash; {{l10n "form.field.groupemail.description"}}</label>
<br clear="all"/>
</div>
<div class="field">
<label for="weight" class="flabel">{{l10n "form.field.groupweight"}}</label>
<div class="fvalue">
<input id="weight" type="text" name="weight" size="40" value="{{formweight}}" class="formauth"/>
</div>
<label for="weight" class="fdescr"> &mdash; {{l10n "form.field.groupweight.description"}}</label>
<br clear="all"/>
</div>
<div class="field">
<label for="parentgroup" class="flabel">{{l10n "form.field.groupparent"}}</label>
<div class="fvalue">
<select name="parentgroup" id="parentgroup">
{{#each availableParentGroups}}
<option value="{{groupid}}"{{#ifEqual groupid ../formparentgroup}} selected="selected"{{/ifEqual}}>{{#repeat level}}&nbsp;&nbsp;{{/repeat}}{{vclocalname}}</option>
{{/each}}
</select>
</div>
<label for="parentgroup" class="fdescr"> &mdash; {{l10n "form.field.groupparent.description"}}</label>
<br clear="all"/>
</div>
<div id="extrafields">
<div class="fheader">{{l10n "page.group.extrafields.title"}}</div>
<div class="field">
<label for="titlefield" class="flabel">{{l10n "settings.company.title"}}</label>
<div class="fvalue">
<input id="titlefield" type="text" name="title" size="40" value="{{formtitle}}" class="formauth"/>
</div>
<label for="titlefield" class="fdescr"> &mdash; {{l10n "settings.company.title.description"}}</label>
<br clear="all"/>
</div>
<div class="field">
<label for="chattitle" class="flabel">{{l10n "settings.chat.title"}}</label>
<div class="fvalue">
<input id="chattitle" type="text" name="chattitle" size="40" value="{{formchattitle}}" class="formauth"/>
</div>
<label for="chattitle" class="fdescr"> &mdash; {{l10n "settings.chat.title"}}</label>
<br clear="all"/>
</div>
<div class="field">
<label for="logofield" class="flabel">{{l10n "settings.logo"}}</label>
<div class="fvalue">
<input id="logofield" type="text" name="logo" size="40" value="{{formlogo}}" class="formauth"/>
</div>
<label for="logofield" class="fdescr"> &mdash; {{l10n "settings.logo.description"}}</label>
<br clear="all"/>
</div>
<div class="field">
<label for="hosturl" class="flabel">{{l10n "settings.host"}}</label>
<div class="fvalue">
<input id="hosturl" type="text" name="hosturl" size="40" value="{{formhosturl}}" class="formauth"/>
</div>
<label for="hosturl" class="fdescr"> &mdash; {{l10n "settings.host.description"}}</label>
<br clear="all"/>
</div>
</div>
<div class="fbutton">
<input type="image" name="save" value="" src="{{mibewRoot}}{{l10n "image.button.save"}}" alt="{{l10n "button.save"}}"/>
</div>
</div>
</div>
<div class="formbottom">
<div class="formbottomi"></div>
</div>
</div>
</div>
<div class="asterisk">
{{l10n "common.asterisk_explanation"}}
</div>
</form>
{{/override}}
{{/extends}}

View File

@ -0,0 +1,52 @@
{{#extends "layout"}}
{{#override "menu"}}{{> _menu}}{{/override}}
{{#override "content"}}
{{l10n "page.groupmembers.intro"}}
<br />
<br />
{{> _errors}}
{{#if stored}}
<div id="formmessage">{{l10n "data.saved"}}</div>
{{/if}}
<form name="membersForm" method="post" action="{{mibewRoot}}/operator/groupmembers.php">
{{csrfTokenInput}}
<input type="hidden" name="gid" value="{{groupid}}"/>
<div>
{{> _tabs}}
<div class="mform">
<div class="formtop">
<div class="formtopi"></div>
</div>
<div class="forminner">
<p><b>{{currentgroup}}</b></p>
{{#each operators}}
<div class="field">
<div class="fvaluenodesc">
<input id="op{{operatorid}}" type="checkbox" name="op{{operatorid}}" value="on"{{#if checked}} checked="checked"{{/if}}/>
<label for="op{{operatorid}}">{{vclocalename}} (<a href="operator.php?op={{operatorid}}">{{vclogin}}</a>)</label>
</div>
</div>
{{/each}}
<div class="fbutton">
<input type="image" name="save" value="" src="{{mibewRoot}}{{l10n "image.button.save"}}" alt="{{l10n "button.save"}}"/>
</div>
</div>
<div class="formbottom">
<div class="formbottomi"></div>
</div>
</div>
</div>
</form>
{{/override}}
{{/extends}}

View File

@ -0,0 +1,142 @@
{{#extends "layout"}}
{{#override "menu"}}{{> _menu}}{{/override}}
{{#override "header"}}
<script type="text/javascript" language="javascript" src="{{mibewRoot}}/js/libs/jquery.min.js"></script>
<script type="text/javascript" language="javascript"><!--
(function($) {
$(document).ready(function(){
var confirmMessage = "{{#jsString}}{{l10n 'page.groups.confirm' '{groupName}'}}{{/jsString}}";
$('a.removelink').click(function(){
var groupName = $.trim($("#t" + this.id).text());
return confirm(confirmMessage.replace("{groupName}", groupName));
});
});
})(jQuery);
//--></script>
{{/override}}
{{#override "content"}}
{{l10n "page.groups.intro"}}
<br />
<br />
{{> _errors}}
<form name="groupsForm" method="get" action="{{mibewRoot}}/operator/groups.php">
<div class="mform">
<div class="formtop">
<div class="formtopi"></div>
</div>
<div class="forminner">
<div class="packedFormField">
{{l10n "page.groups.sort"}}<br/>
<select name="sortby" onchange="this.form.submit();">
{{#each availableOrders}}
<option value="{{id}}"{{#ifEqual id ../formsortby}} selected="selected"{{/ifEqual}}>{{name}}</option>
{{/each}}
</select>
</div>
<div class="packedFormField">
{{l10n "page.groups.sortdirection"}}<br/>
<select name="sortdirection" onchange="this.form.submit();">
{{#each availableDirections}}
<option value="{{id}}"{{#ifEqual id ../formsortdirection}} selected="selected"{{/ifEqual}}>{{name}}</option>
{{/each}}
</select>
</div>
<br clear="all"/>
</div>
<div class="formbottom">
<div class="formbottomi"></div>
</div>
</div>
</form>
<br />
{{#if canmodify}}
<div class="tabletool">
<img src="{{stylePath}}/images/buttons/createdep.gif" border="0" alt="" />
<a href="{{mibewRoot}}/operator/group.php" title="{{l10n "page.groups.new"}}">
{{l10n "page.groups.new"}}
</a>
</div>
<br clear="all"/>
{{/if}}
<table class="list">
<thead>
<tr class="header">
<th>{{l10n "form.field.groupname"}}</th>
<th>{{l10n "form.field.groupdesc"}}</th>
<th>{{l10n "page_agents.status"}}</th>
<th>{{l10n "page.group.membersnum"}}</th>
<th>{{l10n "page.groups.weight"}}</th>
{{#if canmodify}}
<th></th>
{{/if}}
</tr>
</thead>
<tbody>
{{#each groups}}
<tr>
<td class="notlast level{{level}}">
<a href="{{../mibewRoot}}/operator/group.php?gid={{groupid}}" id="ti{{groupid}}" class="man">
{{vclocalname}}
</a>
</td>
<td class="notlast">
{{#if vclocaldescription}}
{{vclocaldescription}}
{{else}}
&lt;none&gt;
{{/if}}
</td>
<td class="notlast">
{{#ifAny isOnline isAway}}
{{#if isOnline}}
{{l10n "page.groups.isonline"}}
{{else}}
{{l10n "page.groups.isaway"}}
{{/if}}
{{else}}
{{formatDate lastTimeOnline}}
{{/ifAny}}
</td>
<td>
<a href="{{../mibewRoot}}/operator/groupmembers.php?gid={{groupid}}">
{{inumofagents}}
</a>
</td>
<td>
{{iweight}}
</td>
{{#if ../canmodify}}
<td>
<a href="{{../mibewRoot}}/operator/groups.php?act=del&amp;gid={{groupid}}{{csrfTokenInUrl}}" id="i{{groupid}}" class="removelink">
{{l10n "remove.item"}}
</a>
</td>
{{/if}}
</tr>
{{else}}
<tr>
<td colspan="5">{{l10n "tag.pagination.no_items.elements"}}</td>
</tr>
{{/each}}
</tbody>
</table>
{{/override}}
{{/extends}}

View File

@ -0,0 +1,104 @@
{{#extends "layout"}}
{{#override "menu"}}{{> _menu}}{{/override}}
{{#override "content"}}
{{l10n "page_search.intro"}}
<br />
<br />
<form name="searchForm" method="get" action="{{mibewRoot}}/operator/history.php">
<div class="mform">
<div class="formtop">
<div class="formtopi"></div>
</div>
<div class="forminner">
<div class="fieldForm">
<div class="field">
<label for="q" class="flabel">{{l10n "page_analysis.full.text.search"}}</label>
<div class="fvaluenodesc">
<div id="searchtext">
<input id="q" type="text" name="q" size="60" value="{{formq}}" class="formauth"/>
</div>
<div class="searchctrl">
<label for="type">{{l10n "page_search.type.title"}}</label>
<select id="type" name="type" onchange="if (this.value == 'all' || this.value == 'message') {document.getElementById('inSystemMessages').style.display='inline'} else {document.getElementById('inSystemMessages').style.display='none'}; ">
<option value="all" {{#ifEqual formtype "all"}}selected="selected"{{/ifEqual}}>{{l10n "page_search.type.all"}}</option>
<option value="message" {{#ifEqual formtype "message"}}selected="selected"{{/ifEqual}}>{{l10n "page_search.type.message"}}</option>
<option value="operator" {{#ifEqual formtype "operator"}}selected="selected"{{/ifEqual}}>{{l10n "page_search.type.operator"}}</option>
<option value="visitor" {{#ifEqual formtype "visitor"}}selected="selected"{{/ifEqual}}>{{l10n "page_search.type.visitor"}}</option>
</select>
</div>
<div id="searchbutton">
<input type="image" name="search" src="{{mibewRoot}}{{l10n "image.button.search"}}" alt="{{l10n "button.search"}}"/>
</div><br clear="all"/>
<div class="searchctrl" id="inSystemMessages"{{#if canSearchInSystemMessages}} style="display: none;"{{/if}}>
<input id="insystemmessagesfield" type="checkbox" name="insystemmessages" {{#if forminsystemmessages}}checked="checked"{{/if}}/> <label for="insystemmessagesfield">{{l10n "page_search.search.type.in_system_messages"}}</label>
</div>
</div>
<br clear="all"/>
</div>
</div>
</div>
<div class="formbottom">
<div class="formbottomi"></div>
</div>
</div>
</form>
<br/>
<table class="list">
<thead>
<tr class="header">
<th>{{l10n "page.analysis.search.head_name"}}</th>
<th>{{l10n "page.analysis.search.head_host"}}</th>
<th>{{l10n "page.analysis.search.head_operator"}}</th>
<th>{{l10n "page.analysis.search.head_messages"}}</th>
<th>{{l10n "page.analysis.search.head_time"}}</th>
</tr>
</thead>
<tbody>
{{#each [pagination.items]}}
<tr>
<td>
<a href="{{../mibewRoot}}/operator/threadprocessor.php?threadid={{threadId}}" target="_blank" onclick="this.newWindow = window.open('{{../mibewRoot}}/operator/threadprocessor.php?threadid={{threadId}}', '', 'toolbar=0,scrollbars=1,location=0,status=1,menubar=0,width=720,height=520,resizable=1');this.newWindow.focus();this.newWindow.opener=window;return false;">{{userName}}</a>
</td>
<td>
{{{userAddress}}}
</td>
<td>
{{#if agentName}}
{{agentName}}
{{else}}
{{#if groupName}}
- {{groupName}} -
{{/if}}
{{/if}}
</td>
<td>
{{messageCount}}
</td>
<td>
{{formatDateDiff chatTime}}, {{formatDate chatCreated}}
</td>
</tr>
{{else}}
<tr>
<td colspan="5">
{{l10n "tag.pagination.no_items"}}
</td>
</tr>
{{/each}}
</tbody>
</table>
{{#if pagination}}
<br/>
{{generatePagination stylePath pagination}}
{{/if}}
{{/override}}
{{/extends}}

View File

@ -0,0 +1,186 @@
{{#extends "layout"}}
{{#override "header"}}
{{#if localeLinks}}
<script type="text/javascript" language="javascript" src="{{mibewRoot}}/js/libs/jquery.min.js"></script>
<script type="text/javascript" language="javascript" src="{{mibewRoot}}/js/compiled/locale.js"></script>
{{/if}}
{{/override}}
{{#override "menu"}}{{> _menu}}{{/override}}
{{#override "content"}}
<br/>
{{#if needChangePassword}}
<div id="formmessage">{{l10n "error.no_password"}} {{l10n "error.no_password.visit_profile" profilePage}}</div>
<br/>
{{else}}
{{#if needUpdate}}
<div id="formmessage">{{l10n "install.updatedb" updateWizard}}</div>
<br/>
{{else}}
{{#if newFeatures}}
<div><div id="formmessage">{{l10n "install.newfeatures" featuresPage mibewVersion}}</div></div>
<br/>
{{/if}}
{{/if}}
{{/if}}
<div id="dashboard">
<div class="dashitem">
<div class="dashitem-content">
<img src="{{stylePath}}/images/dash/visitors.gif" alt=""/>
<a href="{{mibewRoot}}/operator/users.php">
{{l10n "topMenu.users"}}
</a>
{{l10n "page_client.pending_users"}}
</div>
</div>
<div class="dashitem">
<div class="dashitem-content">
<img src="{{stylePath}}/images/dash/history.gif" alt=""/>
<a href="{{mibewRoot}}/operator/history.php">
{{l10n "page_analysis.search.title"}}
</a>
{{l10n "content.history"}}
</div>
</div>
{{#if showstat}}
<div class="dashitem">
<div class="dashitem-content">
<img src="{{stylePath}}/images/dash/stat.gif" alt=""/>
<a href="{{mibewRoot}}/operator/statistics.php">
{{l10n "statistics.title"}}
</a>
{{l10n "statistics.description"}}
</div>
</div>
{{/if}}
{{#if showban}}
<div class="dashitem">
<div class="dashitem-content">
<img src="{{stylePath}}/images/dash/blocked.gif" alt=""/>
<a href="{{mibewRoot}}/operator/blocked.php">
{{l10n "menu.blocked"}}
</a>
{{l10n "content.blocked"}}
</div>
</div>
{{/if}}
<div class="dashitem">
<div class="dashitem-content">
<img src="{{stylePath}}/images/dash/canned.gif" alt=""/>
<a href="{{mibewRoot}}/operator/canned.php">
{{l10n "menu.canned"}}
</a>
{{l10n "canned.descr"}}
</div>
</div>
{{#if showadmin}}
<div class="dashitem">
<div class="dashitem-content">
<img src="{{stylePath}}/images/dash/getcode.gif" alt=""/>
<a href="{{mibewRoot}}/operator/getcode.php">
{{l10n "leftMenu.client_gen_button"}}
</a>
{{l10n "admin.content.client_gen_button"}}
</div>
</div>
<div class="dashitem">
<div class="dashitem-content">
<img src="{{stylePath}}/images/dash/operators.gif" alt=""/>
<a href="{{mibewRoot}}/operator/operators.php">
{{l10n "leftMenu.client_agents"}}
</a>
{{l10n "admin.content.client_agents"}}
</div>
</div>
<div class="dashitem">
<div class="dashitem-content">
<img src="{{stylePath}}/images/dash/dep.gif" alt=""/>
<a href="{{mibewRoot}}/operator/groups.php">
{{l10n "menu.groups"}}
</a>
{{l10n "menu.groups.content"}}
</div>
</div>
<div class="dashitem">
<div class="dashitem-content">
<img src="{{stylePath}}/images/dash/settings.gif" alt=""/>
<a href="{{mibewRoot}}/operator/settings.php">
{{l10n "leftMenu.client_settings"}}
</a>
{{l10n "admin.content.client_settings"}}
</div>
</div>
{{/if}}
{{#if currentopid}}
<div class="dashitem">
<div class="dashitem-content">
<img src="{{stylePath}}/images/dash/profile.gif" alt=""/>
<a href="{{mibewRoot}}/operator/operator.php?op={{currentopid}}">
{{l10n "menu.profile"}}
</a>
{{l10n "menu.profile.content"}}
</div>
</div>
{{/if}}
{{#if localeLinks}}
<div class="dashitem">
<div class="dashitem-content">
<img src="{{stylePath}}/images/dash/locale.gif" alt=""/>
<a href="#" id="changelang">
{{l10n "menu.locale"}}
</a>
{{l10n "menu.locale.content"}}
</div>
</div>
{{/if}}
{{#if showadmin}}
<div class="dashitem">
<div class="dashitem-content">
<img src="{{stylePath}}/images/dash/updates.gif" alt=""/>
<a href="{{mibewRoot}}/operator/updates.php">
{{l10n "menu.updates"}}
</a>
{{l10n "menu.updates.content"}}
</div>
</div>
{{/if}}
<div class="dashitem">
<div class="dashitem-content">
<img src="{{stylePath}}/images/dash/exit.gif" alt=""/>
<a href="{{mibewRoot}}/operator/logout.php">
{{l10n "topMenu.logoff"}}
</a>
{{l10n "content.logoff"}}
</div>
</div>
</div>
{{#if localeLinks}}
<div id="dashlocalesPopup">
<a href="#" id="dashlocalesPopupClose"><img src="{{stylePath}}/images/dash/close.gif" alt="X"/></a>
<h2><img src="{{stylePath}}/images/dash/locale.gif" alt=""/><b>{{l10n "lang.choose"}}</b></h2>
<ul class="locales">
{{#each localeLinks}}
<li{{#ifEqual currentLocale @key}} class="active"{{/ifEqual}}><a href="?locale={{@key}}">{{this}}</a></li>
{{/each}}
</ul>
</div>
<div id="backgroundPopup"></div>
{{/if}}
{{/override}}
{{/extends}}

View File

@ -0,0 +1,7 @@
{{#extends "layout"}}
{{#override "content"}}
{{> _errors}}
{{l10n "install.err.back"}}
{{/override}}
{{/extends}}

View File

@ -0,0 +1,79 @@
{{#extends "layout"}}
{{#if localeLinks}}
{{#override "menu"}}{{> _locales}}{{/override}}
{{/if}}
{{#override "header"}}
{{#if soundcheck}}
<!-- External libs -->
<script type="text/javascript" src="{{mibewRoot}}/js/libs/jquery.min.js"></script>
<script type="text/javascript" src="{{mibewRoot}}/js/libs/json2.js"></script>
<script type="text/javascript" src="{{mibewRoot}}/js/libs/underscore-min.js"></script>
<script type="text/javascript" src="{{mibewRoot}}/js/libs/backbone-min.js"></script>
<script type="text/javascript" src="{{mibewRoot}}/js/libs/backbone.marionette.min.js"></script>
<script type="text/javascript" src="{{mibewRoot}}/js/libs/handlebars.js"></script>
<!-- Client side templates -->
<script type="text/javascript" src="{{stylePath}}/templates_compiled/client_side/default_app.tpl.js"></script>
<!-- Default application files -->
<script type="text/javascript" src="{{mibewRoot}}/js/compiled/mibewapi.js"></script>
<script type="text/javascript" src="{{mibewRoot}}/js/compiled/default_app.js"></script>
<script type="text/javascript" language="javascript" src="{{mibewRoot}}/js/compiled/soundcheck.js"></script>
{{/if}}
{{/override}}
{{#override "content"}}
{{l10n "install.message"}}
<br/>
<br/>
{{> _errors}}
{{#if done}}
<div id="install">
<div class="mform">
<div class="formtop">
<div class="formtopi"></div>
</div>
<div class="forminner">
{{l10n "install.done"}}
<ul>
{{#each done}}
<li>{{{this}}}</li>
{{/each}}
</ul>
{{#if nextstep}}
<br/>
<br/>
{{l10n "install.next"}}
<ul>
<li>
{{#if nextnotice}}
{{nextnotice}}<br/><br/>
{{/if}}
<a href="{{nextstepurl}}">{{nextstep}}</a>
</li>
</ul>
{{/if}}
</div>
<div class="formbottom">
<div class="formbottomi"></div>
</div>
</div>
</div>
{{/if}}
<br/>
<a href="{{mibewRoot}}/license.php">{{l10n "install.license"}}</a>
{{/override}}
{{/extends}}

View File

@ -0,0 +1,57 @@
{{#extends "layout"}}
{{#override "menu"}}{{> _menu}}{{/override}}
{{#override "header"}}
<link href="{{mibewRoot}}/styles/invitations/{{preview}}/invite.css" rel="stylesheet" type="text/css" />
{{/override}}
{{#override "content"}}
{{l10n "page.preview.intro"}}
<br />
<br />
<form name="preview" method="get" action="{{mibewRoot}}/operator/invitationthemes.php">
<div>
{{> _tabs}}
<div class="mform">
<div class="formtop">
<div class="formtopi"></div>
</div>
<div class="forminner">
<div class="fieldForm">
<div class="field">
<label for="preview" class="flabel">{{l10n "page.preview.choose"}}</label>
<div class="fvaluenodesc">
<select id="preview" name="preview" onchange="this.form.submit();">
{{#each availablePreviews}}
<option value="{{this}}"{{#ifEqual this ../formpreview}} selected="selected"{{/ifEqual}}>{{this}}</option>
{{/each}}
</select>
</div>
</div>
</div>
</div>
<div class="formbottom">
<div class="formbottomi"></div>
</div>
</div>
</div>
</form>
<div id="mibewinvitation">
<div id="mibewinvitationpopup">
<div id="mibewinvitationclose">
<a onclick="void(0);" href="javascript:void(0);">&times;</a>
</div>
<h1 onclick="void(0);">{{operatorName}}</h1>
<div id="mibewinvitationframe">{{l10n "invitation.message"}}</div>
<div id="mibewinvitationaccept" onclick="void(0);">{{l10n "invitation.accept.caption"}}</div>
<div style="clear: both;"></div>
</div>
</div>
{{/override}}
{{/extends}}

View File

@ -0,0 +1,65 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"{{#if rtl}} dir="rtl"{{/if}}>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link rel="shortcut icon" href="{{stylePath}}/images/favicon.ico" type="image/x-icon"/>
<title>
{{title}} - {{l10n "app.title"}}
</title>
<link href="{{stylePath}}/css/default.css" rel="stylesheet" type="text/css" />
<!--[if lte IE 7]><link href="{{stylePath}}/css/default_ie.css" rel="stylesheet" type="text/css" /><![endif] -->
<!--[if lte IE 6]><script language="JavaScript" type="text/javascript" src="{{mibewRoot}}/js/compiled/ie.js"></script><![endif]-->
{{#block "header"}}{{/block}}
</head>
<body{{#unlessOverridden "menu"}} style="min-width: 400px;"{{/unlessOverridden}}>
<div id="{{#if fixedwrap}}fixedwrap{{else}}{{#ifOverridden "menu"}}wrap700{{else}}wrap400{{/ifOverridden}}{{/if}}" class="l{{l10n "localedirection"}}">
<div id="header">
<div id="title">
<h1><img src="{{mibewRoot}}/styles/pages/default/images/logo.png" alt="" width="32" height="32" class="left logo" />
<a href="#">{{#if headertitle}}{{headertitle}}{{else}}{{title}}{{/if}}</a></h1>
</div>
{{#if operator}}
<div id="path"><p>{{l10n "menu.operator" operator}}</p></div>
{{else}}
{{#if show_small_login}}
<div id="loginsmallpane">
<form name="smallLogin" method="post" action="{{mibewRoot}}/operator/login.php">
{{l10n "page_login.login"}}
<input type="text" name="login" size="8" class="formauth"/>
<input type="password" name="password" size="8" class="formauth" autocomplete="off"/>
<input type="hidden" name="isRemember" value=""/>
<input type="submit" value="&gt;&gt;" class="butt"/>
</form>
</div>
{{/if}}
{{/if}}
</div>
<br clear="all"/>
<div class="contentdiv">
{{#ifOverridden "menu"}}
<div id="wcontent" class="contentinner">
{{else}}
<div id="wcontent" class="contentnomenu">
{{/ifOverridden}}
{{#block "content"}}{{/block}}
</div>
</div>
{{#block "menu"}}{{/block}}
<div style="clear: both;">&nbsp;</div>
<div class="empty_inner" style="">&#160;</div>
</div>
<div id="footer">
<p id="legal"><a href="http://mibew.org/" target="_blank" class="flink">Mibew Messenger</a> {{mibewVersion}} | (c) 2011-2013 mibew.org</p>
</div>
</body>
</html>

View File

@ -0,0 +1,21 @@
{{#extends "layout"}}
{{#override "content"}}
<p>Copyright 2005-2013 the original author or authors.</p>
<br/>
<p>Licensed under the <b>Apache License, Version 2.0</b> (the "License").</p>
<br/>
<p>You may obtain a copy of the License at <a href="http://www.apache.org/licenses/LICENSE-2.0">http://www.apache.org/licenses/LICENSE-2.0</a></p>
<br/>
<p>Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.</p>
{{/override}}
{{/extends}}

View File

@ -0,0 +1,66 @@
{{#extends "layout"}}
{{#if localeLinks}}
{{#override "menu"}}{{> _locales}}{{/override}}
{{/if}}
{{#override "content"}}
<div id="loginintro">
<p>{{l10n "app.descr"}}</p>
</div>
<form name="loginForm" method="post" action="{{mibewRoot}}/operator/login.php">
<div id="loginpane">
<div class="header">
<h2>{{l10n "page_login.title"}}</h2>
</div>
<div class="fieldForm">
{{l10n "page_login.intro"}}
<br/>
<br/>
{{> _errors}}
<div class="field">
<div class="fleftlabel">{{l10n "page_login.login"}}</div>
<div class="fvalue">
<input type="text" name="login" size="25" value="{{formlogin}}" class="formauth"/>
</div>
<br clear="all"/>
</div>
<div class="field">
<div class="fleftlabel">{{l10n "page_login.password"}}</div>
<div class="fvalue">
<input type="password" name="password" size="25" value="" class="formauth" autocomplete="off"/>
</div>
<br clear="all"/>
</div>
<div class="field">
<div class="fleftlabel">&nbsp;</div>
<div class="fvalue">
<label>
<input type="checkbox" name="isRemember" value="on"{{#if formisRemember}} checked="checked"{{/if}} />
{{l10n "page_login.remember"}}
</label>
</div>
<br clear="all"/>
</div>
<div class="fbutton">
<input type="image" name="login" src="{{mibewRoot}}{{l10n "image.button.login"}}" alt="{{l10n "button.enter"}}"/>
<div class="links">
<a href="restore.php">{{l10n "restore.pwd.message"}}</a><br/>
</div>
</div>
</div>
</div>
</form>
{{/override}}
{{/extends}}

View File

@ -0,0 +1,129 @@
{{#extends "layout"}}
{{#override "menu"}}{{> _menu}}{{/override}}
{{#override "content"}}
{{#if opid}}
{{l10n "page_agent.intro"}}
{{else}}
{{l10n "page_agent.create_new"}}
{{/if}}
<br />
<br />
{{> _errors}}
{{#if needChangePassword}}
<div id="formmessage">{{l10n "error.no_password"}}</div>
<br/>
{{else}}
{{#if stored}}
<div id="formmessage">{{l10n "data.saved"}}</div>
{{/if}}
{{/if}}
{{#ifAny opid canmodify}}
<form name="agentForm" method="post" action="{{mibewRoot}}/operator/operator.php">
{{csrfTokenInput}}
<input type="hidden" name="opid" value="{{opid}}"/>
<div>
{{#unless needChangePassword}}{{> _tabs}}{{/unless}}
<div class="mform">
<div class="formtop">
<div class="formtopi"></div>
</div>
<div class="forminner">
<div class="fieldForm">
<div class="field">
<label for="login" class="flabel">{{l10n "form.field.login"}}<span class="required">*</span></label>
<div class="fvalue">
<input id="login" type="text" name="login" size="40" value="{{formlogin}}" class="formauth"{{#unless canchangelogin}} disabled="disabled"{{/unless}}/>
</div>
<label for="login" class="fdescr"> &mdash; {{l10n "form.field.login.description"}}</label>
<br clear="all"/>
</div>
<div class="field">
<label for="email" class="flabel">{{l10n "form.field.mail"}}<span class="required">*</span></label>
<div class="fvalue">
<input id="email" type="text" name="email" size="40" value="{{formemail}}" class="formauth"{{#unless canmodify}} disabled="disabled"{{/unless}}/>
</div>
<label for="email" class="fdescr"> &mdash; {{l10n "form.field.mail.description"}}</label>
<br clear="all"/>
</div>
<div class="field">
<label for="password" class="flabel">
{{l10n "form.field.password"}}{{#if requirePassword}}<span class="required">*</span>{{/if}}
</label>
<div class="fvalue">
<input id="password" type="password" name="password" size="40" value="" class="formauth"{{#unless canmodify}} disabled="disabled"{{/unless}} autocomplete="off"/>
</div>
<label for="password" class="fdescr"> &mdash; {{l10n "form.field.password.description"}}</label>
<br clear="all"/>
</div>
<div class="field">
<label for="passwordConfirm" class="flabel">
{{l10n "form.field.password_confirm"}}{{#if requirePassword}}<span class="required">*</span>{{/if}}
</label>
<div class="fvalue">
<input id="passwordConfirm" type="password" name="passwordConfirm" size="40" value="" class="formauth"{{#unless canmodify}} disabled="disabled"{{/unless}} autocomplete="off"/>
</div>
<label for="passwordConfirm" class="fdescr"> &mdash; {{l10n "form.field.password_confirm.description"}}</label>
<br clear="all"/>
</div>
<div class="field">
<label for="name" class="flabel">{{l10n "form.field.agent_name"}}<span class="required">*</span></label>
<div class="fvalue">
<input id="name" type="text" name="name" size="40" value="{{formname}}" class="formauth"{{#unless canmodify}} disabled="disabled"{{/unless}}/>
</div>
<label for="name" class="fdescr"> &mdash; {{l10n "form.field.agent_name.description"}}</label>
<br clear="all"/>
</div>
<div class="field">
<label for="commonname" class="flabel">{{l10n "form.field.agent_commonname"}}<span class="required">*</span></label>
<div class="fvalue">
<input id="commonname" type="text" name="commonname" size="40" value="{{formcommonname}}" class="formauth"{{#unless canmodify}} disabled="disabled"{{/unless}}/>
</div>
<label for="commonname" class="fdescr"> &mdash; {{l10n "form.field.agent_commonname.description"}}</label>
<br clear="all"/>
</div>
<div class="field">
<label for="code" class="flabel">{{l10n "form.field.agent_code"}}</label>
<div class="fvalue">
<input id="code" type="text" name="code" size="40" value="{{formcode}}" class="formauth"{{#unless canmodify}} disabled="disabled"{{/unless}}/>
</div>
<label for="code" class="fdescr"> &mdash; {{l10n "form.field.agent_code.description"}}</label>
<br clear="all"/>
</div>
{{#if canmodify}}
<div class="fbutton">
<input type="image" name="save" value="" src="{{mibewRoot}}{{l10n "image.button.save"}}" alt="{{l10n "button.save"}}"/>
</div>
{{/if}}
</div>
</div>
<div class="formbottom">
<div class="formbottomi"></div>
</div>
</div>
</div>
<div class="asterisk">
{{l10n "common.asterisk_explanation"}}
</div>
</form>
{{/ifAny}}
{{/override}}
{{/extends}}

View File

@ -0,0 +1,58 @@
{{#extends "layout"}}
{{#override "menu"}}{{> _menu}}{{/override}}
{{#override "content"}}
{{l10n "operator.groups.intro"}}
<br />
<br />
{{> _errors}}
{{#if stored}}
<div id="formmessage">{{l10n "data.saved"}}</div>
{{/if}}
<form name="opgroupsForm" method="post" action="{{mibewRoot}}/operator/opgroups.php">
{{csrfTokenInput}}
<input type="hidden" name="op" value="{{opid}}"/>
<div>
{{> _tabs}}
<div class="mform">
<div class="formtop">
<div class="formtopi"></div>
</div>
<div class="forminner">
<p><b>{{currentop}}&lrm;</b></p>
{{#each groups}}
<div class="field level{{level}}">
<label for="group{{groupid}}" class="flabel">{{vclocalname}}</label>
<div class="fvalue">
<input id="group{{groupid}}" type="checkbox" name="group{{groupid}}" value="on"{{#if checked}} checked="checked"{{/if}}{{#unless ../canmodify}} disabled="disabled"{{/unless}}/>
</div>
<label for="group{{groupid}}" class="fdescr">
&mdash; {{#if vclocaldescription}}{{vclocaldescription}}{{else}}{{l10n "operator.group.no_description"}}{{/if}}
</label>
<br clear="all"/>
</div>
{{/each}}
{{#if canmodify}}
<div class="fbutton">
<input type="image" name="save" value="" src="{{mibewRoot}}{{l10n "image.button.save"}}" alt="{{l10n "button.save"}}"/>
</div>
{{/if}}
</div>
<div class="formbottom">
<div class="formbottomi"></div>
</div>
</div>
</div>
</form>
{{/override}}
{{/extends}}

View File

@ -0,0 +1,131 @@
{{#extends "layout"}}
{{#override "menu"}}{{> _menu}}{{/override}}
{{#override "header"}}
<script type="text/javascript" language="javascript" src="{{mibewRoot}}/js/libs/jquery.min.js"></script>
<script type="text/javascript" language="javascript"><!--
(function($) {
$(document).ready(function(){
var confirmMessage = "{{#jsString}}{{l10n 'page_agents.confirm' '{login}'}}{{/jsString}}";
$('a.removelink').click(function(){
var login = $.trim($("#t" + this.id).text());
return confirm(confirmMessage.replace("{login}", login));
});
});
})(jQuery);
//--></script>
{{/override}}
{{#override "content"}}
{{l10n "page_agents.intro"}}
<br />
<br />
{{> _errors}}
<form name="agentsForm" method="get" action="{{mibewRoot}}/operator/operators.php">
<div class="mform">
<div class="formtop">
<div class="formtopi"></div>
</div>
<div class="forminner">
<div class="packedFormField">
{{l10n "page_agents.sort"}}<br/>
<select name="sortby" onchange="this.form.submit();">
{{#each availableOrders}}
<option value="{{id}}"{{#ifEqual id ../formsortby}} selected="selected"{{/ifEqual}}>{{name}}</option>
{{/each}}
</select>
</div>
<div class="packedFormField">
{{l10n "page_agents.sortdirection"}}<br/>
<select name="sortdirection" onchange="this.form.submit();">
{{#each availableDirections}}
<option value="{{id}}"{{#ifEqual id ../formsortdirection}} selected="selected"{{/ifEqual}}>{{name}}</option>
{{/each}}
</select>
</div>
<br clear="all"/>
</div>
<div class="formbottom">
<div class="formbottomi"></div>
</div>
</div>
</form>
<br />
{{#if canmodify}}
<div class="tabletool">
<img src="{{stylePath}}/images/buttons/createagent.gif" border="0" alt="" />
<a href="{{mibewRoot}}/operator/operator.php" title="{{l10n "page_agents.new_agent"}}">
{{l10n "page_agents.new_agent"}}
</a>
</div>
<br clear="all"/>
{{/if}}
<table class="list">
<thead>
<tr class="header">
<th>{{l10n "page_agents.login"}}</th>
<th>{{l10n "page_agents.agent_name"}}</th>
<th>{{l10n "page_agents.status"}}</th>
{{#if canmodify}}
<th></th>
<th></th>
{{/if}}
</tr>
</thead>
<tbody>
{{#each allowedAgents}}
<tr>
<td class="notlast">
<a id="ti{{operatorid}}" href="{{../mibewRoot}}/operator/operator.php?op={{operatorid}}" class="man">
{{vclogin}}
</a>
</td>
<td class="notlast">
{{vclocalename}} / {{vccommonname}}
</td>
<td class="notlast">
{{#ifAny isAvailable isAway}}
{{#if isAvailable}}
{{l10n "page_agents.isonline"}}
{{else}}
{{l10n "page_agents.isaway"}}
{{/if}}
{{else}}
{{formatDate lastTimeOnline}}
{{/ifAny}}
</td>
{{#if ../canmodify}}
<td>
{{#if isDisabled}}
<a href="{{../mibewRoot}}/operator/operators.php?act=enable&amp;id={{operatorid}}">{{l10n "page_agents.enable.agent"}}</a>
{{else}}
<a href="{{../mibewRoot}}/operator/operators.php?act=disable&amp;id={{operatorid}}">{{l10n "page_agents.disable.agent"}}</a>
{{/if}}
</td>
<td>
<a class="removelink" id="i{{operatorid}}" href="{{../mibewRoot}}/operator/operators.php?act=del&amp;id={{operatorid}}{{csrfTokenInUrl}}">
{{l10n "remove.item"}}
</a>
</td>
{{/if}}
</tr>
{{/each}}
</tbody>
</table>
{{/override}}
{{/extends}}

View File

@ -0,0 +1,48 @@
{{#extends "layout"}}
{{#override "menu"}}{{> _menu}}{{/override}}
{{#override "content"}}
{{l10n "page.preview.intro"}}
<br />
<br />
<form name="preview" method="get" action="{{mibewRoot}}/operator/page_themes.php">
<div>
{{> _tabs}}
<div class="mform">
<div class="formtop">
<div class="formtopi"></div>
</div>
<div class="forminner">
<div class="fieldForm">
<div class="field">
<label for="preview" class="flabel">{{l10n "page.preview.choose"}}</label>
<div class="fvaluenodesc">
<select id="preview" name="preview" onchange="this.form.submit();">
{{#each availablePreviews}}
<option value="{{this}}"{{#ifEqual this ../formpreview}} selected="selected"{{/ifEqual}}>{{this}}</option>
{{/each}}
</select>
</div>
</div>
{{#each screenshotsList}}
<div class="field">
<div class="flabel">{{description}}</div>
<div class="fvalueframe">
<img class="screenshot" alt="{{name}}" src="{{file}}" />
</div>
</div>
{{/each}}
</div>
</div>
<div class="formbottom">
<div class="formbottomi"></div>
</div>
</div>
</div>
</form>
{{/override}}
{{/extends}}

View File

@ -0,0 +1,140 @@
{{#extends "layout"}}
{{#override "menu"}}{{> _menu}}{{/override}}
{{#override "content"}}
{{l10n "page_settings.intro"}}
<br />
<br />
{{> _errors}}
{{#if stored}}
<div id="formmessage">{{l10n "settings.saved"}}</div>
{{/if}}
<form name="performance" method="post" action="{{mibewRoot}}/operator/performance.php">
{{csrfTokenInput}}
<div>
{{> _tabs}}
<div class="mform">
<div class="formtop">
<div class="formtopi"></div>
</div>
<div class="forminner">
<div class="fieldForm">
<div class="field">
<label for="onlinetimeout" class="flabel">{{l10n "settings.onlinetimeout"}}</label>
<div class="fvalue">
<input id="onlinetimeout" type="text" name="onlinetimeout" size="40" value="{{formonlinetimeout}}" class="formauth"/>
</div>
<label for="onlinetimeout" class="fdescr"> &mdash; {{l10n "settings.onlinetimeout.description"}}</label>
<br clear="all"/>
</div>
<div class="field">
<label for="frequencyoperator" class="flabel">{{l10n "settings.frequencyoperator"}}</label>
<div class="fvalue">
<input id="frequencyoperator" type="text" name="frequencyoperator" size="40" value="{{formfrequencyoperator}}" class="formauth"/>
</div>
<label for="frequencyoperator" class="fdescr"> &mdash; {{l10n "settings.frequencyoperator.description"}}</label>
<br clear="all"/>
</div>
<div class="field">
<label for="frequencychat" class="flabel">{{l10n "settings.frequencychat"}}</label>
<div class="fvalue">
<input id="frequencychat" type="text" name="frequencychat" size="40" value="{{formfrequencychat}}" class="formauth"/>
</div>
<label for="frequencychat" class="fdescr"> &mdash; {{l10n "settings.frequencychat.description"}}</label>
<br clear="all"/>
</div>
<div class="field">
<label for="onehostconnections" class="flabel">{{l10n "settings.onehostconnections"}}</label>
<div class="fvalue">
<input id="onehostconnections" type="text" name="onehostconnections" size="40" value="{{formonehostconnections}}" class="formauth"/>
</div>
<label for="onehostconnections" class="fdescr"> &mdash; {{l10n "settings.onehostconnections.description"}}</label>
<br clear="all"/>
</div>
<div class="field">
<label for="threadlifetime" class="flabel">{{l10n "settings.threadlifetime"}}</label>
<div class="fvalue">
<input id="threadlifetime" type="text" name="threadlifetime" size="40" value="{{formthreadlifetime}}" class="formauth"/>
</div>
<label for="threadlifetime" class="fdescr"> &mdash; {{l10n "settings.threadlifetime.description"}}</label>
<br clear="all"/>
</div>
<div class="field">
<label for="statistics_aggregation_interval" class="flabel">{{l10n "settings.statistics_aggregation_interval"}}</label>
<div class="fvalue">
<input id="statistics_aggregation_interval" type="text" name="statistics_aggregation_interval" size="40" value="{{formstatistics_aggregation_interval}}" class="formauth"/>
</div>
<label for="statistics_aggregation_interval" class="fdescr"> &mdash; {{l10n "settings.statistics_aggregation_interval.description"}}</label>
<br clear="all"/>
</div>
{{#if enabletracking}}
<div class="field">
<label for="frequencytracking" class="flabel">{{l10n "settings.frequencytracking"}}</label>
<div class="fvalue">
<input id="frequencytracking" type="text" name="frequencytracking" size="40" value="{{formfrequencytracking}}" class="formauth"/>
</div>
<label for="frequencytracking" class="fdescr"> &mdash; {{l10n "settings.frequencytracking.description"}}</label>
<br clear="all"/>
</div>
<div class="field">
<label for="visitorslimit" class="flabel">{{l10n "settings.visitorslimit"}}</label>
<div class="fvalue">
<input id="visitorslimit" type="text" name="visitorslimit" size="40" value="{{formvisitorslimit}}" class="formauth"/>
</div>
<label for="visitorslimit" class="fdescr"> &mdash; {{l10n "settings.visitorslimit.description"}}</label>
<br clear="all"/>
</div>
<div class="field">
<label for="invitationlifetime" class="flabel">{{l10n "settings.invitationlifetime"}}</label>
<div class="fvalue">
<input id="invitationlifetime" type="text" name="invitationlifetime" size="40" value="{{forminvitationlifetime}}" class="formauth"/>
</div>
<label for="invitationlifetime" class="fdescr"> &mdash; {{l10n "settings.invitationlifetime.description"}}</label>
<br clear="all"/>
</div>
<div class="field">
<label for="trackinglifetime" class="flabel">{{l10n "settings.trackinglifetime"}}</label>
<div class="fvalue">
<input id="trackinglifetime" type="text" name="trackinglifetime" size="40" value="{{formtrackinglifetime}}" class="formauth"/>
</div>
<label for="trackinglifetime" class="fdescr"> &mdash; {{l10n "settings.trackinglifetime.description"}}</label>
<br clear="all"/>
</div>
{{/if}}
<div class="fbutton">
<input type="image" name="save" value="" src="{{mibewRoot}}{{l10n "image.button.save"}}" alt="{{l10n "button.save"}}"/>
</div>
</div>
</div>
<div class="formbottom">
<div class="formbottomi"></div>
</div>
</div>
</div>
<div class="asterisk">
{{l10n "common.asterisk_explanation"}}
</div>
</form>
{{/override}}
{{/extends}}

View File

@ -0,0 +1,53 @@
{{#extends "layout"}}
{{#override "menu"}}{{> _menu}}{{/override}}
{{#override "content"}}
{{l10n "permissions.intro"}}
<br />
<br />
{{> _errors}}
{{#if stored}}
<div id="formmessage">{{l10n "data.saved"}}</div>
{{/if}}
<form name="permissionsForm" method="post" action="{{mibewRoot}}/operator/permissions.php">
{{csrfTokenInput}}
<input type="hidden" name="op" value="{{opid}}"/>
<div>
{{> _tabs}}
<div class="mform">
<div class="formtop">
<div class="formtopi"></div>
</div>
<div class="forminner">
<p><b>{{currentop}}&lrm;</b></p>
{{#each permissionsList}}
<label>
<input type="checkbox" name="permissions{{id}}" value="on"{{#if checked}} checked="checked"{{/if}}{{#unless ../canmodify}} disabled="disabled"{{/unless}}/>
{{descr}}
</label>
<br/>
{{/each}}
{{#if canmodify}}
<div class="fbutton">
<input type="image" name="save" value="" src='{{mibewRoot}}{{l10n "image.button.save"}}' alt='{{l10n "button.save"}}'/>
</div>
{{/if}}
</div>
<div class="formbottom">
<div class="formbottomi"></div>
</div>
</div>
</div>
</form>
{{/override}}
{{/extends}}

View File

@ -0,0 +1,90 @@
{{#extends "layout"}}
{{#if localeLinks}}
{{#override "menu"}}{{> _locales}}{{/override}}
{{/if}}
{{#override "content"}}
{{#if isdone}}
<div id="loginpane">
<div class="header">
<h2>{{l10n "resetpwd.changed.title"}}</h2>
</div>
<div class="fieldForm">
{{l10n "resetpwd.changed"}}
<br/>
<br/>
<a href="login.php?login={{loginname}}">{{l10n "resetpwd.login"}}</a>
</div>
</div>
{{else}}
<form name="resetForm" method="post" action="{{mibewRoot}}/operator/resetpwd.php">
<input type="hidden" name="id" value="{{id}}"/>
<input type="hidden" name="token" value="{{token}}"/>
<div id="loginpane">
<div class="header">
<h2>{{l10n "resetpwd.title"}}</h2>
</div>
<div class="fieldForm">
{{l10n "resetpwd.intro"}}
<br/>
<br/>
{{> _errors}}
{{#if showform}}
<div class="field">
<div class="fleftlabel">{{l10n "form.field.password"}}</div>
<div class="fvalue">
<input type="password" name="password" size="25" value="" class="formauth" autocomplete="off"/>
</div>
<br clear="all"/>
</div>
<div class="field">
<div class="fleftlabel">{{l10n "form.field.password_confirm"}}</div>
<div class="fvalue">
<input type="password" name="passwordConfirm" size="25" value="" class="formauth" autocomplete="off"/>
</div>
<br clear="all"/>
</div>
<div class="fbutton">
<table class="submitbutton">
<tr>
<td>
<a href="javascript:document.resetForm.submit();">
<img src="{{stylePath}}/images/submit.gif" width="40" height="35" border="0" alt="" />
</a>
</td>
<td class="submit">
<a href="javascript:document.resetForm.submit();">
{{l10n "resetpwd.submit"}}
</a>
</td>
<td>
<a href="javascript:document.resetForm.submit();">
<img src="{{stylePath}}/images/submitrest.gif" width="10" height="35" border="0" alt="" />
</a>
</td>
</tr>
</table>
<div class="links">
<a href="login.php">{{l10n "restore.back_to_login"}}</a>
</div>
</div>
{{else}}
<a href="login.php">{{l10n "restore.back_to_login"}}</a>
{{/if}}
</div>
</div>
</form>
{{/if}}
{{/override}}
{{/extends}}

View File

@ -0,0 +1,73 @@
{{#extends "layout"}}
{{#if localeLinks}}
{{#override "menu"}}{{> _locales}}{{/override}}
{{/if}}
{{#override "content"}}
{{#if isdone}}
<div id="loginpane">
<div class="header">
<h2>{{l10n "restore.sent.title"}}</h2>
</div>
<div class="fieldForm">
{{l10n "restore.sent"}}
<br/>
<br/>
<a href="login.php">{{l10n "restore.back_to_login"}}</a>
</div>
</div>
{{else}}
<form name="restoreForm" method="post" action="{{mibewRoot}}/operator/restore.php">
<div id="loginpane">
<div class="header">
<h2>{{l10n "restore.title"}}</h2>
</div>
<div class="fieldForm">
{{l10n "restore.intro"}}<br/><br/>
{{> _errors}}
<div class="field">
<div class="fleftlabel">{{l10n "restore.emailorlogin"}}</div>
<div class="fvalue">
<input type="text" name="loginoremail" size="25" value="{{formloginoremail}}" class="formauth"/>
</div>
<br clear="all"/>
</div>
<div class="fbutton">
<table class="submitbutton">
<tr>
<td>
<a href="javascript:document.restoreForm.submit();">
<img src="{{stylePath}}/images/submit.gif" width="40" height="35" border="0" alt="" />
</a>
</td>
<td class="submit">
<a href="javascript:document.restoreForm.submit();">
{{l10n "restore.submit"}}
</a>
</td>
<td>
<a href="javascript:document.restoreForm.submit();">
<img src="{{stylePath}}/images/submitrest.gif" width="10" height="35" border="0" alt="" />
</a>
</td>
</tr>
</table>
<div class="links">
<a href="login.php">{{l10n "restore.back_to_login"}}</a>
</div>
</div>
</div>
</div>
</form>
{{/if}}
{{/override}}
{{/extends}}

View File

@ -0,0 +1,180 @@
{{#extends "layout"}}
{{#override "menu"}}{{> _menu}}{{/override}}
{{#override "content"}}
{{l10n "page_settings.intro"}}
<br />
<br />
{{> _errors}}
{{#if stored}}
<div id="formmessage">{{l10n "settings.saved"}}</div>
{{/if}}
<form name="settings" method="post" action="{{mibewRoot}}/operator/settings.php">
{{csrfTokenInput}}
<div>
{{> _tabs}}
<div class="mform">
<div class="formtop">
<div class="formtopi"></div>
</div>
<div class="forminner">
<div class="fieldForm">
<div class="field">
<label for="email" class="flabel">{{l10n "settings.email"}}</label>
<div class="fvalue">
<input id="email" type="text" name="email" size="40" value="{{formemail}}" class="formauth"/>
</div>
<label for="email" class="fdescr"> &mdash; {{l10n "settings.email.description"}}</label>
<br clear="all"/>
</div>
<div class="field">
<label for="titlefield" class="flabel">{{l10n "settings.company.title"}}</label>
<div class="fvalue">
<input id="titlefield" type="text" name="title" size="40" value="{{formtitle}}" class="formauth"/>
</div>
<label for="titlefield" class="fdescr"> &mdash; {{l10n "settings.company.title.description"}}</label>
<br clear="all"/>
</div>
<div class="field">
<label for="chattitle" class="flabel">{{l10n "settings.chat.title"}}</label>
<div class="fvalue">
<input id="chattitle" type="text" name="chattitle" size="40" value="{{formchattitle}}" class="formauth"/>
</div>
<label for="chattitle" class="fdescr"> &mdash; {{l10n "settings.chat.title.description"}}</label>
<br clear="all"/>
</div>
<div class="field">
<label for="logofield" class="flabel">{{l10n "settings.logo"}}</label>
<div class="fvalue">
<input id="logofield" type="text" name="logo" size="40" value="{{formlogo}}" class="formauth"/>
</div>
<label for="logofield" class="fdescr"> &mdash; {{l10n "settings.logo.description"}}</label>
<br clear="all"/>
</div>
<div class="field">
<label for="hosturl" class="flabel">{{l10n "settings.host"}}</label>
<div class="fvalue">
<input id="hosturl" type="text" name="hosturl" size="40" value="{{formhosturl}}" class="formauth"/>
</div>
<label for="hosturl" class="fdescr"> &mdash; {{l10n "settings.host.description"}}</label>
<br clear="all"/>
</div>
<div class="field">
<label for="geolink" class="flabel">{{l10n "settings.geolink"}}</label>
<div class="fvalue">
<input id="geolink" type="text" name="geolink" size="40" value="{{formgeolink}}" class="formauth"/>
</div>
<label for="geolink" class="fdescr"> &mdash; {{l10n "settings.geolink.description"}}</label>
<br clear="all"/>
</div>
<div class="field">
<label for="geolinkparams" class="flabel">{{l10n "settings.geolinkparams"}}</label>
<div class="fvalue">
<input id="geolinkparams" type="text" name="geolinkparams" size="40" value="{{formgeolinkparams}}" class="formauth"/>
</div>
<label for="geolinkparams" class="fdescr"> &mdash; {{l10n "settings.geolinkparams.description"}}</label>
<br clear="all"/>
</div>
<div class="field">
<label for="usernamepattern" class="flabel">{{l10n "settings.usernamepattern"}}</label>
<div class="fvalue">
<input id="usernamepattern" type="text" name="usernamepattern" size="40" value="{{formusernamepattern}}" class="formauth"/>
</div>
<label for="usernamepattern" class="fdescr"> &mdash; {{l10n "settings.usernamepattern.description"}}</label>
<br clear="all"/>
</div>
<div class="field">
<label for="cronkey" class="flabel">{{l10n "settings.cronkey"}}</label>
<div class="fvalue">
<input id="cronkey" type="text" name="cronkey" size="40" value="{{formcronkey}}" class="formauth"/>
</div>
<label for="cronkey" class="fdescr"> &mdash; {{l10n "settings.cronkey.description" cron_path}}</label>
<br clear="all"/>
</div>
<div class="field">
<label for="page_style" class="flabel">{{l10n "settings.page_style"}}</label>
<div class="fvalue">
<select id="pages_style" name="page_style">
{{#each availablePageStyles}}
<option value="{{this}}"{{#ifEqual this ../formpagestyle}} selected="selected"{{/ifEqual}}>{{this}}</option>
{{/each}}
</select>
</div>
<label for="page_style" class="fdescr"> &mdash; {{l10n "settings.page_style.description"}}</label>
<br clear="all"/>
</div>
<div class="field">
<label for="chat_style" class="flabel">{{l10n "settings.chatstyle"}}</label>
<div class="fvalue">
<select id="chat_style" name="chat_style" >
{{#each availableChatStyles}}
<option value="{{this}}"{{#ifEqual this ../formchatstyle}} selected="selected"{{/ifEqual}}>{{this}}</option>
{{/each}}
</select>
</div>
<label for="chat_style" class="fdescr"> &mdash; {{l10n "settings.chatstyle.description"}}</label>
<br clear="all"/>
</div>
{{#if enabletracking}}
<div class="field">
<label for="invitation_style" class="flabel">{{l10n "settings.invitationstyle"}}</label>
<div class="fvalue">
<select id="invitation_style" name="invitation_style" >
{{#each availableInvitationStyles}}
<option value="{{this}}"{{#ifEqual this ../forminvitationstyle}} selected="selected"{{/ifEqual}}>{{this}}</option>
{{/each}}
</select>
</div>
<label for="invitation_style" class="fdescr"> &mdash; {{l10n "settings.invitationstyle.description"}}</label>
<br clear="all"/>
</div>
{{/if}}
<div class="field">
<div class="flabel">{{l10n "settings.sendmessagekey"}}</div>
<div class="fvaluenodesc">
<input id="sendmessagekeyenter" type="radio" name="sendmessagekey" value="enter" {{#ifEqual formsendmessagekey "enter"}} checked="checked"{{/ifEqual}}/><label for="sendmessagekeyenter">Enter</label>
<input id="sendmessagekeycenter" type="radio" name="sendmessagekey" value="center" {{#ifEqual formsendmessagekey "center"}} checked="checked"{{/ifEqual}}/><label for="sendmessagekeycenter">Ctrl-Enter</label>
</div>
</div>
<div class="fbutton">
<input type="image" name="save" value="" src="{{mibewRoot}}{{l10n "image.button.save"}}" alt="{{l10n "button.save"}}"/>
</div>
</div>
</div>
<div class="formbottom">
<div class="formbottomi"></div>
</div>
</div>
</div>
<div class="asterisk">
{{l10n "common.asterisk_explanation"}}
</div>
</form>
{{/override}}
{{/extends}}

Some files were not shown because too many files have changed in this diff Show More