diff --git a/core-ext/app/install/config.php b/core-ext/app/install/config.php index 2d397e4a..7da7057c 100644 --- a/core-ext/app/install/config.php +++ b/core-ext/app/install/config.php @@ -1,5 +1,5 @@ getSetting('Notifications: Send Document Expiry Emails') != '1'){ + LogManager::getInstance()->info("Notifications: Send Document Expiry Emails is set to No. Do not send emails"); + return; + } + + //Get documents + + $dayList = array(); + $dayList[30] = 'expire_notification_month'; + $dayList[7] = 'expire_notification_week'; + $dayList[1] = 'expire_notification_day'; + $dayList[0] = 'expire_notification'; + + foreach($dayList as $k => $v){ + $this->expiryDayNotification($k, $v); + } + + $this->getExpireDocumentHTMLByEmployee(); + $this->sendEmployeeEmails($this->employeeEmails, "IceHrm Employee Document Expiry Reminder"); + + } + + private function expiryDayNotification($day, $param){ + $date = date('Y-m-d', strtotime("+".$day." days")); + + $employeeDocument = new EmployeeDocument(); + $employeeDocuments = $employeeDocument->Find("valid_until IS NOT NULL and valid_until = ? and (expire_notification_last > ? or expire_notification_last = -1) and status = ?", + array($date, $day, 'Active')); + + if(!$employeeDocuments){ + LogManager::getInstance()->error("Error :".$employeeDocument->ErrorMsg()); + return; + } + + $query = "valid_until IS NOT NULL and valid_until = $date and + (expire_notification_last > $day or expire_notification_last == -1) + and status = 'Active';"; + + LogManager::getInstance()->debug($query); + + foreach($employeeDocuments as $doc){ + + LogManager::getInstance()->debug("Employee Doc :".print_r($doc, true)); + + if(empty($doc->document)){ + continue; + } + $document = null; + if(isset($this->documentCache[$doc->id])){ + $document = $this->documentCache[$doc->id]; + }else{ + $document = new Document(); + $document->Load("id = ?",array($doc->document)); + $this->documentCache[$document->id] = $document; + } + + if($document->$param == "Yes"){ + if(!isset($this->notificationList[$doc->employee])){ + $this->notificationList[$doc->employee] = array(); + } + $this->notificationList[$doc->employee][] = array($doc, $document, $day); + } + + $doc->expire_notification_last = $day; + $doc->Save(); + + } + } + + private function getExpireDocumentHTMLByEmployee(){ + $row = '

#_name_# - Expire in #_days_# day(s)


#_description_#
'; + + foreach($this->notificationList as $key => $val){ + $employeeEmail = ""; + + foreach($val as $list){ + $trow = $row; + $doc = $list[0]; + $document = $list[1]; + $days = $list[2]; + + $trow = str_replace("#_name_#",$document->name,$trow); + $trow = str_replace("#_days_#",$days,$trow); + $trow = str_replace("#_description_#",$doc->details,$trow); + + $employeeEmail.=$trow; + } + + $employee = new Employee(); + $employee->Load("id = ?",array($key)); + + if(empty($employee->id) || $employee->id != $key){ + LogManager::getInstance()->error("Could not load employee with id"); + return; + } + + $emailBody = file_get_contents(APP_BASE_PATH.'/admin/documents/emailTemplates/documentExpireEmailTemplate.html'); + $emailBody = str_replace("#_employee_#",$employee->first_name,$emailBody); + $emailBody = str_replace("#_documents_#",$employeeEmail,$emailBody); + + $this->employeeEmails[$employee->id] = $emailBody; + } + } + + + +} \ No newline at end of file diff --git a/core-ext/config.base.php b/core-ext/config.base.php index 52b088cb..d970e062 100644 --- a/core-ext/config.base.php +++ b/core-ext/config.base.php @@ -9,13 +9,13 @@ define('HOME_LINK_ADMIN', CLIENT_BASE_URL."?g=admin&n=dashboard&m=admin_Admin"); define('HOME_LINK_OTHERS', CLIENT_BASE_URL."?g=modules&n=dashboard&m=module_Personal_Information"); //Version -define('VERSION', '13.1.OS'); -define('CACHE_VALUE', '13.1'); -define('VERSION_DATE', '09/10/2015'); +define('VERSION', '14.0.OS'); +define('CACHE_VALUE', '14.0.OS'); +define('VERSION_DATE', '12/12/2015'); if(!defined('CONTACT_EMAIL')){define('CONTACT_EMAIL','icehrm@gamonoid.com');} if(!defined('KEY_PREFIX')){define('KEY_PREFIX','IceHrm');} -if(!defined('APP_SEC')){define('APP_SEC','dbcs234d2saaqw');} +if(!defined('APP_SEC')){define('APP_SEC','dbcs234d2s111');} define('UI_SHOW_SWITCH_PROFILE', true); define('CRON_LOG', '/var/log/nginx/icehrmcron.log'); \ No newline at end of file diff --git a/core-ext/css/style.css b/core-ext/css/style.css deleted file mode 100644 index ef7a613a..00000000 --- a/core-ext/css/style.css +++ /dev/null @@ -1,519 +0,0 @@ -.redFont{ - color: red; -} -.box_ws{ - background: white; - border-left: 1px solid #DDD; - border-right: 1px solid #DDD; - border-bottom: 1px solid #DDD; - color: #555; -} - -.cal_box_ws{ - background: white; - border: 1px solid #DDD; - color: #555; - height: 100px; -} - -.cal_box_ws .wd_date_full{ - font-weight:bold; - font-size:10px; - float: right; - margin-right: 5px; -} - -.cal_box_ws .wd_date{ - font-size:10px; - float: right; - margin-right: 5px; -} - -.nav-pills li a:hover{ - background: #1D64AD; - color:white; -}; - -.navbar-inverse .brand, .navbar-inverse .nav > li > a { -font-weight: bold; -font-size: 12px; -} - -.categoryWrap p{ - font-size:16px; - font-weight:bold; - padding: 3px; -} - -.categoryWrap p:hover{ - font-size:16px; - font-weight:bold; - color:white; - background: gray; - padding: 3px; - cursor:pointer; - border-radius: 4px; - -} - -.resultLogo{ - text-align: center; -} - -.pbar{ - font-weight:bold; - font-size:11px; -} - -.pbar .progress{ - height: 10px; -} - -.bs-docs-sidenav { - width: 228px; - margin: 30px 0 0; - padding: 0; - background-color: #fff; - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; - -webkit-box-shadow: 0 1px 4px rgba(0,0,0,.065); - -moz-box-shadow: 0 1px 4px rgba(0,0,0,.065); - box-shadow: 0 1px 4px rgba(0,0,0,.065); -} -.bs-docs-sidenav > li > a { - display: block; - *width: 190px; - margin: 0 0 -1px; - padding: 8px 14px; - border: 1px solid #e5e5e5; -} -.bs-docs-sidenav > li:first-child > a { - -webkit-border-radius: 6px 6px 0 0; - -moz-border-radius: 6px 6px 0 0; - border-radius: 6px 6px 0 0; -} -.bs-docs-sidenav > li:last-child > a { - -webkit-border-radius: 0 0 6px 6px; - -moz-border-radius: 0 0 6px 6px; - border-radius: 0 0 6px 6px; -} -.bs-docs-sidenav > .active > a { - position: relative; - z-index: 2; - padding: 9px 15px; - border: 0; - text-shadow: 0 1px 0 rgba(0,0,0,.15); - -webkit-box-shadow: inset 1px 0 0 rgba(0,0,0,.1), inset -1px 0 0 rgba(0,0,0,.1); - -moz-box-shadow: inset 1px 0 0 rgba(0,0,0,.1), inset -1px 0 0 rgba(0,0,0,.1); - box-shadow: inset 1px 0 0 rgba(0,0,0,.1), inset -1px 0 0 rgba(0,0,0,.1); -} -/* Chevrons */ -.bs-docs-sidenav .icon-chevron-right { - float: right; - margin-top: 2px; - margin-right: -6px; - opacity: .25; -} -.bs-docs-sidenav > li > a:hover { - background-color: #f5f5f5; -} -.bs-docs-sidenav a:hover .icon-chevron-right { - opacity: .5; -} -.bs-docs-sidenav .active .icon-chevron-right, -.bs-docs-sidenav .active a:hover .icon-chevron-right { - background-image: url(../img/glyphicons-halflings-white.png); - opacity: 1; -} -.bs-docs-sidenav.affix { - top: 40px; -} -.bs-docs-sidenav.affix-bottom { - position: absolute; - top: auto; - bottom: 270px; -} - - - - -/* Responsive --------------------------------------------------- */ - -/* Desktop large -------------------------- */ -@media (min-width: 1200px) { - .bs-docs-container { - max-width: 970px; - } - .bs-docs-sidenav { - width: 258px; - } -} - -.reviewPoints{ - margin-top:10px; -} - -.reviewPoints .star{ - margin-left: 10px; -} - -.reviewBlock { -position: relative; -margin: 0px 0; -padding: 39px 19px 14px; -background-color: white; -border: 1px solid #DDD; -/* --webkit-border-radius: 4px; --moz-border-radius: 4px; -border-radius: 4px; -*/ -font-size:12px; -} - -/*.reviewBlock::after { -content: attr(data-content); -position: absolute; -top: -1px; -left: -1px; -padding: 3px 7px; -font-size: 12px; -font-weight: bold; -background-color: whiteSmoke; -border: 1px solid #DDD; -color: #9DA0A4; --webkit-border-radius: 4px 0 4px 0; --moz-border-radius: 4px 0 4px 0; -border-radius: 4px 0 4px 0; -}*/ - -.box_ws{ - background: white; - border-left: 1px solid #DDD; - border-right: 1px solid #DDD; - border-bottom: 1px solid #DDD; - color: #555; -} - -.cal_box_ws{ - background: white; - border: 1px solid #DDD; - color: #555; - height: 100px; -} - -.cal_box_ws .wd_date_full{ - font-weight:bold; - font-size:10px; - float: right; - margin-right: 5px; -} - -.cal_box_ws .wd_date{ - font-size:10px; - float: right; - margin-right: 5px; -} - -.nav-pills li a:hover{ - background: #1D64AD; - color:white; -}; - -.nav-tabs > li > a { - color:white; -} - -.nav-tabs > li > a:hover{ - color:#555; -} - - -.topheader { -background: -moz-linear-gradient(#829AA8, #405A6A); -background: -webkit-linear-gradient(#829AA8, #405A6A); -background: linear-gradient(#829AA8, #405A6A); -border: 1px solid #677C89; -border-bottom-color: #6B808D; -box-shadow: 0 1px 0 rgba(255, 255, 255, 0.4),0 0px 10px rgba(0, 0, 0, 0.1); -} - - -.bgbody{ -background: #FAFAFA; -background: -moz-linear-gradient(#FAFAFA, #EAEAEA); -background: -webkit-linear-gradient(#FAFAFA, #EAEAEA); -background: linear-gradient(#FAFAFA, #EAEAEA); -border-bottom: 1px solid #CACACA; -box-shadow: 0 1px 0 rgba(255, 255, 255, 0.4),0 0px 10px rgba(0, 0, 0, 0.1); -} - -.leftMenu{ - background-color: #E9F1F4; - border-style: solid; - border-width: 1px 1px 2px; - border-color: #E9F1F4 #D8DEE2 #D8DEE2; - border-radius: 0 0 5px 5px; -} - -.nav > li > a:hover { -text-decoration: none; -background-color: whitesmoke; -border-radius: 5px; -} - -/* -.nav-list > .active > a, .nav-list > .active > a:hover{ -color: white; -text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.2); -background-color: #405A6A; -box-shadow: 0 1px 0 rgba(255, 255, 255, 0.4),0 0px 10px rgba(0, 0, 0, 0.1); -border-radius: 5px; -} -*/ - -a { -color: #405A6A; -text-decoration: none; -} - -.nav-header { -display: block; -padding: 3px 15px; -font-size: 15px; -font-weight: bold; -line-height: 20px; -text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); -text-transform: none; -background: -moz-linear-gradient(#829AA8, #405A6A); -background: -webkit-linear-gradient(#829AA8, #405A6A); -background: linear-gradient(#829AA8, #405A6A); -color: white; -border-radius: 2px; -} - -.modal-backdrop, -.modal-backdrop.fade.in { - opacity: 0.4; - filter: alpha(opacity=40); -} - -.error{ - color:red; -} - -.columnMain{ - font-weight: bold; -} - -.borderBox{ -padding-bottom: 10px; -padding-left: 10px; -padding-top: 10px; --moz-border-radius: 5px; -border-radius: 5px; --webkit-border-radius: 5px; -margin-bottom: 20px; --moz-box-shadow: 1px 3px 3px rgba(0, 0, 0, 0.1); --webkit-box-shadow: 1px 3px 3px rgba(0, 0, 0, 0.1); -box-shadow: 1px 3px 3px rgba(0, 0, 0, 0.1); -border: 1px solid #EEE; -} - - -.iceicon_edit{ - background-image: url("../images/edit.png"); -} - -.iceicon_delete{ - background-image: url("../images/delete.png"); -} - -.iceicon_user{ - background-image: url("../images/user.png"); -} - -.dropdown-menu{ - z-index: 10000; -} - -.lightface .lightfaceContent .lightfaceTitle { -font-size: 14px; -color: #fff; -background-color: #405A6A; -border: 1px solid #405A6A; -font-weight: bold; -margin: -1px; -margin-bottom: 0; -padding: 5px 10px; -line-height: 30px; -} - -.label-ice, .badge-ice{ -background-color: #405A6A; -} - -.dataTables_processing{ -position: absolute; -margin-left: 40px; -font-weight: bold; -font-size: 13px; -color: gray; -} - - - -/*changes to full caledar*/ -.fc-header-title h2 { -margin-top: 0; -white-space: nowrap; -font-size: 20px; -margin-left: 10px; -color:#405A6A; -} - -table.dataTable{ - font-size: 1.1em; -} - -.form-horizontal{ - font-size: 1.2em; -} - -.form-horizontal .row{ - margin-bottom: 10px; -} - -.table.dataTable {width:100% !important;} - -.iceLabel{ - font-size: 12px !important; - font-weight: bold; - color: #3c8dbc; -} - -.nav-tabs>li>a{ - border-radius:0px; -} - -.nav > li > a:hover { - border-radius:0px; -} - -.btn { - -webkit-border-radius: 0px; - -moz-border-radius: 0px; - border-radius: 0px; - -} - - -/* select2 style overide */ -.select2-choice{ -border: none !important; -width: 100% !important; -border-radius: 0px !important; -background-color: #FFF !important; -background-image: none !important; -} - - -.select2-container{ - padding:3px !important; -} - -.select2-container-multi{ - padding:0px !important; - border:none; -} - -.select2-arrow{ -background-image: none !important; -background: #FFF !important; -border: none !important; -} - -.select2-drop-active { -/*border: 1px solid black !important;*/ -border-top: none !important; -background: #f0f0f0 !important; -} - -.logTime{ - font-weight: bold; - font-size: 13px; - font-style: italic; -} - -.popupForm{ - border: none !important; - padding: 0px 19px 14px !important; -} - -.content { -background: #FFF; -} - -.wrapper { -background: #FFF; -} - -.user-panel > .info > p { -margin-bottom: 9px; -max-width: 135px; -line-height: 17px; -} - -.list-group-item-text{ - margin-bottom:5px; -} - -.list-group-item{ - padding-bottom:30px; -} - - - - - - - - - - - - - - -/custom for v11.0 */ - - -.table-bordered>thead>tr>th{ - border:none !important; -} - -.table-bordered>thead>tr>th, .table-bordered>thead>tr>td { - border-bottom-width: 2px; - border: none; -} - -.table{ - -webkit-transition: margin-left .15s linear; - transition: margin-left .15s linear; - -webkit-user-select: none; - background-color: #fff; - -webkit-box-shadow: 0 1px 2px 0 rgba(0,0,0,.2); - box-shadow: 0 1px 2px 0 rgba(0,0,0,.2); -} - -.reviewBlock{ - -webkit-box-sizing: border-box; - box-sizing: border-box -} - -.treeview-menu li:hover{ - font-weight:bold; -} \ No newline at end of file diff --git a/src/api/AdapterBase.js b/src/api/AdapterBase.js index 08da122c..61e2960e 100644 --- a/src/api/AdapterBase.js +++ b/src/api/AdapterBase.js @@ -117,6 +117,9 @@ AdapterBase.method('addSuccessCallBack', function(callBackData,serverData, callG }); AdapterBase.method('addFailCallBack', function(callBackData,serverData) { + try{ + this.closePlainMessage(); + }catch(e){} this.showMessage("Error saving",serverData); this.trackEvent("addFailed",this.tab,this.table); }); @@ -513,6 +516,163 @@ IdNameAdapter.method('getFormFields', function() { }); +/** + * ApproveAdminAdapter + */ + +function ApproveAdminAdapter(endPoint,tab,filter,orderBy) { + this.initAdapter(endPoint,tab,filter,orderBy); +} + +ApproveAdminAdapter.inherits(AdapterBase); + + +ApproveAdminAdapter.method('openStatus', function(id,status) { + $('#'+this.itemNameLower+'StatusModel').modal('show'); + $('#'+this.itemNameLower+'_status').val(status); + this.statusChangeId = id; +}); + +ApproveAdminAdapter.method('closeDialog', function() { + $('#'+this.itemNameLower+'StatusModel').modal('hide'); +}); + +ApproveAdminAdapter.method('changeStatus', function() { + var status = $('#'+this.itemNameLower+'_status').val(); + var reason = $('#'+this.itemNameLower+'_reason').val(); + + if(status == undefined || status == null || status == ""){ + this.showMessage("Error", "Please select "+this.itemNameLower+" status"); + return; + } + + var object = {"id":this.statusChangeId,"status":status,"reason":reason}; + + var reqJson = JSON.stringify(object); + + var callBackData = []; + callBackData['callBackData'] = []; + callBackData['callBackSuccess'] = 'changeStatusSuccessCallBack'; + callBackData['callBackFail'] = 'changeStatusFailCallBack'; + + this.customAction('changeStatus','admin='+this.modulePathName,reqJson,callBackData); + + this.closeDialog(); + this.statusChangeId = null; +}); + +ApproveAdminAdapter.method('changeStatusSuccessCallBack', function(callBackData) { + this.showMessage("Successful", this.itemName + " Request status changed successfully"); + this.get([]); +}); + +ApproveAdminAdapter.method('changeStatusFailCallBack', function(callBackData) { + this.showMessage("Error", "Error occurred while changing "+this.itemName+" request status"); +}); + + + +ApproveAdminAdapter.method('getActionButtonsHtml', function(id,data) { + var editButton = ''; + var deleteButton = ''; + var statusChangeButton = ''; + + var html = '
_edit__delete__status_
'; + + html = html.replace('_status_',statusChangeButton); + + if(this.showDelete){ + html = html.replace('_delete_',deleteButton); + + }else{ + html = html.replace('_delete_',''); + } + + if(this.showEdit){ + html = html.replace('_edit_',editButton); + }else{ + html = html.replace('_edit_',''); + } + + html = html.replace(/_id_/g,id); + html = html.replace(/_BASE_/g,this.baseUrl); + return html; +}); + +ApproveAdminAdapter.method('isSubProfileTable', function() { + if(this.user.user_level == "Admin"){ + return false; + }else{ + return true; + } +}); + + +/** + * ApproveModuleAdapter + */ + +function ApproveModuleAdapter(endPoint,tab,filter,orderBy) { + this.initAdapter(endPoint,tab,filter,orderBy); +} + +ApproveModuleAdapter.inherits(AdapterBase); + +ApproveModuleAdapter.method('cancelRequest', function(id) { + var that = this; + var object = {}; + object['id'] = id; + + var reqJson = JSON.stringify(object); + + var callBackData = []; + callBackData['callBackData'] = []; + callBackData['callBackSuccess'] = 'cancelSuccessCallBack'; + callBackData['callBackFail'] = 'cancelFailCallBack'; + + this.customAction('cancel','modules='+this.modulePathName,reqJson,callBackData); +}); + +ApproveModuleAdapter.method('cancelSuccessCallBack', function(callBackData) { + this.showMessage("Successful", this.itemName + " cancellation request sent"); + this.get([]); +}); + +ApproveModuleAdapter.method('cancelFailCallBack', function(callBackData) { + this.showMessage("Error Occurred while cancelling "+this.itemName, callBackData); +}); + +ApproveModuleAdapter.method('getActionButtonsHtml', function(id,data) { + var editButton = ''; + var deleteButton = ''; + var requestCancellationButton = ''; + + var html = '
_edit__delete_
'; + + if(this.showDelete){ + if(data[7] == "Approved"){ + html = html.replace('_delete_',requestCancellationButton); + }else{ + html = html.replace('_delete_',deleteButton); + } + + }else{ + html = html.replace('_delete_',''); + } + + if(this.showEdit){ + html = html.replace('_edit_',editButton); + }else{ + html = html.replace('_edit_',''); + } + + html = html.replace(/_id_/g,id); + html = html.replace(/_BASE_/g,this.baseUrl); + return html; +}); + + + /** * RequestCache @@ -538,7 +698,16 @@ RequestCache.method('getData', function(key) { var strData = localStorage.getItem(key); if(strData != undefined && strData != null && strData != ""){ - return JSON.parse(strData); + data = JSON.parse(strData); + if(data == undefined || data == null){ + return null; + } + + if(data.status != undefined && data.status != null && data.status != "SUCCESS"){ + return null; + } + + return data; } return null; @@ -550,6 +719,10 @@ RequestCache.method('setData', function(key, data) { return null; } + if(data.status != undefined && data.status != null && data.status != "SUCCESS"){ + return null; + } + var strData = JSON.stringify(data); var strData = localStorage.setItem(key,strData); return strData; diff --git a/src/api/Base.js b/src/api/Base.js index e786d19b..26273b1f 100644 --- a/src/api/Base.js +++ b/src/api/Base.js @@ -411,7 +411,7 @@ IceHRMBase.method('getTableTopButtonHtml', function() { if(html != ""){ html += "  "; } - html+=''; + html+=''; html += "  "; if(this.filtersAlreadySet){ html+=''; @@ -445,6 +445,10 @@ IceHRMBase.method('getTableHTMLTemplate', function() { return '
'; }); +IceHRMBase.method('isSortable', function() { + return true; +}); + /** * Create the data table on provided element id * @method createTable @@ -452,6 +456,9 @@ IceHRMBase.method('getTableHTMLTemplate', function() { */ IceHRMBase.method('createTable', function(elementId) { + + + var that = this; if(this.getRemoteTable()){ this.createTableServer(elementId); @@ -497,7 +504,7 @@ IceHRMBase.method('createTable', function(elementId) { }, "aaData": data, "aoColumns": headers, - "bSort": true, + "bSort": that.isSortable(), "iDisplayLength": 15, "iDisplayStart": start }; @@ -559,7 +566,7 @@ IceHRMBase.method('createTableServer', function(elementId) { "bServerSide": true, "sAjaxSource": that.getDataUrl(that.getDataMapping()), "aoColumns": headers, - "bSort": true, + "bSort": that.isSortable(), "parent":that, "iDisplayLength": 15, "iDisplayStart": start @@ -683,6 +690,38 @@ IceHRMBase.method('renderModel', function(id,header,body) { $('#'+id+'ModelBody').html(body); }); + +IceHRMBase.method('renderYesNoModel', function(header,body,yesBtnName,noBtnName,callback, callbackParams) { + var that = this; + var modelId = "#yesnoModel"; + + if(body == undefined || body == null){ + body = ""; + } + + $(modelId+'Label').html(header); + $(modelId+'Body').html(body); + if(yesBtnName != null){ + $(modelId+'YesBtn').html(yesBtnName); + } + if(noBtnName != null){ + $(modelId+'NoBtn').html(noBtnName); + } + + $(modelId+'YesBtn').off().on('click',function(){ + if(callback != undefined && callback != null){ + callback.apply(that,callbackParams); + that.cancelYesno(); + } + }); + + $(modelId).modal({ + backdrop: 'static' + }); + + +}); + IceHRMBase.method('renderModelFromDom', function(id,header,element) { $('#'+id+'ModelBody').html(""); @@ -746,8 +785,8 @@ IceHRMBase.method('showDomElement', function(title,element,closeCallback,closeCa var that = this; var modelId = ""; if(isPlain){ - modelId = "#plainMessageModel"; - this.renderModelFromDom('plainMessage',title,element); + modelId = "#dataMessageModel"; + this.renderModelFromDom('dataMessage',title,element); }else{ modelId = "#messageModel"; this.renderModelFromDom('message',title,element); @@ -781,10 +820,18 @@ IceHRMBase.method('closeMessage', function() { $('#messageModel').modal('hide'); }); +IceHRMBase.method('cancelYesno', function() { + $('#yesnoModel').modal('hide'); +}); + IceHRMBase.method('closePlainMessage', function() { $('#plainMessageModel').modal('hide'); }); +IceHRMBase.method('closeDataMessage', function() { + $('#dataMessageModel').modal('hide'); +}); + /** * Create or edit an element @@ -1435,7 +1482,7 @@ IceHRMBase.method('addDataGroup', function() { $("#"+field[0]+"_div").html(html); - this.closePlainMessage(); + this.closeDataMessage(); } }); @@ -1482,7 +1529,7 @@ IceHRMBase.method('editDataGroup', function() { $("#"+field[0]+"_div").html(html); - this.closePlainMessage(); + this.closeDataMessage(); } } diff --git a/src/app/config.sample.php b/src/app/config.sample.php index 3aa84d4e..0decf7da 100644 --- a/src/app/config.sample.php +++ b/src/app/config.sample.php @@ -15,7 +15,7 @@ define('APP_DB', '_APP_DB_'); define('APP_USERNAME', '_APP_USERNAME_'); define('APP_PASSWORD', '_APP_PASSWORD_'); define('APP_HOST', '_APP_HOST_'); -define('APP_CON_STR', 'mysql://'.APP_USERNAME.':'.APP_PASSWORD.'@'.APP_HOST.'/'.APP_DB); +define('APP_CON_STR', 'mysqli://'.APP_USERNAME.':'.APP_PASSWORD.'@'.APP_HOST.'/'.APP_DB); //file upload define('FILE_TYPES', 'jpg,png,jpeg'); diff --git a/src/app/cron.php b/src/app/cron.php new file mode 100644 index 00000000..ad4c7726 --- /dev/null +++ b/src/app/cron.php @@ -0,0 +1,7 @@ +Connect($_REQUEST["APP_HOST"], $_REQUEST["APP_USERNAME"], $_REQUEST["APP_PASSWORD"], $_REQUEST["APP_DB"]); if (!$res){ @@ -72,7 +72,7 @@ if($action == "TEST_DB"){ $con = mysql_connect($_REQUEST["APP_HOST"],$_REQUEST["APP_USERNAME"],$_REQUEST["APP_PASSWORD"]); - $db = NewADOConnection('mysql'); + $db = NewADOConnection('mysqli'); $res = $db->Connect($_REQUEST["APP_HOST"], $_REQUEST["APP_USERNAME"], $_REQUEST["APP_PASSWORD"], $_REQUEST["APP_DB"]); diff --git a/src/app/update.php b/src/app/update.php new file mode 100644 index 00000000..454f6c0d --- /dev/null +++ b/src/app/update.php @@ -0,0 +1,18 @@ +getModelClass(); + $itemName = $this->getItemName(); + + + $obj = new $class(); + $obj->Load("id = ?",array($req->id)); + + if($obj->id != $req->id){ + return new IceResponse(IceResponse::ERROR,"$itemName not found"); + } + + if($this->user->user_level != 'Admin' && $this->user->user_level != 'Manager'){ + return new IceResponse(IceResponse::ERROR,"Only an admin or manager can do this"); + } + + $oldStatus = $obj->status; + $obj->status = $req->status; + $ok = $obj->Save(); + if(!$ok){ + LogManager::getInstance()->info($obj->ErrorMsg()); + return new IceResponse(IceResponse::ERROR,"Error occurred while saving $itemName information. Please contact admin"); + } + + $this->baseService->audit(IceConstants::AUDIT_ACTION, "$itemName status changed from:".$oldStatus." to:".$obj->status." id:".$obj->id); + + $currentEmpId = $this->getCurrentProfileId(); + + if(!empty($currentEmpId)){ + $employee = $this->baseService->getElement('Employee',$currentEmpId); + + $notificationMsg = "Your $itemName has been $obj->status by ".$employee->first_name." ".$employee->last_name; + if(!empty($req->reason)){ + $notificationMsg.=" (Note:".$req->reason.")"; + } + + $this->baseService->notificationManager->addNotification($obj->employee,$notificationMsg,'{"type":"url","url":"'.$this->getModuleTabUrl().'"}',$this->getModuleName(), null, false, true); + + } + + + return new IceResponse(IceResponse::SUCCESS,""); + } + +} + + +abstract class ApproveModuleActionManager extends SubActionManager{ + + public abstract function getModelClass(); + public abstract function getItemName(); + public abstract function getModuleName(); + public abstract function getModuleTabUrl(); + + public function cancel($req){ + + $employee = $this->baseService->getElement('Employee',$this->getCurrentProfileId(),null,true); + + $class = $this->getModelClass(); + $itemName = $this->getItemName(); + $obj = new $class(); + $obj->Load("id = ?",array($req->id)); + if($obj->id != $req->id){ + return new IceResponse(IceResponse::ERROR,"$itemName record not found"); + } + + + if($this->user->user_level != 'Admin' && $this->getCurrentProfileId() != $obj->employee){ + return new IceResponse(IceResponse::ERROR,"Only an admin or owner of the $itemName can do this"); + } + + if($obj->status != 'Approved'){ + return new IceResponse(IceResponse::ERROR,"Only an approved $itemName can be cancelled"); + } + + $obj->status = 'Cancellation Requested'; + $ok = $obj->Save(); + if(!$ok){ + LogManager::getInstance()->error("Error occurred while cancelling the $itemName:".$obj->ErrorMsg()); + return new IceResponse(IceResponse::ERROR,"Error occurred while cancelling the $itemName. Please contact admin."); + } + + + $this->baseService->audit(IceConstants::AUDIT_ACTION, "Expense cancellation | start:".$obj->date_start."| end:".$obj->date_end); + $notificationMsg = $employee->first_name." ".$employee->last_name." cancelled a expense. Visit expense management module to approve"; + + $this->baseService->notificationManager->addNotification($employee->supervisor,$notificationMsg,'{"type":"url","url":"'.$this->getModuleTabUrl().'"}', + $this->getModuleTabUrl(), null, false, true); + return new IceResponse(IceResponse::SUCCESS,$obj); + } +} + + + +class ApproveModel extends ICEHRM_Record { + + public function executePreSaveActions($obj){ + $preApprove = SettingsManager::getInstance()->getSetting($this->preApproveSettingName); + $sendNotificationEmail = true; + if(empty($obj->status)){ + if($preApprove == "1"){ + $obj->status = "Approved"; + $sendNotificationEmail = false; + }else{ + $obj->status = "Pending"; + } + } + + if($preApprove){ + return new IceResponse(IceResponse::SUCCESS,$obj); + } + + $currentEmpId = BaseService::getInstance()->getCurrentProfileId(); + + //Auto approve if the current user is an admin + + if(!empty($currentEmpId)){ + $employee = BaseService::getInstance()->getElement('Employee',$currentEmpId); + + if(!empty($employee->supervisor)) { + $notificationMsg = "A new ".$this->notificationUnitName." has been added by " . $employee->first_name . " " . $employee->last_name . ". Please visit ".$this->notificationModuleName." module to review it"; + + BaseService::getInstance()->notificationManager->addNotification($employee->supervisor, $notificationMsg, '{"type":"url","url":"'.$this->notificationUnitAdminUrl.'"}', $this->notificationModuleName, null, false, $sendNotificationEmail); + }else{ + + $user = BaseService::getInstance()->getCurrentUser(); + + if($user->user_level == "Admin"){ + //Auto approve + $obj->status = "Approved"; + $notificationMsg = "Your ".$this->notificationUnitName." is auto approved since you are an administrator and do not have any supervisor assigned"; + BaseService::getInstance()->notificationManager->addNotification(null, $notificationMsg, '{"type":"url","url":"'.$this->notificationUnitAdminUrl.'"}', $this->notificationModuleName, $user->id, false, $sendNotificationEmail); + }else{ + //If the user do not have a supervisor, notify all admins + $admins = BaseService::getInstance()->getAllAdmins(); + foreach($admins as $admin){ + $notificationMsg = "A new ".$this->notificationUnitName." has been added by " . $employee->first_name . " " . $employee->last_name . ". Please visit ".$this->notificationModuleName." module to review it. You are getting this notification since you are an administrator and the user do not have any supervisor assigned."; + BaseService::getInstance()->notificationManager->addNotification(null, $notificationMsg, '{"type":"url","url":"'.$this->notificationUnitAdminUrl.'"}', $this->notificationModuleName, $admin->id, false, $sendNotificationEmail); + } + } + + + } + } + + return new IceResponse(IceResponse::SUCCESS,$obj); + } + + public function executePreUpdateActions($obj){ + + $preApprove = SettingsManager::getInstance()->getSetting($this->preApproveSettingName); + $sendNotificationEmail = true; + + $fieldsToCheck = $this->fieldsNeedToBeApproved(); + + $travelRequest = new EmployeeTravelRecord(); + $travelRequest->Load('id = ?',array($obj->id)); + + $needToApprove = false; + if($preApprove != "1"){ + foreach($fieldsToCheck as $field){ + if($obj->$field != $travelRequest->$field) { + $needToApprove = true; + break; + } + } + }else{ + $sendNotificationEmail = false; + } + + if($preApprove){ + return new IceResponse(IceResponse::SUCCESS,$obj); + } + + if($needToApprove && $obj->status != 'Pending'){ + $currentEmpId = BaseService::getInstance()->getCurrentProfileId(); + + //Auto approve if the current user is an admin + + if(!empty($currentEmpId)){ + $employee = BaseService::getInstance()->getElement('Employee',$currentEmpId); + + if(!empty($employee->supervisor)) { + $notificationMsg = $this->notificationUnitPrefix." ".$this->notificationUnitName." has been updated by " . $employee->first_name . " " . $employee->last_name . ". Please visit ".$this->notificationModuleName." module to review it"; + + BaseService::getInstance()->notificationManager->addNotification($employee->supervisor, $notificationMsg, '{"type":"url","url":"'.$this->notificationUnitAdminUrl.'"}', $this->notificationModuleName, null, false, $sendNotificationEmail); + }else{ + + $user = BaseService::getInstance()->getCurrentUser(); + + if($user->user_level == "Admin"){ + + }else{ + //If the user do not have a supervisor, notify all admins + $admins = BaseService::getInstance()->getAllAdmins(); + foreach($admins as $admin){ + $notificationMsg = $this->notificationUnitPrefix." ".$this->notificationUnitName." request has been updated by " . $employee->first_name . " " . $employee->last_name . ". Please visit ".$this->notificationModuleName." module to review it. You are getting this notification since you are an administrator and the user do not have any supervisor assigned."; + BaseService::getInstance()->notificationManager->addNotification(null, $notificationMsg, '{"type":"url","url":"g=admin&n=travel&m=admin_Employees"}', "Travel Module", $admin->id, false, $sendNotificationEmail); + } + } + + + } + } + } + + return new IceResponse(IceResponse::SUCCESS,$obj); + } +} \ No newline at end of file diff --git a/src/classes/BaseService.php b/src/classes/BaseService.php index e419500f..630a66f2 100644 --- a/src/classes/BaseService.php +++ b/src/classes/BaseService.php @@ -1103,6 +1103,30 @@ class BaseService{ $data = $customField->Find("type = ?",array($type)); return $data; } + + public function getAllAdmins(){ + $user = new User(); + $admins = $user->Find('user_level = ?',array('Admin')); + return $admins; + } + + public function getCurrentEmployeeTimeZone(){ + $cemp = $this->getCurrentProfileId(); + if(empty($cemp)){ + return NULL; + } + $emp = new Employee(); + $emp->Load("id = ?",array($cemp)); + if(empty($emp->id) || empty($emp->department)){ + return NULL; + } + + $dept = new CompanyStructure(); + $dept->Load("id = ?",array($emp->department)); + + return $dept->timezone; + + } } class IceConstants{ diff --git a/src/classes/CronUtils.php b/src/classes/CronUtils.php index dca96ef3..d22fbc2d 100644 --- a/src/classes/CronUtils.php +++ b/src/classes/CronUtils.php @@ -6,7 +6,7 @@ class CronUtils{ private static $me = null; private function __construct($clientBasePath, $cronFile){ - $this->clientBasePath = $clientBasePath; + $this->clientBasePath = $clientBasePath."/"; $this->cronFile = $cronFile; } @@ -20,14 +20,178 @@ class CronUtils{ public function run(){ $ams = scandir($this->clientBasePath); - + $count = 0; foreach($ams as $am){ if(is_dir($this->clientBasePath.$am) && $am != '.' && $am != '..'){ - $command = "php ".$this->cronFile." -c".$this->clientBasePath.$am; + //$command = "php ".$this->cronFile." -c".$this->clientBasePath.$am; + $command = "php ".$this->clientBasePath.$am."/".$this->cronFile; echo "Run:".$command."\r\n"; passthru($command, $res); echo "Result :".$res."\r\n"; + + $count++; + if($count > 25){ + sleep(1); + $count = 0; + } } } } -} \ No newline at end of file +} + + +class IceCron{ + + const MINUTELY = "Minutely"; + const HOURLY = "Hourly"; + const DAILY = "Daily"; + const WEEKLY = "Weekly"; + const MONTHLY = "Monthly"; + const YEARLY = "Yearly"; + + private $cron; + + public function __construct($cron){ + $this->cron = $cron; + } + + public function isRunNow(){ + LogManager::getInstance()->debug("Cron ".print_r($this->cron,true)); + $lastRunTime = $this->cron->lastrun; + if(empty($lastRunTime)){ + LogManager::getInstance()->debug("Cron ".$this->cron->name." is running since last run time is empty"); + return true; + } + + $type = $this->cron->type; + $frequency = intval($this->cron->frequency); + $time = intval($this->cron->time); + + if(empty($frequency) || !is_int($frequency)){ + LogManager::getInstance()->debug("Cron ".$this->cron->name." is not running since frequency is not an integer"); + return false; + } + + + if($type == self::MINUTELY){ + + $diff = (strtotime("now") - strtotime($lastRunTime)); + if(empty($this->time) || !is_int($time)){ + if($diff > 60){ + return true; + } + }else{ + if($diff > 60 * $time){ + return true; + } + } + + + }else if($type == self::HOURLY){ + if(empty($time) || !is_int($time)){ + + if(date('H') != date('H',strtotime($lastRunTime))){ + return true; + } + }else{ + if(intval(date('m')) <= intval($time) && date('H') != date('H',strtotime($lastRunTime))){ + return true; + } + } + }else if($type == self::DAILY){ + if(empty($time) || !is_int($time)){ + + if(date('d') != date('d',strtotime($lastRunTime))){ + return true; + } + }else{ + if(intval(date('H')) <= intval($time) && date('d') != date('d',strtotime($lastRunTime))){ + return true; + } + } + }else if($type == self::MONTHLY){ + if(empty($time) || !is_int($time)){ + + if(date('m') != date('m',strtotime($lastRunTime))){ + return true; + } + }else{ + if(intval(date('d')) <= intval($time) && date('m') != date('m',strtotime($lastRunTime))){ + return true; + } + } + }else if($type == self::YEARLY){ + if(empty($time) || !is_int($time)){ + if(date('Y') != date('Y',strtotime($lastRunTime))){ + return true; + } + }else{ + if(intval(date('m')) <= intval($time) && date('Y') != date('Y',strtotime($lastRunTime))){ + return true; + } + } + } + + return false; + } + + public function execute(){ + $class = $this->cron->class; + $obj = new $class(); + $obj->execute($this->cron); + $this->cronCompleted(); + } + + + private function cronCompleted(){ + $this->cron->lastrun = date("Y-m-d H:i:s"); + $ok = $this->cron->Save(); + if(!$ok){ + LogManager::getInstance()->error("Error saving cron due to :".$this->cron->ErrorMsg()); + } + } + +} + +interface IceTask{ + public function execute($cron); +} + +abstract class EmailIceTask implements IceTask{ + public abstract function execute($cron); + + public function sendEmployeeEmails($emailList, $subject){ + + + foreach($emailList as $employeeId => $emailData){ + $ccList = array(); + if(SettingsManager::getInstance()->getSetting('Notifications: Copy Document Expiry Emails to Manager') == '1'){ + $employee = new Employee(); + $employee->Load("id = ?",array($employeeId)); + if(!empty($employee->supervisor)){ + $supperuser = BaseService::getInstance()->getUserFromProfileId($employee->supervisor); + if(!empty($supperuser)){ + $ccList[] = $supperuser->email; + } + } + } + $user = BaseService::getInstance()->getUserFromProfileId($employeeId); + if(!empty($user) && !empty($user->email)){ + $email = new IceEmail(); + $email->subject = $subject; + $email->toEmail = $user->email; + $email->template = $emailData; + $email->params = '[]'; + $email->cclist = json_encode($ccList); + $email->bcclist = '[]'; + $email->status = 'Pending'; + $email->created = date('Y-m-d H:i:s'); + $email->updated = date('Y-m-d H:i:s'); + $ok = $email->Save(); + if(!$ok){ + LogManager::getInstance()->error("Error Saving Email: ".$email->ErrorMsg()); + } + } + } + } +} diff --git a/src/classes/EmailSender.php b/src/classes/EmailSender.php index 52e49f06..5c37156e 100644 --- a/src/classes/EmailSender.php +++ b/src/classes/EmailSender.php @@ -13,6 +13,56 @@ abstract class EmailSender{ $this->settings = $settings; } + public function sendEmailFromNotification($notification){ + $toEmail = null; + $user = new User(); + $user->Load("id = ?",array($notification->toUser)); + + if(!empty($user->email)){ + $name = "User"; + $employee = new Employee(); + $employee->Load("id = ?",array($user->employee)); + if($employee->id == $user->employee && !empty($employee->id)){ + $name = $employee->first_name; + } + + $action = json_decode($notification->action); + + $emailBody = file_get_contents(APP_BASE_PATH.'/templates/email/notificationEmail.html'); + $emailBody = str_replace("#_user_#", $name, $emailBody); + $emailBody = str_replace("#_message_#", $notification->message, $emailBody); + if($action->type == "url"){ + $emailBody = str_replace("#_url_#", CLIENT_BASE_URL."?".$action->url, $emailBody); + } + $this->sendEmail('IceHrm Notification from '.$notification->type, + $user->email, + $emailBody, + array(), + array(), + array() + ); + } + } + + public function sendEmailFromDB($email){ + $params = array(); + if(!empty($email->params)){ + $params = json_decode($email->params, true); + } + + $cclist = array(); + if(!empty($email->cclist)){ + $cclist = json_decode($email->cclist, true); + } + + $bcclist = array(); + if(!empty($email->bcclist)){ + $bcclist = json_decode($email->bcclist, true); + } + + $resp = $this->sendEmail($email->subject, $email->toEmail, $email->template, $params, $cclist, $bcclist); + } + public function sendEmail($subject, $toEmail, $template, $params, $ccList = array(), $bccList = array()){ $body = $template; @@ -225,7 +275,7 @@ class SMTPEmailSender extends EmailSender{ $mail = $smtp->send($toEmail, $headers, $body); - return true; + return $mail; } } @@ -255,6 +305,6 @@ class PHPMailer extends EmailSender{ LogManager::getInstance()->info("PHP mailer result : ".$res); - return true; + return $res; } } \ No newline at end of file diff --git a/src/classes/ReportHandler.php b/src/classes/ReportHandler.php index 98750519..7d74e2e9 100644 --- a/src/classes/ReportHandler.php +++ b/src/classes/ReportHandler.php @@ -12,8 +12,8 @@ class ReportHandler{ return $this->executeReport($report,$query,$where[1]); }else if($report->type == 'Class'){ $className = $report->query; - include MODULE_PATH.'/reportClasses/ReportBuilder.php'; - include MODULE_PATH.'/reportClasses/'.$className.".php"; + include APP_BASE_PATH.'admin/reports/reportClasses/ReportBuilder.php'; + include APP_BASE_PATH.'admin/reports/reportClasses/'.$className.".php"; $cls = new $className(); $data = $cls->getData($report,$request); return $this->generateReport($report,$data); diff --git a/src/classes/UIManager.php b/src/classes/UIManager.php index 34288af4..e59d6d1e 100644 --- a/src/classes/UIManager.php +++ b/src/classes/UIManager.php @@ -153,10 +153,27 @@ class UIManager{ } if($this->user->user_level == "Admin"){ + + $reg = ''; + $num = ''; + if(class_exists('ProVersion')){ + $pro = new ProVersion(); + if(!empty($pro->employeeLimit)){ + $num = "
Employee Limit: ".$pro->employeeLimit; + } + + if(method_exists($pro,'getRegisteredTo')){ + $reg = "
Registered To: ".$pro->getRegisteredTo(); + } + } + + $manuItems[] = new MenuItemTemplate('menuButtonHelp', array( "APP_NAME"=>APP_NAME, "VERSION"=>VERSION, - "VERSION_DATE"=>VERSION_DATE + "VERSION_DATE"=>VERSION_DATE, + "REG"=>$reg, + "NUM"=>$num )); } @@ -199,6 +216,23 @@ class UIManager{ return $str; } + + public function getCompanyLogoUrl(){ + $logoFileSet = false; + $logoFileName = CLIENT_BASE_PATH."data/logo.png"; + $logoSettings = SettingsManager::getInstance()->getSetting("Company: Logo"); + if(!empty($logoSettings)){ + $logoFileName = FileService::getInstance()->getFileUrl($logoSettings); + $logoFileSet = true; + } + + if(!$logoFileSet && !file_exists($logoFileName)){ + return BASE_URL."images/logo.png"; + } + + return $logoFileName; + } + } diff --git a/src/common.cron.tasks.php b/src/common.cron.tasks.php new file mode 100644 index 00000000..c38150ca --- /dev/null +++ b/src/common.cron.tasks.php @@ -0,0 +1,23 @@ +Find("status = ? limit 10",array('Pending')); + $emailSender = BaseService::getInstance()->getEmailSender(); + foreach($emails as $email){ + try{ + $emailSender->sendEmailFromDB($email); + }catch(Exception $e){ + LogManager::getInstance()->error("Error sending email:".$e->getMessage()); + } + + $email->status = 'Sent'; + $email->updated = date('Y-m-d H:i:s'); + $email->Save(); + } + } +} + + +include('common.cron.tasks.ext.php'); \ No newline at end of file diff --git a/src/config.base.php b/src/config.base.php index cebbe14e..e1bf1ead 100644 --- a/src/config.base.php +++ b/src/config.base.php @@ -9,4 +9,4 @@ if(!defined('SIGN_IN_ELEMENT_MAPPING_FIELD_NAME')){define('SIGN_IN_ELEMENT_MAPPI if(!defined('CONTACT_EMAIL')){define('CONTACT_EMAIL','ice-framework@gamonoid.com');} if(!defined('KEY_PREFIX')){define('KEY_PREFIX','iCEf');} -if(!defined('APP_SEC')){define('APP_SEC','4dcxswfrds');} \ No newline at end of file +if(!defined('APP_SEC')){define('APP_SEC','4dcxudersqw');} \ No newline at end of file diff --git a/src/crons/cron.php b/src/crons/cron.php new file mode 100644 index 00000000..748560a6 --- /dev/null +++ b/src/crons/cron.php @@ -0,0 +1,22 @@ +Find("status = ?",array('Enabled')); + +if(!$crons){ + LogManager::getInstance()->info(CLIENT_NAME." error :".$cron->ErrorMsg()); +} + +LogManager::getInstance()->info(CLIENT_NAME." cron count :".count($crons)); +foreach($crons as $cron){ + $count++; + $iceCron = new IceCron($cron); + LogManager::getInstance()->info(CLIENT_NAME." check cron :".$cron->name); + if($iceCron->isRunNow()){ + LogManager::getInstance()->info(CLIENT_NAME." execute cron :".$cron->name); + $iceCron->execute(); + sleep(1); + } +} + diff --git a/src/crons/cronRunner.php b/src/crons/cronRunner.php index 646d22bc..1a904fd5 100644 --- a/src/crons/cronRunner.php +++ b/src/crons/cronRunner.php @@ -10,7 +10,7 @@ $basePath = $opts['p']; include (dirname(__FILE__)."/../classes/CronUtils.php"); -$cronUtils = CronUtils::getInstance($basePath, dirname(__FILE__)."/".$file); +$cronUtils = CronUtils::getInstance($basePath, $file); echo "Cron Runner created \r\n"; diff --git a/src/crons/include.cron.php b/src/crons/include.cron.php index 4e3fe807..f6acbb1b 100644 --- a/src/crons/include.cron.php +++ b/src/crons/include.cron.php @@ -2,14 +2,10 @@ if(php_sapi_name() != 'cli'){ exit(); } -$opts = getopt('c:'); -$clientPath = $opts['c']; -if(empty($clientPath)){ - echo "No client path defined\r\n"; - exit(); -} +define('CLIENT_PATH',dirname(__FILE__)."/.."); + +include (APP_BASE_PATH."config.base.php"); -include $clientPath."/config.php"; include (APP_BASE_PATH."include.common.php"); -include("server.includes.inc.php"); \ No newline at end of file +include(APP_BASE_PATH."server.includes.inc.php"); \ No newline at end of file diff --git a/src/css/style.css b/src/css/style.css index 603fd98e..87eedef3 100644 --- a/src/css/style.css +++ b/src/css/style.css @@ -407,7 +407,7 @@ table.dataTable{ -webkit-border-radius: 0px; -moz-border-radius: 0px; border-radius: 0px; - + box-shadow: 0 1px 1px rgba(0,0,0,.12),0 1px 1px rgba(0,0,0,.24); } @@ -457,6 +457,13 @@ table.dataTable{ background: #FFF; } +/* +@media (min-width:1025px) { + .content { + min-height: 1100px; + } +}*/ + .wrapper { background: #FFF; } @@ -481,6 +488,16 @@ table.dataTable{ + + + + + + + +/*custom for v11.0 */ + + .table-bordered>thead>tr>th{ border:none !important; } @@ -499,9 +516,11 @@ table.dataTable{ box-shadow: 0 1px 2px 0 rgba(0,0,0,.2); } -.reviewBlock{ +.reviewBlock{/* -webkit-box-sizing: border-box; - box-sizing: border-box + box-sizing: border-box*/ + box-shadow: 0 1px 3px rgba(0,0,0,.12),0 1px 2px rgba(0,0,0,.24); + border: none; } .treeview-menu li:hover{ @@ -588,4 +607,48 @@ table.dataTable{ .fc-toolbar h2{ font-size: 15px; +} + +.navbar, .right-side{ + box-shadow: 0 1px 3px rgba(0,0,0,.12),0 1px 2px rgba(0,0,0,.24); + border: none; +} + +.right-side{ + margin-bottom: 20px; +} + +.sidebar .sidebar-menu { + box-shadow: 0 1px 3px rgba(0,0,0,.12),0 1px 2px rgba(0,0,0,.24); + border: none; + background: #FFF; +} + +.treeview.active{ + box-shadow: 0 1px 3px rgba(0,0,0,.12),0 1px 2px rgba(0,0,0,.24); + border: none; + background: #FFF; +} + +.sidebar .sidebar-menu .treeview-menu > li { + background: #FFF; +} + +.skin-blue .sidebar > .sidebar-menu > li > a:hover, .skin-blue .sidebar > .sidebar-menu > li.active > a { + color: #222; + background: #fff !important; +} + +.right-side > .content-header > h1 > small { + color: #FFF; +} + +.modal-content { + border-radius: 0px; +} + +.panel { + border-radius: 0px; + -moz-border-radius: 0px; + -webkit-border-radius: 0px; } \ No newline at end of file diff --git a/src/entry_footer.php b/src/entry_footer.php new file mode 100644 index 00000000..1d7a6bf4 --- /dev/null +++ b/src/entry_footer.php @@ -0,0 +1,49 @@ + + + + + + + + \ No newline at end of file diff --git a/src/entry_header.php b/src/entry_header.php new file mode 100644 index 00000000..f593c536 --- /dev/null +++ b/src/entry_header.php @@ -0,0 +1,91 @@ + + + + + <?=$meta->title?> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/fileupload.php b/src/fileupload.php index b82da239..55231c64 100644 --- a/src/fileupload.php +++ b/src/fileupload.php @@ -10,7 +10,7 @@ include_once ('server.includes.inc.php'); /** * Handle file uploads via regular form post (uses the $_FILES array) */ -class qqUploadedFileForm { +class qqUploadedFileForm { /** * Save the file to the specified path * @return boolean TRUE on success @@ -30,64 +30,64 @@ class qqUploadedFileForm { } class qqFileUploader { - var $log = null; + var $log = null; private $allowedExtensions = array(); private $sizeLimit = 10485760; //private $sizeLimit = 2485760; private $file; - function __construct(array $allowedExtensions = array(), $sizeLimit = 10485760){ + function __construct(array $allowedExtensions = array(), $sizeLimit = 10485760){ $allowedExtensions = array_map("strtolower", $allowedExtensions); - $this->allowedExtensions = $allowedExtensions; + $this->allowedExtensions = $allowedExtensions; $this->sizeLimit = $sizeLimit; - $this->checkServerSettings(); - $this->file = new qqUploadedFileForm(); + $this->checkServerSettings(); + $this->file = new qqUploadedFileForm(); } - - private function checkServerSettings(){ + + private function checkServerSettings(){ $postSize = $this->toBytes(ini_get('post_max_size')); - $uploadSize = $this->toBytes(ini_get('upload_max_filesize')); - + $uploadSize = $this->toBytes(ini_get('upload_max_filesize')); + /*if ($postSize < $this->sizeLimit || $uploadSize < $this->sizeLimit){ - $size = max(1, $this->sizeLimit / 1024 / 1024) . 'M'; - die("{'error':'increase post_max_size and upload_max_filesize to $size'}"); - }*/ + $size = max(1, $this->sizeLimit / 1024 / 1024) . 'M'; + die("{'error':'increase post_max_size and upload_max_filesize to $size'}"); + }*/ } - + private function toBytes($str){ $val = trim($str); $last = strtolower($str[strlen($str)-1]); switch($last) { case 'g': $val *= 1024; case 'm': $val *= 1024; - case 'k': $val *= 1024; + case 'k': $val *= 1024; } return $val; } - + /** * Returns array('success'=>1) or array('error'=>'error message') */ function handleUpload($uploadDirectory,$saveFileName, $replaceOldFile = FALSE){ if (!is_writable($uploadDirectory)){ - return array('success'=>0,'error' => "Server error. Upload directory isn't writable."); + return array('success'=>0,'error' => "Server error. Upload directory ($uploadDirectory) is not writable"); } - + if (!$this->file){ return array('success'=>0,'error' => 'No files were uploaded.'); } - + $size = $this->file->getSize(); LogManager::getInstance()->info('file size ='.$size); LogManager::getInstance()->info('file size limit ='.$this->sizeLimit); if ($size == 0) { return array('success'=>0,'error' => 'File is empty'); } - + if ($size > $this->sizeLimit) { return array('success'=>0,'error' => 'File is too large'); } - + $pathinfo = pathinfo($this->file->getName()); $filename = $pathinfo['filename']; //$filename = md5(uniqid()); @@ -100,18 +100,18 @@ class qqFileUploader { //$filename .= microtime(true); $filename = $saveFileName; // file with only name $saveFileName = $saveFileName.'.'.strtolower($ext); // file with extention - + $final_img_location = $uploadDirectory . $saveFileName; if ($this->file->save($final_img_location)){ - $arr = explode("/", $final_img_location); - return array('success'=>1,'filename'=>$arr[count($arr)-1],'error'=>''); + $arr = explode("/", $final_img_location); + return array('success'=>1,'filename'=>$arr[count($arr)-1],'error'=>''); } else { return array('success'=>0,'error'=> 'Could not save uploaded file.' . 'The upload was cancelled, or server error encountered'); } - - } + + } } //Generate File Name $saveFileName = $_POST['file_name']; @@ -119,12 +119,12 @@ $saveFileName = str_replace("..","",$saveFileName); $saveFileName = str_replace("/","",$saveFileName); if(stristr($saveFileName,".php")){ - $saveFileName = str_replace(".php","",$saveFileName); + $saveFileName = str_replace(".php","",$saveFileName); } if(empty($saveFileName) || $saveFileName == "_NEW_"){ - $saveFileName = microtime(); - $saveFileName = str_replace(".", "-", $saveFileName); + $saveFileName = microtime(); + $saveFileName = str_replace(".", "-", $saveFileName); } $file = new File(); @@ -150,45 +150,45 @@ $uploadedToS3 = false; LogManager::getInstance()->info($uploadFilesToS3."|".$uploadFilesToS3Key."|".$uploadFilesToS3Secret."|".$s3Bucket."|".$s3WebUrl."|".CLIENT_NAME); if($uploadFilesToS3.'' == '1' && !empty($uploadFilesToS3Key) && !empty($uploadFilesToS3Secret) && - !empty($s3Bucket) && !empty($s3WebUrl)){ - - $localFile = CLIENT_BASE_PATH.'data/'.$result['filename']; - - $f_size = filesize($localFile); - $uploadname = CLIENT_NAME."/".$result['filename']; - LogManager::getInstance()->info("Upload file to s3:".$uploadname); - LogManager::getInstance()->info("Local file:".$localFile); - LogManager::getInstance()->info("Local file size:".$f_size); - - - $s3FileSys = new S3FileSystem($uploadFilesToS3Key, $uploadFilesToS3Secret); - $res = $s3FileSys->putObject($s3Bucket, $uploadname, $localFile, 'authenticated-read'); - - $file_url = $s3WebUrl.$uploadname; - $file_url = $s3FileSys->generateExpiringURL($file_url); - LogManager::getInstance()->info("Response from s3 file sys:".print_r($res,true)); - unlink($localFile); - - $uploadedToS3 = true; + !empty($s3Bucket) && !empty($s3WebUrl)){ + + $localFile = CLIENT_BASE_PATH.'data/'.$result['filename']; + + $f_size = filesize($localFile); + $uploadname = CLIENT_NAME."/".$result['filename']; + LogManager::getInstance()->info("Upload file to s3:".$uploadname); + LogManager::getInstance()->info("Local file:".$localFile); + LogManager::getInstance()->info("Local file size:".$f_size); + + + $s3FileSys = new S3FileSystem($uploadFilesToS3Key, $uploadFilesToS3Secret); + $res = $s3FileSys->putObject($s3Bucket, $uploadname, $localFile, 'authenticated-read'); + + $file_url = $s3WebUrl.$uploadname; + $file_url = $s3FileSys->generateExpiringURL($file_url); + LogManager::getInstance()->info("Response from s3 file sys:".print_r($res,true)); + unlink($localFile); + + $uploadedToS3 = true; } if($result['success'] == 1){ - $file->name = $saveFileName; - $file->filename = $result['filename']; - $signInMappingField = SIGN_IN_ELEMENT_MAPPING_FIELD_NAME; - $file->$signInMappingField = $_POST['user']=="_NONE_"?null:$_POST['user']; - $file->file_group = $_POST['file_group']; - $file->Save(); - if($uploadedToS3){ - $result['data'] = $file_url; - }else{ - $result['data'] = CLIENT_BASE_URL.'data/'.$result['filename']; - } - $result['data'] .= "|".$saveFileName; - $result['data'] .= "|".$file->id; + $file->name = $saveFileName; + $file->filename = $result['filename']; + $signInMappingField = SIGN_IN_ELEMENT_MAPPING_FIELD_NAME; + $file->$signInMappingField = $_POST['user']=="_NONE_"?null:$_POST['user']; + $file->file_group = $_POST['file_group']; + $file->Save(); + if($uploadedToS3){ + $result['data'] = $file_url; + }else{ + $result['data'] = CLIENT_BASE_URL.'data/'.$result['filename']; + } + $result['data'] .= "|".$saveFileName; + $result['data'] .= "|".$file->id; } -echo ""; +echo ""; diff --git a/src/font/roboto/Roboto-Black-webfont.woff b/src/font/roboto/Roboto-Black-webfont.woff new file mode 100644 index 00000000..b9731ba7 Binary files /dev/null and b/src/font/roboto/Roboto-Black-webfont.woff differ diff --git a/src/font/roboto/Roboto-BlackItalic-webfont.woff b/src/font/roboto/Roboto-BlackItalic-webfont.woff new file mode 100644 index 00000000..54a2a259 Binary files /dev/null and b/src/font/roboto/Roboto-BlackItalic-webfont.woff differ diff --git a/src/font/roboto/Roboto-Bold-webfont.woff b/src/font/roboto/Roboto-Bold-webfont.woff new file mode 100644 index 00000000..03357ce4 Binary files /dev/null and b/src/font/roboto/Roboto-Bold-webfont.woff differ diff --git a/src/font/roboto/Roboto-BoldCondensed-webfont.woff b/src/font/roboto/Roboto-BoldCondensed-webfont.woff new file mode 100644 index 00000000..be472c3e Binary files /dev/null and b/src/font/roboto/Roboto-BoldCondensed-webfont.woff differ diff --git a/src/font/roboto/Roboto-BoldCondensedItalic-webfont.woff b/src/font/roboto/Roboto-BoldCondensedItalic-webfont.woff new file mode 100644 index 00000000..ef522c8b Binary files /dev/null and b/src/font/roboto/Roboto-BoldCondensedItalic-webfont.woff differ diff --git a/src/font/roboto/Roboto-BoldItalic-webfont.woff b/src/font/roboto/Roboto-BoldItalic-webfont.woff new file mode 100644 index 00000000..78879251 Binary files /dev/null and b/src/font/roboto/Roboto-BoldItalic-webfont.woff differ diff --git a/src/font/roboto/Roboto-Condensed-webfont.woff b/src/font/roboto/Roboto-Condensed-webfont.woff new file mode 100644 index 00000000..7bee5623 Binary files /dev/null and b/src/font/roboto/Roboto-Condensed-webfont.woff differ diff --git a/src/font/roboto/Roboto-CondensedItalic-webfont.woff b/src/font/roboto/Roboto-CondensedItalic-webfont.woff new file mode 100644 index 00000000..0a456352 Binary files /dev/null and b/src/font/roboto/Roboto-CondensedItalic-webfont.woff differ diff --git a/src/font/roboto/Roboto-Italic-webfont.woff b/src/font/roboto/Roboto-Italic-webfont.woff new file mode 100644 index 00000000..2586e11d Binary files /dev/null and b/src/font/roboto/Roboto-Italic-webfont.woff differ diff --git a/src/font/roboto/Roboto-Light-webfont.woff b/src/font/roboto/Roboto-Light-webfont.woff new file mode 100644 index 00000000..f6abd871 Binary files /dev/null and b/src/font/roboto/Roboto-Light-webfont.woff differ diff --git a/src/font/roboto/Roboto-LightItalic-webfont.woff b/src/font/roboto/Roboto-LightItalic-webfont.woff new file mode 100644 index 00000000..c9ec37db Binary files /dev/null and b/src/font/roboto/Roboto-LightItalic-webfont.woff differ diff --git a/src/font/roboto/Roboto-Medium-webfont.woff b/src/font/roboto/Roboto-Medium-webfont.woff new file mode 100644 index 00000000..15166091 Binary files /dev/null and b/src/font/roboto/Roboto-Medium-webfont.woff differ diff --git a/src/font/roboto/Roboto-MediumItalic-webfont.eot b/src/font/roboto/Roboto-MediumItalic-webfont.eot new file mode 100644 index 00000000..9e6f7090 Binary files /dev/null and b/src/font/roboto/Roboto-MediumItalic-webfont.eot differ diff --git a/src/font/roboto/Roboto-MediumItalic-webfont.woff b/src/font/roboto/Roboto-MediumItalic-webfont.woff new file mode 100644 index 00000000..5ea094a7 Binary files /dev/null and b/src/font/roboto/Roboto-MediumItalic-webfont.woff differ diff --git a/src/font/roboto/Roboto-Regular-webfont.woff b/src/font/roboto/Roboto-Regular-webfont.woff new file mode 100644 index 00000000..6ff6afd8 Binary files /dev/null and b/src/font/roboto/Roboto-Regular-webfont.woff differ diff --git a/src/font/roboto/Roboto-Thin-webfont.woff b/src/font/roboto/Roboto-Thin-webfont.woff new file mode 100644 index 00000000..0b65ccf8 Binary files /dev/null and b/src/font/roboto/Roboto-Thin-webfont.woff differ diff --git a/src/font/roboto/Roboto-ThinItalic-webfont.woff b/src/font/roboto/Roboto-ThinItalic-webfont.woff new file mode 100644 index 00000000..035a8187 Binary files /dev/null and b/src/font/roboto/Roboto-ThinItalic-webfont.woff differ diff --git a/src/font/roboto/Roboto.css b/src/font/roboto/Roboto.css new file mode 100644 index 00000000..cdd4f63d --- /dev/null +++ b/src/font/roboto/Roboto.css @@ -0,0 +1,106 @@ +@font-face { + font-family: 'Roboto'; + src: local('Roboto'), url('https://roboto-webfont.googlecode.com/files/Roboto-Regular-webfont.woff') format('woff'); + font-weight: 400; + font-style: normal; +} +@font-face { + font-family: 'Roboto'; + src: local('Roboto'), url('https://roboto-webfont.googlecode.com/files/Roboto-Italic-webfont.woff') format('woff'); + font-weight: 400; + font-style: italic; +} +@font-face { + font-family: 'Roboto'; + src: local('Roboto'), url('https://roboto-webfont.googlecode.com/files/Roboto-Bold-webfont.woff') format('woff'); + font-weight: 700; + font-style: normal; +} +@font-face { + font-family: 'Roboto'; + src: local('Roboto'), url('https://roboto-webfont.googlecode.com/files/Roboto-BoldItalic-webfont.woff') format('woff'); + font-weight: 700; + font-style: italic; +} + +@font-face { + font-family: 'Roboto Condensed'; + src: local('Roboto Condensed'), url('https://roboto-webfont.googlecode.com/files/Roboto-Condensed-webfont.woff') format('woff'); + font-weight: 400; + font-style: normal; +} +@font-face { + font-family: 'Roboto Condensed'; + src: local('Roboto Condensed'), url('https://roboto-webfont.googlecode.com/files/Roboto-CondensedItalic-webfont.woff') format('woff'); + font-weight: 400; + font-style: italic; +} +@font-face { + font-family: 'Roboto Condensed'; + src: local('Roboto Condensed'), url('https://roboto-webfont.googlecode.com/files/Roboto-BoldCondensed-webfont.woff') format('woff'); + font-weight: 700; + font-style: normal; +} +@font-face { + font-family: 'Roboto Condensed'; + src: local('Roboto Condensed'), url('https://roboto-webfont.googlecode.com/files/Roboto-BoldCondensedItalic-webfont.woff') format('woff'); + font-weight: 700; + font-style: italic; +} + +@font-face { + font-family: 'Roboto Thin'; + src: local('Roboto Thin'), url('https://roboto-webfont.googlecode.com/files/Roboto-Thin-webfont.woff') format('woff'); + font-weight: 400; + font-style: normal; +} +@font-face { + font-family: 'Roboto Thin'; + src: local('Roboto Thin'), url('https://roboto-webfont.googlecode.com/files/Roboto-ThinItalic-webfont.woff') format('woff'); + font-weight: 400; + font-style: italic; + +} + +@font-face { + font-family: 'Roboto Light'; + src: local('Roboto Light'), url('https://roboto-webfont.googlecode.com/files/Roboto-Light-webfont.woff') format('woff'); + font-weight: 400; + font-style: normal; + +} +@font-face { + font-family: 'Roboto Light'; + src: local('Roboto Light'), url('https://roboto-webfont.googlecode.com/files/Roboto-LightItalic-webfont.woff') format('woff'); + font-weight: 400; + font-style: italic; + +} + +@font-face { + font-family: 'Roboto Medium'; + src: local('Roboto Medium'), url('https://roboto-webfont.googlecode.com/files/Roboto-Medium-webfont.woff') format('woff'); + font-weight: 400; + font-style: normal; + +} +@font-face { + font-family: 'Roboto Medium'; + src: local('Roboto Medium'), url('https://roboto-webfont.googlecode.com/files/Roboto-MediumItalic-webfont.woff') format('woff'); + font-weight: 400; + font-style: italic; + +} + +@font-face { + font-family: 'Roboto Black'; + src: local('Roboto Black'), url('https://roboto-webfont.googlecode.com/files/Roboto-Black-webfont.woff') format('woff'); + font-weight: 400; + font-style: normal; +} +@font-face { + font-family: 'Roboto Black'; + src: local('Roboto Black'), url('https://roboto-webfont.googlecode.com/files/Roboto-BlackItalic-webfont.woff') format('woff'); + font-weight: 400; + font-style: italic; +} \ No newline at end of file diff --git a/src/header.php b/src/header.php index 98a01984..53fbc916 100644 --- a/src/header.php +++ b/src/header.php @@ -23,6 +23,8 @@ Developer: Thilina Hasantha (thilina.hasantha[at]gmail.com / facebook.com/thilin include 'includes.inc.php'; if(empty($user)){ + $actual_link = "http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]"; + SessionUtils::saveSessionObject('loginRedirect',$actual_link); header("Location:".CLIENT_BASE_URL."login.php"); } @@ -54,6 +56,7 @@ if(!in_array($user->user_level, $modulePermissions['user'])){ $commonRoles = array_intersect($modulePermissions['user_roles'], $userRoles); if(empty($commonRoles)){ echo "You are not allowed to access this page"; + header("Location:".CLIENT_BASE_URL."logout.php"); exit(); } @@ -193,7 +196,7 @@ include('configureUIManager.php');
-
+ + + + + + + + +