Latest updates from IceHrmPro
This commit is contained in:
@@ -52,6 +52,8 @@ class BaseService
|
||||
public $modelClassMap = array();
|
||||
public $currentProfileId = false;
|
||||
|
||||
protected $cacheService = null;
|
||||
|
||||
protected $pro = null;
|
||||
|
||||
private static $me = null;
|
||||
@@ -109,14 +111,11 @@ class BaseService
|
||||
$filter = json_decode($filterStr, true);
|
||||
|
||||
if (!empty($filter)) {
|
||||
LogManager::getInstance()->debug("Building filter query");
|
||||
if (method_exists($obj, 'getCustomFilterQuery')) {
|
||||
LogManager::getInstance()->debug("Method: getCustomFilterQuery exists");
|
||||
$response = $obj->getCustomFilterQuery($filter);
|
||||
$query = $response[0];
|
||||
$queryData = $response[1];
|
||||
} else {
|
||||
LogManager::getInstance()->debug("Method: getCustomFilterQuery not found");
|
||||
$defaultFilterResp = $this->buildDefaultFilterQuery($filter);
|
||||
$query = $defaultFilterResp[0];
|
||||
$queryData = $defaultFilterResp[1];
|
||||
@@ -134,8 +133,6 @@ class BaseService
|
||||
$cemp = $this->getCurrentProfileId();
|
||||
if (!empty($cemp)) {
|
||||
$signInMappingField = SIGN_IN_ELEMENT_MAPPING_FIELD_NAME;
|
||||
LogManager::getInstance()->debug("Query: ".$signInMappingField." = ?".$query.$orderBy);
|
||||
LogManager::getInstance()->debug("Query Data: ".print_r(array_merge(array($cemp), $queryData), true));
|
||||
$list = $obj->Find($signInMappingField." = ?".$query.$orderBy, array_merge(array($cemp), $queryData));
|
||||
} else {
|
||||
$list = array();
|
||||
@@ -194,14 +191,14 @@ class BaseService
|
||||
$query.=" and (";
|
||||
}
|
||||
|
||||
$query.=$k." like ?";
|
||||
$query.=$k." = ?";
|
||||
|
||||
if ($i < $length -1) {
|
||||
$query.=" or ";
|
||||
} else {
|
||||
$query.=")";
|
||||
}
|
||||
$queryData[] = "%".$v[$i]."%";
|
||||
$queryData[] = $v[$i];
|
||||
}
|
||||
} else {
|
||||
if (!empty($v) && $v != 'NULL') {
|
||||
@@ -231,6 +228,132 @@ class BaseService
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function getDataCount()
|
||||
{
|
||||
//Get Total row count
|
||||
$totalRows = 0;
|
||||
|
||||
if (!isset($_REQUEST['objects'])) {
|
||||
$countFilterQuery = "";
|
||||
$countFilterQueryData = array();
|
||||
if (!empty($_REQUEST['ft'])) {
|
||||
$filter = json_decode($_REQUEST['ft']);
|
||||
if (!empty($filter)) {
|
||||
\Utils\LogManager::getInstance()->debug("Filter:" . print_r($filter, true));
|
||||
if (method_exists($obj, 'getCustomFilterQuery')) {
|
||||
$response = $obj->getCustomFilterQuery($filter);
|
||||
$countFilterQuery = $response[0];
|
||||
$countFilterQueryData = $response[1];
|
||||
} else {
|
||||
$defaultFilterResp = \Classes\BaseService::getInstance()->buildDefaultFilterQuery($filter);
|
||||
$countFilterQuery = $defaultFilterResp[0];
|
||||
$countFilterQueryData = $defaultFilterResp[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (in_array($table, \Classes\BaseService::getInstance()->userTables)
|
||||
&& !$skipProfileRestriction && !$isSubOrdinates) {
|
||||
$cemp = \Classes\BaseService::getInstance()->getCurrentProfileId();
|
||||
$sql = "Select count(id) as count from "
|
||||
. $obj->_table . " where " . SIGN_IN_ELEMENT_MAPPING_FIELD_NAME . " = ? " . $countFilterQuery;
|
||||
array_unshift($countFilterQueryData, $cemp);
|
||||
|
||||
$rowCount = $obj->DB()->Execute($sql, $countFilterQueryData);
|
||||
} else {
|
||||
if ($isSubOrdinates) {
|
||||
$cemp = \Classes\BaseService::getInstance()->getCurrentProfileId();
|
||||
$profileClass = \Classes\BaseService::getInstance()->getFullQualifiedModelClassName(
|
||||
ucfirst(SIGN_IN_ELEMENT_MAPPING_FIELD_NAME)
|
||||
);
|
||||
$subordinate = new $profileClass();
|
||||
$subordinates = $subordinate->Find("supervisor = ?", array($cemp));
|
||||
|
||||
$cempObj = new \Employees\Common\Model\Employee();
|
||||
$cempObj->Load("id = ?", array($cemp));
|
||||
|
||||
if ($obj->getUserOnlyMeAccessField() == 'id'
|
||||
&& \Classes\SettingsManager::getInstance()->getSetting(
|
||||
'System: Company Structure Managers Enabled'
|
||||
) == 1
|
||||
&& \Company\Common\Model\CompanyStructure::isHeadOfCompanyStructure($cempObj->department, $cemp)
|
||||
) {
|
||||
if (empty($subordinates)) {
|
||||
$subordinates = array();
|
||||
}
|
||||
|
||||
$childCompaniesIds = array();
|
||||
if (\Classes\SettingsManager::getInstance()->getSetting(
|
||||
'System: Child Company Structure Managers Enabled'
|
||||
) == '1'
|
||||
) {
|
||||
$childCompaniesResp = \Company\Common\Model\CompanyStructure::getAllChildCompanyStructures(
|
||||
$cempObj->department
|
||||
);
|
||||
$childCompanies = $childCompaniesResp->getObject();
|
||||
|
||||
foreach ($childCompanies as $cc) {
|
||||
$childCompaniesIds[] = $cc->id;
|
||||
}
|
||||
} else {
|
||||
$childCompaniesIds[] = $cempObj->department;
|
||||
}
|
||||
|
||||
if (!empty($childCompaniesIds)) {
|
||||
$childStructureSubordinates = $subordinate->Find(
|
||||
"department in (" . implode(',', $childCompaniesIds) . ") and id != ?",
|
||||
array($cemp)
|
||||
);
|
||||
$subordinates = array_merge($subordinates, $childStructureSubordinates);
|
||||
}
|
||||
}
|
||||
|
||||
$subordinatesIds = "";
|
||||
foreach ($subordinates as $sub) {
|
||||
if ($subordinatesIds != "") {
|
||||
$subordinatesIds .= ",";
|
||||
}
|
||||
$subordinatesIds .= $sub->id;
|
||||
}
|
||||
if ($obj->allowIndirectMapping()) {
|
||||
$indeirectEmployees = $subordinate->Find(
|
||||
"indirect_supervisors IS NOT NULL and indirect_supervisors <> '' and status = 'Active'",
|
||||
array()
|
||||
);
|
||||
foreach ($indeirectEmployees as $ie) {
|
||||
$indirectSupervisors = json_decode($ie->indirect_supervisors, true);
|
||||
if (in_array($cemp, $indirectSupervisors)) {
|
||||
if ($subordinatesIds != "") {
|
||||
$subordinatesIds .= ",";
|
||||
}
|
||||
$subordinatesIds .= $ie->id;
|
||||
}
|
||||
}
|
||||
}
|
||||
$sql = "Select count(id) as count from " . $obj->_table .
|
||||
" where " . $obj->getUserOnlyMeAccessField() . " in (" . $subordinatesIds . ") "
|
||||
. $countFilterQuery;
|
||||
$rowCount = $obj->DB()->Execute($sql, $countFilterQueryData);
|
||||
} else {
|
||||
$sql = "Select count(id) as count from " . $obj->_table;
|
||||
if (!empty($countFilterQuery)) {
|
||||
$sql .= " where 1=1 " . $countFilterQuery;
|
||||
}
|
||||
$rowCount = $obj->DB()->Execute($sql, $countFilterQueryData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($rowCount) && !empty($rowCount)) {
|
||||
foreach ($rowCount as $cnt) {
|
||||
$totalRows = $cnt['count'];
|
||||
}
|
||||
}
|
||||
|
||||
return $totalRows;
|
||||
}
|
||||
|
||||
/**
|
||||
* An extention of get method for the use of data tables with ability to search
|
||||
* @method getData
|
||||
@@ -545,7 +668,13 @@ class BaseService
|
||||
foreach ($map as $k => $v) {
|
||||
$fTable = $this->getFullQualifiedModelClassName($v[0]);
|
||||
$tObj = new $fTable();
|
||||
$tObj->Load($v[1]."= ?", array($item->$k));
|
||||
$tObj = $tObj->Find($v[1]."= ?", array($item->$k));
|
||||
|
||||
if (is_array($tObj)) {
|
||||
$tObj = $tObj[0];
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($tObj->{$v[1]} == $item->$k) {
|
||||
$v[2] = str_replace("+", " ", $v[2]);
|
||||
@@ -556,11 +685,11 @@ class BaseService
|
||||
$item->$k = $tObj->{$v[2]};
|
||||
} else {
|
||||
$objVal = "";
|
||||
foreach ($values as $v) {
|
||||
foreach ($values as $val2) {
|
||||
if ($objVal != "") {
|
||||
$objVal .= " ";
|
||||
}
|
||||
$objVal .= $tObj->$v;
|
||||
$objVal .= $tObj->$val2;
|
||||
}
|
||||
$idField = $k."_id";
|
||||
$item->$idField = $item->$k;
|
||||
@@ -629,12 +758,16 @@ class BaseService
|
||||
if (count($values) == 1) {
|
||||
return $targetObject->{$nameField};
|
||||
}
|
||||
$objVal = "";
|
||||
$objVal = '';
|
||||
foreach ($values as $value) {
|
||||
if ($objVal != "") {
|
||||
$objVal .= " ";
|
||||
}
|
||||
$objVal .= $targetObject->$value;
|
||||
if (substr($value, 0, 1) !== ':') {
|
||||
$objVal .= $targetObject->{$value};
|
||||
} else {
|
||||
$objVal .= substr($value, 1);
|
||||
}
|
||||
}
|
||||
|
||||
return $objVal;
|
||||
@@ -646,7 +779,9 @@ class BaseService
|
||||
* @param $table {String} model class name of the table to add data (e.g for Users table model class name is User)
|
||||
* @param $obj {Array} an associative array with field names and values for the new object.
|
||||
* If the object id is not empty an existing object will be updated
|
||||
* @return {Object} newly added or updated element of type $table
|
||||
* @param null $postObject
|
||||
* @return IceResponse {Object} newly added or updated element of type $table newly added or updated
|
||||
* element of type $table
|
||||
*/
|
||||
|
||||
public function addElement($table, $obj, $postObject = null)
|
||||
@@ -757,7 +892,6 @@ class BaseService
|
||||
}
|
||||
|
||||
$customFields = $ele->getCustomFields($obj);
|
||||
LogManager::getInstance()->error("Custom:".json_encode($customFields));
|
||||
foreach ($obj as $k => $v) {
|
||||
if (isset($customFields[$k])) {
|
||||
$this->customFieldManager->addCustomField($table, $ele->id, $k, $v);
|
||||
@@ -898,7 +1032,7 @@ class BaseService
|
||||
$list = $ele->$method(array());
|
||||
}
|
||||
} else {
|
||||
LogManager::getInstance()->debug("Could not find method:".$method." in Class:".$table);
|
||||
LogManager::getInstance()->error("Could not find method:".$method." in Class:".$table);
|
||||
$list = $ele->Find('1 = 1', array());
|
||||
}
|
||||
} else {
|
||||
@@ -1106,10 +1240,12 @@ class BaseService
|
||||
|
||||
public function cleanUpUser($obj)
|
||||
{
|
||||
$obj = $this->cleanUpAdoDB($obj);
|
||||
$obj = $this->cleanUpAll($obj);
|
||||
unset($obj->password);
|
||||
unset($obj->login_hash);
|
||||
unset($obj->googleUserData);
|
||||
unset($obj->wrong_password_count);
|
||||
unset($obj->last_wrong_attempt_at);
|
||||
|
||||
return $obj;
|
||||
}
|
||||
@@ -1137,14 +1273,12 @@ class BaseService
|
||||
|
||||
public function checkSecureAccess($type, $object, $table, $request)
|
||||
{
|
||||
$accessMatrix = array();
|
||||
|
||||
//Construct permission method
|
||||
$permMethod = "get".$this->currentUser->user_level."Access";
|
||||
$permMethod = "get".str_replace(' ', '', $this->currentUser->user_level)."Access";
|
||||
$userOnlyMeAccessRequestField = $object->getUserOnlyMeAccessRequestField();
|
||||
$userOnlyMeAccessField = $object->getUserOnlyMeAccessField();
|
||||
if (method_exists($object, $permMethod)) {
|
||||
$accessMatrix = $object->$permMethod();
|
||||
$accessMatrix = $object->$permMethod($this->currentUser->user_roles);
|
||||
} else {
|
||||
$accessMatrix = $object->getDefaultAccessLevel();
|
||||
}
|
||||
@@ -1174,7 +1308,7 @@ class BaseService
|
||||
// Employees should be able to update their own records
|
||||
if (!empty($table) && in_array($type, $accessMatrix)) {
|
||||
if (!empty($this->currentUser->$userOnlyMeAccessRequestField)
|
||||
&& in_array($table, $this->userTables) ) {
|
||||
&& in_array($table, $this->userTables)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1183,7 +1317,15 @@ class BaseService
|
||||
$ret['status'] = "ERROR";
|
||||
$ret['message'] = $type." ".get_class($object)." Access violation";
|
||||
echo json_encode($ret);
|
||||
exit();
|
||||
$exception = new \Exception(
|
||||
sprintf(
|
||||
'%s : %s',
|
||||
'Access violation',
|
||||
json_encode([$type, $table, get_class($object), $request, json_encode($this->currentUser)])
|
||||
)
|
||||
);
|
||||
LogManager::getInstance()->notifyException($exception);
|
||||
throw $exception;
|
||||
}
|
||||
|
||||
public function getInstanceId()
|
||||
@@ -1740,13 +1882,19 @@ END;
|
||||
if ($obj->$name != '') {
|
||||
$obj->$name .= ', ';
|
||||
}
|
||||
$tObj->Load($v[1] . "= ?", array($partialId));
|
||||
$obj->$name .= $this->getCombinedValue($v[2], $tObj);
|
||||
$tObjArr = $tObj->Find($v[1] . "= ?", [$partialId]);
|
||||
if (!is_array($tObjArr) || empty($tObjArr[0])) {
|
||||
continue;
|
||||
}
|
||||
$obj->$name .= $this->getCombinedValue($v[2], $tObjArr[0]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$tObj->Load($v[1] . "= ?", array($obj->$k));
|
||||
$obj->$name = $this->getCombinedValue($v[2], $tObj);
|
||||
$tObjArr = $tObj->Find($v[1] . "= ?", [$obj->$k]);
|
||||
if (!is_array($tObjArr) || empty($tObjArr[0])) {
|
||||
continue;
|
||||
}
|
||||
$obj->$name = $this->getCombinedValue($v[2], $tObjArr[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1767,4 +1915,25 @@ END;
|
||||
}
|
||||
return $obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return RedisCacheService
|
||||
*/
|
||||
public function getCacheService()
|
||||
{
|
||||
return $this->cacheService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CacheService $redisCacheService
|
||||
*/
|
||||
public function setCacheService($redisCacheService)
|
||||
{
|
||||
$this->cacheService = $redisCacheService;
|
||||
}
|
||||
|
||||
public function queryCacheEnabled()
|
||||
{
|
||||
return defined('QUERY_CACHE') && QUERY_CACHE === true;
|
||||
}
|
||||
}
|
||||
|
||||
12
core/src/Classes/CacheService.php
Normal file
12
core/src/Classes/CacheService.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace Classes;
|
||||
|
||||
interface CacheService
|
||||
{
|
||||
public function setDBQuery($entity, $query, $params, $result, $ttl = 600);
|
||||
|
||||
public function getDBQuery($entity, $query, $params);
|
||||
|
||||
public function deleteByEntity($entity);
|
||||
}
|
||||
@@ -42,7 +42,7 @@ class IceCron
|
||||
$time = intval($this->cron->time);
|
||||
|
||||
if (empty($frequency) || !is_int($frequency)) {
|
||||
LogManager::getInstance()->debug(
|
||||
LogManager::getInstance()->error(
|
||||
"Cron ".$this->cron->name." is not running since frequency is not an integer"
|
||||
);
|
||||
return false;
|
||||
|
||||
@@ -26,6 +26,7 @@ class EmailSenderTask implements IceTask
|
||||
$emailSender->sendEmailFromDB($email);
|
||||
} catch (\Exception $e) {
|
||||
LogManager::getInstance()->error("Error sending email:".$e->getMessage());
|
||||
LogManager::getInstance()->notifyException($e);
|
||||
}
|
||||
|
||||
$email->status = 'Sent';
|
||||
|
||||
64
core/src/Classes/Cron/Task/NewCandidateEmailTask.php
Normal file
64
core/src/Classes/Cron/Task/NewCandidateEmailTask.php
Normal file
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Classes\Cron\Task;
|
||||
|
||||
use Candidates\Admin\Api\CandidatesActionManager;
|
||||
use Candidates\Common\Email\CandidatesEmailSender;
|
||||
use Candidates\Common\Model\Candidate;
|
||||
use Classes\BaseService;
|
||||
use Classes\Cron\IceTask;
|
||||
use Employees\Common\Model\Employee;
|
||||
use JobPositions\Common\Model\Job;
|
||||
use Users\Common\Model\User;
|
||||
|
||||
class NewCandidateEmailTask implements IceTask
|
||||
{
|
||||
|
||||
public function execute($cron)
|
||||
{
|
||||
$candidate = new Candidate();
|
||||
$candidates = $candidate->Find('source = ? and emailSent = ?', [Candidate::SOURCE_APPLIED, 0]);
|
||||
foreach ($candidates as $candidate) {
|
||||
$job = new Job();
|
||||
$job->Load('id = ?', [$candidate->jobId]);
|
||||
|
||||
$candidateActionManager = new CandidatesActionManager();
|
||||
$candidateActionManager->setBaseService(BaseService::getInstance());
|
||||
$candidateEmailSender = new CandidatesEmailSender(
|
||||
BaseService::getInstance()->getEmailSender(),
|
||||
$candidateActionManager
|
||||
);
|
||||
|
||||
$candidate->emailSent = 1;
|
||||
$ok = $candidate->Save();
|
||||
|
||||
if (!$ok) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$candidateEmailSender->sendNewCandidateUserEmail($job->title, $candidate);
|
||||
|
||||
if (empty($job->hiringManager)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$manager = new Employee();
|
||||
$manager->Load('id = ?', [$job->hiringManager]);
|
||||
|
||||
$managerUser = new User();
|
||||
$managerUser->Load('employee = ?', [$manager->id]);
|
||||
|
||||
if (empty($managerUser->email)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$candidateEmailSender->sendNewCandidateManagerEmail(
|
||||
$job->title,
|
||||
$candidate,
|
||||
$manager->first_name,
|
||||
$managerUser->email
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
108
core/src/Classes/Cron/Task/RecruitmentEmailTask.php
Normal file
108
core/src/Classes/Cron/Task/RecruitmentEmailTask.php
Normal file
@@ -0,0 +1,108 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Classes\Cron\Task;
|
||||
|
||||
use Candidates\Admin\Api\CandidatesActionManager;
|
||||
use Candidates\Common\Email\CandidatesEmailSender;
|
||||
use Candidates\Common\Model\Candidate;
|
||||
use Candidates\Common\Model\Interview;
|
||||
use Classes\BaseService;
|
||||
use Classes\Cron\IceTask;
|
||||
use Employees\Common\Model\Employee;
|
||||
use JobPositions\Common\Model\Job;
|
||||
use Users\Common\Model\User;
|
||||
use Utils\LogManager;
|
||||
|
||||
class RecruitmentEmailTask implements IceTask
|
||||
{
|
||||
public function execute($cron)
|
||||
{
|
||||
$interview = new Interview();
|
||||
$interviews = $interview->Find('scheduleUpdated = ?', [1]);
|
||||
foreach ($interviews as $interview) {
|
||||
$job = new Job();
|
||||
$job->Load('id = ?', [$interview->job]);
|
||||
|
||||
$candidate = new Candidate();
|
||||
$candidate->Load('id = ?', [$interview->candidate]);
|
||||
|
||||
$manager = new Employee();
|
||||
$manager->Load('id = ?', [$job->hiringManager]);
|
||||
|
||||
$managerUser = new User();
|
||||
$managerUser->Load('employee = ?', [$manager->id]);
|
||||
|
||||
$candidateActionManager = new CandidatesActionManager();
|
||||
$candidateActionManager->setBaseService(BaseService::getInstance());
|
||||
$candidateEmailSender = new CandidatesEmailSender(
|
||||
BaseService::getInstance()->getEmailSender(),
|
||||
$candidateActionManager
|
||||
);
|
||||
|
||||
$interview->scheduleUpdated = 0;
|
||||
$ok = $interview->Save();
|
||||
|
||||
if (!$ok) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!empty($job->hiringManager)) {
|
||||
$manager = new Employee();
|
||||
$manager->Load('id = ?', [$job->hiringManager]);
|
||||
|
||||
$managerUser = new User();
|
||||
$managerUser->Load('employee = ?', [$manager->id]);
|
||||
|
||||
if (empty($managerUser->email)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$candidateEmailSender->interviewScheduledManagerEmail(
|
||||
$job->title,
|
||||
$candidate,
|
||||
$manager->first_name,
|
||||
$managerUser->email,
|
||||
$interview
|
||||
);
|
||||
}
|
||||
|
||||
if (empty($interview->interviewers)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$interviewerIds = null;
|
||||
try {
|
||||
$interviewerIds = json_decode($interview->interviewers, true);
|
||||
} catch (\Exception $e) {
|
||||
LogManager::getInstance()->notifyException($e);
|
||||
}
|
||||
|
||||
if (empty($interviewerIds) && !is_array($interviewerIds)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ($interviewerIds as $interviewerId) {
|
||||
$interviewer = new Employee();
|
||||
$interviewer->Load('id = ?', [$interviewerId]);
|
||||
|
||||
$interviewerUser = new User();
|
||||
$interviewerUser->Load('employee = ?', [$interviewer->id]);
|
||||
|
||||
if (empty($interviewerUser->email)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$candidateEmailSender->interviewScheduledInterviewerEmail(
|
||||
$job->title,
|
||||
$candidate,
|
||||
$manager->first_name,
|
||||
$managerUser->email,
|
||||
$interviewerUser->email,
|
||||
$interview,
|
||||
$interviewer
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -23,8 +23,7 @@ class Aes
|
||||
$Nr = count($w)/$Nb - 1; // no of rounds: 10/12/14 for 128/192/256-bit keys
|
||||
|
||||
$state = array(); // initialise 4xNb byte-array 'state' with input [<5B>3.4]
|
||||
for ($i = 0; $i<4*$Nb;
|
||||
$i++) {
|
||||
for ($i = 0; $i<4*$Nb; $i++) {
|
||||
$state[$i%4][floor($i/4)] = $input[$i];
|
||||
}
|
||||
|
||||
@@ -42,8 +41,7 @@ class Aes
|
||||
$state = self::addRoundKey($state, $w, $Nr, $Nb);
|
||||
|
||||
$output = array(4*$Nb); // convert state to 1-d array before returning [<5B>3.4]
|
||||
for ($i = 0; $i<4*$Nb;
|
||||
$i++) {
|
||||
for ($i = 0; $i<4*$Nb; $i++) {
|
||||
$output[$i] = $state[$i%4][floor($i/4)];
|
||||
}
|
||||
return $output;
|
||||
@@ -53,8 +51,7 @@ class Aes
|
||||
{
|
||||
// xor Round Key into state S [<5B>5.1.4]
|
||||
for ($r = 0; $r<4; $r++) {
|
||||
for ($c = 0; $c<$Nb;
|
||||
$c++) {
|
||||
for ($c = 0; $c<$Nb; $c++) {
|
||||
$state[$r][$c] ^= $w[$rnd*4+$c][$r];
|
||||
}
|
||||
}
|
||||
@@ -65,8 +62,7 @@ class Aes
|
||||
{
|
||||
// apply SBox to state S [<5B>5.1.1]
|
||||
for ($r = 0; $r<4; $r++) {
|
||||
for ($c = 0; $c<$Nb;
|
||||
$c++) {
|
||||
for ($c = 0; $c<$Nb; $c++) {
|
||||
$s[$r][$c] = self::$sBox[$s[$r][$c]];
|
||||
}
|
||||
}
|
||||
@@ -78,12 +74,10 @@ class Aes
|
||||
// shift row r of state S left by r bytes [<5B>5.1.2]
|
||||
$t = array(4);
|
||||
for ($r = 1; $r<4; $r++) {
|
||||
for ($c = 0; $c<4;
|
||||
$c++) {
|
||||
for ($c = 0; $c<4; $c++) {
|
||||
$t[$c] = $s[$r][($c+$r)%$Nb]; // shift into temp copy
|
||||
}
|
||||
for ($c = 0; $c<4;
|
||||
$c++) {
|
||||
for ($c = 0; $c<4; $c++) {
|
||||
$s[$r][$c] = $t[$c]; // and copy back
|
||||
}
|
||||
} // note that this will work for Nb=4,5,6, but not 7,8 (always 4 for AES):
|
||||
@@ -133,21 +127,18 @@ class Aes
|
||||
|
||||
for ($i = $Nk; $i<($Nb*($Nr+1)); $i++) {
|
||||
$w[$i] = array();
|
||||
for ($t = 0; $t<4;
|
||||
$t++) {
|
||||
for ($t = 0; $t<4; $t++) {
|
||||
$temp[$t] = $w[$i-1][$t];
|
||||
}
|
||||
if ($i % $Nk == 0) {
|
||||
$temp = self::subWord(self::rotWord($temp));
|
||||
for ($t = 0; $t<4;
|
||||
$t++) {
|
||||
for ($t = 0; $t<4; $t++) {
|
||||
$temp[$t] ^= self::$rCon[$i/$Nk][$t];
|
||||
}
|
||||
} elseif ($Nk > 6 && $i%$Nk == 4) {
|
||||
$temp = self::subWord($temp);
|
||||
}
|
||||
for ($t = 0; $t<4;
|
||||
$t++) {
|
||||
for ($t = 0; $t<4; $t++) {
|
||||
$w[$i][$t] = $w[$i-$Nk][$t] ^ $temp[$t];
|
||||
}
|
||||
}
|
||||
@@ -157,8 +148,7 @@ class Aes
|
||||
private static function subWord($w)
|
||||
{
|
||||
// apply SBox to 4-byte word w
|
||||
for ($i = 0; $i<4;
|
||||
$i++) {
|
||||
for ($i = 0; $i<4; $i++) {
|
||||
$w[$i] = self::$sBox[$w[$i]];
|
||||
}
|
||||
return $w;
|
||||
@@ -168,8 +158,7 @@ class Aes
|
||||
{
|
||||
// rotate 4-byte word w left by one byte
|
||||
$tmp = $w[0];
|
||||
for ($i = 0; $i<3;
|
||||
$i++) {
|
||||
for ($i = 0; $i<3; $i++) {
|
||||
$w[$i] = $w[$i+1];
|
||||
}
|
||||
$w[3] = $tmp;
|
||||
|
||||
@@ -32,8 +32,7 @@ class AesCtr extends Aes
|
||||
// key expansion) - gives us well encrypted key
|
||||
$nBytes = $nBits/8; // no bytes in key
|
||||
$pwBytes = array();
|
||||
for ($i = 0; $i<$nBytes;
|
||||
$i++) {
|
||||
for ($i = 0; $i<$nBytes; $i++) {
|
||||
$pwBytes[$i] = ord(substr($password, $i, 1)) & 0xff;
|
||||
}
|
||||
$key = Aes::cipher($pwBytes, Aes::keyExpansion($pwBytes));
|
||||
@@ -47,23 +46,19 @@ class AesCtr extends Aes
|
||||
$nonceSec = floor($nonce/1000);
|
||||
$nonceRnd = floor(rand(0, 0xffff));
|
||||
|
||||
for ($i = 0; $i<2;
|
||||
$i++) {
|
||||
for ($i = 0; $i<2; $i++) {
|
||||
$counterBlock[$i] = self::urs($nonceMs, $i*8) & 0xff;
|
||||
}
|
||||
for ($i = 0; $i<2;
|
||||
$i++) {
|
||||
for ($i = 0; $i<2; $i++) {
|
||||
$counterBlock[$i+2] = self::urs($nonceRnd, $i*8) & 0xff;
|
||||
}
|
||||
for ($i = 0; $i<4;
|
||||
$i++) {
|
||||
for ($i = 0; $i<4; $i++) {
|
||||
$counterBlock[$i+4] = self::urs($nonceSec, $i*8) & 0xff;
|
||||
}
|
||||
|
||||
// and convert it to a string to go on the front of the ciphertext
|
||||
$ctrTxt = '';
|
||||
for ($i = 0; $i<8;
|
||||
$i++) {
|
||||
for ($i = 0; $i<8; $i++) {
|
||||
$ctrTxt .= chr($counterBlock[$i]);
|
||||
}
|
||||
|
||||
@@ -77,12 +72,10 @@ class AesCtr extends Aes
|
||||
for ($b = 0; $b<$blockCount; $b++) {
|
||||
// set counter (block #) in last 8 bytes of counter block (leaving nonce in 1st 8 bytes)
|
||||
// done in two stages for 32-bit ops: using two words allows us to go past 2^32 blocks (68GB)
|
||||
for ($c = 0; $c<4;
|
||||
$c++) {
|
||||
for ($c = 0; $c<4; $c++) {
|
||||
$counterBlock[15-$c] = self::urs($b, $c*8) & 0xff;
|
||||
}
|
||||
for ($c = 0; $c<4;
|
||||
$c++) {
|
||||
for ($c = 0; $c<4; $c++) {
|
||||
$counterBlock[15-$c-4] = self::urs($b/0x100000000, $c*8);
|
||||
}
|
||||
|
||||
@@ -124,8 +117,7 @@ class AesCtr extends Aes
|
||||
// use AES to encrypt password (mirroring encrypt routine)
|
||||
$nBytes = $nBits/8; // no bytes in key
|
||||
$pwBytes = array();
|
||||
for ($i = 0; $i<$nBytes;
|
||||
$i++) {
|
||||
for ($i = 0; $i<$nBytes; $i++) {
|
||||
$pwBytes[$i] = ord(substr($password, $i, 1)) & 0xff;
|
||||
}
|
||||
$key = Aes::cipher($pwBytes, Aes::keyExpansion($pwBytes));
|
||||
@@ -134,8 +126,7 @@ class AesCtr extends Aes
|
||||
// recover nonce from 1st element of ciphertext
|
||||
$counterBlock = array();
|
||||
$ctrTxt = substr($ciphertext, 0, 8);
|
||||
for ($i = 0; $i<8;
|
||||
$i++) {
|
||||
for ($i = 0; $i<8; $i++) {
|
||||
$counterBlock[$i] = ord(substr($ctrTxt, $i, 1));
|
||||
}
|
||||
|
||||
@@ -145,8 +136,7 @@ class AesCtr extends Aes
|
||||
// separate ciphertext into blocks (skipping past initial 8 bytes)
|
||||
$nBlocks = ceil((strlen($ciphertext)-8) / $blockSize);
|
||||
$ct = array();
|
||||
for ($b = 0; $b<$nBlocks;
|
||||
$b++) {
|
||||
for ($b = 0; $b<$nBlocks; $b++) {
|
||||
$ct[$b] = substr($ciphertext, 8+$b*$blockSize, 16);
|
||||
}
|
||||
$ciphertext = $ct; // ciphertext is now array of block-length strings
|
||||
@@ -156,12 +146,10 @@ class AesCtr extends Aes
|
||||
|
||||
for ($b = 0; $b<$nBlocks; $b++) {
|
||||
// set counter (block #) in last 8 bytes of counter block (leaving nonce in 1st 8 bytes)
|
||||
for ($c = 0; $c<4;
|
||||
$c++) {
|
||||
for ($c = 0; $c<4; $c++) {
|
||||
$counterBlock[15-$c] = self::urs($b, $c*8) & 0xff;
|
||||
}
|
||||
for ($c = 0; $c<4;
|
||||
$c++) {
|
||||
for ($c = 0; $c<4; $c++) {
|
||||
$counterBlock[15-$c-4] = self::urs(($b+1)/0x100000000-1, $c*8) & 0xff;
|
||||
}
|
||||
|
||||
|
||||
@@ -14,8 +14,8 @@ class DataReader
|
||||
$sortData = $query->getSortingData();
|
||||
$data = \Classes\BaseService::getInstance()->getData(
|
||||
$table,
|
||||
$query->getFieldMapping(),
|
||||
json_encode($query->getFilters()),
|
||||
null,
|
||||
$query->getFilters(),
|
||||
$query->getOrderBy(),
|
||||
$sLimit,
|
||||
json_encode($query->getColumns()),
|
||||
|
||||
@@ -59,7 +59,7 @@ class DataQuery
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
* @return string
|
||||
*/
|
||||
public function getFieldMapping()
|
||||
{
|
||||
@@ -197,7 +197,7 @@ class DataQuery
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $fieldMapping
|
||||
* @param string $fieldMapping
|
||||
*/
|
||||
public function setFieldMapping($fieldMapping)
|
||||
{
|
||||
@@ -205,9 +205,9 @@ class DataQuery
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $filters
|
||||
* @param $filters
|
||||
*/
|
||||
public function setFilters(array $filters)
|
||||
public function setFilters($filters)
|
||||
{
|
||||
$this->filters = $filters;
|
||||
}
|
||||
@@ -229,9 +229,9 @@ class DataQuery
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $sortColumn
|
||||
* @param string $sortColumn
|
||||
*/
|
||||
public function setSortColumn(bool $sortColumn)
|
||||
public function setSortColumn($sortColumn)
|
||||
{
|
||||
$this->sortColumn = $sortColumn;
|
||||
}
|
||||
|
||||
97
core/src/Classes/DomainAwareInputCleaner.php
Normal file
97
core/src/Classes/DomainAwareInputCleaner.php
Normal file
@@ -0,0 +1,97 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Classes;
|
||||
|
||||
|
||||
class DomainAwareInputCleaner
|
||||
{
|
||||
public function cleanTableColumn($input)
|
||||
{
|
||||
if ($this->isEmpty($input) || $this->isValidColumnName($input)) {
|
||||
return $input;
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
public function cleanMapping($mapping)
|
||||
{
|
||||
return $mapping;
|
||||
}
|
||||
|
||||
public function cleanOrderBy($orderBy)
|
||||
{
|
||||
if (empty($orderBy)) {
|
||||
return $orderBy;
|
||||
}
|
||||
|
||||
$suffix = '';
|
||||
if (strstr($orderBy, ' desc')) {
|
||||
$suffix = ' desc';
|
||||
$orderBy = str_replace(' desc', '', $orderBy);
|
||||
}
|
||||
|
||||
if (!$this->cleanTableColumn($orderBy)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return $orderBy.$suffix;
|
||||
}
|
||||
|
||||
public function cleanColumns($columns)
|
||||
{
|
||||
if (empty($columns)) {
|
||||
return $columns;
|
||||
}
|
||||
|
||||
$columnData = json_decode($columns, true);
|
||||
|
||||
foreach ($columnData as $column) {
|
||||
if (!$this->isValidColumnName($column)) {
|
||||
return '[]';
|
||||
}
|
||||
}
|
||||
|
||||
return $columns;
|
||||
}
|
||||
|
||||
public function cleanFilters($filters)
|
||||
{
|
||||
if (empty($filters)) {
|
||||
return $filters;
|
||||
}
|
||||
|
||||
$filterData = json_decode($filters, true);
|
||||
foreach ($filterData as $name => $value) {
|
||||
if (!$this->isValidColumnName($name) || !$this->isValidFilterValue($value)) {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
return $filters;
|
||||
}
|
||||
|
||||
public function cleanSearch($searchTerm) {
|
||||
if (!$this->isValidFilterValue($searchTerm)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return $searchTerm;
|
||||
}
|
||||
|
||||
private function isEmpty($input)
|
||||
{
|
||||
return empty($input) || trim($input) === '';
|
||||
}
|
||||
|
||||
private function isValidColumnName($input)
|
||||
{
|
||||
return !!preg_match('/^[a-zA-Z_]+$/', $input);
|
||||
}
|
||||
|
||||
private function isValidFilterValue($input)
|
||||
{
|
||||
return !!preg_match('/^[-_: \p{L}]+$/u', $input);
|
||||
}
|
||||
}
|
||||
@@ -8,9 +8,10 @@
|
||||
|
||||
namespace Classes\Email;
|
||||
|
||||
use Classes\Crypt\AesCtr;
|
||||
use Classes\PasswordManager;
|
||||
use Classes\UIManager;
|
||||
use Employees\Common\Model\Employee;
|
||||
use Model\EmailLogEntry;
|
||||
use Model\IceEmail;
|
||||
use Users\Common\Model\User;
|
||||
use Utils\LogManager;
|
||||
@@ -145,7 +146,16 @@ abstract class EmailSender
|
||||
$emailBody = str_replace("#_".$k."_#", $v, $emailBody);
|
||||
}
|
||||
|
||||
return $this->sendMail($subject, $emailBody, $toEmail, $fromEmail, $user->email, $ccList, $bccList, APP_NAME);
|
||||
return $this->sendEmailWithLogging(
|
||||
$subject,
|
||||
$emailBody,
|
||||
$toEmail,
|
||||
$fromEmail,
|
||||
$user->email,
|
||||
$ccList,
|
||||
$bccList,
|
||||
APP_NAME
|
||||
);
|
||||
}
|
||||
|
||||
public function sendEmailWithoutWrap($subject, $toEmail, $template, $params, $ccList = array(), $bccList = array())
|
||||
@@ -181,7 +191,47 @@ abstract class EmailSender
|
||||
$emailBody = str_replace("#_".$k."_#", $v, $emailBody);
|
||||
}
|
||||
|
||||
$this->sendMail($subject, $emailBody, $toEmail, $fromEmail, $user->email, $ccList, $bccList);
|
||||
$this->sendEmailWithLogging($subject, $emailBody, $toEmail, $fromEmail, $user->email, $ccList, $bccList);
|
||||
}
|
||||
|
||||
protected function sendEmailWithLogging(
|
||||
$subject,
|
||||
$body,
|
||||
$toEmail,
|
||||
$fromEmail,
|
||||
$replyToEmail = null,
|
||||
$ccList = array(),
|
||||
$bccList = array(),
|
||||
$fromName = null
|
||||
) {
|
||||
$emailLogEntry = new EmailLogEntry();
|
||||
$emailLogEntry->subject = $subject;
|
||||
$emailLogEntry->toEmail = $toEmail;
|
||||
$emailLogEntry->body = $body;
|
||||
$emailLogEntry->cclist = implode(',', $ccList);
|
||||
$emailLogEntry->bcclist = implode(',', $bccList);
|
||||
$emailLogEntry->created = date('Y-m-d H:i:s');
|
||||
$emailLogEntry->updated = date('Y-m-d H:i:s');
|
||||
|
||||
$result = $this->sendMail(
|
||||
$subject,
|
||||
$body,
|
||||
$toEmail,
|
||||
$fromEmail,
|
||||
$replyToEmail,
|
||||
$ccList,
|
||||
$bccList,
|
||||
$fromName
|
||||
);
|
||||
|
||||
$emailLogEntry->status = $result ? 'Sent' : 'Failed';
|
||||
$ok = $emailLogEntry->Save();
|
||||
|
||||
if (!$ok) {
|
||||
LogManager::getInstance()->error('Error adding email log for '.json_encode([$toEmail, $subject, $body]));
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
abstract protected function sendMail(
|
||||
@@ -211,15 +261,8 @@ abstract class EmailSender
|
||||
//$params['user'] = $user->first_name." ".$user->last_name;
|
||||
$params['url'] = CLIENT_BASE_URL;
|
||||
|
||||
$newPassHash = array();
|
||||
$newPassHash["CLIENT_NAME"] = CLIENT_NAME;
|
||||
$newPassHash["oldpass"] = $user->password;
|
||||
$newPassHash["email"] = $user->email;
|
||||
$newPassHash["time"] = time();
|
||||
$json = json_encode($newPassHash);
|
||||
$encJson = PasswordManager::createPasswordRestKey($user);
|
||||
|
||||
$encJson = AesCtr::encrypt($json, $user->password, 256);
|
||||
$encJson = urlencode($user->id."-".$encJson);
|
||||
$params['passurl'] = CLIENT_BASE_URL."service.php?a=rsp&key=".$encJson;
|
||||
|
||||
$emailBody = file_get_contents(APP_BASE_PATH.'/templates/email/passwordReset.html');
|
||||
|
||||
@@ -51,10 +51,11 @@ class PHPMailer extends EmailSender
|
||||
}
|
||||
$headers .= 'ReplyTo: ' . $replyToEmail . "\r\n";
|
||||
$headers .= 'Ice-Mailer: PHP/' . phpversion();
|
||||
|
||||
|
||||
return mail($toEmail, $subject, $body, $headers);
|
||||
} catch (\Exception $e) {
|
||||
LogManager::getInstance()->error("Error sending email:" . $e->getMessage());
|
||||
LogManager::getInstance()->notifyException($e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,6 +83,7 @@ class SMTPEmailSender extends EmailSender
|
||||
return true;
|
||||
} catch (\Exception $e) {
|
||||
LogManager::getInstance()->error("Error sending email:" . $e->getMessage());
|
||||
LogManager::getInstance()->notifyException($e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,6 +77,7 @@ class SNSEmailSender extends EmailSender
|
||||
return true;
|
||||
} catch (\Exception $e) {
|
||||
LogManager::getInstance()->error("Error sending email:" . $e->getMessage());
|
||||
LogManager::getInstance()->notifyException($e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,6 +57,7 @@ class SwiftMailer extends EmailSender
|
||||
return $mailer->send($mail);
|
||||
} catch (\Exception $e) {
|
||||
LogManager::getInstance()->error("Error sending email:" . $e->getMessage());
|
||||
LogManager::getInstance()->notifyException($e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@ class FileService
|
||||
|
||||
return null;
|
||||
} catch (\Exception $e) {
|
||||
LogManager::getInstance()->notifyException($e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -51,6 +52,7 @@ class FileService
|
||||
}
|
||||
$this->memcache->set($key, $data, $expire);
|
||||
} catch (\Exception $e) {
|
||||
LogManager::getInstance()->notifyException($e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,6 +146,7 @@ class FileService
|
||||
$profile->image = $expireUrl;
|
||||
} catch (\Exception $e) {
|
||||
LogManager::getInstance()->error("Error generating profile image: ".$e->getMessage());
|
||||
LogManager::getInstance()->notifyException($e);
|
||||
if ($profile->gender == 'Female') {
|
||||
$profile->image = BASE_URL."images/user_female.png";
|
||||
} else {
|
||||
|
||||
@@ -49,7 +49,7 @@ class LDAPManager
|
||||
ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
|
||||
|
||||
// verify user and password
|
||||
$bind = @ldap_bind($ldap, $managerDN, $managerPassword);
|
||||
$bind = ldap_bind($ldap, $managerDN, $managerPassword);
|
||||
|
||||
LogManager::getInstance()->debug("LDAP Manager Bind:".print_r($bind, true));
|
||||
|
||||
@@ -60,6 +60,7 @@ class LDAPManager
|
||||
$result = ldap_search($ldap, $ldap_dn, $filter);
|
||||
LogManager::getInstance()->debug("LDAP Search Result:".print_r($result, true));
|
||||
if (!$result) {
|
||||
LogManager::getInstance()->error("Unable to search LDAP server");
|
||||
exit("Unable to search LDAP server");
|
||||
}
|
||||
$entries = ldap_get_entries($ldap, $result);
|
||||
|
||||
@@ -52,7 +52,6 @@ class LanguageManager
|
||||
$user = BaseService::getInstance()->getCurrentUser();
|
||||
if (empty($user) || empty($user->lang) || $user->lang == "NULL") {
|
||||
$lang = SettingsManager::getInstance()->getSetting('System: Language');
|
||||
LogManager::getInstance()->info("System Lang:".$lang);
|
||||
} else {
|
||||
$supportedLang = new SupportedLanguage();
|
||||
$supportedLang->Load("id = ?", array($user->lang));
|
||||
|
||||
@@ -41,6 +41,8 @@ class Macaw
|
||||
array_push(self::$routes, $uri);
|
||||
array_push(self::$methods, strtoupper($method));
|
||||
array_push(self::$callbacks, $callback);
|
||||
|
||||
return $uri;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
57
core/src/Classes/MemoryCacheService.php
Normal file
57
core/src/Classes/MemoryCacheService.php
Normal file
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
namespace Classes;
|
||||
|
||||
class MemoryCacheService implements CacheService
|
||||
{
|
||||
protected $appName = null;
|
||||
|
||||
protected $store = [];
|
||||
|
||||
public function __construct($appName)
|
||||
{
|
||||
$this->appName = $appName;
|
||||
}
|
||||
|
||||
protected function getAppKey($keyData)
|
||||
{
|
||||
return sprintf('%s-%s', $this->appName, implode('-', $keyData));
|
||||
}
|
||||
|
||||
|
||||
public function setDBQuery($entity, $query, $params, $result, $ttl = 600)
|
||||
{
|
||||
$this->store[$this->getAppKey($entity, $query, implode('-', $params))] = serialize($result);
|
||||
}
|
||||
|
||||
public function getDBQuery($entity, $query, $params)
|
||||
{
|
||||
|
||||
$data = $this->store[$this->getAppKey([$entity, $query, implode('-', $params)])];
|
||||
if (empty($data)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$data = unserialize($data);
|
||||
if (empty($data)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function deleteByEntity($entity)
|
||||
{
|
||||
$this->deleteByPrefix($entity.'-');
|
||||
$newStore = [];
|
||||
foreach ($this->store as $key => $val) {
|
||||
if (substr($key, 0, strlen($entity.'-')) === $entity.'-') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$newStore[$key] = $val;
|
||||
}
|
||||
|
||||
$this->store = $newStore;
|
||||
}
|
||||
}
|
||||
36
core/src/Classes/ModuleAccess.php
Normal file
36
core/src/Classes/ModuleAccess.php
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace Classes;
|
||||
|
||||
class ModuleAccess
|
||||
{
|
||||
protected $name;
|
||||
protected $group;
|
||||
|
||||
/**
|
||||
* ModuleAccess constructor.
|
||||
* @param $name
|
||||
* @param $group
|
||||
*/
|
||||
public function __construct($name, $group)
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->group = $group;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getGroup()
|
||||
{
|
||||
return $this->group;
|
||||
}
|
||||
}
|
||||
70
core/src/Classes/ModuleAccessService.php
Normal file
70
core/src/Classes/ModuleAccessService.php
Normal file
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
namespace Classes;
|
||||
|
||||
use Modules\Common\Model\Module;
|
||||
|
||||
class ModuleAccessService
|
||||
{
|
||||
protected $moduleMap = [];
|
||||
protected $moduleIdMap = [];
|
||||
|
||||
private static $me = null;
|
||||
|
||||
private function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
public static function getInstance()
|
||||
{
|
||||
if (empty(self::$me)) {
|
||||
self::$me = new ModuleAccessService();
|
||||
}
|
||||
|
||||
return self::$me;
|
||||
}
|
||||
|
||||
public function setModule($name, $group, $module)
|
||||
{
|
||||
$this->moduleMap[$group.'-'.$name] = $module;
|
||||
$this->moduleIdMap[$module->id] = $module;
|
||||
}
|
||||
|
||||
public function getModule($name, $group)
|
||||
{
|
||||
return $this->moduleMap[$group.'-'.$name];
|
||||
}
|
||||
|
||||
public function getModules()
|
||||
{
|
||||
return array_values($this->moduleMap);
|
||||
}
|
||||
|
||||
public function isModuleEnabledForUser($moduleId, $user)
|
||||
{
|
||||
$module = $this->moduleIdMap[$moduleId];
|
||||
$moduleUserLevels = json_decode($module->user_levels, true);
|
||||
$moduleUserRoles = json_decode($module->user_roles, true);
|
||||
$userRoles = json_decode($user->user_roles, true);
|
||||
|
||||
if (empty($moduleUserLevels)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (in_array($user->user_level, PermissionManager::RESTRICTED_USER_LEVELS)) {
|
||||
if (empty($userRoles)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$baseUserLevel = str_replace('Restricted ', '', $user->user_level);
|
||||
// In this case base user level should have access to the module
|
||||
if (!in_array($baseUserLevel, $moduleUserLevels)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return count(array_intersect($userRoles, $moduleUserRoles)) > 0;
|
||||
}
|
||||
|
||||
return in_array($user->user_level, $moduleUserLevels);
|
||||
}
|
||||
}
|
||||
138
core/src/Classes/PasswordManager.php
Normal file
138
core/src/Classes/PasswordManager.php
Normal file
@@ -0,0 +1,138 @@
|
||||
<?php
|
||||
|
||||
namespace Classes;
|
||||
|
||||
use Classes\Crypt\AesCtr;
|
||||
use Users\Common\Model\User;
|
||||
use Utils\CalendarTools;
|
||||
|
||||
class PasswordManager
|
||||
{
|
||||
public static function verifyPassword($password, $hash)
|
||||
{
|
||||
$result = password_verify($password, $hash);
|
||||
if ($result) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (strlen($hash) === 32) {
|
||||
return md5($password) === $hash;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function createPasswordHash($password)
|
||||
{
|
||||
return password_hash($password, PASSWORD_BCRYPT, ['cost' => 13]);
|
||||
}
|
||||
|
||||
public static function passwordChangeWaitingTimeMinutes($user)
|
||||
{
|
||||
if (empty($user->last_password_requested_at)) {
|
||||
$user->last_password_requested_at = date('Y-m-d H:i:s');
|
||||
$user->Save();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
$diff = CalendarTools::getTimeDiffInMinutes($user->last_password_requested_at, date('Y-m-d H:i:s'));
|
||||
if ($diff < 1) {
|
||||
return ceil($diff);
|
||||
}
|
||||
|
||||
$user->last_password_requested_at = date('Y-m-d H:i:s');
|
||||
$user->Save();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static function createPasswordRestKey($user)
|
||||
{
|
||||
$newPassHash = array();
|
||||
$newPassHash["client"] = CLIENT_NAME;
|
||||
$newPassHash["email"] = $user->email;
|
||||
$newPassHash["time"] = date('Y-m-d H:i:s');
|
||||
$json = json_encode($newPassHash);
|
||||
|
||||
$encJson = AesCtr::encrypt($json, $user->password, 256);
|
||||
|
||||
return urlencode(AesCtr::encrypt($user->id, APP_PASSWORD, 256).'-'.$encJson);
|
||||
}
|
||||
|
||||
public static function verifyPasswordRestKey($key)
|
||||
{
|
||||
$arr = explode("-", $key);
|
||||
$userId = AesCtr::decrypt($arr[0], APP_PASSWORD, 256);
|
||||
$user = new User();
|
||||
$user->Load("id = ?", array($userId));
|
||||
|
||||
if (empty($user->id)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
array_shift($arr);
|
||||
$data = AesCtr::decrypt(implode('', $arr), $user->password, 256);
|
||||
|
||||
if (empty($data)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$data = json_decode($data, true);
|
||||
|
||||
if (empty($data)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($data['client'] != CLIENT_NAME || $data['email'] != $user->email) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (CalendarTools::getTimeDiffInMinutes($data['time'], date('Y-m-d H:i:s')) < 30) {
|
||||
return $user;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function isQualifiedPassword($password)
|
||||
{
|
||||
if (strlen($password) < 8) {
|
||||
$error = "Password too short";
|
||||
|
||||
return new IceResponse(IceResponse::ERROR, $error);
|
||||
}
|
||||
|
||||
if (strlen($password) > 20) {
|
||||
$error = "Password too long";
|
||||
|
||||
return new IceResponse(IceResponse::ERROR, $error);
|
||||
}
|
||||
|
||||
if (!preg_match("#[0-9]+#", $password)) {
|
||||
$error = "Password must include at least one number";
|
||||
|
||||
return new IceResponse(IceResponse::ERROR, $error);
|
||||
}
|
||||
|
||||
if (!preg_match("#[a-z]+#", $password)) {
|
||||
$error = "Password must include at least one lowercase letter";
|
||||
|
||||
return new IceResponse(IceResponse::ERROR, $error);
|
||||
}
|
||||
|
||||
if (!preg_match("#[A-Z]+#", $password)) {
|
||||
$error = "Password must include at least one uppercase letter";
|
||||
|
||||
return new IceResponse(IceResponse::ERROR, $error);
|
||||
}
|
||||
|
||||
if (!preg_match("#\W+#", $password)) {
|
||||
$error = "Password must include at least one symbol";
|
||||
|
||||
return new IceResponse(IceResponse::ERROR, $error);
|
||||
}
|
||||
|
||||
return new IceResponse(IceResponse::SUCCESS);
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,13 @@ use Model\BaseModel;
|
||||
|
||||
class PermissionManager
|
||||
{
|
||||
const RESTRICTED_USER_LEVELS = ['Restricted Admin', 'Restricted Manager', 'Restricted Employee'];
|
||||
|
||||
public function isRestrictedUserLevel($userLevel)
|
||||
{
|
||||
return in_array($userLevel, self::RESTRICTED_USER_LEVELS);
|
||||
}
|
||||
|
||||
public static function manipulationAllowed($employeeId, BaseModel $object)
|
||||
{
|
||||
$subIds = self::getSubordinateIds($employeeId, $object->allowIndirectMapping());
|
||||
|
||||
106
core/src/Classes/RedisCacheService.php
Normal file
106
core/src/Classes/RedisCacheService.php
Normal file
@@ -0,0 +1,106 @@
|
||||
<?php
|
||||
|
||||
namespace Classes;
|
||||
|
||||
use Predis\Client;
|
||||
|
||||
class RedisCacheService implements CacheService
|
||||
{
|
||||
protected $client = null;
|
||||
protected $appName = null;
|
||||
|
||||
public function __construct($uri, $appName)
|
||||
{
|
||||
$this->uri = $uri;
|
||||
$this->appName = $appName;
|
||||
}
|
||||
|
||||
protected function getClient()
|
||||
{
|
||||
if ($this->client === null && !empty($this->uri)) {
|
||||
$this->client = new Client($this->uri);
|
||||
}
|
||||
|
||||
return $this->client;
|
||||
}
|
||||
|
||||
protected function getAppKey($keyData)
|
||||
{
|
||||
return sprintf('%s-%s', $this->appName, implode('-', $keyData));
|
||||
}
|
||||
|
||||
|
||||
public function setDBQuery($entity, $query, $params, $result, $ttl = 600)
|
||||
{
|
||||
/** @var Client $client */
|
||||
$client = $this->getClient();
|
||||
if ($client == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$client->set($this->getAppKey([$entity, $query, implode('-', $params)]), base64_encode(serialize($result)));
|
||||
$client->expire($this->getAppKey([$query, $params]), $ttl);
|
||||
}
|
||||
|
||||
public function getDBQuery($entity, $query, $params)
|
||||
{
|
||||
/** @var Client $client */
|
||||
$client = $this->getClient();
|
||||
if ($client == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$base64 = $client->get($this->getAppKey([$entity, $query, implode('-', $params)]));
|
||||
if (empty($base64)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$data = unserialize(base64_decode($base64));
|
||||
|
||||
if (empty($data)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function deleteDatabaseEntity($table, $id)
|
||||
{
|
||||
/** @var Client $client */
|
||||
$client = $this->getClient();
|
||||
if ($client == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$client->del([$this->getAppKey([$table, $id])]);
|
||||
}
|
||||
|
||||
public function deleteQuery($query)
|
||||
{
|
||||
/** @var Client $client */
|
||||
$client = $this->getClient();
|
||||
if ($client == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$client->del([$this->getAppKey([$query])]);
|
||||
}
|
||||
|
||||
protected function deleteByPrefix($prefix)
|
||||
{
|
||||
/** @var Client $client */
|
||||
$client = $this->getClient();
|
||||
if ($client == null) {
|
||||
return null;
|
||||
}
|
||||
$list = $client->keys($this->getAppKey([$prefix]).'*');
|
||||
if (!empty($list)) {
|
||||
$client->del($list);
|
||||
}
|
||||
}
|
||||
|
||||
public function deleteByEntity($entity)
|
||||
{
|
||||
$this->deleteByPrefix($entity.'-');
|
||||
}
|
||||
}
|
||||
@@ -5,11 +5,38 @@ use Classes\Data\DataReader;
|
||||
use Classes\Data\Query\DataQuery;
|
||||
use Classes\Upload\Uploader;
|
||||
use Employees\Common\Model\Employee;
|
||||
use Model\BaseModel;
|
||||
use Users\Common\Model\User;
|
||||
use Utils\SessionUtils;
|
||||
|
||||
class RestEndPoint
|
||||
{
|
||||
/*
|
||||
200
|
||||
GET/PUT
|
||||
Response entity details or list of entities.
|
||||
|
||||
201
|
||||
POST
|
||||
To create a new entity.
|
||||
|
||||
400
|
||||
GET/POST/PUT/DELETE
|
||||
Request payload and query params validation error
|
||||
|
||||
401
|
||||
GET/POST/PUT/DELETE
|
||||
Authentication error
|
||||
|
||||
403
|
||||
GET/POST/PUT/DELETE
|
||||
Authorization issue
|
||||
|
||||
404
|
||||
GET/POST/PUT/DELETE
|
||||
We don’t have the endpoint
|
||||
|
||||
*/
|
||||
const RESPONSE_ERR_ENTITY_NOT_FOUND = 'Entity not found';
|
||||
const RESPONSE_ERR_PERMISSION_DENIED = 'Permission denied';
|
||||
const RESPONSE_ERR_UNPROCESSABLE = 'Unprocessable Entity';
|
||||
@@ -19,6 +46,8 @@ class RestEndPoint
|
||||
|
||||
const ELEMENT_NAME = '';
|
||||
|
||||
protected $cachedObjects = [];
|
||||
|
||||
public function getModelObject($id)
|
||||
{
|
||||
return false;
|
||||
@@ -56,21 +85,38 @@ class RestEndPoint
|
||||
return new IceResponse(IceResponse::SUCCESS);
|
||||
}
|
||||
|
||||
public function process($type, $parameters = [])
|
||||
public function process($type, $parameters = [], $requireAccessToken = true)
|
||||
{
|
||||
if ($parameters === null) {
|
||||
$parameters = [];
|
||||
}
|
||||
|
||||
if (!is_array($parameters)) {
|
||||
$parameters = [$parameters];
|
||||
}
|
||||
$accessTokenValidation = $this->validateAccessToken();
|
||||
if (!empty($accessTokenValidation) && $accessTokenValidation->getStatus() == IceResponse::ERROR) {
|
||||
$resp = $accessTokenValidation;
|
||||
} else {
|
||||
|
||||
if ($requireAccessToken) {
|
||||
$accessTokenValidation = $this->validateAccessToken();
|
||||
if (!empty($accessTokenValidation) && $accessTokenValidation->getStatus() == IceResponse::ERROR) {
|
||||
$resp = $accessTokenValidation;
|
||||
|
||||
return $this->sendResponse($resp);
|
||||
}
|
||||
|
||||
BaseService::getInstance()->setCurrentUser($accessTokenValidation->getData());
|
||||
SessionUtils::saveSessionObject('user', $accessTokenValidation->getData());
|
||||
array_unshift($parameters, $accessTokenValidation->getData());
|
||||
$resp = call_user_func_array(array($this, $type), $parameters);
|
||||
} else {
|
||||
array_unshift($parameters, new User());
|
||||
}
|
||||
|
||||
$resp = call_user_func_array(array($this, $type), $parameters);
|
||||
|
||||
return $this->sendResponse($resp);
|
||||
}
|
||||
|
||||
protected function sendResponse($resp)
|
||||
{
|
||||
header('Content-Type: application/json');
|
||||
|
||||
if ($resp->getStatus() == IceResponse::SUCCESS && $resp->getCode() == null) {
|
||||
@@ -91,25 +137,64 @@ class RestEndPoint
|
||||
);
|
||||
$this->printResponse(array("error" => [$messages]));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param BaseModel $obj
|
||||
* @param $map
|
||||
* @return mixed
|
||||
*/
|
||||
protected function enrichElement($obj, $map)
|
||||
{
|
||||
if (!empty($map)) {
|
||||
foreach ($map as $k => $v) {
|
||||
if ($obj->$k !== null) {
|
||||
$obj->$k = [
|
||||
'type' => $v[0],
|
||||
$v[1] => $obj->$k,
|
||||
'display' => $obj->{$k . '_Name'}
|
||||
];
|
||||
} else {
|
||||
unset($obj->$k);
|
||||
}
|
||||
unset($obj->{$k . '_Name'});
|
||||
if (empty($map)) {
|
||||
return $obj;
|
||||
}
|
||||
|
||||
foreach ($map as $k => $v) {
|
||||
$fTable = BaseService::getInstance()->getFullQualifiedModelClassName($v[0]);
|
||||
$tObj = new $fTable();
|
||||
$tObjArr = $tObj->Find($v[1] . "= ?", [$obj->$k], true);
|
||||
if (!is_array($tObjArr) || empty($tObjArr[0])) {
|
||||
continue;
|
||||
}
|
||||
$obj->$k = [
|
||||
'type' => $v[0],
|
||||
$v[1] => $obj->$k,
|
||||
'display' => $this->getCombinedValue($v[2], $tObjArr[0])
|
||||
];
|
||||
}
|
||||
|
||||
return $obj;
|
||||
}
|
||||
|
||||
protected function enrichElements($items, $map)
|
||||
{
|
||||
return array_map(function ($item) use ($map) {
|
||||
return $this->enrichElement($item, $map);
|
||||
}, $items);
|
||||
}
|
||||
|
||||
protected function getCombinedValue($nameField, $targetObject)
|
||||
{
|
||||
$values = explode("+", $nameField);
|
||||
if (count($values) == 1) {
|
||||
return $targetObject->{$nameField};
|
||||
}
|
||||
$objVal = '';
|
||||
foreach ($values as $value) {
|
||||
if ($objVal != "") {
|
||||
$objVal .= " ";
|
||||
}
|
||||
if (substr($value, 0, 1) !== ':') {
|
||||
$objVal .= $targetObject->{$value};
|
||||
} else {
|
||||
$objVal .= substr($value, 1);
|
||||
}
|
||||
}
|
||||
return $obj;
|
||||
|
||||
return $objVal;
|
||||
}
|
||||
|
||||
protected function cleanObject($obj)
|
||||
@@ -164,6 +249,10 @@ class RestEndPoint
|
||||
$output = array();
|
||||
$columns = $query->getColumns();
|
||||
foreach ($data as $item) {
|
||||
if (!empty($query->getFieldMapping())) {
|
||||
$map = json_decode($query->getFieldMapping(), true);
|
||||
$item = $this->enrichElement($item, $map);
|
||||
}
|
||||
if (!empty($columns)) {
|
||||
$obj = new \stdClass();
|
||||
foreach ($columns as $column) {
|
||||
|
||||
@@ -37,6 +37,7 @@ class S3FileSystem
|
||||
));
|
||||
} catch (\Exception $e) {
|
||||
LogManager::getInstance()->error($e->getMessage());
|
||||
LogManager::getInstance()->error($e);
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -60,7 +61,8 @@ class S3FileSystem
|
||||
'Key' => $key
|
||||
));
|
||||
} catch (\Exception $e) {
|
||||
LogManager::getInstance()->info($e->getMessage());
|
||||
LogManager::getInstance()->error($e->getMessage());
|
||||
LogManager::getInstance()->notifyException($e);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -150,7 +150,7 @@ class UIManager
|
||||
}
|
||||
|
||||
$menuItems[] = new MenuItemTemplate('menuButtonNotification', array());
|
||||
if ($this->user->user_level == "Admin") {
|
||||
if ($this->user->user_level == 'Admin') {
|
||||
$menuItems[] = new MenuItemTemplate('menuButtonSwitchProfile', array());
|
||||
}
|
||||
|
||||
@@ -197,7 +197,7 @@ class UIManager
|
||||
));
|
||||
}
|
||||
|
||||
if ($this->user->user_level == "Admin") {
|
||||
if ($this->user->user_level == 'Admin') {
|
||||
$other = '';
|
||||
if (class_exists('\\Classes\\ProVersion')) {
|
||||
$pro = new ProVersion();
|
||||
|
||||
29
core/src/Classes/Upload/TempFile.php
Normal file
29
core/src/Classes/Upload/TempFile.php
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
namespace Classes\Upload;
|
||||
|
||||
class TempFile
|
||||
{
|
||||
protected $data;
|
||||
public function __construct($data)
|
||||
{
|
||||
$this->data = $data;
|
||||
}
|
||||
|
||||
public function save($path)
|
||||
{
|
||||
if (!move_uploaded_file($this->data['file']['tmp_name'], $path)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return $this->data['file']['name'];
|
||||
}
|
||||
|
||||
public function getSize()
|
||||
{
|
||||
return $this->data['file']['size'];
|
||||
}
|
||||
}
|
||||
159
core/src/Classes/Upload/Uploader.php
Normal file
159
core/src/Classes/Upload/Uploader.php
Normal file
@@ -0,0 +1,159 @@
|
||||
<?php
|
||||
namespace Classes\Upload;
|
||||
|
||||
use Classes\BaseService;
|
||||
use Classes\FileService;
|
||||
use Classes\IceResponse;
|
||||
use Classes\S3FileSystem;
|
||||
use Classes\SettingsManager;
|
||||
use Model\File;
|
||||
use Utils\LogManager;
|
||||
|
||||
class Uploader
|
||||
{
|
||||
private $allowedExtensions = array();
|
||||
private $sizeLimit = 10485760;
|
||||
|
||||
private $file;
|
||||
|
||||
public function __construct($file, array $allowedExtensions = array(), $sizeLimit = 10485760)
|
||||
{
|
||||
$allowedExtensions = array_map("strtolower", $allowedExtensions);
|
||||
$this->allowedExtensions = $allowedExtensions;
|
||||
$this->sizeLimit = $sizeLimit;
|
||||
$this->file = $file;
|
||||
}
|
||||
|
||||
|
||||
protected function handleUpload($uploadDirectory, $saveFileName, $replaceOldFile = false)
|
||||
{
|
||||
if (!is_writable($uploadDirectory)) {
|
||||
return new IceResponse(
|
||||
IceResponse::ERROR,
|
||||
"Server error. Upload directory ($uploadDirectory) is not writable"
|
||||
);
|
||||
}
|
||||
|
||||
if (!$this->file) {
|
||||
return new IceResponse(
|
||||
IceResponse::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 new IceResponse(
|
||||
IceResponse::ERROR,
|
||||
'File is empty'
|
||||
);
|
||||
}
|
||||
|
||||
if ($size > $this->sizeLimit) {
|
||||
return new IceResponse(
|
||||
IceResponse::ERROR,
|
||||
'File is too large'
|
||||
);
|
||||
}
|
||||
|
||||
$pathinfo = pathinfo($this->file->getName());
|
||||
$ext = $pathinfo['extension'];
|
||||
|
||||
if ($this->allowedExtensions && !in_array(strtolower($ext), $this->allowedExtensions)) {
|
||||
$these = implode(', ', $this->allowedExtensions);
|
||||
return new IceResponse(
|
||||
IceResponse::ERROR,
|
||||
'File has an invalid extension, it should be one of '. $these . '.'
|
||||
);
|
||||
}
|
||||
|
||||
$saveFileName = $saveFileName.'.'.strtolower($ext);
|
||||
|
||||
$finalFileLocation = $uploadDirectory . $saveFileName;
|
||||
|
||||
if ($this->file->save($finalFileLocation)) {
|
||||
$arr = explode("/", $finalFileLocation);
|
||||
return new IceResponse(
|
||||
IceResponse::SUCCESS,
|
||||
$arr[count($arr)-1]
|
||||
);
|
||||
//return array('success'=>1,'filename'=>$arr[count($arr)-1],'error'=>'');
|
||||
} else {
|
||||
return new IceResponse(
|
||||
IceResponse::ERROR,
|
||||
'The upload was cancelled, or server error encountered'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public static function upload($postData, $fileData)
|
||||
{
|
||||
//Generate File Name
|
||||
$saveFileName = $postData['file_name'];
|
||||
$saveFileName = str_replace("..", "", $saveFileName);
|
||||
$saveFileName = str_replace("/", "", $saveFileName);
|
||||
|
||||
if (stristr($saveFileName, ".php")) {
|
||||
$saveFileName = str_replace(".php", "", $saveFileName);
|
||||
}
|
||||
|
||||
if (empty($saveFileName) || $saveFileName == "_NEW_") {
|
||||
$saveFileName = microtime();
|
||||
$saveFileName = str_replace(".", "", $saveFileName);
|
||||
$saveFileName = str_replace(" ", "", $saveFileName);
|
||||
}
|
||||
|
||||
$file = new File();
|
||||
$file->Load("name = ?", array($saveFileName));
|
||||
|
||||
$allowedExtensions = explode(',', "csv,doc,xls,docx,xlsx,txt,ppt,pptx,rtf,pdf,xml,jpg,bmp,gif,png,jpeg");
|
||||
// max file size in bytes
|
||||
$sizeLimit =MAX_FILE_SIZE_KB * 1024;
|
||||
$uploader = new Uploader(new TempFile($fileData), $allowedExtensions, $sizeLimit);
|
||||
$result = $uploader->handleUpload(CLIENT_BASE_PATH.'data/', $saveFileName);
|
||||
|
||||
if ($result->getStatus() !== IceResponse::SUCCESS) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
$uploadFilesToS3 = SettingsManager::getInstance()->getSetting("Files: Upload Files to S3");
|
||||
$uploadFilesToS3Key = SettingsManager::getInstance()->getSetting("Files: Amazon S3 Key for File Upload");
|
||||
$uploadFilesToS3Secret = SettingsManager::getInstance()->getSetting(
|
||||
"Files: Amazone S3 Secret for File Upload"
|
||||
);
|
||||
$s3Bucket = SettingsManager::getInstance()->getSetting("Files: S3 Bucket");
|
||||
$s3WebUrl = SettingsManager::getInstance()->getSetting("Files: S3 Web Url");
|
||||
|
||||
$localFile = CLIENT_BASE_PATH.'data/'.$result->getData();
|
||||
$uploadedFileSize = filesize($localFile);
|
||||
if ($uploadFilesToS3.'' == '1' && !empty($uploadFilesToS3Key) && !empty($uploadFilesToS3Secret) &&
|
||||
!empty($s3Bucket) && !empty($s3WebUrl)) {
|
||||
$uploadName = CLIENT_NAME."/".$result->getData();
|
||||
LogManager::getInstance()->info("Upload file to s3:".$uploadName);
|
||||
LogManager::getInstance()->info("Local file:".$localFile);
|
||||
LogManager::getInstance()->info("Local file size:".$uploadedFileSize);
|
||||
|
||||
|
||||
$s3FileSys = new S3FileSystem($uploadFilesToS3Key, $uploadFilesToS3Secret);
|
||||
$res = $s3FileSys->putObject($s3Bucket, $uploadName, $localFile, 'authenticated-read');
|
||||
|
||||
LogManager::getInstance()->info("Response from s3 file sys:".print_r($res, true));
|
||||
unlink($localFile);
|
||||
}
|
||||
|
||||
$file->name = $saveFileName;
|
||||
$file->filename = $result->getData();
|
||||
$signInMappingField = SIGN_IN_ELEMENT_MAPPING_FIELD_NAME;
|
||||
$file->$signInMappingField = $postData['user']=="_NONE_"?null:$postData['user'];
|
||||
$file->file_group = $postData['file_group'];
|
||||
$file->size = $uploadedFileSize;
|
||||
$file->size_text = FileService::getInstance()->getReadableSize($uploadedFileSize);
|
||||
$file->Save();
|
||||
return new IceResponse(
|
||||
IceResponse::SUCCESS,
|
||||
$saveFileName
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user