parent
387a330fc0
commit
fd8ba446cc
@ -0,0 +1,212 @@ |
||||
<?php |
||||
/* For licensing terms, see /license.txt */ |
||||
|
||||
use Symfony\Component\Finder\Finder; |
||||
|
||||
/** |
||||
* Class MailTemplateManager. |
||||
*/ |
||||
class MailTemplateManager extends Model |
||||
{ |
||||
public $columns = [ |
||||
'id', |
||||
'name', |
||||
'template', |
||||
'type', |
||||
'system', |
||||
'url_id', |
||||
'default_template', |
||||
'created_at', |
||||
'updated_at', |
||||
'author_id', |
||||
]; |
||||
|
||||
public function __construct() |
||||
{ |
||||
parent::__construct(); |
||||
|
||||
$this->table = 'mail_template'; |
||||
} |
||||
|
||||
/** |
||||
* @return int |
||||
*/ |
||||
public function get_count() |
||||
{ |
||||
$row = Database::select( |
||||
'count(*) as count', |
||||
$this->table, |
||||
['where' => ['url_id = ? ' => api_get_current_access_url_id()]], |
||||
'first' |
||||
); |
||||
|
||||
return $row['count']; |
||||
} |
||||
|
||||
/** |
||||
* Displays the title + grid. |
||||
* |
||||
* @return string html code |
||||
*/ |
||||
public function display() |
||||
{ |
||||
// Action links |
||||
$html = '<div class="actions" style="margin-bottom:20px">'; |
||||
$html .= '<a href="'.api_get_path(WEB_CODE_PATH).'admin">'. |
||||
Display::return_icon( |
||||
'back.png', |
||||
get_lang('Back'), |
||||
'', |
||||
'32' |
||||
) |
||||
.'</a>'; |
||||
$html .= '<a href="'.api_get_self().'?action=add">'. |
||||
Display::return_icon( |
||||
'add.png', |
||||
get_lang('Add'), |
||||
'', |
||||
'32' |
||||
).'</a>'; |
||||
$html .= '</div>'; |
||||
$html .= Display::grid_html('mail_template'); |
||||
|
||||
return $html; |
||||
} |
||||
|
||||
/** |
||||
* Returns a Form validator Obj. |
||||
* |
||||
* @param string $url |
||||
* @param string $action |
||||
* |
||||
* @return FormValidator |
||||
*/ |
||||
public function returnForm($url, $action = 'add') |
||||
{ |
||||
$form = new FormValidator('template', 'post', $url); |
||||
// Setting the form elements |
||||
$header = get_lang('Add'); |
||||
if ($action === 'edit') { |
||||
$header = get_lang('Modify'); |
||||
} |
||||
$id = isset($_GET['id']) ? (int) $_GET['id'] : ''; |
||||
|
||||
$form->addElement('header', '', $header); |
||||
$form->addElement('hidden', 'id', $id); |
||||
$form->addElement( |
||||
'text', |
||||
'name', |
||||
get_lang('Name'), |
||||
['size' => '70', 'id' => 'name'] |
||||
); |
||||
|
||||
/*$form->addHtmlEditor( |
||||
'email_template', |
||||
get_lang('Template'), |
||||
false, |
||||
false, |
||||
[ |
||||
'ToolbarSet' => 'Careers', |
||||
'Width' => '100%', |
||||
'Height' => '250', |
||||
] |
||||
);*/ |
||||
$form->addTextarea( |
||||
'email_template', |
||||
get_lang('Template') |
||||
); |
||||
|
||||
$finder = new Finder(); |
||||
$files = $finder |
||||
->files() |
||||
->in(api_get_path(SYS_CODE_PATH).'template/default/mail') |
||||
->sort( |
||||
function ($a, $b) { |
||||
return strcmp($a->getRealpath(), $b->getRealpath()); |
||||
} |
||||
); |
||||
|
||||
$options = []; |
||||
/** @var SplFileInfo $file */ |
||||
foreach ($files as $file) { |
||||
$options[$file->getFilename()] = $file->getFilename(); |
||||
} |
||||
|
||||
$form->addSelect( |
||||
'type', |
||||
get_lang('Type'), |
||||
$options |
||||
); |
||||
|
||||
$defaults = $this->get($id); |
||||
|
||||
if ($action === 'edit') { |
||||
$form->addLabel(get_lang('CreatedAt'), Display::dateToStringAgoAndLongDate($defaults['created_at'])); |
||||
$form->addLabel(get_lang('UpdatedAt'), Display::dateToStringAgoAndLongDate($defaults['updated_at'])); |
||||
$form->addButtonSave(get_lang('Modify'), 'submit'); |
||||
} else { |
||||
$form->addButtonCreate(get_lang('Add'), 'submit'); |
||||
} |
||||
|
||||
// Setting the defaults |
||||
if (!empty($defaults)) { |
||||
$defaults['email_template'] = $defaults['template']; |
||||
} |
||||
$form->setDefaults($defaults); |
||||
|
||||
// Setting the rules |
||||
$form->addRule('name', get_lang('ThisFieldIsRequired'), 'required'); |
||||
|
||||
return $form; |
||||
} |
||||
|
||||
/** |
||||
* @param int $id |
||||
* |
||||
* @return bool |
||||
*/ |
||||
public function setDefault($id) |
||||
{ |
||||
$template = $this->get($id); |
||||
if (empty($template)) { |
||||
return false; |
||||
} |
||||
$type = $template['type']; |
||||
$urlId = api_get_current_access_url_id(); |
||||
$sql = "UPDATE {$this->table} SET default_template = 0 |
||||
WHERE type = '$type' AND url_id = $urlId"; |
||||
Database::query($sql); |
||||
|
||||
$sql = "UPDATE {$this->table} SET default_template = 1 |
||||
WHERE id = $id"; |
||||
Database::query($sql); |
||||
|
||||
return true; |
||||
} |
||||
|
||||
/** |
||||
* @param int $templateId |
||||
* @param array $userInfo |
||||
* |
||||
* @return string|false |
||||
*/ |
||||
public function parseTemplate($templateId, $userInfo) |
||||
{ |
||||
$templateInfo = $this->get($templateId); |
||||
if (!empty($templateInfo)) { |
||||
$emailTemplate = $templateInfo['template']; |
||||
|
||||
$keys = array_keys($userInfo); |
||||
foreach ($keys as $key) { |
||||
$emailTemplate = str_replace("{{user.$key}}", $userInfo[$key], $emailTemplate); |
||||
} |
||||
$template = new Template(); |
||||
$template->twig->setLoader(new \Twig_Loader_String()); |
||||
$emailBody = $template->twig->render($emailTemplate); |
||||
|
||||
return $emailBody; |
||||
} |
||||
|
||||
return false; |
||||
} |
||||
} |
||||
@ -0,0 +1,25 @@ |
||||
/** |
||||
* When included, this snippet prevents contextual menus and keystrokes that |
||||
* make it possible to cut/paste/copy text from the page. |
||||
* This is useful for very secure exams. |
||||
* @author Alberto Torreblanca |
||||
*/ |
||||
$(document).ready(function(){ |
||||
$(document).on("cut copy paste contextmenu",function(e) { |
||||
e.preventDefault(); |
||||
}); |
||||
$(document).keydown(function(e) { |
||||
var forbiddenKeys = new Array('c', 'x', 'v', 'p', 's'); |
||||
var keyCode = (e.keyCode) ? e.keyCode : e.which; |
||||
var isCtrl; |
||||
isCtrl = e.ctrlKey |
||||
if (isCtrl) { |
||||
for (i = 0; i < forbiddenKeys.length; i++) { |
||||
if (forbiddenKeys[i] == String.fromCharCode(keyCode).toLowerCase()) { |
||||
return false; |
||||
} |
||||
} |
||||
} |
||||
return true; |
||||
}); |
||||
}); |
||||
@ -0,0 +1,37 @@ |
||||
body { |
||||
font-size: 25px; |
||||
line-height: 1.25em !important; |
||||
text-align: justify; |
||||
-webkit-touch-callout: none; |
||||
-webkit-user-select: none; |
||||
-khtml-user-select: none; |
||||
-moz-user-select: none; |
||||
-ms-user-select: none; |
||||
user-select: none; |
||||
} |
||||
|
||||
.text-highlight { |
||||
-webkit-transition: color .3s linear, text-shadow .3s linear; |
||||
-khtml-transition: color .3s linear, text-shadow .3s linear; |
||||
-moz-transition: color .3s linear, text-shadow .3s linear; |
||||
-ms-transition: color .3s linear, text-shadow .3s linear; |
||||
transition: color .3s linear, text-shadow .3s linear; |
||||
} |
||||
|
||||
.text-highlight.active { |
||||
color: red; |
||||
-webkit-text-shadow: 0px 0px 1px rgba(255, 0, 0, 1); |
||||
-khtml-text-shadow: 0px 0px 1px rgba(255, 0, 0, 1); |
||||
-moz-text-shadow: 0px 0px 1px rgba(255, 0, 0, 1); |
||||
-ms-text-shadow: 0px 0px 1px rgba(255, 0, 0, 1); |
||||
text-shadow: 0px 0px 1px rgba(255, 0, 0, 1); |
||||
-webkit-transition: color .3s linear, text-shadow .3s linear; |
||||
-khtml-transition: color .3s linear, text-shadow .3s linear; |
||||
-moz-transition: color .3s linear, text-shadow .3s linear; |
||||
-ms-transition: color .3s linear, text-shadow .3s linear; |
||||
transition: color .3s linear, text-shadow .3s linear; |
||||
} |
||||
|
||||
br { |
||||
margin-bottom: 1em; |
||||
} |
||||
@ -0,0 +1,76 @@ |
||||
/* For licensing terms, see /license.txt */ |
||||
|
||||
$(function () { |
||||
var parent$ = window.parent.$, |
||||
playerSelector = '#' + parent$('mediaelementwrapper').attr('id') + '_html5', |
||||
$player = parent$(playerSelector); |
||||
|
||||
var player = $player.get(0), |
||||
def = $.Deferred(); |
||||
|
||||
if (!$player.length) { |
||||
processText(wordsCount); |
||||
|
||||
return; |
||||
} |
||||
|
||||
player.preload = 'auto'; |
||||
|
||||
function processText(turns) { |
||||
var tagEnd = '</span> ', |
||||
tagStart = tagEnd + '<span class="text-highlight">', |
||||
wordsPerSecond = Math.ceil(wordsCount / turns); |
||||
|
||||
var indexes = Object.keys(words); |
||||
|
||||
var output = ''; |
||||
|
||||
for (var i = 0; i < turns; i++) { |
||||
var block = indexes.slice(i * wordsPerSecond, i * wordsPerSecond + wordsPerSecond), |
||||
index = block[0]; |
||||
|
||||
if (!index) { |
||||
continue; |
||||
} |
||||
|
||||
output += tagStart + words[index]; |
||||
|
||||
for (var j = 1; j < block.length; j++) { |
||||
index = block[j]; |
||||
output += ' ' + words[index]; |
||||
} |
||||
} |
||||
|
||||
output += tagEnd; |
||||
output = output.slice(tagEnd.length); |
||||
|
||||
$('.page-blank').html(output); |
||||
|
||||
def.resolve(output); |
||||
|
||||
return def.promise(); |
||||
} |
||||
|
||||
player.ontimeupdate = function () { |
||||
var block = Math.ceil(this.currentTime); |
||||
|
||||
$('.text-highlight') |
||||
.removeClass('active') |
||||
.filter(function (index) { |
||||
return index + 1 == block; |
||||
}) |
||||
.addClass('active'); |
||||
}; |
||||
player.onloadedmetadata = function () { |
||||
var turns = Math.ceil(this.duration); |
||||
|
||||
processText(turns) |
||||
.then(function (output) { |
||||
var to = window.setTimeout(function () { |
||||
player.play(); |
||||
|
||||
window.clearTimeout(to); |
||||
}, 1500); |
||||
}); |
||||
} |
||||
}); |
||||
File diff suppressed because it is too large
Load Diff
Loading…
Reference in new issue