Upgrade to v26 (#172)

* A bunch of new updates from icehrm pro

* Push changes to frontend
This commit is contained in:
Thilina Hasantha
2019-02-03 14:00:34 +01:00
committed by GitHub
parent a75325fb52
commit 16014bb38e
734 changed files with 131230 additions and 17430 deletions

View File

@@ -18,7 +18,7 @@ along with Ice Framework. If not, see <http://www.gnu.org/licenses/>.
------------------------------------------------------------------
Original work Copyright (c) 2012 [Gamonoid Media Pvt. Ltd]
Developer: Thilina Hasantha (thilina.hasantha[at]gmail.com / facebook.com/thilinah)
Developer: Thilina Hasantha (http://lk.linkedin.com/in/thilinah | https://github.com/thilinah)
*/
namespace Classes;

View File

@@ -129,7 +129,7 @@ abstract class ApproveAdminActionManager extends ApproveCommonActionManager
$currentEmpId = $this->getCurrentProfileId();
if (!empty($currentEmpId)) {
$employee = $this->baseService->getElement('Employee', $currentEmpId);
$employee = $this->baseService->getElement('Employee', $currentEmpId, null, true);
$notificationMsg
= "Your $itemName has been $obj->status by ".$employee->first_name." ".$employee->last_name;
@@ -151,7 +151,9 @@ abstract class ApproveAdminActionManager extends ApproveCommonActionManager
if (!empty($sendApprovalEmailto)) {
$employee = $this->baseService->getElement(
'Employee',
BaseService::getInstance()->getCurrentProfileId()
BaseService::getInstance()->getCurrentProfileId(),
null,
true
);
$notificationMsg

View File

@@ -19,7 +19,7 @@ along with Ice Framework. If not, see <http://www.gnu.org/licenses/>.
------------------------------------------------------------------
Original work Copyright (c) 2012 [Gamonoid Media Pvt. Ltd]
Developer: Thilina Hasantha (thilina.hasantha[at]gmail.com / facebook.com/thilinah)
Developer: Thilina Hasantha (http://lk.linkedin.com/in/thilinah | https://github.com/thilinah)
*/
/**
@@ -1131,7 +1131,7 @@ class BaseService
if (in_array($type, $accessMatrix)) {
//The user has required permission, so return true
return true;
} else if (!empty($this->currentUser->$userOnlyMeAccessField)){
} elseif (!empty($this->currentUser->$userOnlyMeAccessField)) {
//Now we need to check whther the user has access to his own records
if ($this->isEmployeeSwitched()) {
$accessMatrix = $object->getUserOnlyMeSwitchedAccess();
@@ -1632,7 +1632,8 @@ END;
* @return string
* @throws \Exception
*/
public function safeJsonEncode($value, $options = 0, $depth = 512){
public function safeJsonEncode($value, $options = 0, $depth = 512)
{
$encoded = json_encode($value, $options, $depth);
switch (json_last_error()) {
case JSON_ERROR_NONE:
@@ -1653,22 +1654,24 @@ END;
}
}
protected function utf8ize($mixed) {
protected function utf8ize($mixed)
{
if (is_array($mixed)) {
foreach ($mixed as $key => $value) {
$mixed[$key] = $this->utf8ize($value);
}
} else if (is_object($mixed)) {
} elseif (is_object($mixed)) {
foreach ($mixed as $key => $value) {
$mixed->$key = $this->utf8ize($value);
}
} else if (is_string ($mixed)) {
} elseif (is_string($mixed)) {
return utf8_encode($mixed);
}
return $mixed;
}
public function generateCsrf($formId) {
public function generateCsrf($formId)
{
$csrfToken = sha1(rand(4500, 100000) . time(). CLIENT_BASE_URL. $this->currentUser->id);
SessionUtils::saveSessionObject('csrf-'.$formId, $csrfToken);
return $csrfToken;

View File

@@ -31,7 +31,6 @@ class IceCron
public function isRunNow()
{
LogManager::getInstance()->debug("Cron ".print_r($this->cron, true));
$lastRunTime = $this->cron->lastrun;
if (empty($lastRunTime)) {
LogManager::getInstance()->debug("Cron ".$this->cron->name." is running since last run time is empty");

View File

@@ -0,0 +1,140 @@
<?php
/**
* Created by PhpStorm.
* User: Thilina
* Date: 8/20/17
* Time: 1:31 PM
*/
namespace Classes\Cron\Task;
use Classes\SettingsManager;
use Documents\Common\Model\Document;
use Documents\Common\Model\EmployeeDocument;
use Employees\Common\Model\Employee;
use Utils\LogManager;
class DocumentExpiryNotificationTask extends EmailIceTask
{
protected $documentCache = array();
protected $notificationList = array();
protected $employeeDocList = array();
protected $employeeEmails = array();
public function execute($cron)
{
if (SettingsManager::getInstance()->getSetting('Notifications: Send Document Expiry Emails') != '1') {
LogManager::getInstance()->info(
"Notifications: Send Document Expiry Emails is set to No. Do not send emails"
);
return;
}
//Get documents
$dayList = array();
$dayList[30] = 'expire_notification_month';
$dayList[7] = 'expire_notification_week';
$dayList[1] = 'expire_notification_day';
$dayList[0] = 'expire_notification';
foreach ($dayList as $k => $v) {
$this->expiryDayNotification($k, $v);
}
$this->getExpireDocumentHTMLByEmployee();
$this->sendEmployeeEmails($this->employeeEmails, "IceHrm Employee Document Expiry Reminder");
}
private function expiryDayNotification($day, $param)
{
$date = date('Y-m-d', strtotime("+".$day." days"));
$employeeDocument = new EmployeeDocument();
$employeeDocuments = $employeeDocument->Find(
"valid_until IS NOT NULL and valid_until = ?
and (expire_notification_last > ? or expire_notification_last = -1) and status = ?",
array($date, $day, 'Active')
);
if (!$employeeDocuments) {
LogManager::getInstance()->error("Error :".$employeeDocument->ErrorMsg());
return;
}
$query = "valid_until IS NOT NULL and valid_until = $date and
(expire_notification_last > $day or expire_notification_last == -1)
and status = 'Active';";
LogManager::getInstance()->debug($query);
foreach ($employeeDocuments as $doc) {
LogManager::getInstance()->debug("Employee Doc :".print_r($doc, true));
if (empty($doc->document)) {
continue;
}
$document = null;
if (isset($this->documentCache[$doc->id])) {
$document = $this->documentCache[$doc->id];
} else {
$document = new Document();
$document->Load("id = ?", array($doc->document));
$this->documentCache[$document->id] = $document;
}
if ($document->$param == "Yes") {
if (!isset($this->notificationList[$doc->employee])) {
$this->notificationList[$doc->employee] = array();
}
$this->notificationList[$doc->employee][] = array($doc, $document, $day);
}
$doc->expire_notification_last = $day;
$doc->Save();
}
}
private function getExpireDocumentHTMLByEmployee()
{
$row = '<p style="background-color: #EEE;padding: 5px;font-size: 0.9em;font-weight: bold;">'
.'<span style="font-size: 1em;font-weight: bold;">'
.'#_name_#</span> - Expire in #_days_# day(s)</p><br/><span style="font-size: 0.8em;font-weight: bold;">'
.'#_description_#</span><hr/>';
foreach ($this->notificationList as $key => $val) {
$employeeEmail = "";
foreach ($val as $list) {
$trow = $row;
$doc = $list[0];
$document = $list[1];
$days = $list[2];
$trow = str_replace("#_name_#", $document->name, $trow);
$trow = str_replace("#_days_#", $days, $trow);
$trow = str_replace("#_description_#", $doc->details, $trow);
$employeeEmail.=$trow;
}
$employee = new Employee();
$employee->Load("id = ?", array($key));
if (empty($employee->id) || $employee->id != $key) {
LogManager::getInstance()->error("Could not load employee with id");
return;
}
$emailBody = file_get_contents(
APP_BASE_PATH.'/admin/documents/emailTemplates/documentExpireEmailTemplate.html'
);
$emailBody = str_replace("#_employee_#", $employee->first_name, $emailBody);
$emailBody = str_replace("#_documents_#", $employeeEmail, $emailBody);
$this->employeeEmails[$employee->id] = $emailBody;
}
}
}

View File

@@ -0,0 +1,29 @@
<?php
namespace Classes\Data;
use Classes\Data\Query\DataQuery;
class DataReader
{
public static function getData(DataQuery $query)
{
$table = $query->getTable();
$sLimit = " LIMIT " . intval($query->getStartPage()) . ", " . intval($query->getLength());
$sortData = $query->getSortingData();
$data = \Classes\BaseService::getInstance()->getData(
$table,
$query->getFieldMapping(),
json_encode($query->getFilters()),
$query->getOrderBy(),
$sLimit,
json_encode($query->getColumns()),
$query->getSearchTerm(),
$query->isIsSubOrdinates(),
$query->isSkipProfileRestriction(),
$sortData
);
return $data;
}
}

View File

@@ -0,0 +1,262 @@
<?php
namespace Classes\Data\Query;
class DataQuery
{
protected $table;
protected $columns = [];
protected $fieldMapping;
protected $filters = null;
protected $startPage = 0;
protected $length = 15;
protected $isSubOrdinates = false;
protected $skipProfileRestriction = false;
protected $sortingEnabled = false;
protected $sortColumn;
protected $sortOrder = '';
protected $searchTerm = null;
protected $isLengthSet = false;
protected $orderBy = null;
/**
* DataQuery constructor.
* @param $table
* @param bool $sortingEnabled
* @param $sortColumn
* @param string $sortOrder
*/
public function __construct($table, $sortingEnabled = false, $sortColumn = false, $sortOrder = '', $orderBy = null)
{
$this->table = $table;
$this->sortingEnabled = $sortingEnabled;
$this->sortColumn = $sortColumn;
$this->sortOrder = $sortOrder;
$this->orderBy = $orderBy;
}
public function addColumn($column)
{
$this->columns[] = $column;
return $this;
}
public function addFilter($filter)
{
if ($this->filters === null) {
$this->filters = new \stdClass();
}
$this->filters->{$filter->getName()} = $filter->getValue();
return $this;
}
/**
* @return array
*/
public function getColumns()
{
return $this->columns;
}
/**
* @return array
*/
public function getFieldMapping()
{
return $this->fieldMapping;
}
/**
* @return array
*/
public function getFilters()
{
return $this->filters;
}
/**
* @return int
*/
public function getStartPage()
{
return $this->startPage;
}
/**
* @return int
*/
public function getLength()
{
return $this->length;
}
/**
* @return string
*/
public function getSearchTerm()
{
return $this->searchTerm;
}
/**
* @param string $searchTerm
*/
public function setSearchTerm($searchTerm)
{
$this->searchTerm = $searchTerm;
}
/**
* @return boolean
*/
public function isIsSubOrdinates()
{
return $this->isSubOrdinates;
}
/**
* @return boolean
*/
public function isSkipProfileRestriction()
{
return $this->skipProfileRestriction;
}
/**
* @return mixed
*/
public function getTable()
{
return $this->table;
}
public function getSortingData()
{
$data = array();
$data['sorting'] = $this->sortingEnabled ? '1' : '0';
if (!$this->sortingEnabled) {
return $data;
}
$data['column'] = $this->sortColumn;
$data['order'] = $this->sortOrder;
return $data;
}
/**
* @param int $length
*/
public function setLength($length)
{
$this->length = $length;
if ($length > 0) {
$this->isLengthSet = true;
}
}
/**
* @param int $startPage
*/
public function setStartPage($startPage)
{
$this->startPage = $startPage;
}
/**
* @param boolean $isSubOrdinates
*/
public function setIsSubOrdinates($isSubOrdinates)
{
$this->isSubOrdinates = $isSubOrdinates;
}
/**
* @return bool
*/
public function isLengthSet(): bool
{
return $this->isLengthSet;
}
/**
* @param mixed $table
*/
public function setTable($table)
{
$this->table = $table;
}
/**
* @param array $columns
*/
public function setColumns(array $columns)
{
$this->columns = $columns;
}
/**
* @param array $fieldMapping
*/
public function setFieldMapping($fieldMapping)
{
$this->fieldMapping = $fieldMapping;
}
/**
* @param array $filters
*/
public function setFilters(array $filters)
{
$this->filters = $filters;
}
/**
* @param bool $skipProfileRestriction
*/
public function setSkipProfileRestriction(bool $skipProfileRestriction)
{
$this->skipProfileRestriction = $skipProfileRestriction;
}
/**
* @param bool $sortingEnabled
*/
public function setSortingEnabled(bool $sortingEnabled)
{
$this->sortingEnabled = $sortingEnabled;
}
/**
* @param bool $sortColumn
*/
public function setSortColumn(bool $sortColumn)
{
$this->sortColumn = $sortColumn;
}
/**
* @param string $sortOrder
*/
public function setSortOrder(string $sortOrder)
{
$this->sortOrder = $sortOrder;
}
/**
* @return null
*/
public function getOrderBy()
{
return $this->orderBy;
}
/**
* @param null $orderBy
*/
public function setOrderBy($orderBy)
{
$this->orderBy = $orderBy;
}
}

View File

@@ -0,0 +1,39 @@
<?php
namespace Classes\Data\Query;
class FieldMapping implements \JsonSerializable
{
protected $class;
protected $idField;
protected $nameField;
/**
* FieldMapping constructor.
* @param $class
* @param $idField
* @param $nameField
*/
public function __construct($class, $idField, $nameField)
{
$this->class = $class;
$this->idField = $idField;
$this->nameField = $nameField;
}
/**
* Specify data which should be serialized to JSON
* @link http://php.net/manual/en/jsonserializable.jsonserialize.php
* @return mixed data which can be serialized by <b>json_encode</b>,
* which is a value of any type other than a resource.
* @since 5.4.0
*/
public function jsonSerialize()
{
return [
$this->class,
$this->idField,
$this->nameField,
];
}
}

View File

@@ -0,0 +1,51 @@
<?php
namespace Classes\Data\Query;
class Filter
{
private $name;
private $value;
/**
* Filter constructor.
* @param $name
* @param $value
*/
public function __construct($name, $value)
{
$this->name = $name;
$this->value = $value;
}
/**
* @return mixed
*/
public function getName()
{
return $this->name;
}
/**
* @param mixed $name
*/
public function setName($name)
{
$this->name = $name;
}
/**
* @return mixed
*/
public function getValue()
{
return $this->value;
}
/**
* @param mixed $value
*/
public function setValue($value)
{
$this->value = $value;
}
}

View File

@@ -11,7 +11,9 @@ namespace Classes\Email;
use Classes\Crypt\AesCtr;
use Classes\UIManager;
use Employees\Common\Model\Employee;
use Model\IceEmail;
use Users\Common\Model\User;
use Utils\LogManager;
abstract class EmailSender
{
@@ -22,7 +24,7 @@ abstract class EmailSender
$this->settings = $settings;
}
public function sendEmailFromNotification($notification)
public function sendEmailFromNotification($notification, $delayed = false)
{
$toEmail = null;
$user = new User();
@@ -44,17 +46,50 @@ abstract class EmailSender
if ($action->type == "url") {
$emailBody = str_replace("#_url_#", CLIENT_BASE_URL."?".$action->url, $emailBody);
}
$this->sendEmail(
'IceHrm Notification from '.$notification->type,
$user->email,
$emailBody,
array(),
array(),
array()
);
if ($delayed) {
$this->sendEmailDelayed(
'IceHrm Notification from '.$notification->type,
$user->email,
$emailBody,
array(),
array(),
array()
);
} else {
$this->sendEmail(
'IceHrm Notification from '.$notification->type,
$user->email,
$emailBody,
array(),
array(),
array()
);
}
}
}
public function sendEmailDelayed($subject, $toEmail, $template, $params, $ccList = array(), $bccList = array())
{
$email = new IceEmail();
$email->subject = $subject;
$email->toEmail = $toEmail;
$email->template = $template;
$email->params = json_encode($params);
$email->cclist = json_encode($ccList);
$email->bcclist = json_encode($bccList);
$email->status = 'Pending';
$email->created = date('Y-m-d H:i:s');
$email->updated = date('Y-m-d H:i:s');
$ok = $email->Save();
if (!$ok) {
LogManager::getInstance()->error("Error Saving Email: ".$email->ErrorMsg());
return false;
}
return true;
}
public function sendEmailFromDB($email)
{
$params = array();

View File

@@ -18,7 +18,7 @@ along with Ice Framework. If not, see <http://www.gnu.org/licenses/>.
------------------------------------------------------------------
Original work Copyright (c) 2012 [Gamonoid Media Pvt. Ltd]
Developer: Thilina Hasantha (thilina.hasantha[at]gmail.com / facebook.com/thilinah)
Developer: Thilina Hasantha (http://lk.linkedin.com/in/thilinah | https://github.com/thilinah)
*/
namespace Classes;
@@ -171,6 +171,8 @@ class FileService
$profile->image = BASE_URL."images/user_male.png";
}
}
} elseif (substr($file->filename, 0, 8) === 'https://') {
$profile->image = $file->filename;
} else {
$profile->image = CLIENT_BASE_URL.'data/'.$file->filename;
}
@@ -210,6 +212,8 @@ class FileService
}
$profile->image = $expireUrl;
} elseif (substr($file->filename, 0, 8) === 'https://') {
$profile->image = $file->filename;
} else {
$profile->image = CLIENT_BASE_URL.'data/'.$file->filename;
}
@@ -224,7 +228,7 @@ class FileService
return $profile;
}
public function getFileUrl($fileName, $isExpiring = true)
public function getFileUrl($fileName, $isExpiring = true)
{
$file = new File();
$file->Load('name = ?', array($fileName));

View File

@@ -30,7 +30,7 @@ class NotificationManager
if ($employee->id === $fromEmployee) {
continue;
}
$this->addNotification($employee->id, $message, $action, $type, $toUserId, $fromSystem, $sendEmail);
$this->addNotification($employee->id, $message, $action, $type, $toUserId, $fromSystem, $sendEmail, true);
}
}
@@ -41,7 +41,8 @@ class NotificationManager
$type,
$toUserId = null,
$fromSystem = false,
$sendEmail = false
$sendEmail = false,
$isEmailDelayed = false
) {
@@ -108,7 +109,7 @@ class NotificationManager
} elseif ($sendEmail) {
$emailSender = BaseService::getInstance()->getEmailSender();
if (!empty($emailSender)) {
$emailSender->sendEmailFromNotification($noti);
$emailSender->sendEmailFromNotification($noti, $isEmailDelayed);
}
}
}

View File

@@ -0,0 +1,46 @@
<?php
/**
* Created by PhpStorm.
* User: Thilina
* Date: 11/3/17
* Time: 4:11 PM
*/
namespace Classes;
use Company\Common\Model\CompanyStructure;
use Employees\Common\Model\Employee;
use Model\BaseModel;
class PermissionManager
{
public static function manipulationAllowed($employeeId, BaseModel $object)
{
$subIds = self::getSubordinateIds($employeeId, $object->allowIndirectMapping());
if ($object->table === 'Employees') {
return in_array($object->id, $subIds);
}
return in_array($object->employee, $subIds);
}
private static function getSubordinateIds($employeeId, $addIndirect)
{
$subIds = [$employeeId];
$employee = new Employee();
$list = $employee->Find("supervisor = ?", array($employeeId));
foreach ($list as $emp) {
$subIds[] = $emp->id;
}
if ($addIndirect) {
$list = $employee->Find("indirect_supervisors like ?", array('%\"'.$employeeId.'\"%'));
foreach ($list as $emp) {
$subIds[] = $emp->id;
}
}
return $subIds;
}
}

View File

@@ -120,6 +120,7 @@ class RestEndPoint
unset($obj->historyUpdateList);
unset($obj->oldObjOrig);
unset($obj->oldObj);
unset($obj->_org);
return $obj;
}
@@ -147,9 +148,13 @@ class RestEndPoint
$page = intval($_GET['page']);
}
$limit = static::DEFAULT_LIMIT;
if (isset($_GET['limit']) && intval($_GET['limit']) > 0) {
$limit = intval($_GET['limit']);
if (!$query->isLengthSet()) {
$limit = static::DEFAULT_LIMIT;
if (isset($_GET['limit']) && intval($_GET['limit']) > 0) {
$limit = intval($_GET['limit']);
}
} else {
$limit = $query->getLength();
}
$query->setStartPage(($page - 1) * $limit);

View File

@@ -18,7 +18,7 @@ along with Ice Framework. If not, see <http://www.gnu.org/licenses/>.
------------------------------------------------------------------
Original work Copyright (c) 2012 [Gamonoid Media Pvt. Ltd]
Developer: Thilina Hasantha (thilina.hasantha[at]gmail.com / facebook.com/thilinah)
Developer: Thilina Hasantha (http://lk.linkedin.com/in/thilinah | https://github.com/thilinah)
*/
namespace Classes;

View File

@@ -21,6 +21,8 @@ class UIManager
protected $quickAccessMenuItems = [];
protected $languageMenuItems = [];
protected $currentLanguageCode = '';
private function __construct()
{
}
@@ -164,6 +166,8 @@ class UIManager
"CURRENT_CODE" => $this->getCountryCodeByLanguage($language)
)
);
$this->currentLanguageCode = $this->getCountryCodeByLanguage($language);
}
}
@@ -263,6 +267,10 @@ class UIManager
$currentCountryCode = 'cn';
} elseif ($currentLanguage === 'ja') {
$currentCountryCode = 'jp';
} elseif ($currentLanguage === 'sr') {
$currentCountryCode = 'rs';
} elseif ($currentLanguage === 'sv') {
$currentCountryCode = 'se';
}
return $currentCountryCode;
@@ -299,4 +307,12 @@ class UIManager
return $logoFileName;
}
/**
* @return string
*/
public function getCurrentLanguageCode()
{
return $this->currentLanguageCode;
}
}