Latest updates from IceHrmPro

This commit is contained in:
Thilina Pituwala
2020-05-20 18:47:29 +02:00
parent 60c92d7935
commit 7453a58aad
18012 changed files with 2089245 additions and 10173 deletions

View File

@@ -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;
}
}

View 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);
}

View File

@@ -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;

View File

@@ -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';

View 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
);
}
}
}

View 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
);
}
}
}
}

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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()),

View File

@@ -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;
}

View 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);
}
}

View File

@@ -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');

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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 {

View File

@@ -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);

View File

@@ -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));

View File

@@ -41,6 +41,8 @@ class Macaw
array_push(self::$routes, $uri);
array_push(self::$methods, strtoupper($method));
array_push(self::$callbacks, $callback);
return $uri;
}
/**

View 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;
}
}

View 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;
}
}

View 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);
}
}

View 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);
}
}

View File

@@ -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());

View 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.'-');
}
}

View File

@@ -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 dont 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) {

View File

@@ -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;
}

View File

@@ -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();

View 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'];
}
}

View 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
);
}
}