added image cropping
This commit is contained in:
parent
ac70ea60e3
commit
a0c8f5b1e7
|
@ -1,6 +1,7 @@
|
||||||
June 2018 6.4
|
June 2018 6.4
|
||||||
- Imagick PHP extension required
|
- Imagick PHP extension required
|
||||||
- Passwords can be checked against external service (e.g. https://api.pwnedpasswords.com/range)
|
- Passwords can be checked against external service (e.g. https://api.pwnedpasswords.com/range)
|
||||||
|
- Personal/Windows: image cropping support
|
||||||
- IMAP: create mailbox via file upload
|
- IMAP: create mailbox via file upload
|
||||||
- PHP 7.2 support
|
- PHP 7.2 support
|
||||||
- LAM Pro:
|
- LAM Pro:
|
||||||
|
|
|
@ -354,11 +354,8 @@
|
||||||
|
|
||||||
<para>The Personal module provides support for managing various personal
|
<para>The Personal module provides support for managing various personal
|
||||||
data of your users including mail addresses and telephone numbers. You
|
data of your users including mail addresses and telephone numbers. You
|
||||||
can also add photos of your users (please install <ulink
|
can also add photos of your users. If you do not need to manage all
|
||||||
url="http://www.php.net/manual/en/book.imagick.php">PHP
|
attributes then you can deactivate them in your server profile.</para>
|
||||||
Imagick/ImageMagick</ulink> for full file format support). If you do not
|
|
||||||
need to manage all attributes then you can deactivate them in your
|
|
||||||
server profile.</para>
|
|
||||||
|
|
||||||
<para><emphasis role="bold">Configuration</emphasis></para>
|
<para><emphasis role="bold">Configuration</emphasis></para>
|
||||||
|
|
||||||
|
|
|
@ -56,6 +56,8 @@ class inetOrgPerson extends baseModule implements passwordService {
|
||||||
|
|
||||||
/** session variable for existing user certificates in self service */
|
/** session variable for existing user certificates in self service */
|
||||||
const SESS_CERTIFICATES_LIST = 'inetOrgPerson_certificatesList';
|
const SESS_CERTIFICATES_LIST = 'inetOrgPerson_certificatesList';
|
||||||
|
/** session variable for existing user certificates in self service */
|
||||||
|
const SESS_PHOTO = 'inetOrgPerson_jpegPhoto';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function fills the message array.
|
* This function fills the message array.
|
||||||
|
@ -1648,7 +1650,7 @@ class inetOrgPerson extends baseModule implements passwordService {
|
||||||
$name = $_FILES['photoFile']['name'];
|
$name = $_FILES['photoFile']['name'];
|
||||||
$extension = strtolower(substr($name, strpos($name, '.') + 1));
|
$extension = strtolower(substr($name, strpos($name, '.') + 1));
|
||||||
$handle = fopen($_FILES['photoFile']['tmp_name'], "r");
|
$handle = fopen($_FILES['photoFile']['tmp_name'], "r");
|
||||||
$data = fread($handle, 10000000);
|
$data = fread($handle, 100000000);
|
||||||
if (!empty($this->moduleSettings['inetOrgPerson_jpegPhoto_maxSize'][0]) && (strlen($data) > (1024 * $this->moduleSettings['inetOrgPerson_jpegPhoto_maxSize'][0]))) {
|
if (!empty($this->moduleSettings['inetOrgPerson_jpegPhoto_maxSize'][0]) && (strlen($data) > (1024 * $this->moduleSettings['inetOrgPerson_jpegPhoto_maxSize'][0]))) {
|
||||||
$errMsg = $this->messages['file'][3];
|
$errMsg = $this->messages['file'][3];
|
||||||
$errMsg[] = null;
|
$errMsg[] = null;
|
||||||
|
@ -2740,31 +2742,18 @@ class inetOrgPerson extends baseModule implements passwordService {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (in_array('jpegPhoto', $fields)) {
|
if (in_array('jpegPhoto', $fields)) {
|
||||||
|
$_SESSION[self::SESS_PHOTO] = null;
|
||||||
if (isset($attributes['jpegPhoto'][0])) {
|
if (isset($attributes['jpegPhoto'][0])) {
|
||||||
$jpeg_filename = 'jpegPhoto' . session_id() . '.jpg';
|
$_SESSION[self::SESS_PHOTO] = $attributes['jpegPhoto'][0];
|
||||||
$outjpeg = fopen(realpath('../../') . '/tmp/' . $jpeg_filename, "wb");
|
|
||||||
fwrite($outjpeg, $attributes['jpegPhoto'][0]);
|
|
||||||
fclose ($outjpeg);
|
|
||||||
$photoFile = '../../tmp/' . $jpeg_filename;
|
|
||||||
$photoSub = new htmlTable();
|
|
||||||
$img = new htmlImage($photoFile);
|
|
||||||
$img->setCSSClasses(array('photo'));
|
|
||||||
$photoSub->addElement($img, true);
|
|
||||||
if (!in_array('jpegPhoto', $readOnlyFields)) {
|
|
||||||
$photoSubSub = new htmlTable();
|
|
||||||
$upload = new htmlInputFileUpload('photoFile');
|
|
||||||
$upload->colspan = 2;
|
|
||||||
$photoSubSub->addElement($upload, true);
|
|
||||||
$photoSubSub->addElement(new htmlTableExtendedInputCheckbox('removeReplacePhoto', false, _('Remove/replace photo'), null, false));
|
|
||||||
$photoSub->addElement($photoSubSub);
|
|
||||||
}
|
}
|
||||||
$return['jpegPhoto'] = new htmlResponsiveRow(new htmlOutputText($this->getSelfServiceLabel('jpegPhoto', _('Photo'))), $photoSub);
|
$readOnlyPhoto = in_array('jpegPhoto', $readOnlyFields);
|
||||||
}
|
if (!empty($attributes['jpegPhoto'][0]) || !$readOnlyPhoto) {
|
||||||
elseif (!in_array('jpegPhoto', $readOnlyFields)) {
|
$photoSub = new htmlDiv('inetOrgPersonPhotoUploadContent', $this->getSelfServicePhoto($readOnlyPhoto, false));
|
||||||
$photoSub = new htmlTable();
|
$photoRow = new htmlResponsiveRow();
|
||||||
$photoSub->addElement(new htmlTableExtendedInputFileUpload('photoFile', _('Add photo')));
|
$photoRow->add($this->getSelfServicePhotoJS($readOnlyPhoto), 0);
|
||||||
$photoSub->addElement(new htmlHiddenInput('addPhoto', 'true'));
|
$photoRow->addLabel(new htmlOutputText($this->getSelfServiceLabel('jpegPhoto', _('Photo'))));
|
||||||
$return['jpegPhoto'] = new htmlResponsiveRow(new htmlOutputText($this->getSelfServiceLabel('jpegPhoto', _('Photo'))), $photoSub);
|
$photoRow->addField(new htmlDiv('jpegPhotoDiv', $photoSub));
|
||||||
|
$return['jpegPhoto'] = $photoRow;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (in_array('departmentNumber', $fields)) {
|
if (in_array('departmentNumber', $fields)) {
|
||||||
|
@ -2822,7 +2811,6 @@ class inetOrgPerson extends baseModule implements passwordService {
|
||||||
// upload status
|
// upload status
|
||||||
$uploadStatus = new htmlDiv('inetOrgPerson_upload_status_cert', new htmlOutputText(''));
|
$uploadStatus = new htmlDiv('inetOrgPerson_upload_status_cert', new htmlOutputText(''));
|
||||||
$uploadStatus->setCSSClasses(array('qq-upload-list'));
|
$uploadStatus->setCSSClasses(array('qq-upload-list'));
|
||||||
$uploadStatus->colspan = 7;
|
|
||||||
$certTable->add($uploadStatus, 12);
|
$certTable->add($uploadStatus, 12);
|
||||||
$certLabel = new htmlOutputText($this->getSelfServiceLabel('userCertificate', _('User certificates')));
|
$certLabel = new htmlOutputText($this->getSelfServiceLabel('userCertificate', _('User certificates')));
|
||||||
$return['userCertificate'] = new htmlResponsiveRow($certLabel, $certTable);
|
$return['userCertificate'] = new htmlResponsiveRow($certLabel, $certTable);
|
||||||
|
@ -2926,6 +2914,110 @@ class inetOrgPerson extends baseModule implements passwordService {
|
||||||
return $return;
|
return $return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renders the photo area for self service.
|
||||||
|
*
|
||||||
|
* @param boolean $readOnly content is read-only
|
||||||
|
* @param boolean $crop enable cropping
|
||||||
|
* @return htmlResponsiveRow content
|
||||||
|
*/
|
||||||
|
private function getSelfServicePhoto($readOnly, $crop) {
|
||||||
|
$photo = $_SESSION[self::SESS_PHOTO];
|
||||||
|
$row = new htmlResponsiveRow();
|
||||||
|
if (!empty($photo)) {
|
||||||
|
$jpeg_filename = 'jpegPhoto' . getRandomNumber() . '.jpg';
|
||||||
|
$outjpeg = fopen(realpath('../../') . '/tmp/' . $jpeg_filename, "wb");
|
||||||
|
fwrite($outjpeg, $photo);
|
||||||
|
fclose ($outjpeg);
|
||||||
|
$photoFile = '../../tmp/' . $jpeg_filename;
|
||||||
|
$img = new htmlImage($photoFile);
|
||||||
|
$img->setCSSClasses(array('photo'));
|
||||||
|
if ($crop) {
|
||||||
|
$img->enableCropping();
|
||||||
|
}
|
||||||
|
$row->add($img, 12);
|
||||||
|
if (!$readOnly) {
|
||||||
|
$row->addVerticalSpacer('0.5rem');
|
||||||
|
$deleteButton = new htmlLink(_('Delete'), '#', '../../graphics/delete.png', true);
|
||||||
|
$deleteButton->setOnClick('inetOrgPersonDeletePhoto(); return false;');
|
||||||
|
$row->add($deleteButton, 12);
|
||||||
|
}
|
||||||
|
$row->addVerticalSpacer('0.5rem');
|
||||||
|
}
|
||||||
|
// upload button
|
||||||
|
$row->add(new htmlDiv('inetOrgPersonPhotoUploadId', new htmlOutputText('')), 12);
|
||||||
|
$row->add(new htmlJavaScript('inetOrgPersonUploadPhoto(\'inetOrgPersonPhotoUploadId\');'), 0);
|
||||||
|
$uploadStatus = new htmlDiv('inetOrgPersonPhotoUploadStatus', new htmlOutputText(''));
|
||||||
|
$uploadStatus->setCSSClasses(array('qq-upload-list'));
|
||||||
|
$row->add($uploadStatus, 12);
|
||||||
|
return $row;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the Java Script functions to manage the photo.
|
||||||
|
*
|
||||||
|
* @param boolean $readOnly content is read-only
|
||||||
|
* @return htmlJavaScript JS block
|
||||||
|
*/
|
||||||
|
private static function getSelfServicePhotoJS($readOnly) {
|
||||||
|
if ($readOnly) {
|
||||||
|
return new htmlGroup();
|
||||||
|
}
|
||||||
|
$content = '
|
||||||
|
function inetOrgPersonUploadPhoto(elementID) {
|
||||||
|
var uploadStatus = document.getElementById(\'inetOrgPersonPhotoUploadStatus\');
|
||||||
|
var params = { action: \'ajaxPhotoUpload\' };
|
||||||
|
params["' . getSecurityTokenName() . '"] = "' . getSecurityTokenValue() . '";
|
||||||
|
var uploader = new qq.FineUploader({
|
||||||
|
element: document.getElementById(elementID),
|
||||||
|
listElement: uploadStatus,
|
||||||
|
request: {
|
||||||
|
endpoint: \'../misc/ajax.php?selfservice=1&module=inetOrgPerson&scope=user'
|
||||||
|
. '&' . getSecurityTokenName() . '=' . getSecurityTokenValue() . '\',
|
||||||
|
forceMultipart: true,
|
||||||
|
params: params
|
||||||
|
},
|
||||||
|
multiple: false,
|
||||||
|
callbacks: {
|
||||||
|
onComplete: function(id, fileName, data) {
|
||||||
|
if (data.success) {
|
||||||
|
if (data.html) {
|
||||||
|
jQuery(\'#inetOrgPersonPhotoUploadContent\').html(data.html);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
alert(data.error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function inetOrgPersonDeletePhoto(id) {
|
||||||
|
var actionJSON = {
|
||||||
|
"action": "deletePhoto",
|
||||||
|
"id": id
|
||||||
|
};
|
||||||
|
var data = {jsonInput: actionJSON};
|
||||||
|
data["' . getSecurityTokenName() . '"] = "' . getSecurityTokenValue() . '";
|
||||||
|
jQuery.post(\'../misc/ajax.php?selfservice=1&module=inetOrgPerson&scope=user\',
|
||||||
|
data, function(data) {inetOrgPersonDeletePhotoHandleReply(data);}, \'json\');
|
||||||
|
}
|
||||||
|
|
||||||
|
function inetOrgPersonDeletePhotoHandleReply(data) {
|
||||||
|
if (data.errorsOccured == "false") {
|
||||||
|
jQuery(\'#inetOrgPersonPhotoUploadContent\').html(data.html);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
alert(data.errormessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
';
|
||||||
|
return new htmlJavaScript($content);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the meta HTML code to display the certificate area.
|
* Returns the meta HTML code to display the certificate area.
|
||||||
* This also includes the file upload.
|
* This also includes the file upload.
|
||||||
|
@ -2986,7 +3078,7 @@ class inetOrgPerson extends baseModule implements passwordService {
|
||||||
$content = '
|
$content = '
|
||||||
function inetOrgPersonDeleteCertificate(id) {
|
function inetOrgPersonDeleteCertificate(id) {
|
||||||
var actionJSON = {
|
var actionJSON = {
|
||||||
"action": "delete",
|
"action": "deleteCert",
|
||||||
"id": id
|
"id": id
|
||||||
};
|
};
|
||||||
var data = {jsonInput: actionJSON};
|
var data = {jsonInput: actionJSON};
|
||||||
|
@ -3243,39 +3335,40 @@ class inetOrgPerson extends baseModule implements passwordService {
|
||||||
}
|
}
|
||||||
// photo
|
// photo
|
||||||
if (in_array('jpegPhoto', $fields) && !in_array('jpegPhoto', $readOnlyFields)) {
|
if (in_array('jpegPhoto', $fields) && !in_array('jpegPhoto', $readOnlyFields)) {
|
||||||
|
$data = $_SESSION[self::SESS_PHOTO];
|
||||||
// remove photo
|
// remove photo
|
||||||
if (isset($_POST['removeReplacePhoto']) && ($_POST['removeReplacePhoto'] == 'on')
|
if (!empty($attributes['jpegPhoto'][0]) && empty($data)) {
|
||||||
&& (empty($_FILES['replacePhotoFile']) || ($_FILES['replacePhotoFile']['size'] == 0))) {
|
|
||||||
$return['mod']['jpegPhoto'] = array();
|
$return['mod']['jpegPhoto'] = array();
|
||||||
}
|
}
|
||||||
// set/replace photo
|
// set/replace photo
|
||||||
if (isset($_FILES['photoFile']) && ($_FILES['photoFile']['size'] > 0)) {
|
elseif (!empty($data) && (empty($attributes['jpegPhoto'][0]) || ($data != $attributes['jpegPhoto'][0]))) {
|
||||||
$moduleSettings = $this->selfServiceSettings->moduleSettings;
|
$moduleSettings = $this->selfServiceSettings->moduleSettings;
|
||||||
if (!empty($moduleSettings['inetOrgPerson_jpegPhoto_maxSize'][0]) && ($moduleSettings['inetOrgPerson_jpegPhoto_maxSize'][0] < ($_FILES['photoFile']['size'] / 1024))) {
|
try {
|
||||||
|
$image = new Imagick();
|
||||||
|
$image->readimageblob($data);
|
||||||
|
$image->cropimage($_POST['croppingDataWidth'], $_POST['croppingDataHeight'], $_POST['croppingDataX'], $_POST['croppingDataY']);
|
||||||
|
$data = $image->getimageblob();
|
||||||
|
$data = inetOrgPerson::resizeAndConvertImage($data, $moduleSettings);
|
||||||
|
if (!empty($moduleSettings['inetOrgPerson_jpegPhoto_maxSize'][0]) && ($moduleSettings['inetOrgPerson_jpegPhoto_maxSize'][0] < (strlen($data) / 1024))) {
|
||||||
$msg = $this->messages['file'][3];
|
$msg = $this->messages['file'][3];
|
||||||
$msg[] = null;
|
$msg[] = null;
|
||||||
$msg[] = htmlspecialchars($moduleSettings['inetOrgPerson_jpegPhoto_maxSize'][0]);
|
$msg[] = htmlspecialchars($moduleSettings['inetOrgPerson_jpegPhoto_maxSize'][0]);
|
||||||
$return['messages'][] = $msg;
|
$return['messages'][] = $msg;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$handle = fopen($_FILES['photoFile']['tmp_name'], "r");
|
if (!empty($attributes['jpegPhoto'][0])) {
|
||||||
$data = fread($handle, 100000000);
|
$return['mod']['jpegPhoto'][0] = $data;
|
||||||
fclose($handle);
|
}
|
||||||
try {
|
else {
|
||||||
$data = inetOrgPerson::resizeAndConvertImage($data, $moduleSettings);
|
$return['add']['jpegPhoto'][0] = $data;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (Exception $e) {
|
catch (Exception $e) {
|
||||||
$msg = $this->messages['file'][2];
|
$msg = $this->messages['file'][2];
|
||||||
$msg[] = htmlspecialchars($e->getMessage());
|
$msg[] = htmlspecialchars($e->getMessage());
|
||||||
$return['messages'][] = $msg;
|
$return['messages'][] = $msg;
|
||||||
}
|
}
|
||||||
if (isset($_POST['removeReplacePhoto']) && ($_POST['removeReplacePhoto'] == 'on')) {
|
|
||||||
$return['mod']['jpegPhoto'][0] = $data;
|
|
||||||
}
|
|
||||||
elseif (isset($_POST['addPhoto'])) {
|
|
||||||
$return['add']['jpegPhoto'][0] = $data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// departments
|
// departments
|
||||||
|
@ -3408,23 +3501,30 @@ class inetOrgPerson extends baseModule implements passwordService {
|
||||||
public function handleAjaxRequest() {
|
public function handleAjaxRequest() {
|
||||||
// AJAX uploads are non-JSON
|
// AJAX uploads are non-JSON
|
||||||
if (isset($_GET['action']) && ($_GET['action'] == 'ajaxCertUpload')) {
|
if (isset($_GET['action']) && ($_GET['action'] == 'ajaxCertUpload')) {
|
||||||
$this->ajaxUpload();
|
$this->ajaxUploadCert();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (isset($_GET['action']) && ($_GET['action'] == 'ajaxPhotoUpload')) {
|
||||||
|
$this->ajaxUploadPhoto();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$jsonInput = $_POST['jsonInput'];
|
$jsonInput = $_POST['jsonInput'];
|
||||||
$jsonReturn = self::invalidAjaxRequest();
|
$jsonReturn = self::invalidAjaxRequest();
|
||||||
if (isset($jsonInput['action'])) {
|
if (isset($jsonInput['action'])) {
|
||||||
if ($jsonInput['action'] == 'delete') {
|
if ($jsonInput['action'] == 'deleteCert') {
|
||||||
$jsonReturn = $this->ajaxDeleteSelfServiceUserCertificate($jsonInput);
|
$jsonReturn = $this->ajaxDeleteSelfServiceUserCertificate($jsonInput);
|
||||||
}
|
}
|
||||||
|
elseif ($jsonInput['action'] == 'deletePhoto') {
|
||||||
|
$jsonReturn = $this->ajaxDeleteSelfServicePhoto($jsonInput);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
echo json_encode($jsonReturn);
|
echo json_encode($jsonReturn);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles an AJAX file upload and prints the JSON result.
|
* Handles an AJAX certificate file upload and prints the JSON result.
|
||||||
*/
|
*/
|
||||||
private function ajaxUpload() {
|
private function ajaxUploadCert() {
|
||||||
$result = array('success' => true);
|
$result = array('success' => true);
|
||||||
if (!isset($_FILES['qqfile']) || ($_FILES['qqfile']['size'] < 100)) {
|
if (!isset($_FILES['qqfile']) || ($_FILES['qqfile']['size'] < 100)) {
|
||||||
$result = array('error' => _('No file received.'));
|
$result = array('error' => _('No file received.'));
|
||||||
|
@ -3458,6 +3558,65 @@ class inetOrgPerson extends baseModule implements passwordService {
|
||||||
echo json_encode($result);
|
echo json_encode($result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles an AJAX photo file upload and prints the JSON result.
|
||||||
|
*/
|
||||||
|
private function ajaxUploadPhoto() {
|
||||||
|
$result = array('success' => true);
|
||||||
|
if (!isset($_FILES['qqfile']) || ($_FILES['qqfile']['size'] < 100)) {
|
||||||
|
$result = array('error' => _('No file received.'));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$handle = fopen($_FILES['qqfile']['tmp_name'], "r");
|
||||||
|
$data = fread($handle, 100000000);
|
||||||
|
fclose($handle);
|
||||||
|
$image = new Imagick();
|
||||||
|
try {
|
||||||
|
$image->readImageBlob($data);
|
||||||
|
$image->setImageCompression(Imagick::COMPRESSION_JPEG);
|
||||||
|
$image->setImageFormat('jpeg');
|
||||||
|
$data = $image->getimageblob();
|
||||||
|
}
|
||||||
|
catch (Exception $e) {
|
||||||
|
$result = array('success' => false, 'error' => htmlspecialchars($e->getMessage()));
|
||||||
|
echo json_encode($result);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$_SESSION[inetOrgPerson::SESS_PHOTO] = $data;
|
||||||
|
ob_start();
|
||||||
|
$contentElement = $this->getSelfServicePhoto(false, true);
|
||||||
|
ob_end_clean();
|
||||||
|
ob_start();
|
||||||
|
$tabindex = 999;
|
||||||
|
parseHtml(null, $contentElement, array(), true, $tabindex, $this->get_scope());
|
||||||
|
$content = ob_get_contents();
|
||||||
|
ob_end_clean();
|
||||||
|
$result['html'] = $content;
|
||||||
|
}
|
||||||
|
echo json_encode($result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Manages the deletion of a photo.
|
||||||
|
*
|
||||||
|
* @param array $data JSON data
|
||||||
|
*/
|
||||||
|
private function ajaxDeleteSelfServicePhoto($data) {
|
||||||
|
$_SESSION[self::SESS_PHOTO] = null;
|
||||||
|
ob_start();
|
||||||
|
$contentElement = $this->getSelfServicePhoto(false, false);
|
||||||
|
ob_end_clean();
|
||||||
|
ob_start();
|
||||||
|
$tabindex = 999;
|
||||||
|
parseHtml(null, $contentElement, array(), true, $tabindex, $this->get_scope());
|
||||||
|
$content = ob_get_contents();
|
||||||
|
ob_end_clean();
|
||||||
|
return array(
|
||||||
|
'errorsOccured' => 'false',
|
||||||
|
'html' => $content,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manages the deletion of a certificate.
|
* Manages the deletion of a certificate.
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in New Issue