Upload Admin face with Face Detection

This commit is contained in:
iBNu Maksum 2024-10-30 17:48:05 +07:00
parent 73993c4f25
commit 71d6024d62
No known key found for this signature in database
GPG Key ID: 7FC82848810579E5
18 changed files with 275 additions and 52 deletions

View File

@ -166,7 +166,7 @@ DROP TABLE IF EXISTS `tbl_users`;
CREATE TABLE `tbl_users` (
`id` int UNSIGNED NOT NULL,
`root` int NOT NULL DEFAULT '0' COMMENT 'for sub account',
`photo` VARCHAR(128) NOT NULL DEFAULT '',
`photo` VARCHAR(128) NOT NULL DEFAULT '/admin.default.png',
`username` varchar(45) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '',
`fullname` varchar(45) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '',
`password` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,

View File

@ -1,4 +1,5 @@
<?php
/**
* PHP Mikrotik Billing (https://github.com/hotspotbilling/phpnuxbill/)
* by https://t.me/ibnux
@ -93,6 +94,48 @@ class File
return file_exists($dst_dir);
}
public static function makeThumb($srcFile, $thumbFile, $thumbSize = 200)
{
/* Determine the File Type */
$type = substr($srcFile, strrpos($srcFile, '.') + 1);
$imgsize = getimagesize($srcFile);
$oldW = $imgsize[0];
$oldH = $imgsize[1];
$mime = $imgsize['mime'];
switch ($mime) {
case 'image/gif':
$src = imagecreatefromgif($srcFile);
break;
case 'image/png':
$src = imagecreatefrompng($srcFile);
break;
case 'image/jpeg':
$src = imagecreatefromjpeg($srcFile);
break;
default:
return false;
break;
}
/* Calculate the New Image Dimensions */
$limiting_dim = 0;
if ($oldH > $oldW) {
/* Portrait */
$limiting_dim = $oldW;
} else {
/* Landscape */
$limiting_dim = $oldH;
}
/* Create the New Image */
$new = imagecreatetruecolor($thumbSize, $thumbSize);
/* Transcribe the Source Image into the New (Square) Image */
imagecopyresampled($new, $src, 0, 0, ($oldW - $limiting_dim) / 2, ($oldH - $limiting_dim) / 2, $thumbSize, $thumbSize, $limiting_dim, $limiting_dim);
imagejpeg($new, $thumbFile, 100);
imagedestroy($new);
return file_exists($thumbFile);
}
/**
* file path fixer

View File

@ -1,6 +1,7 @@
{
"require": {
"mpdf/mpdf": "^8.1",
"smarty/smarty": "=4.5.3"
"smarty/smarty": "=4.5.3",
"yosiazwan/php-facedetection": "^0.1.0"
}
}

44
system/composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "a33a5e0440af423877195440decefd29",
"content-hash": "a5f201dce3d594a500f2b9e9a8532e66",
"packages": [
{
"name": "mpdf/mpdf",
@ -476,6 +476,48 @@
"source": "https://github.com/smarty-php/smarty/tree/v4.5.3"
},
"time": "2024-05-28T21:46:01+00:00"
},
{
"name": "yosiazwan/php-facedetection",
"version": "0.1.0",
"source": {
"type": "git",
"url": "https://github.com/yosiazwan/php-facedetection.git",
"reference": "b016273ceceacd85562bbc50384fbabc947fe525"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/yosiazwan/php-facedetection/zipball/b016273ceceacd85562bbc50384fbabc947fe525",
"reference": "b016273ceceacd85562bbc50384fbabc947fe525",
"shasum": ""
},
"require": {
"ext-gd": "*",
"php": ">=5.2.0"
},
"type": "library",
"autoload": {
"classmap": [
"FaceDetector.php",
"Exception/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"GPL-2.0"
],
"authors": [
{
"name": "Maurice Svay",
"homepage": "https://github.com/mauricesvay/php-facedetection/graphs/contributors"
}
],
"description": "PHP class to detect one face in images. A pure PHP port of an existing JS code from Karthik Tharavad.",
"homepage": "https://github.com/mauricesvay/php-facedetection",
"support": {
"source": "https://github.com/yosiazwan/php-facedetection/tree/0.1.0"
},
"time": "2016-01-26T22:10:00+00:00"
}
],
"packages-dev": [],

View File

@ -474,6 +474,23 @@ switch ($action) {
}
}
if ($d) {
if(isset($routes['3']) && $routes['3'] == 'deletePhoto'){
if($d['photo'] != '' && $d['photo'] != '/admin.default.png'){
if(file_exists($UPLOAD_PATH.$d['photo'])){
unlink($UPLOAD_PATH.$d['photo']);
if(file_exists($UPLOAD_PATH.$d['photo'].'.thumb.jpg')){
unlink($UPLOAD_PATH.$d['photo'].'.thumb.jpg');
}
}
$d->photo = '/admin.default.png';
$d->save();
$ui->assign('notify_t', 's');
$ui->assign('notify', 'You have successfully deleted the photo');
}else{
$ui->assign('notify_t', 'e');
$ui->assign('notify', 'No photo found to delete');
}
}
$ui->assign('id', $id);
$ui->assign('d', $d);
run_hook('view_edit_admin'); #HOOK
@ -636,6 +653,55 @@ switch ($action) {
}
run_hook('edit_admin'); #HOOK
if ($msg == '') {
if (!empty($_FILES['photo']['name'])) {
if (function_exists('imagecreatetruecolor')) {
$hash = md5_file($_FILES['photo']['tmp_name']);
$subfolder = substr($hash, 0, 2);
$folder = $UPLOAD_PATH . DIRECTORY_SEPARATOR . 'photos'. DIRECTORY_SEPARATOR;
if(!file_exists($folder)){
mkdir($folder);
}
$folder = $UPLOAD_PATH . DIRECTORY_SEPARATOR . 'photos'. DIRECTORY_SEPARATOR. $subfolder. DIRECTORY_SEPARATOR;
if(!file_exists($folder)){
mkdir($folder);
}
$imgPath = $folder . $hash . '.jpg';
if (!file_exists($imgPath)){
File::resizeCropImage($_FILES['photo']['tmp_name'], $imgPath, 1600, 1600, 100);
}
if (!file_exists($imgPath.'.thumb.jpg')){
if(_post('faceDetect') == 'yes'){
try{
$detector = new svay\FaceDetector();
$detector->setTimeout(5000);
$detector->faceDetect($imgPath);
$detector->cropFaceToJpeg($imgPath.'.thumb.jpg', false);
}catch (Exception $e) {
File::makeThumb($imgPath, $imgPath.'.thumb.jpg', 200);
} catch (Throwable $e) {
File::makeThumb($imgPath, $imgPath.'.thumb.jpg', 200);
}
}else{
File::makeThumb($imgPath, $imgPath.'.thumb.jpg', 200);
}
}
if(file_exists($imgPath)){
if($d['photo'] != ''){
if(file_exists($UPLOAD_PATH.$d['photo'])){
unlink($UPLOAD_PATH.$d['photo']);
if(file_exists($UPLOAD_PATH.$d['photo'].'.thumb.jpg')){
unlink($UPLOAD_PATH.$d['photo'].'.thumb.jpg');
}
}
}
$d->photo = '/photos/'. $subfolder. '/'. $hash. '.jpg';
}
if (file_exists($_FILES['photo']['tmp_name'])) unlink($_FILES['photo']['tmp_name']);
} else {
r2(U . 'settings/app', 'e', 'PHP GD is not installed');
}
}
$d->username = $username;
if ($password != '') {
$password = Password::_crypt($password);
@ -666,7 +732,7 @@ switch ($action) {
$d->save();
_log('[' . $admin['username'] . ']: $username ' . Lang::T('User Updated Successfully'), $admin['user_type'], $admin['id']);
r2(U . 'settings/users', 's', 'User Updated Successfully');
r2(U . 'settings/users-view/' . $id, 's', 'User Updated Successfully');
} else {
r2(U . 'settings/users-edit/' . $id, 'e', $msg);
}

View File

@ -751,5 +751,14 @@
"Buy_Balance_Plans": "Beli Paket Saldo",
"New_Voucher_for_10mbps_Created": "Voucher Baru untuk 10mbps Dibuat",
"Previous": "Sebelumnya",
"Share": "Membagikan"
"Share": "Membagikan",
"Agent": "Agen",
"Sub_District": "Kecamatan",
"Ward": "Bangsal",
"Profile": "Profil",
"Credentials": "Kredensial",
"Cron_has_not_run_for_over_1_hour__Please_check_your_setup_": "Cron tidak berjalan selama lebih dari 1 jam. Harap periksa pengaturan Anda.",
"Photo": "Foto",
"just_now": "baru saja",
"Face_Detection": "Deteksi Wajah"
}

View File

@ -169,7 +169,7 @@
"CREATE TABLE IF NOT EXISTS `tbl_meta` ( `id` int UNSIGNED NOT NULL AUTO_INCREMENT, `tbl` varchar(32) COLLATE utf8mb4_general_ci NOT NULL COMMENT 'Table name', `tbl_id` int NOT NULL COMMENT 'table value id', `name` varchar(32) COLLATE utf8mb4_general_ci NOT NULL, `value` mediumtext COLLATE utf8mb4_general_ci, PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='This Table to add additional data for any table';"
],
"2024.10.30" : [
"ALTER TABLE `tbl_users` ADD `photo` VARCHAR(128) NOT NULL DEFAULT '' AFTER `root`;",
"ALTER TABLE `tbl_users` ADD `photo` VARCHAR(128) NOT NULL DEFAULT '/admin.default.png' AFTER `root`;",
"ALTER TABLE `tbl_users` ADD `data` TEXT NULL DEFAULT NULL COMMENT 'to put additional data' AFTER `status`;"
]
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

View File

@ -176,4 +176,6 @@ return array(
'Smarty_Variable' => $vendorDir . '/smarty/smarty/libs/sysplugins/smarty_variable.php',
'TPC_yyStackEntry' => $vendorDir . '/smarty/smarty/libs/sysplugins/smarty_internal_configfileparser.php',
'TP_yyStackEntry' => $vendorDir . '/smarty/smarty/libs/sysplugins/smarty_internal_templateparser.php',
'svay\\Exception\\NoFaceException' => $vendorDir . '/yosiazwan/php-facedetection/Exception/NoFaceException.php',
'svay\\FaceDetector' => $vendorDir . '/yosiazwan/php-facedetection/FaceDetector.php',
);

View File

@ -22,8 +22,6 @@ class ComposerAutoloaderInit405fa5c7a0972c286ef93b1161b83367
return self::$loader;
}
require __DIR__ . '/platform_check.php';
spl_autoload_register(array('ComposerAutoloaderInit405fa5c7a0972c286ef93b1161b83367', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
spl_autoload_unregister(array('ComposerAutoloaderInit405fa5c7a0972c286ef93b1161b83367', 'loadClassLoader'));

View File

@ -229,6 +229,8 @@ class ComposerStaticInit405fa5c7a0972c286ef93b1161b83367
'Smarty_Variable' => __DIR__ . '/..' . '/smarty/smarty/libs/sysplugins/smarty_variable.php',
'TPC_yyStackEntry' => __DIR__ . '/..' . '/smarty/smarty/libs/sysplugins/smarty_internal_configfileparser.php',
'TP_yyStackEntry' => __DIR__ . '/..' . '/smarty/smarty/libs/sysplugins/smarty_internal_templateparser.php',
'svay\\Exception\\NoFaceException' => __DIR__ . '/..' . '/yosiazwan/php-facedetection/Exception/NoFaceException.php',
'svay\\FaceDetector' => __DIR__ . '/..' . '/yosiazwan/php-facedetection/FaceDetector.php',
);
public static function getInitializer(ClassLoader $loader)

View File

@ -494,6 +494,51 @@
"source": "https://github.com/smarty-php/smarty/tree/v4.5.3"
},
"install-path": "../smarty/smarty"
},
{
"name": "yosiazwan/php-facedetection",
"version": "0.1.0",
"version_normalized": "0.1.0.0",
"source": {
"type": "git",
"url": "https://github.com/yosiazwan/php-facedetection.git",
"reference": "b016273ceceacd85562bbc50384fbabc947fe525"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/yosiazwan/php-facedetection/zipball/b016273ceceacd85562bbc50384fbabc947fe525",
"reference": "b016273ceceacd85562bbc50384fbabc947fe525",
"shasum": ""
},
"require": {
"ext-gd": "*",
"php": ">=5.2.0"
},
"time": "2016-01-26T22:10:00+00:00",
"type": "library",
"installation-source": "source",
"autoload": {
"classmap": [
"FaceDetector.php",
"Exception/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"GPL-2.0"
],
"authors": [
{
"name": "Maurice Svay",
"homepage": "https://github.com/mauricesvay/php-facedetection/graphs/contributors"
}
],
"description": "PHP class to detect one face in images. A pure PHP port of an existing JS code from Karthik Tharavad.",
"homepage": "https://github.com/mauricesvay/php-facedetection",
"support": {
"source": "https://github.com/yosiazwan/php-facedetection/tree/0.1.0"
},
"install-path": "../yosiazwan/php-facedetection"
}
],
"dev": true,

View File

@ -3,7 +3,7 @@
'name' => '__root__',
'pretty_version' => 'dev-master',
'version' => 'dev-master',
'reference' => 'a9c0e955937e3ccb2ff050c71b77353b298a982b',
'reference' => '925c24cbd822f776eb913df987a063f95c6d9cc0',
'type' => 'library',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
@ -13,7 +13,7 @@
'__root__' => array(
'pretty_version' => 'dev-master',
'version' => 'dev-master',
'reference' => 'a9c0e955937e3ccb2ff050c71b77353b298a982b',
'reference' => '925c24cbd822f776eb913df987a063f95c6d9cc0',
'type' => 'library',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
@ -91,5 +91,14 @@
'aliases' => array(),
'dev_requirement' => false,
),
'yosiazwan/php-facedetection' => array(
'pretty_version' => '0.1.0',
'version' => '0.1.0.0',
'reference' => 'b016273ceceacd85562bbc50384fbabc947fe525',
'type' => 'library',
'install_path' => __DIR__ . '/../yosiazwan/php-facedetection',
'aliases' => array(),
'dev_requirement' => false,
),
),
);

View File

@ -1,26 +0,0 @@
<?php
// platform_check.php @generated by Composer
$issues = array();
if (!(PHP_VERSION_ID >= 70200)) {
$issues[] = 'Your Composer dependencies require a PHP version ">= 7.2.0". You are running ' . PHP_VERSION . '.';
}
if ($issues) {
if (!headers_sent()) {
header('HTTP/1.1 500 Internal Server Error');
}
if (!ini_get('display_errors')) {
if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL);
} elseif (!headers_sent()) {
echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL;
}
}
trigger_error(
'Composer detected issues in your platform: ' . implode(' ', $issues),
E_USER_ERROR
);
}

@ -0,0 +1 @@
Subproject commit b016273ceceacd85562bbc50384fbabc947fe525

View File

@ -1,7 +1,8 @@
{include file="sections/header.tpl"}
<!-- user-edit -->
<form class="form-horizontal" method="post" role="form" action="{$_url}settings/users-edit-post">
<form class="form-horizontal" method="post" enctype="multipart/form-data" role="form"
action="{$_url}settings/users-edit-post">
<input type="hidden" name="csrf_token" value="{$csrf_token}">
<div class="row">
<div class="col-sm-6 col-md-6">
@ -10,6 +11,20 @@
<div class="panel-heading">{Lang::T('Profile')}</div>
<div class="panel-body">
<input type="hidden" name="id" value="{$d['id']}">
<center>
<img src="{$UPLOAD_PATH}{$d['photo']}.thumb.jpg" width="200"
onerror="this.src='{$UPLOAD_PATH}/admin.default.png'" class="img-circle img-responsive" alt="Foto"
onclick="return deletePhoto({$d['id']})">
</center><br>
<div class="form-group">
<label class="col-md-3 col-xs-12 control-label">{Lang::T('Photo')}</label>
<div class="col-md-6 col-xs-8">
<input type="file" class="form-control" name="photo">
</div>
<div class="form-group col-md-3 col-xs-4">
<label class=""><input type="checkbox" checked name="faceDetect" value="yes"> Facedetect</label>
</div>
</div>
<div class="form-group">
<label class="col-md-3 control-label">{Lang::T('Full Name')}</label>
<div class="col-md-9">
@ -93,7 +108,8 @@
<div class="col-md-9">
<select name="root" id="root" class="form-control">
{foreach $agents as $agent}
<option value="{$agent['id']}">{$agent['username']} | {$agent['fullname']} | {$agent['phone']}</option>
<option value="{$agent['id']}">{$agent['username']} | {$agent['fullname']} |
{$agent['phone']}</option>
{/foreach}
</select>
</div>
@ -126,20 +142,27 @@
</div>
</div>
<div class="form-group text-center">
<button class="btn btn-primary" onclick="return confirm('Continue the Admin change process?')" type="submit">{Lang::T('Save Changes')}</button>
<button class="btn btn-primary" onclick="return confirm('Continue the Admin change process?')"
type="submit">{Lang::T('Save Changes')}</button>
Or <a href="{$_url}settings/users">{Lang::T('Cancel')}</a>
</div>
</form>
{literal}
<script>
function checkUserType($field){
if($field.value=='Sales'){
<script>
function checkUserType($field) {
if ($field.value == 'Sales') {
$('#agentChooser').removeClass('hidden');
}else{
} else {
$('#agentChooser').addClass('hidden');
}
}
function deletePhoto(id) {
if (confirm('Delete photo?')) {
if (confirm('Are you sure to delete photo?')) {
window.location.href = '{$_url}settings/users-edit/'+id+'/deletePhoto'
}
}
}
</script>
{/literal}
{include file="sections/footer.tpl"}

View File

@ -8,6 +8,12 @@
class="panel panel-{if $d['status'] != 'Active'}danger{else}primary{/if} panel-hovered panel-stacked mb30">
<div class="panel-heading">{$d['fullname']}</div>
<div class="panel-body">
<center>
<a href="{$UPLOAD_PATH}{$d['photo']}" target="foto">
<img src="{$UPLOAD_PATH}{$d['photo']}.thumb.jpg" width="200"
onerror="this.src='{$UPLOAD_PATH}/admin.default.png'" class="img-circle img-responsive" alt="Foto">
</a>
</center><br>
<ul class="list-group list-group-unbordered">
<li class="list-group-item">
<b>{Lang::T('Username')}</b> <span class="pull-right">{$d['username']}</span>
@ -47,10 +53,12 @@
<div class="panel-body">
<ul class="list-group list-group-unbordered">
<li class="list-group-item">
<b>{Lang::T('Phone Number')}</b> <span class="pull-right"><a href="tel:{$agent['phone']}">{$agent['phone']}</a></span>
<b>{Lang::T('Phone Number')}</b> <span class="pull-right"><a
href="tel:{$agent['phone']}">{$agent['phone']}</a></span>
</li>
<li class="list-group-item">
<b>{Lang::T('Email')}</b> <span class="pull-right"><a href="mailto:{$agent['email']}">{$agent['email']}</a></span>
<b>{Lang::T('Email')}</b> <span class="pull-right"><a
href="mailto:{$agent['email']}">{$agent['email']}</a></span>
</li>
<li class="list-group-item">
<b>{Lang::T('City')}</b> <span class="pull-right">{$agent['city']}</span>

View File

@ -1182,14 +1182,14 @@
</li>
<li class="dropdown user user-menu">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
<img src="https://robohash.org/{$_admin['id']}?set=set3&size=100x100&bgset=bg1"
<img src="{$UPLOAD_PATH}{$d['photo']}.thumb.jpg"
onerror="this.src='{$UPLOAD_PATH}/admin.default.png'" class="user-image"
alt="Avatar">
<span class="hidden-xs">{$_admin['fullname']}</span>
</a>
<ul class="dropdown-menu">
<li class="user-header">
<img src="https://robohash.org/{$_admin['id']}?set=set3&size=100x100&bgset=bg1"
<img src="{$UPLOAD_PATH}{$d['photo']}.thumb.jpg"
onerror="this.src='{$UPLOAD_PATH}/admin.default.png'" class="img-circle"
alt="Avatar">
<p>