Merge pull request #102 from LDAPAccountManager/feature/webcam
Feature/webcam
This commit is contained in:
commit
3368b4ab10
|
@ -3,6 +3,7 @@ September 2020
|
|||
- Configuration export and import
|
||||
- Show password prompt when a user with expired password logs into LAM admin interface (requires PHP 7.2)
|
||||
- Better error messages on login when account is expired/deactivated/...
|
||||
- Personal: photo can be uploaded via webcam
|
||||
- Windows users: group display format can be configured (cn/dn)
|
||||
- LAM Pro:
|
||||
-> Windows: new cron job to send users a summary of their managed groups
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 3.4 KiB |
|
@ -3078,7 +3078,13 @@ class htmlStatusMessage extends htmlElement {
|
|||
* @return array List of input field names and their type (name => type)
|
||||
*/
|
||||
public function generateHTML($module, $input, $values, $restricted, &$tabindex, $scope) {
|
||||
if (!empty($this->cssClasses)) {
|
||||
echo '<div class="' . implode(' ', $this->cssClasses) . '">';
|
||||
}
|
||||
StatusMessage($this->type, $this->title, $this->text, $this->params);
|
||||
if (!empty($this->cssClasses)) {
|
||||
echo '</div>';
|
||||
}
|
||||
return array();
|
||||
}
|
||||
|
||||
|
@ -3344,6 +3350,8 @@ class htmlLink extends htmlElement {
|
|||
private $onClick = null;
|
||||
/** show as button */
|
||||
private $showAsButton = false;
|
||||
/** link id */
|
||||
private $id;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
|
@ -3393,8 +3401,8 @@ class htmlLink extends htmlElement {
|
|||
$onClick = ' onclick="' . $this->onClick . '"';
|
||||
}
|
||||
$idAttr = '';
|
||||
if ($this->showAsButton) {
|
||||
$id = 'a_' . preg_replace('/[^a-zA-Z0-9_]+/', '_', $this->target);
|
||||
if ($this->showAsButton || !empty($this->id)) {
|
||||
$id = !empty($this->id) ? $this->id : 'a_' . preg_replace('/[^a-zA-Z0-9_]+/', '_', $this->target);
|
||||
$idAttr = ' id="' . $id . '"';
|
||||
}
|
||||
$classAttr = '';
|
||||
|
@ -3457,6 +3465,15 @@ class htmlLink extends htmlElement {
|
|||
$this->onClick = htmlspecialchars($event);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the element id.
|
||||
*
|
||||
* @param string $id unique id
|
||||
*/
|
||||
public function setId($id) {
|
||||
$this->id = $id;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -4973,5 +4990,68 @@ class htmlResponsiveTable extends htmlElement {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders a canvas.
|
||||
*
|
||||
* @author Roland Gruber
|
||||
*/
|
||||
class htmlCanvas extends htmlElement {
|
||||
|
||||
private $id;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param string $id html id
|
||||
*/
|
||||
public function __construct($id) {
|
||||
$this->id = $id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
function generateHTML($module, $input, $values, $restricted, &$tabindex, $scope) {
|
||||
$classesValue = '';
|
||||
if (!empty($this->cssClasses)) {
|
||||
$classesValue = ' class="' . implode(' ', $this->cssClasses) . '"';
|
||||
}
|
||||
echo '<canvas id="' . $this->id . '" ' . $classesValue . '>';
|
||||
echo '</canvas>';
|
||||
return array();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders a video.
|
||||
*
|
||||
* @author Roland Gruber
|
||||
*/
|
||||
class htmlVideo extends htmlElement {
|
||||
|
||||
private $id;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param string $id html id
|
||||
*/
|
||||
public function __construct($id) {
|
||||
$this->id = $id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
function generateHTML($module, $input, $values, $restricted, &$tabindex, $scope) {
|
||||
$classesValue = '';
|
||||
if (!empty($this->cssClasses)) {
|
||||
$classesValue = ' class="' . implode(' ', $this->cssClasses) . '"';
|
||||
}
|
||||
echo '<video id="' . $this->id . '" ' . $classesValue . '>';
|
||||
echo '</video>';
|
||||
return array();
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
|
|
@ -1629,7 +1629,7 @@ class inetOrgPerson extends baseModule implements passwordService {
|
|||
if ($this->isAdminReadOnly('jpegPhoto')) {
|
||||
return array();
|
||||
}
|
||||
if (isset($_POST['form_subpage_' . get_class($this) . '_photo_upload'])) {
|
||||
if (isset($_POST['form_subpage_' . get_class($this) . '_photo_upload']) || isset($_POST['webcamData'])) {
|
||||
return $this->uploadPhoto();
|
||||
}
|
||||
if (isset($_POST['form_subpage_' . get_class($this) . '_attributes_crop'])) {
|
||||
|
@ -1656,40 +1656,46 @@ class inetOrgPerson extends baseModule implements passwordService {
|
|||
*/
|
||||
private function uploadPhoto() {
|
||||
$messages = array();
|
||||
if ($_FILES['photoFile'] && ($_FILES['photoFile']['size'] > 0)) {
|
||||
if ((empty($_FILES['photoFile']) || ($_FILES['photoFile']['size'] <= 0)) && empty($_POST['webcamData'])) {
|
||||
$messages[] = $this->messages['file'][0];
|
||||
return $messages;
|
||||
}
|
||||
if (!empty($_FILES['photoFile']['tmp_name'])) {
|
||||
$handle = fopen($_FILES['photoFile']['tmp_name'], "r");
|
||||
$data = fread($handle, 100000000);
|
||||
fclose($handle);
|
||||
if (!empty($this->moduleSettings['inetOrgPerson_jpegPhoto_maxSize'][0]) && (strlen($data) > (1024 * $this->moduleSettings['inetOrgPerson_jpegPhoto_maxSize'][0]))) {
|
||||
$errMsg = $this->messages['file'][3];
|
||||
$errMsg[] = null;
|
||||
$errMsg[] = array($this->moduleSettings['inetOrgPerson_jpegPhoto_maxSize'][0]);
|
||||
return array($errMsg);
|
||||
}
|
||||
fclose($handle);
|
||||
// convert to JPG
|
||||
try {
|
||||
include_once dirname(__FILE__) . '/../imageutils.inc';
|
||||
$imageManipulator = ImageManipulationFactory::getImageManipulator($data);
|
||||
// resize if maximum values specified
|
||||
if (!empty($this->moduleSettings['inetOrgPerson_jpegPhoto_maxWidth'][0]) || !empty($this->moduleSettings['inetOrgPerson_jpegPhoto_maxHeight'][0])) {
|
||||
$maxWidth = empty($this->moduleSettings['inetOrgPerson_jpegPhoto_maxWidth'][0]) ? $imageManipulator->getWidth() : $this->moduleSettings['inetOrgPerson_jpegPhoto_maxWidth'][0];
|
||||
$maxHeight = empty($this->moduleSettings['inetOrgPerson_jpegPhoto_maxHeight'][0]) ? $imageManipulator->getHeight() : $this->moduleSettings['inetOrgPerson_jpegPhoto_maxHeight'][0];
|
||||
$imageManipulator->thumbnail($maxWidth, $maxHeight);
|
||||
}
|
||||
$imageManipulator->convertToJpeg();
|
||||
$data = $imageManipulator->getImageData();
|
||||
}
|
||||
catch (Exception $e) {
|
||||
$msg = $this->messages['file'][2];
|
||||
$msg[] = htmlspecialchars($e->getMessage());
|
||||
$messages[] = $msg;
|
||||
return $messages;
|
||||
}
|
||||
$this->attributes['jpegPhoto'][0] = $data;
|
||||
}
|
||||
else {
|
||||
$messages[] = $this->messages['file'][0];
|
||||
elseif (isset($_POST['webcamData'])) {
|
||||
$data = $_POST['webcamData'];
|
||||
$data = str_replace('data:image/png;base64,', '', $data);
|
||||
$data = base64_decode($data);
|
||||
}
|
||||
// convert to JPG
|
||||
try {
|
||||
include_once dirname(__FILE__) . '/../imageutils.inc';
|
||||
$imageManipulator = ImageManipulationFactory::getImageManipulator($data);
|
||||
// resize if maximum values specified
|
||||
if (!empty($this->moduleSettings['inetOrgPerson_jpegPhoto_maxWidth'][0]) || !empty($this->moduleSettings['inetOrgPerson_jpegPhoto_maxHeight'][0])) {
|
||||
$maxWidth = empty($this->moduleSettings['inetOrgPerson_jpegPhoto_maxWidth'][0]) ? $imageManipulator->getWidth() : $this->moduleSettings['inetOrgPerson_jpegPhoto_maxWidth'][0];
|
||||
$maxHeight = empty($this->moduleSettings['inetOrgPerson_jpegPhoto_maxHeight'][0]) ? $imageManipulator->getHeight() : $this->moduleSettings['inetOrgPerson_jpegPhoto_maxHeight'][0];
|
||||
$imageManipulator->thumbnail($maxWidth, $maxHeight);
|
||||
}
|
||||
$imageManipulator->convertToJpeg();
|
||||
$data = $imageManipulator->getImageData();
|
||||
}
|
||||
catch (Exception $e) {
|
||||
$msg = $this->messages['file'][2];
|
||||
$msg[] = htmlspecialchars($e->getMessage());
|
||||
$messages[] = $msg;
|
||||
return $messages;
|
||||
}
|
||||
$this->attributes['jpegPhoto'][0] = $data;
|
||||
return $messages;
|
||||
}
|
||||
|
||||
|
@ -1704,9 +1710,33 @@ class inetOrgPerson extends baseModule implements passwordService {
|
|||
$container->add(new htmlSubTitle(_('Upload image')), 12);
|
||||
$label = _('Photo file');
|
||||
$container->add(new htmlResponsiveInputFileUpload('photoFile', $label, 'photoUpload'), 12);
|
||||
$container->addVerticalSpacer('0.5rem');
|
||||
$container->addLabel(new htmlOutputText(' ', false));
|
||||
$container->addField(new htmlAccountPageButton(get_class($this), 'photo', 'upload', _('Upload')));
|
||||
$container->addVerticalSpacer('1rem');
|
||||
$container->addLabel(new htmlAccountPageButton(get_class($this), 'photo', 'upload', _('Upload')));
|
||||
$container->addField(new htmlAccountPageButton(get_class($this), 'attributes', 'back', _('Back')));
|
||||
$webcamContent = new htmlResponsiveRow();
|
||||
$webcamContent->add(new htmlSubTitle(_('Use webcam')), 12);
|
||||
$errorMessage = new htmlStatusMessage('ERROR', '');
|
||||
$errorMessage->setCSSClasses(array('hidden', 'lam-webcam-message'));
|
||||
$webcamContent->add($errorMessage, 12);
|
||||
$captureButton = new htmlButton('lam-webcam-capture', _('Start capture'));
|
||||
$captureButton->setOnClick('window.lam.tools.webcam.capture(event);');
|
||||
$webcamContent->add($captureButton, 12, 12, 12, 'text-center');
|
||||
$video = new htmlVideo('lam-webcam-video');
|
||||
$video->setCSSClasses(array('hidden'));
|
||||
$webcamContent->add($video, 12, 12, 12, 'text-center');
|
||||
$webcamContent->addVerticalSpacer('0.5rem');
|
||||
$webcamUploadButton = new htmlButton('uploadWebcam', _('Upload'));
|
||||
$webcamUploadButton->setCSSClasses(array('btn-lam-webcam-upload', 'hidden'));
|
||||
$webcamUploadButton->setOnClick('window.lam.tools.webcam.upload();');
|
||||
$webcamContent->add($webcamUploadButton, 12, 12, 12, 'text-center');
|
||||
$canvas = new htmlCanvas('lam-webcam-canvas');
|
||||
$canvas->setCSSClasses(array('hidden'));
|
||||
$webcamContent->add($canvas, 12);
|
||||
$webcamDiv = new htmlDiv('lam_webcam_div', $webcamContent, array('hidden'));
|
||||
$container->add($webcamDiv, 12);
|
||||
$container->addVerticalSpacer('1rem');
|
||||
$container->add(new htmlAccountPageButton(get_class($this), 'attributes', 'back', _('Back')), 12);
|
||||
}
|
||||
else {
|
||||
$container->add(new htmlSubTitle(_('Crop image')), 12);
|
||||
|
@ -3062,6 +3092,33 @@ class inetOrgPerson extends baseModule implements passwordService {
|
|||
$uploadStatus = new htmlDiv('inetOrgPersonPhotoUploadStatus', new htmlOutputText(''));
|
||||
$uploadStatus->setCSSClasses(array('qq-upload-list'));
|
||||
$row->add($uploadStatus, 12);
|
||||
// webcam button
|
||||
$webcamContent = new htmlResponsiveRow();
|
||||
$webcamContent->addVerticalSpacer('0.5rem');
|
||||
$errorMessage = new htmlStatusMessage('ERROR', '');
|
||||
$errorMessage->setCSSClasses(array('hidden', 'lam-webcam-message'));
|
||||
$webcamContent->add($errorMessage, 12);
|
||||
$webcamContent->addVerticalSpacer('0.5rem');
|
||||
$captureButton = new htmlLink(_('Use webcam'), '#', '../../graphics/webcam.png', true);
|
||||
$captureButton->setId('btn_lam-webcam-capture');
|
||||
$captureButton->setOnClick('window.lam.tools.webcam.capture(event);');
|
||||
$webcamContent->add($captureButton, 12, 12, 12);
|
||||
$video = new htmlVideo('lam-webcam-video');
|
||||
$video->setCSSClasses(array('hidden'));
|
||||
$webcamContent->add($video, 12, 12, 12, 'text-center');
|
||||
$webcamContent->addVerticalSpacer('1rem');
|
||||
$webcamUploadButton = new htmlLink(_('Upload'), '#', '../../graphics/up.gif', true);
|
||||
$webcamUploadButton->setId('btn-lam-webcam-upload');
|
||||
$webcamUploadButton->setCSSClasses(array('btn-lam-webcam-upload', 'hidden'));
|
||||
$webcamUploadButton->setOnClick('window.lam.tools.webcam.uploadSelfService(event, "' . getSecurityTokenName()
|
||||
. '", "' . getSecurityTokenValue() . '", "inetOrgPerson", "user", "' . _('File upload failed!') . '", "inetOrgPersonPhotoUploadContent");');
|
||||
$webcamContent->add($webcamUploadButton, 12, 12, 12);
|
||||
$canvas = new htmlCanvas('lam-webcam-canvas');
|
||||
$canvas->setCSSClasses(array('hidden'));
|
||||
$webcamContent->add($canvas, 12);
|
||||
$webcamDiv = new htmlDiv('lam_webcam_div', $webcamContent, array('hidden'));
|
||||
$webcamContent->addVerticalSpacer('1rem');
|
||||
$row->add($webcamDiv, 12);
|
||||
return $row;
|
||||
}
|
||||
|
||||
|
@ -3095,6 +3152,7 @@ class inetOrgPerson extends baseModule implements passwordService {
|
|||
if (data.success) {
|
||||
if (data.html) {
|
||||
jQuery(\'#inetOrgPersonPhotoUploadContent\').html(data.html);
|
||||
window.lam.tools.webcam.init();
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -3119,6 +3177,7 @@ class inetOrgPerson extends baseModule implements passwordService {
|
|||
function inetOrgPersonDeletePhotoHandleReply(data) {
|
||||
if (data.errorsOccured == "false") {
|
||||
jQuery(\'#inetOrgPersonPhotoUploadContent\').html(data.html);
|
||||
window.lam.tools.webcam.init();
|
||||
}
|
||||
else {
|
||||
alert(data.errormessage);
|
||||
|
@ -3790,13 +3849,20 @@ class inetOrgPerson extends baseModule implements passwordService {
|
|||
*/
|
||||
private function ajaxUploadPhoto() {
|
||||
$result = array('success' => true);
|
||||
if (!isset($_FILES['qqfile']) || ($_FILES['qqfile']['size'] < 100)) {
|
||||
if ((!isset($_FILES['qqfile']) || ($_FILES['qqfile']['size'] < 100)) && empty($_POST['webcamData'])) {
|
||||
$result = array('error' => _('No file received.'));
|
||||
}
|
||||
else {
|
||||
$handle = fopen($_FILES['qqfile']['tmp_name'], "r");
|
||||
$data = fread($handle, 100000000);
|
||||
fclose($handle);
|
||||
if (empty($_POST['webcamData'])) {
|
||||
$handle = fopen($_FILES['qqfile']['tmp_name'], "r");
|
||||
$data = fread($handle, 100000000);
|
||||
fclose($handle);
|
||||
}
|
||||
else {
|
||||
$data = $_POST['webcamData'];
|
||||
$data = str_replace('data:image/png;base64,', '', $data);
|
||||
$data = base64_decode($data);
|
||||
}
|
||||
try {
|
||||
include_once dirname(__FILE__) . '/../imageutils.inc';
|
||||
$imageManipulator = ImageManipulationFactory::getImageManipulator($data);
|
||||
|
|
|
@ -2087,9 +2087,33 @@ class windowsUser extends baseModule implements passwordService {
|
|||
$container->add(new htmlSubTitle(_('Upload image')), 12);
|
||||
$label = _('Photo file');
|
||||
$container->add(new htmlResponsiveInputFileUpload('photoFile', $label, 'photoUpload'), 12);
|
||||
$container->addVerticalSpacer('2rem');
|
||||
$container->addLabel(new htmlAccountPageButton(get_class($this), 'photo', 'upload', _('Upload')));
|
||||
$container->addField(new htmlAccountPageButton(get_class($this), 'attributes', 'back', _('Back')));
|
||||
$container->addVerticalSpacer('0.5rem');
|
||||
$container->addLabel(new htmlOutputText(' ', false));
|
||||
$container->addField(new htmlAccountPageButton(get_class($this), 'photo', 'upload', _('Upload')));
|
||||
$container->addVerticalSpacer('1rem');
|
||||
$webcamContent = new htmlResponsiveRow();
|
||||
$webcamContent->add(new htmlSubTitle(_('Use webcam')), 12);
|
||||
$errorMessage = new htmlStatusMessage('ERROR', '');
|
||||
$errorMessage->setCSSClasses(array('hidden', 'lam-webcam-message'));
|
||||
$webcamContent->add($errorMessage, 12);
|
||||
$captureButton = new htmlButton('lam-webcam-capture', _('Start capture'));
|
||||
$captureButton->setOnClick('window.lam.tools.webcam.capture(event);');
|
||||
$webcamContent->add($captureButton, 12, 12, 12, 'text-center');
|
||||
$video = new htmlVideo('lam-webcam-video');
|
||||
$video->setCSSClasses(array('hidden'));
|
||||
$webcamContent->add($video, 12, 12, 12, 'text-center');
|
||||
$webcamContent->addVerticalSpacer('0.5rem');
|
||||
$webcamUploadButton = new htmlButton('uploadWebcam', _('Upload'));
|
||||
$webcamUploadButton->setCSSClasses(array('btn-lam-webcam-upload', 'hidden'));
|
||||
$webcamUploadButton->setOnClick('window.lam.tools.webcam.upload();');
|
||||
$webcamContent->add($webcamUploadButton, 12, 12, 12, 'text-center');
|
||||
$canvas = new htmlCanvas('lam-webcam-canvas');
|
||||
$canvas->setCSSClasses(array('hidden'));
|
||||
$webcamContent->add($canvas, 12);
|
||||
$webcamDiv = new htmlDiv('lam_webcam_div', $webcamContent, array('hidden'));
|
||||
$container->add($webcamDiv, 12);
|
||||
$container->addVerticalSpacer('1rem');
|
||||
$container->add(new htmlAccountPageButton(get_class($this), 'attributes', 'back', _('Back')), 12);
|
||||
}
|
||||
else {
|
||||
$container->add(new htmlSubTitle(_('Crop image')), 12);
|
||||
|
@ -2115,7 +2139,7 @@ class windowsUser extends baseModule implements passwordService {
|
|||
if (isset($_POST['form_subpage_' . get_class($this) . '_attributes_back'])) {
|
||||
return array();
|
||||
}
|
||||
if (isset($_POST['form_subpage_' . get_class($this) . '_photo_upload'])) {
|
||||
if (isset($_POST['form_subpage_' . get_class($this) . '_photo_upload']) || isset($_POST['webcamData'])) {
|
||||
return $this->uploadPhoto();
|
||||
}
|
||||
if (isset($_POST['form_subpage_' . get_class($this) . '_attributes_crop'])) {
|
||||
|
@ -2142,40 +2166,46 @@ class windowsUser extends baseModule implements passwordService {
|
|||
*/
|
||||
private function uploadPhoto() {
|
||||
$messages = array();
|
||||
if ($_FILES['photoFile'] && ($_FILES['photoFile']['size'] > 0)) {
|
||||
if ((empty($_FILES['photoFile']) || ($_FILES['photoFile']['size'] <= 0)) && empty($_POST['webcamData'])) {
|
||||
$messages[] = $this->messages['file'][0];
|
||||
return $messages;
|
||||
}
|
||||
if (!empty($_FILES['photoFile']['tmp_name'])) {
|
||||
$handle = fopen($_FILES['photoFile']['tmp_name'], "r");
|
||||
$data = fread($handle, 10000000);
|
||||
fclose($handle);
|
||||
if (!empty($this->moduleSettings['windowsUser_jpegPhoto_maxSize'][0]) && (strlen($data) > (1024 * $this->moduleSettings['windowsUser_jpegPhoto_maxSize'][0]))) {
|
||||
$errMsg = $this->messages['file'][3];
|
||||
$errMsg[] = null;
|
||||
$errMsg[] = array($this->moduleSettings['windowsUser_jpegPhoto_maxSize'][0]);
|
||||
return array($errMsg);
|
||||
}
|
||||
fclose($handle);
|
||||
// convert to JPG
|
||||
try {
|
||||
include_once dirname(__FILE__) . '/../imageutils.inc';
|
||||
$imageManipulator = ImageManipulationFactory::getImageManipulator($data);
|
||||
// resize if maximum values specified
|
||||
if (!empty($this->moduleSettings['windowsUser_jpegPhoto_maxWidth'][0]) || !empty($this->moduleSettings['windowsUser_jpegPhoto_maxHeight'][0])) {
|
||||
$maxWidth = empty($this->moduleSettings['windowsUser_jpegPhoto_maxWidth'][0]) ? $imageManipulator->getWidth() : $this->moduleSettings['windowsUser_jpegPhoto_maxWidth'][0];
|
||||
$maxHeight = empty($this->moduleSettings['windowsUser_jpegPhoto_maxHeight'][0]) ? $imageManipulator->getHeight() : $this->moduleSettings['windowsUser_jpegPhoto_maxHeight'][0];
|
||||
$imageManipulator->thumbnail($maxWidth, $maxHeight);
|
||||
}
|
||||
$imageManipulator->convertToJpeg();
|
||||
$data = $imageManipulator->getImageData();
|
||||
}
|
||||
catch (Exception $e) {
|
||||
$msg = $this->messages['file'][2];
|
||||
$msg[] = htmlspecialchars($e->getMessage());
|
||||
$messages[] = $msg;
|
||||
return $messages;
|
||||
}
|
||||
$this->attributes['jpegPhoto'][0] = $data;
|
||||
}
|
||||
else {
|
||||
$messages[] = $this->messages['file'][0];
|
||||
elseif (isset($_POST['webcamData'])) {
|
||||
$data = $_POST['webcamData'];
|
||||
$data = str_replace('data:image/png;base64,', '', $data);
|
||||
$data = base64_decode($data);
|
||||
}
|
||||
// convert to JPG
|
||||
try {
|
||||
include_once dirname(__FILE__) . '/../imageutils.inc';
|
||||
$imageManipulator = ImageManipulationFactory::getImageManipulator($data);
|
||||
// resize if maximum values specified
|
||||
if (!empty($this->moduleSettings['windowsUser_jpegPhoto_maxWidth'][0]) || !empty($this->moduleSettings['windowsUser_jpegPhoto_maxHeight'][0])) {
|
||||
$maxWidth = empty($this->moduleSettings['windowsUser_jpegPhoto_maxWidth'][0]) ? $imageManipulator->getWidth() : $this->moduleSettings['windowsUser_jpegPhoto_maxWidth'][0];
|
||||
$maxHeight = empty($this->moduleSettings['windowsUser_jpegPhoto_maxHeight'][0]) ? $imageManipulator->getHeight() : $this->moduleSettings['windowsUser_jpegPhoto_maxHeight'][0];
|
||||
$imageManipulator->thumbnail($maxWidth, $maxHeight);
|
||||
}
|
||||
$imageManipulator->convertToJpeg();
|
||||
$data = $imageManipulator->getImageData();
|
||||
}
|
||||
catch (Exception $e) {
|
||||
$msg = $this->messages['file'][2];
|
||||
$msg[] = htmlspecialchars($e->getMessage());
|
||||
$messages[] = $msg;
|
||||
return $messages;
|
||||
}
|
||||
$this->attributes['jpegPhoto'][0] = $data;
|
||||
return $messages;
|
||||
}
|
||||
|
||||
|
@ -4349,7 +4379,7 @@ if (interface_exists('\LAM\JOB\Job', false)) {
|
|||
/**
|
||||
* Returns the month interval.
|
||||
*
|
||||
* @param arry $options config options
|
||||
* @param array $options config options
|
||||
* @param $jobId job id
|
||||
* @return int interval
|
||||
*/
|
||||
|
|
|
@ -193,6 +193,11 @@ table.responsive-table td {
|
|||
padding: 5px 5px 5px 5px;
|
||||
}
|
||||
|
||||
#lam-webcam-video {
|
||||
max-width: 200px;
|
||||
max-height: 200px;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* tablet */
|
||||
|
@ -222,6 +227,11 @@ table.responsive-table td {
|
|||
padding: 5px 20px 5px 20px;
|
||||
}
|
||||
|
||||
#lam-webcam-video {
|
||||
max-width: 300px;
|
||||
max-height: 300px;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* desktop */
|
||||
|
@ -255,4 +265,9 @@ table.responsive-table td {
|
|||
padding: 5px 20px 5px 20px;
|
||||
}
|
||||
|
||||
#lam-webcam-video {
|
||||
max-width: 400px;
|
||||
max-height: 400px;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -934,6 +934,144 @@ window.lam.tools.setInitialFocus = function() {
|
|||
jQuery('.lam-initial-focus').focus();
|
||||
};
|
||||
|
||||
window.lam.tools.webcam = window.lam.tools.webcam || {};
|
||||
|
||||
/**
|
||||
* Initializes the webcam capture.
|
||||
*/
|
||||
window.lam.tools.webcam.init = function() {
|
||||
var contentDiv = jQuery('#lam_webcam_div');
|
||||
if (contentDiv.length === 0) {
|
||||
return;
|
||||
}
|
||||
if (navigator.mediaDevices && navigator.mediaDevices.enumerateDevices) {
|
||||
navigator.mediaDevices.enumerateDevices()
|
||||
.then(function(mediaDevices) {
|
||||
mediaDevices.forEach(mediaDevice => {
|
||||
if (mediaDevice.kind === 'videoinput') {
|
||||
contentDiv.show();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Starts the webcam capture.
|
||||
*/
|
||||
window.lam.tools.webcam.capture = function(event) {
|
||||
event.preventDefault();
|
||||
var video = document.getElementById('lam-webcam-video');
|
||||
var msg = jQuery('.lam-webcam-message');
|
||||
msg.hide();
|
||||
navigator.mediaDevices.getUserMedia({
|
||||
video: {
|
||||
facingMode: 'user',
|
||||
width: { min: 1024, ideal: 1280, max: 1920 },
|
||||
height: { min: 576, ideal: 720, max: 1080 }
|
||||
},
|
||||
audio: false
|
||||
})
|
||||
.then(function(stream) {
|
||||
video.srcObject = stream;
|
||||
video.play();
|
||||
window.lam.tools.webcamStream = stream;
|
||||
jQuery('#btn_lam-webcam-capture').hide();
|
||||
jQuery('.btn-lam-webcam-upload').show();
|
||||
jQuery('#lam-webcam-video').show();
|
||||
})
|
||||
.catch(function(err) {
|
||||
msg.find('.statusTitle').text(err);
|
||||
msg.show();
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the webcam upload.
|
||||
*/
|
||||
window.lam.tools.webcam.upload = function() {
|
||||
var form = jQuery('#lam-webcam-canvas').closest('form');
|
||||
canvasData = window.lam.tools.webcam.prepareData();
|
||||
var canvasDataInput = jQuery("<input></input>");
|
||||
canvasDataInput.attr('name', 'webcamData');
|
||||
canvasDataInput.attr('id', 'webcamData');
|
||||
canvasDataInput.attr('type', 'hidden');
|
||||
canvasDataInput.attr('value', canvasData);
|
||||
form.append(canvasDataInput);
|
||||
form.submit();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the webcam upload.
|
||||
*
|
||||
* @param event click event
|
||||
* @param tokenName security token name
|
||||
* @param tokenValue security token value
|
||||
* @param moduleName module name
|
||||
* @param scope account type
|
||||
* @param uploadErrorMessage error message if upload fails
|
||||
* @param contentId id of content to replace
|
||||
*/
|
||||
window.lam.tools.webcam.uploadSelfService = function(event, tokenName, tokenValue, moduleName, scope, uploadErrorMessage, contentId) {
|
||||
event.preventDefault();
|
||||
var msg = jQuery('.lam-webcam-message');
|
||||
canvasData = window.lam.tools.webcam.prepareData();
|
||||
var data = {
|
||||
webcamData: canvasData
|
||||
};
|
||||
data[tokenName] = tokenValue;
|
||||
jQuery.ajax({
|
||||
url: '../misc/ajax.php?selfservice=1&action=ajaxPhotoUpload'
|
||||
+ '&module=' + moduleName + '&scope=' + scope,
|
||||
method: 'POST',
|
||||
data: data
|
||||
})
|
||||
.done(function(jsonData) {
|
||||
if (jsonData.success) {
|
||||
if (jsonData.html) {
|
||||
jQuery('#' + contentId).html(jsonData.html);
|
||||
window.lam.tools.webcam.init();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
else if (jsonData.error) {
|
||||
msg.find('.statusTitle').text(jsonData.error);
|
||||
msg.show();
|
||||
}
|
||||
})
|
||||
.fail(function() {
|
||||
msg.find('.statusTitle').text(errorMessage);
|
||||
msg.show();
|
||||
});
|
||||
jQuery('#btn_lam-webcam-capture').show();
|
||||
jQuery('.btn-lam-webcam-upload').hide();
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the webcam upload.
|
||||
*
|
||||
* @return webcam data as string
|
||||
*/
|
||||
window.lam.tools.webcam.prepareData = function() {
|
||||
var canvas = document.getElementById('lam-webcam-canvas');
|
||||
var video = document.getElementById('lam-webcam-video');
|
||||
canvas.setAttribute('width', video.videoWidth);
|
||||
canvas.setAttribute('height', video.videoHeight);
|
||||
var context = canvas.getContext('2d');
|
||||
context.drawImage(video, 0, 0, video.videoWidth, video.videoHeight);
|
||||
var canvasData = canvas.toDataURL("image/png");
|
||||
video.pause();
|
||||
window.lam.tools.webcamStream.getTracks().forEach(function(track) {
|
||||
track.stop();
|
||||
});
|
||||
jQuery(canvas).hide();
|
||||
jQuery(video).hide();
|
||||
return canvasData;
|
||||
}
|
||||
|
||||
window.lam.tools.schema = window.lam.tools.schema || {};
|
||||
|
||||
/**
|
||||
|
@ -1788,6 +1926,7 @@ jQuery(document).ready(function() {
|
|||
window.lam.tools.addSavedSelectListener();
|
||||
window.lam.tools.activateTab();
|
||||
window.lam.tools.setInitialFocus();
|
||||
window.lam.tools.webcam.init();
|
||||
window.lam.tools.schema.select();
|
||||
window.lam.html.activateLightboxes();
|
||||
window.lam.html.preventEnter();
|
||||
|
|
|
@ -80,6 +80,7 @@ use PHPUnit\Framework\TestCase;
|
|||
|
||||
public function testWindowsManagedGroupsNotifyJob_getLastEffectiveExecutionDate() {
|
||||
if (!interface_exists('\LAM\JOB\Job', false)) {
|
||||
$this->markTestSkipped();
|
||||
return;
|
||||
}
|
||||
$resultLog = new \LAM\JOB\JobResultLog();
|
||||
|
|
|
@ -86,7 +86,7 @@ class ConfigDataExporterTest extends TestCase {
|
|||
$exporter = $this->getMockBuilder('\LAM\PERSISTENCE\ConfigDataExporter')
|
||||
->setMethods(array('_getMainConfigData', '_getCertificates', '_getServerProfiles',
|
||||
'_getAccountProfiles', '_getAccountProfileTemplates', '_getPdfProfiles',
|
||||
'_getPdfProfileTemplates', '_getSelfServiceProfiles'))
|
||||
'_getPdfProfileTemplates', '_getSelfServiceProfiles', '_getWebauthn'))
|
||||
->getMock();
|
||||
$exporter->method('_getMainConfigData')->willReturn($mainData);
|
||||
$exporter->method('_getCertificates')->willReturn('certs');
|
||||
|
|
Loading…
Reference in New Issue