Merged in release/3.7.7 (pull request #8551)

release/3.7.7

Approved-by: Julio Cesar Laura Avendaño
This commit is contained in:
Paula Quispe
2022-09-05 16:46:50 +00:00
committed by Julio Cesar Laura Avendaño
49 changed files with 2311 additions and 1004 deletions

View File

@@ -65,7 +65,8 @@
"aws/aws-sdk-php": "~3.0",
"cretueusebiu/laravel-javascript": "^0.2.1",
"stevenmaguire/oauth2-microsoft": "^2.2",
"phpseclib/mcrypt_compat": "^2.0"
"phpseclib/mcrypt_compat": "^2.0",
"microsoft/microsoft-graph": "^1.7"
},
"require-dev": {
"guzzlehttp/guzzle": "^6.3",
@@ -128,5 +129,11 @@
"bootstrap/classaliasmap.php"
]
}
},
"config": {
"allow-plugins": {
"kylekatarnls/update-helper": true,
"typo3/class-alias-loader": true
}
}
}

2030
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -12,9 +12,7 @@
ref="table"
>
<div slot="actions" slot-scope="props">
<div @mouseover="updateDataEllipsis(props.row)">
<ellipsis v-if="dataEllipsis" :data="dataEllipsis"> </ellipsis>
</div>
<ellipsis :data="updateDataEllipsis(props.row)"> </ellipsis>
</div>
<div slot="owner" slot-scope="props">
<OwnerCell :data="props.row.owner" />
@@ -46,10 +44,6 @@ export default {
},
data() {
return {
dataEllipsis: {
buttons: {}
},
showEllipsis: false,
newList: {
title: this.$i18n.t("New List"),
class: "btn-success",
@@ -278,9 +272,8 @@ export default {
*/
updateDataEllipsis(data) {
let that = this;
this.showEllipsis = !this.showEllipsis;
if (this.showEllipsis) {
this.dataEllipsis = {
return {
APP_UID: data.id,
buttons: {
note: {
name: "edit",
@@ -314,7 +307,6 @@ export default {
}
}
}
}
},
importCustomCaseList() {
this.$refs["modal-import"].show();
@@ -323,6 +315,9 @@ export default {
};
</script>
<style>
.VueTables__row {
height: 75px;
}
.float-right {
padding-left: 1.5%;
}

View File

@@ -33,6 +33,7 @@
{{ $t("ID_BY_PROCESS_NAME") }}
</b-form-checkbox>
<b-form-checkbox
v-if="!(title === $t('ID_DRAFT'))"
id="checkbox-3"
v-model="byReviewStatus"
name="checkbox-3"

View File

@@ -26,6 +26,7 @@
>
</b-form-checkbox-group>
<b-form-checkbox
v-if="!(title === $t('ID_DRAFT'))"
id="checkbox-review-status"
v-model="byReviewStatus"
name="checkbox-review"

View File

@@ -45,6 +45,9 @@ export default {
]
};
},
created() {
this.selected = this.filter[0].value;
},
methods: {
/**
* On Ok event handler

View File

@@ -1,5 +1,14 @@
<template>
<div>
<div
class="ellipsis-button align-middle"
v-show="!showActions"
@mouseenter="showActionButtons"
>
<span>
<i class="fas fa-ellipsis-v"></i>
</span>
</div>
<div class="float-right" v-show="showActions">
<transition name="fade">
<div
@@ -21,19 +30,11 @@
</div>
</transition>
</div>
<div
class="ellipsis-button align-middle"
v-show="!showActions"
@mouseover="showActionButtons"
>
<span>
<i class="fas fa-ellipsis-v"></i>
</span>
</div>
</div>
</template>
<script>
import eventBus from "./../../home/EventBus/eventBus"
export default {
name: "Ellipsis",
props: {
@@ -44,7 +45,16 @@ export default {
showActions: false
}
},
mounted () {},
mounted () {
eventBus.$on('closeEllipsis', this.hideActionButtons);
},
deactivated () {
eventBus.$off('closeEllipsis', this.hideActionButtons);
},
destroyed () {
eventBus.$off('closeEllipsis', this.hideActionButtons);
},
methods: {
/**
* Callback function from parent
@@ -63,6 +73,7 @@ export default {
this.showActions = true;
if (this.showActions) {
if (this.$parent.Row !== undefined) {
eventBus.$emit('closeEllipsis', this.data);
for (i = 0; i < this.$parent.$parent.$parent.$children.length -1 ; i++){
this.$parent.$parent.$parent.$children[i].$el.style.opacity = 0.15
}
@@ -82,16 +93,20 @@ export default {
},
/**
* Hide action buttons
* @param {object} dataE
*/
hideActionButtons() {
hideActionButtons(dataE) {
var i,
elelemts;
this.showActions = false;
if (this.$parent.Row !== undefined) {
if (this.data.APP_UID !== dataE.APP_UID) {
this.showActions = false;
for (i = 0; i < this.$parent.$parent.$parent.$children.length -1 ; i++){
this.$parent.$parent.$parent.$children[i].$el.style.opacity = 1
}
}
} else if (this.$parent.item !== undefined) {
this.showActions = false;
if (this.$parent.$parent.$parent.$refs.vueListView !== undefined) {
elelemts = this.$parent.$el.getElementsByClassName('col-sm-5');
elelemts[0].style.opacity = 1;
@@ -124,6 +139,7 @@ export default {
z-index: 999;
display: inline-flex !important;
opacity: 1 !important;
height: 50px !important;
}
.btn-outline-info {
border: none;

View File

@@ -662,6 +662,9 @@ export default {
};
</script>
<style>
.VueTables__row {
height: 75px;
}
.VuePagination__count {
display: none;
}

View File

@@ -128,13 +128,7 @@
slot="actions"
slot-scope="props"
>
<div @mouseover="updateDataEllipsis(props.row)">
<ellipsis
v-if="dataEllipsis"
:data="dataEllipsis"
>
</ellipsis>
</div>
<ellipsis :data="updateDataEllipsis(props.row)"> </ellipsis>
</div>
</v-server-table>
<VueCardView
@@ -159,12 +153,7 @@
</div>
</b-col>
<b-col sm="12">
<div @mouseover="updateDataEllipsis(props.item)">
<ellipsis
v-if="dataEllipsis"
:data="dataEllipsis">
</ellipsis>
</div>
<ellipsis class="ellipsis-container" :data="updateDataEllipsis(props.item)"> </ellipsis>
</b-col>
</b-row>
</b-col>
@@ -222,9 +211,7 @@
</div>
</b-col>
<b-col sm="12">
<div class="ellipsis-container" @mouseover="updateDataEllipsis(props.item)">
<ellipsis v-if="dataEllipsis" :data="dataEllipsis"> </ellipsis>
</div>
<ellipsis class="ellipsis-container" :data="updateDataEllipsis(props.item)"> </ellipsis>
</b-col>
</b-row>
</div>
@@ -445,10 +432,6 @@ export default {
PAUSED: this.$i18n.t("ID_PAUSED"),
UNASSIGNED: this.$i18n.t("ID_UNASSIGNED"),
},
dataEllipsis: {
buttons: {},
},
showEllipsis: false,
dataSubtitle: {
subtitle: this.data.pageName,
icon: this.data.pageIcon,
@@ -868,7 +851,7 @@ export default {
}
}
that.headings[item.field] = item.name;
if(item.enableFilter){
if(item.set){
columns.push(item.field);
}
});
@@ -1152,10 +1135,7 @@ export default {
* @param {objec} data
*/
updateDataEllipsis(data) {
this.showEllipsis = !this.showEllipsis;
if (this.showEllipsis) {
this.dataEllipsis = this.ellipsisItemFactory(data, this.data.pageParent);
}
return this.ellipsisItemFactory(data, this.data.pageParent);
},
/**
* Show the alert message
@@ -1220,6 +1200,7 @@ export default {
let that = this;
let dataEllipsisMap = {
inbox: {
APP_UID: data.APP_UID,
buttons: {
open: {
name: "open",
@@ -1252,6 +1233,7 @@ export default {
},
},
draft: {
APP_UID: data.APP_UID,
buttons: {
open: {
name: "open",
@@ -1270,6 +1252,7 @@ export default {
}
},
paused: {
APP_UID: data.APP_UID,
buttons: {
note: {
name: "case note",
@@ -1295,6 +1278,7 @@ export default {
}
},
unassigned: {
APP_UID: data.APP_UID,
buttons: {
note: {
name: "case note",
@@ -1334,6 +1318,9 @@ export default {
};
</script>
<style>
.VueTables__row {
height: 75px;
}
.v-container-todo {
padding-top: 20px;
padding-bottom: 20px;

View File

@@ -96,9 +96,7 @@
slot="actions"
slot-scope="props"
>
<div @mouseover="updateDataEllipsis(props.row)">
<ellipsis v-if="dataEllipsis" :data="dataEllipsis"> </ellipsis>
</div>
<ellipsis :data="updateDataEllipsis(props.row)"> </ellipsis>
</div>
</v-server-table>
<VueCardView
@@ -118,9 +116,7 @@
</div>
</b-col>
<b-col sm="12">
<div class="ellipsis-container" @mouseover="updateDataEllipsis(props.item)">
<ellipsis v-if="dataEllipsis" :data="dataEllipsis"> </ellipsis>
</div>
<ellipsis class="ellipsis-container" :data="updateDataEllipsis(props.item)"> </ellipsis>
</b-col>
</b-row>
</div>
@@ -249,9 +245,7 @@
</div>
</b-col>
<b-col sm="12">
<div class="ellipsis-container" @mouseover="updateDataEllipsis(props.item)">
<ellipsis v-if="dataEllipsis" :data="dataEllipsis"> </ellipsis>
</div>
<ellipsis class="ellipsis-container" :data="updateDataEllipsis(props.item)"> </ellipsis>
</b-col>
</b-row>
</div>
@@ -502,10 +496,6 @@ export default {
"PAUSED": this.$i18n.t("ID_PAUSED"),
"UNASSIGNED": this.$i18n.t("ID_UNASSIGNED")
},
dataEllipsis: {
buttons: {}
},
showEllipsis: false,
dataSubtitle: null,
hiddenItems: ['bySendBy']
};
@@ -808,9 +798,8 @@ export default {
*/
updateDataEllipsis(data) {
let that = this;
this.showEllipsis = !this.showEllipsis;
if (this.showEllipsis) {
this.dataEllipsis = {
return {
APP_UID: data.APP_UID,
buttons: {
open: {
name: "open",
@@ -828,7 +817,6 @@ export default {
},
}
}
}
},
/**
* Show the alert message
@@ -884,6 +872,9 @@ export default {
};
</script>
<style>
.VueTables__row {
height: 75px;
}
.v-container-draft {
padding-top: 20px;
padding-bottom: 20px;

View File

@@ -119,9 +119,7 @@
slot="actions"
slot-scope="props"
>
<div @mouseover="updateDataEllipsis(props.row)">
<ellipsis v-if="dataEllipsis" :data="dataEllipsis"> </ellipsis>
</div>
<ellipsis :data="updateDataEllipsis(props.row)"> </ellipsis>
</div>
</v-server-table>
<VueCardView
@@ -141,9 +139,7 @@
</div>
</b-col>
<b-col sm="12">
<div class="ellipsis-container" @mouseover="updateDataEllipsis(props.item)">
<ellipsis v-if="dataEllipsis" :data="dataEllipsis"> </ellipsis>
</div>
<ellipsis class="ellipsis-container" :data="updateDataEllipsis(props.item)"> </ellipsis>
</b-col>
</b-row>
</div>
@@ -285,9 +281,7 @@
</div>
</b-col>
<b-col sm="12">
<div class="ellipsis-container" @mouseover="updateDataEllipsis(props.item)">
<ellipsis v-if="dataEllipsis" :data="dataEllipsis"> </ellipsis>
</div>
<ellipsis class="ellipsis-container" :data="updateDataEllipsis(props.item)"> </ellipsis>
</b-col>
</b-row>
</div>
@@ -564,10 +558,6 @@ export default {
PAUSED: this.$i18n.t("ID_PAUSED"),
UNASSIGNED: this.$i18n.t("ID_UNASSIGNED"),
},
dataEllipsis: {
buttons: {}
},
showEllipsis: false,
dataSubtitle: null,
};
},
@@ -934,9 +924,8 @@ export default {
*/
updateDataEllipsis(data) {
let that = this;
this.showEllipsis = !this.showEllipsis;
if (this.showEllipsis) {
this.dataEllipsis = {
return {
APP_UID: data.APP_UID,
buttons: {
open: {
name: "open",
@@ -968,7 +957,6 @@ export default {
}
}
}
}
},
/**
* Show the alert message
@@ -1024,6 +1012,9 @@ export default {
};
</script>
<style>
.VueTables__row {
height: 75px;
}
.v-container-todo {
padding-top: 20px;
padding-bottom: 20px;

View File

@@ -796,15 +796,13 @@ export default {
};
</script>
<style>
.VueTables__row {
height: 75px;
}
.v-container-mycases {
padding-top: 20px;
padding-bottom: 20px;
padding-left: 50px;
padding-right: 50px;
}
/*.btn-clear-sort {
position: fixed;
margin-top: 16px;
margin-left: -11px;
}*/
</style>

View File

@@ -118,9 +118,7 @@
slot="actions"
slot-scope="props"
>
<div @mouseover="updateDataEllipsis(props.row)">
<ellipsis v-if="dataEllipsis" :data="dataEllipsis"> </ellipsis>
</div>
<ellipsis :data="updateDataEllipsis(props.row)"> </ellipsis>
</div>
</v-server-table>
<VueCardView
@@ -140,9 +138,7 @@
</div>
</b-col>
<b-col sm="12">
<div class="ellipsis-container" @mouseover="updateDataEllipsis(props.item)">
<ellipsis v-if="dataEllipsis" :data="dataEllipsis"> </ellipsis>
</div>
<ellipsis class="ellipsis-container" :data="updateDataEllipsis(props.item)"> </ellipsis>
</b-col>
</b-row>
</div>
@@ -267,9 +263,7 @@
</div>
</b-col>
<b-col sm="12">
<div class="ellipsis-container" @mouseover="updateDataEllipsis(props.item)">
<ellipsis v-if="dataEllipsis" :data="dataEllipsis"> </ellipsis>
</div>
<ellipsis class="ellipsis-container" :data="updateDataEllipsis(props.item)"> </ellipsis>
</b-col>
</b-row>
</div>
@@ -530,10 +524,6 @@ export default {
"PAUSED": this.$i18n.t("ID_PAUSED"),
"UNASSIGNED": this.$i18n.t("ID_UNASSIGNED")
},
dataEllipsis: {
buttons: {}
},
showEllipsis: false,
dataSubtitle: null
};
},
@@ -890,9 +880,8 @@ export default {
*/
updateDataEllipsis(data) {
let that = this;
this.showEllipsis = !this.showEllipsis;
if (this.showEllipsis) {
this.dataEllipsis = {
return {
APP_UID: data.APP_UID,
buttons: {
note: {
name: "case note",
@@ -917,7 +906,6 @@ export default {
}
}
}
}
},
/**
* Show the alert message
@@ -973,6 +961,9 @@ export default {
};
</script>
<style>
.VueTables__row {
height: 75px;
}
.v-container-paused {
padding-top: 20px;
padding-bottom: 20px;

View File

@@ -107,9 +107,7 @@
slot="actions"
slot-scope="props"
>
<div @mouseover="updateDataEllipsis(props.row)">
<ellipsis v-if="dataEllipsis" :data="dataEllipsis"> </ellipsis>
</div>
<ellipsis :data="updateDataEllipsis(props.row)"> </ellipsis>
</div>
</v-server-table>
<VueCardView
@@ -129,9 +127,7 @@
</div>
</b-col>
<b-col sm="12">
<div class="ellipsis-container" @mouseover="updateDataEllipsis(props.item)">
<ellipsis v-if="dataEllipsis" :data="dataEllipsis"> </ellipsis>
</div>
<ellipsis class="ellipsis-container" :data="updateDataEllipsis(props.item)"> </ellipsis>
</b-col>
</b-row>
</div>
@@ -273,9 +269,7 @@
</div>
</b-col>
<b-col sm="12">
<div class="ellipsis-container" @mouseover="updateDataEllipsis(props.item)">
<ellipsis v-if="dataEllipsis" :data="dataEllipsis"> </ellipsis>
</div>
<ellipsis class="ellipsis-container" :data="updateDataEllipsis(props.item)"> </ellipsis>
</b-col>
</b-row>
</div>
@@ -549,10 +543,6 @@ export default {
"PAUSED": this.$i18n.t("ID_PAUSED"),
"UNASSIGNED": this.$i18n.t("ID_UNASSIGNED")
},
dataEllipsis: {
buttons: {}
},
showEllipsis: false,
dataSubtitle: null
};
},
@@ -881,9 +871,8 @@ export default {
*/
updateDataEllipsis(data) {
let that = this;
this.showEllipsis = !this.showEllipsis;
if (this.showEllipsis) {
this.dataEllipsis = {
return {
APP_UID: data.APP_UID,
buttons: {
note: {
name: "case note",
@@ -901,7 +890,6 @@ export default {
}
}
}
}
},
/**
* Show the alert message
@@ -957,6 +945,9 @@ export default {
};
</script>
<style>
.VueTables__row {
height: 75px;
}
.v-container-unassigned {
padding-top: 20px;
padding-bottom: 20px;

View File

@@ -50,7 +50,7 @@ class PMFNewUserTest extends TestCase
public function it_should_test_the_pmfnewuser_function()
{
global $RBAC;
$user = User::where('USR_ID', '=', 1)->get()->first();
$user = User::where('USR_ID', '=', 1)->first();
$_SESSION['USER_LOGGED'] = $user['USR_UID'];
$RBAC = RBAC::getSingleton(PATH_DATA, session_id());
$RBAC->initRBAC();

View File

@@ -706,7 +706,7 @@ class ReportTablesTest extends TestCase
$proUid = $result->processUid;
$grid = '';
$app = Application::where('APP_UID', '=', $result->applicationUid)->get()->first();
$app = Application::where('APP_UID', '=', $result->applicationUid)->first();
$appData = unserialize($app->APP_DATA);
unset($appData['var_Textarea1']);
$appData = serialize($appData);
@@ -742,7 +742,7 @@ class ReportTablesTest extends TestCase
$proUid = $result->processUid;
$grid = '';
$app = Application::where('APP_UID', '=', $result->applicationUid)->get()->first();
$app = Application::where('APP_UID', '=', $result->applicationUid)->first();
$appData = unserialize($app->APP_DATA);
$appData['var_Textarea1'] = [];
$appData = serialize($appData);
@@ -779,7 +779,7 @@ class ReportTablesTest extends TestCase
$proUid = $result->processUid;
$grid = 'var_Grid1';
$app = Application::where('APP_UID', '=', $result->applicationUid)->get()->first();
$app = Application::where('APP_UID', '=', $result->applicationUid)->first();
$appData = unserialize($app->APP_DATA);
unset($appData['var_Grid1'][1]['var_Textarea1']);
$appData = serialize($appData);
@@ -897,7 +897,7 @@ class ReportTablesTest extends TestCase
$proUid = $result->processUid;
$grid = 'var_Grid1';
$app = Application::where('APP_UID', '=', $result->applicationUid)->get()->first();
$app = Application::where('APP_UID', '=', $result->applicationUid)->first();
$appData = unserialize($app->APP_DATA);
$appData['var_Textarea1'] = [];
$appData = serialize($appData);

View File

@@ -1005,7 +1005,7 @@ class WsBaseTest extends TestCase
{
// Definition for avoid the error: Trying to get property 'aUserInfo' of non-object in the action buildAppDelayRow()
global $RBAC;
$user = User::where('USR_ID', '=', 1)->get()->first();
$user = User::where('USR_ID', '=', 1)->first();
$_SESSION['USER_LOGGED'] = $user['USR_UID'];
$RBAC = RBAC::getSingleton(PATH_DATA, session_id());
$RBAC->initRBAC();
@@ -1067,7 +1067,7 @@ class WsBaseTest extends TestCase
{
// Definition for avoid the error: Trying to get property 'aUserInfo' of non-object in the action buildAppDelayRow()
global $RBAC;
$user = User::where('USR_ID', '=', 1)->get()->first();
$user = User::where('USR_ID', '=', 1)->first();
$_SESSION['USER_LOGGED'] = $user['USR_UID'];
$RBAC = RBAC::getSingleton(PATH_DATA, session_id());
$RBAC->initRBAC();

View File

@@ -139,7 +139,6 @@ class AppNotesTest extends TestCase
public function it_should_test_send_note_notification_without_user()
{
$user = User::where('USR_UID', '=', '00000000000000000000000000000001')
->get()
->first();
$application = factory(Application::class)->create();
$delegation = factory(Delegation::class)->create([
@@ -159,7 +158,7 @@ class AppNotesTest extends TestCase
$appNotes->sendNoteNotification(...$params);
//assert
$appMessage = AppMessage::where('APP_UID', '=', $application->APP_UID)->get()->first()->toArray();
$appMessage = AppMessage::where('APP_UID', '=', $application->APP_UID)->first()->toArray();
$this->assertArrayHasKey('APP_UID', $appMessage);
$this->assertEquals($appMessage['APP_UID'], $application->APP_UID);
}
@@ -172,7 +171,6 @@ class AppNotesTest extends TestCase
public function it_should_test_send_note_notification_with_attach_files()
{
$user = User::where('USR_UID', '=', '00000000000000000000000000000001')
->get()
->first();
$application = factory(Application::class)->create();
$delegation = factory(Delegation::class)->create([
@@ -200,7 +198,7 @@ class AppNotesTest extends TestCase
$appNotes->sendNoteNotification(...$params);
//assert
$appMessage = AppMessage::where('APP_UID', '=', $application->APP_UID)->get()->first()->toArray();
$appMessage = AppMessage::where('APP_UID', '=', $application->APP_UID)->first()->toArray();
$this->assertArrayHasKey('APP_UID', $appMessage);
$this->assertEquals($appMessage['APP_UID'], $application->APP_UID);
}

View File

@@ -35,7 +35,7 @@ class CasesMenuHighlightTest extends TestCase
{
global $RBAC;
$this->user = User::where('USR_ID', '=', 1)->get()->first();
$this->user = User::where('USR_ID', '=', 1)->first();
$_SESSION['USER_LOGGED'] = $this->user['USR_UID'];

View File

@@ -61,7 +61,7 @@ class EmailServerTest extends TestCase
private function loadUserSession()
{
global $RBAC;
$user = User::where('USR_ID', '=', 1)->get()->first();
$user = User::where('USR_ID', '=', 1)->first();
$_SESSION['USER_LOGGED'] = $user['USR_UID'];
$RBAC = RBAC::getSingleton(PATH_DATA, session_id());
$RBAC->initRBAC();

View File

@@ -41,7 +41,7 @@ class CasesTraitTest extends TestCase
*/
private function prepareDerivationData()
{
$user = User::where('USR_ID', '=', 1)->get()->first();
$user = User::where('USR_ID', '=', 1)->first();
$process = factory(Process::class)->create([
'PRO_CREATE_USER' => $user->USR_UID
@@ -176,7 +176,7 @@ class CasesTraitTest extends TestCase
$cases = new Cases();
$cases->routeCase($processUid, $application, $postForm, $status, $flagGmail, $tasUid, $index, $userLogged);
$result = Delegation::where('APP_UID', '=', $application)->where('DEL_INDEX', '=', $index)->get()->first();
$result = Delegation::where('APP_UID', '=', $application)->where('DEL_INDEX', '=', $index)->first();
$this->assertEquals('CLOSED', $result->DEL_THREAD_STATUS);
}
@@ -231,7 +231,7 @@ class CasesTraitTest extends TestCase
$cases = new Cases();
$cases->routeCase($processUid, $appUid, $postForm, $status, $flagGmail, $tasUid, $index, $userLogged);
$result = Delegation::where('APP_UID', '=', $appUid)->where('DEL_INDEX', '=', $index)->get()->first();
$result = Delegation::where('APP_UID', '=', $appUid)->where('DEL_INDEX', '=', $index)->first();
$this->assertEquals('CLOSED', $result->DEL_THREAD_STATUS);
}
@@ -302,7 +302,7 @@ class CasesTraitTest extends TestCase
*/
public function it_should_verify_if_abe_is_completed()
{
$user = User::where('USR_ID', '=', 1)->get()->first();
$user = User::where('USR_ID', '=', 1)->first();
$process = factory(Process::class)->create([
'PRO_CREATE_USER' => $user->USR_UID

View File

@@ -147,7 +147,7 @@ class GmailOAuthTest extends TestCase
public function it_should_create_email_server()
{
global $RBAC;
$user = User::where('USR_ID', '=', 1)->get()->first();
$user = User::where('USR_ID', '=', 1)->first();
$_SESSION['USER_LOGGED'] = $user['USR_UID'];
$RBAC = RBAC::getSingleton(PATH_DATA, session_id());
$RBAC->initRBAC();

View File

@@ -42,7 +42,7 @@ class ServerTest extends TestCase
*/
public function it_should_test_post_token_with_valid_credentials()
{
$user = User::where('USR_ID', '=', 1)->get()->first();
$user = User::where('USR_ID', '=', 1)->first();
$oauthClients = factory(OauthClients::class)->create([
"USR_UID" => $user->USR_UID
]);
@@ -80,7 +80,7 @@ class ServerTest extends TestCase
*/
public function it_should_test_post_token_with_return_handle_token()
{
$user = User::where('USR_ID', '=', 1)->get()->first();
$user = User::where('USR_ID', '=', 1)->first();
$oauthClients = factory(OauthClients::class)->create([
"USR_UID" => $user->USR_UID
]);
@@ -116,7 +116,7 @@ class ServerTest extends TestCase
*/
public function it_should_test_post_token_with_empty_client_id()
{
$user = User::where('USR_ID', '=', 1)->get()->first();
$user = User::where('USR_ID', '=', 1)->first();
$oauthClients = factory(OauthClients::class)->create([
"USR_UID" => $user->USR_UID
]);
@@ -155,8 +155,8 @@ class ServerTest extends TestCase
*/
public function it_should_test_post_token_for_pm_client_id()
{
$user = User::where('USR_ID', '=', 1)->get()->first();
$oauthClients = OauthClients::where('CLIENT_ID', '=', 'x-pm-local-client')->get()->first();
$user = User::where('USR_ID', '=', 1)->first();
$oauthClients = OauthClients::where('CLIENT_ID', '=', 'x-pm-local-client')->first();
$data = '{
"grant_type":"password",

View File

@@ -0,0 +1,88 @@
<?php
namespace Tests\unit\workflow\engine\src\ProcessMaker\Util;
use ProcessMaker\Util\BatchProcessWithIndexes;
use Tests\TestCase;
class BatchProcessWithIndexesTest extends TestCase
{
/**
* Testing object.
* @var BatchProcessWithIndexesTest
*/
protected $batchProcessWithIndexes = null;
/**
* Set up method.
* @return void
*/
public function setUp(): void
{
parent::setUp();
}
/**
* Tear down method.
* @return void
*/
public function tearDown(): void
{
parent::tearDown();
}
/**
* This test the setLimit() method.
* @test
* @covers \ProcessMaker\Util\BatchProcessWithIndexes::setLimit()
*/
public function it_should_test_setLimit_method()
{
$this->batchProcessWithIndexes = new BatchProcessWithIndexes(1);
$result = $this->batchProcessWithIndexes->setLimit(1);
$this->assertInstanceOf(BatchProcessWithIndexes::class, $result);
}
/**
* This test the process() method.
* @test
* @covers \ProcessMaker\Util\BatchProcessWithIndexes::process()
*/
public function it_should_test_process_method()
{
//for 10 elements will be expect the next indexes
$expected = [
[0, 2], [2, 2], [4, 2], [6, 2], [8, 2]
];
$size = 10;
$limit = 2;
$result = [];
$this->batchProcessWithIndexes = new BatchProcessWithIndexes($size);
$this->batchProcessWithIndexes->setLimit($limit);
$this->batchProcessWithIndexes->process(function ($start, $limit) use (&$result) {
$result[] = [$start, $limit];
});
$this->assertEquals(count($expected), count($result));
$this->assertEquals(json_encode($expected), json_encode($result));
//for 17 elements will be expect the next indexes
$expected = [
[0, 3], [3, 3], [6, 3], [9, 3], [12, 3], [15, 3]
];
$size = 17;
$limit = 3;
$result = [];
$this->batchProcessWithIndexes = new BatchProcessWithIndexes($size);
$this->batchProcessWithIndexes->setLimit($limit);
$this->batchProcessWithIndexes->process(function ($start, $limit) use (&$result) {
$result[] = [$start, $limit];
});
$this->assertEquals(count($expected), count($result));
$this->assertEquals(json_encode($expected), json_encode($result));
}
}

View File

@@ -2561,7 +2561,6 @@ class LdapAdvanced
->where('GRP_STATUS', '=', 'ACTIVE')
->where('GRP_TITLE', '=', $title)
->orderBy('GRP_ID', 'ASC')
->get()
->first();
if (!empty($groupWf)) {
return $groupWf->GRP_UID;

View File

@@ -4,6 +4,7 @@ use Illuminate\Support\Facades\Log;
use PHPMailer\PHPMailer\OAuth;
use PHPMailer\PHPMailer\PHPMailer;
use ProcessMaker\Core\System;
use ProcessMaker\Office365OAuth\Office365OAuth;
/**
* @package workflow.engine.ProcessMaker
@@ -565,6 +566,12 @@ class SpoolRun
$phpMailer->Username = $this->config['MESS_ACCOUNT'];
$phpMailer->Password = $this->config['MESS_PASSWORD'];
} else {
// Define initial options for the provider
$options = [
'clientId' => $this->config['OAUTH_CLIENT_ID'],
'clientSecret' => $this->config['OAUTH_CLIENT_SECRET'],
'accessType' => 'offline'
];
// Get provider
switch ($this->config['MESS_ENGINE']) {
case 'GMAILAPI':
@@ -572,18 +579,14 @@ class SpoolRun
break;
case 'OFFICE365API':
$providerClass = '\Stevenmaguire\OAuth2\Client\Provider\Microsoft';
$options['urlAuthorize'] = Office365OAuth::URL_AUTHORIZE;
$options['urlAccessToken'] = Office365OAuth::URL_ACCESS_TOKEN;
break;
default:
throw new Exception('Only Google and Microsoft OAuth2 providers are currently supported.');
break;
}
$provider = new $providerClass(
[
'clientId' => $this->config['OAUTH_CLIENT_ID'],
'clientSecret' => $this->config['OAUTH_CLIENT_SECRET'],
'accessType' => 'offline'
]
);
$provider = new $providerClass($options);
// Set OAuth to use
$phpMailer->setOAuth(

View File

@@ -7,6 +7,7 @@ use ProcessMaker\Core\JobsManager;
use ProcessMaker\Core\System;
use ProcessMaker\Model\Application;
use ProcessMaker\Model\Fields;
use ProcessMaker\Util\BatchProcessWithIndexes;
require_once 'classes/model/om/BaseAdditionalTables.php';
@@ -782,19 +783,17 @@ class AdditionalTables extends BaseAdditionalTables
$reportTableBatchRegeneration = $config['report_table_batch_regeneration'];
// Initializing more variables
$size = $n;
$start = 0;
$limit = $reportTableBatchRegeneration;
$batch = new BatchProcessWithIndexes($n);
$batch->setLimit($reportTableBatchRegeneration);
// Creating jobs
for ($i = 1; $start < $size; $i++) {
$batch->process(function ($start, $limit) use ($workspace, $tableName, $type, $processUid, $gridKey, $addTabUid) {
$closure = function () use ($workspace, $tableName, $type, $processUid, $gridKey, $addTabUid, $start, $limit) {
$workspaceTools = new WorkspaceTools($workspace);
$workspaceTools->generateDataReport($tableName, $type, $processUid, $gridKey, $addTabUid, $start, $limit);
};
JobsManager::getSingleton()->dispatch(GenerateReportTable::class, $closure);
$start = $i * $limit;
}
});
}
/**

View File

@@ -1,32 +1,9 @@
<?php
/**
* AppDelegation.php
*
* @package workflow.engine.classes.model
*
* ProcessMaker Open Source Edition
* Copyright (C) 2004 - 2011 Colosa Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* For more information, contact Colosa Inc, 2566 Le Jeune Rd.,
* Coral Gables, FL, 33134, USA, or email info@colosa.com.
*
*/
use Illuminate\Database\Eloquent\Builder;
use ProcessMaker\Model\Delegation;
use ProcessMaker\Plugins\PluginRegistry;
use ProcessMaker\Util\BatchProcessWithIndexes;
/**
* Skeleton subclass for representing a row from the 'APP_DELEGATION' table.
@@ -569,35 +546,97 @@ class AppDelegation extends BaseAppDelegation
}
}
//usually this function is called when routing in the flow, so by default cron =0
public function calculateDuration($cron = 0)
/**
* Usually this function is called when routing in the flow, so by default cron = 0
* @param int $cron
* @return void
*/
public function calculateDuration($cron = 0): void
{
$this->writeFileIfCalledFromCronForCalculateDuration($cron);
$this->patchDataWithValuesForCalculateDuration();
$rs = $this->recordSetForCalculateDuration();
$rs->next();
$row = $rs->getRow();
$i = 0;
$calendar = new Calendar();
$now = new DateTime();
while (is_array($row)) {
$oAppDel = AppDelegationPeer::retrieveByPk($row['APP_UID'], $row['DEL_INDEX']);
$calendar = new Calendar();
$calendar->getCalendar($row['USR_UID'], $row['PRO_UID'], $row['TAS_UID']);
$calData = $calendar->getCalendarData();
$calculatedValues = $this->getValuesToStoreForCalculateDuration($row, $calendar, $calData, $now);
$oAppDel->setDelStarted($calculatedValues['isStarted']);
$oAppDel->setDelFinished($calculatedValues['isFinished']);
$oAppDel->setDelDelayed($calculatedValues['isDelayed']);
$oAppDel->setDelQueueDuration($calculatedValues['queueTime']);
$oAppDel->setDelDelayDuration($calculatedValues['delayTime']);
$oAppDel->setDelDuration($calculatedValues['durationTime']);
$oAppDel->setAppOverduePercentage($calculatedValues['percentDelay']);
$RES = $oAppDel->save();
$rs->next();
$row = $rs->getRow();
$builder = $this->getAppDelegationTask();
$count = $builder->count();
$now = new DateTime();
$batch = new BatchProcessWithIndexes($count);
$batch->process(function ($start, $limit) use ($builder, $now) {
$results = $builder
->offset($start)
->limit($limit)
->get();
foreach ($results as $object) {
$appDelegationTask = $object->toArray();
$this->updateAppDelegationWithCalendar($appDelegationTask, $now);
}
});
}
/**
* Get APP_DELEGATION and TASK tables where 'started' and 'finished' are 0.
* @return iterable
*/
private function getAppDelegationTask(): Builder
{
$columns = [
'APP_DELEGATION.APP_UID',
'APP_DELEGATION.DEL_INDEX',
'APP_DELEGATION.USR_UID',
'APP_DELEGATION.PRO_UID',
'APP_DELEGATION.TAS_UID',
'APP_DELEGATION.DEL_DELEGATE_DATE',
'APP_DELEGATION.DEL_INIT_DATE',
'APP_DELEGATION.DEL_TASK_DUE_DATE',
'APP_DELEGATION.DEL_FINISH_DATE',
'APP_DELEGATION.DEL_DURATION',
'APP_DELEGATION.DEL_QUEUE_DURATION',
'APP_DELEGATION.DEL_DELAY_DURATION',
'APP_DELEGATION.DEL_STARTED',
'APP_DELEGATION.DEL_FINISHED',
'APP_DELEGATION.DEL_DELAYED',
'TASK.TAS_DURATION',
'TASK.TAS_TIMEUNIT',
'TASK.TAS_TYPE_DAY'
];
$builder = Delegation::query()
->select($columns)
->leftjoin('TASK', function ($join) {
$join->on('APP_DELEGATION.TAS_UID', '=', 'TASK.TAS_UID');
})
->where(function ($query) {
$query->where('APP_DELEGATION.DEL_STARTED', '=', 0)
->orWhere('APP_DELEGATION.DEL_FINISHED', '=', 0);
})
->orderBy('DELEGATION_ID', 'asc');
return $builder;
}
/**
* Update the APP_DELEGATION table with the calculated calendar results.
* @param array $appDelegationTask
* @param DateTime $date
* @return void
*/
private function updateAppDelegationWithCalendar(array $appDelegationTask, DateTime $date): void
{
$calendar = new Calendar();
$calendar->getCalendar($appDelegationTask['USR_UID'], $appDelegationTask['PRO_UID'], $appDelegationTask['TAS_UID']);
$calData = $calendar->getCalendarData();
$calculatedValues = $this->getValuesToStoreForCalculateDuration($appDelegationTask, $calendar, $calData, $date);
Delegation::select()
->where('APP_UID', '=', $appDelegationTask['APP_UID'])
->where('DEL_INDEX', '=', $appDelegationTask['DEL_INDEX'])
->update([
'DEL_STARTED' => $calculatedValues['isStarted'],
'DEL_FINISHED' => $calculatedValues['isFinished'],
'DEL_DELAYED' => $calculatedValues['isDelayed'],
'DEL_QUEUE_DURATION' => $calculatedValues['queueTime'],
'DEL_DELAY_DURATION' => $calculatedValues['delayTime'],
'DEL_DURATION' => $calculatedValues['durationTime'],
'APP_OVERDUE_PERCENTAGE' => $calculatedValues['percentDelay']
]);
}
public function getValuesToStoreForCalculateDuration($row, $calendar, $calData, $nowDate)
@@ -706,39 +745,6 @@ class AppDelegation extends BaseAppDelegation
return new DateTime($stringDate);
}
private function recordSetForCalculateDuration()
{
//walk in all rows with DEL_STARTED = 0 or DEL_FINISHED = 0
$c = new Criteria('workflow');
$c->clearSelectColumns();
$c->addSelectColumn(AppDelegationPeer::APP_UID);
$c->addSelectColumn(AppDelegationPeer::DEL_INDEX);
$c->addSelectColumn(AppDelegationPeer::USR_UID);
$c->addSelectColumn(AppDelegationPeer::PRO_UID);
$c->addSelectColumn(AppDelegationPeer::TAS_UID);
$c->addSelectColumn(AppDelegationPeer::DEL_DELEGATE_DATE);
$c->addSelectColumn(AppDelegationPeer::DEL_INIT_DATE);
$c->addSelectColumn(AppDelegationPeer::DEL_TASK_DUE_DATE);
$c->addSelectColumn(AppDelegationPeer::DEL_FINISH_DATE);
$c->addSelectColumn(AppDelegationPeer::DEL_DURATION);
$c->addSelectColumn(AppDelegationPeer::DEL_QUEUE_DURATION);
$c->addSelectColumn(AppDelegationPeer::DEL_DELAY_DURATION);
$c->addSelectColumn(AppDelegationPeer::DEL_STARTED);
$c->addSelectColumn(AppDelegationPeer::DEL_FINISHED);
$c->addSelectColumn(AppDelegationPeer::DEL_DELAYED);
$c->addSelectColumn(TaskPeer::TAS_DURATION);
$c->addSelectColumn(TaskPeer::TAS_TIMEUNIT);
$c->addSelectColumn(TaskPeer::TAS_TYPE_DAY);
$c->addJoin(AppDelegationPeer::TAS_UID, TaskPeer::TAS_UID, Criteria::LEFT_JOIN);
$cton1 = $c->getNewCriterion(AppDelegationPeer::DEL_STARTED, 0);
$cton2 = $c->getNewCriterion(AppDelegationPeer::DEL_FINISHED, 0);
$cton1->addOR($cton2);
$c->add($cton1);
$rs = AppDelegationPeer::doSelectRS($c);
$rs->setFetchmode(ResultSet::FETCHMODE_ASSOC);
return $rs;
}
private function writeFileIfCalledFromCronForCalculateDuration($cron)
{
if ($cron == 1) {

View File

@@ -104,7 +104,6 @@ switch ($function) {
$authenticationSource = RbacAuthenticationSource::query()
->select(['AUTH_SOURCE_UID', 'AUTH_SOURCE_NAME'])
->where('AUTH_SOURCE_NAME', '=', $authSourceName)
->get()
->first();
$row = false;
$suggestName = "";
@@ -114,7 +113,6 @@ switch ($function) {
->select(['AUTH_SOURCE_NAME'])
->where('AUTH_SOURCE_NAME', 'LIKE', "%{$authSourceName}%")
->orderBy('AUTH_SOURCE_NAME', 'desc')
->get()
->first();
if (!empty($lastAuthenticationSource)) {
$name = $lastAuthenticationSource->AUTH_SOURCE_NAME;

View File

@@ -20,11 +20,10 @@ try {
$office365Client = $office365OAuth->getOffice365Client();
$accessToken = $office365Client->getAccessToken('authorization_code', [
'code' => $_GET['code']
'code' => $_GET['code'],
'scope' => Office365OAuth::SMTP_SCOPE
]);
$token = $accessToken->getToken();
$office365OAuth->setRefreshToken($accessToken->getRefreshToken());
$office365OAuth->saveEmailServer();

View File

@@ -162,7 +162,6 @@ try {
$dateCreate = empty($_REQUEST["UEA_DATE_CREATE"]) ? date("Y-m-d H:i:s") : $_REQUEST["UEA_DATE_CREATE"];
$userExtendedAttributes = UserExtendedAttributes::where('UEA_ID', '=', $id)
->get()
->first();
if (empty($userExtendedAttributes)) {
$userExtendedAttributes = new UserExtendedAttributes();
@@ -194,7 +193,6 @@ try {
$userExtendedAttributes = UserExtendedAttributes::query()
->where('UEA_NAME', '=', trim($name))
->where('UEA_ID', '<>', $id)
->get()
->first();
$result = [
"valid" => empty($userExtendedAttributes),
@@ -208,7 +206,6 @@ try {
$userExtendedAttributes = UserExtendedAttributes::query()
->where('UEA_ATTRIBUTE_ID', '=', trim($attributeId))
->where('UEA_ID', '<>', $id)
->get()
->first();
$result = [
"valid" => empty($userExtendedAttributes),
@@ -221,7 +218,6 @@ try {
$attributeId = empty($_REQUEST["attributeId"]) ? "" : $_REQUEST["attributeId"];
$user = User::query()
->where("USR_EXTENDED_ATTRIBUTES_DATA", "LIKE", "%\"{$attributeId}\"%")
->get()
->first();
$isUsed = false;
$message = "";

View File

@@ -718,7 +718,7 @@
this.validate.USR_EMAIL.message = this.$root.translation('ID_IS_REQUIRED');
return;
}
if (/^[_a-z0-9-]+(\.[_a-z0-9-]+)*@([a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,4}))|((([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))$/i.test(this.form.USR_EMAIL) === false) {
if (/^(\w+)([-+.'][\w]+)*@(\w[-\w]*\.){1,5}([A-Za-z]){2,6}$/.test(this.form.USR_EMAIL) === false) {
this.validate.USR_EMAIL.state = false;
this.validate.USR_EMAIL.message = this.$root.translation('ID_INVALID_VALUE', [this.$root.translation('ID_EMAIL')]);
}

View File

@@ -0,0 +1,190 @@
<?php
namespace ProcessMaker\BusinessModel\ActionsByEmail;
use Exception;
use Google_Client;
use Google_Service_Gmail;
use Google_Service_Gmail_ModifyMessageRequest;
use stdClass;
/**
* Class GmailMailbox
* @package ProcessMaker\BusinessModel\ActionsByEmail
*/
class GmailMailbox
{
private $service;
/**
* GmailMailbox constructor.
* @param array $emailSetup
*/
public function __construct(array $emailSetup)
{
// Google Client instance
$googleClient = new Google_Client();
$googleClient->setClientId($emailSetup['OAUTH_CLIENT_ID']);
$googleClient->setClientSecret($emailSetup['OAUTH_CLIENT_SECRET']);
$googleClient->refreshToken($emailSetup['OAUTH_REFRESH_TOKEN']);
$googleClient->setAccessType('offline');
$googleClient->addScope(Google_Service_Gmail::MAIL_GOOGLE_COM);
// Set Gmail service instance
$this->service = new Google_Service_Gmail($googleClient);
}
/**
* This function uses Gmail API to perform a search on the mailbox.
*
* @param string $criteria
* @return array
* @throws Exception
*/
public function searchMailbox(string $criteria = 'ALL'): array
{
// Transform criteria to values accepted by Gmail service
switch ($criteria) {
case 'UNSEEN':
$criteria = 'is:unread';
break;
case 'SEEN':
$criteria = 'is:read';
break;
default:
$criteria = '';
}
// Initialize variables
$nextPageToken = null;
$mailsIds = [];
// Get unread user's messages
try {
do {
// Build optional parameters array
$optParams = [
'q' => $criteria,
'pageToken' => $nextPageToken
];
// Get service response
$response = $this->service->users_messages->listUsersMessages('me', $optParams);
// Get the mails identifiers
$messages = $response->getMessages();
foreach ($messages as $message) {
$mailsIds[] = $message->getId();
}
// Get next page token
$nextPageToken = $response->getNextPageToken();
} while (!is_null($nextPageToken));
} catch (Exception $e) {
throw $e;
}
return $mailsIds;
}
/**
* Get mail data.
*
* @param string $mailId ID of the mail
* @param bool $markAsSeen Mark the email as seen, maintained by compatibility reasons, currently not used
* @return object
* @throws Exception
*/
public function getMail(string $mailId, bool $markAsSeen = true): object
{
try {
// Get message data
$response = $this->service->users_messages->get('me', $mailId);
// Get payload
$payload = $response->getPayload();
// Get headers
$headers = [];
foreach ($payload['headers'] as $item) {
$headers[$item->name] = $item->value;
}
// Get complete and decoded message body
$body = $this->getMessageBodyRecursive($payload);
} catch (Exception $e) {
throw $e;
}
// Build message object
$message = new stdClass();
$message->fromAddress = $headers['From'];
$message->toString = $headers['To'];
$message->subject = $headers['Subject'];
$message->textPlain = $body['plain'] ?? $body['html'];
return $message;
}
/**
* Remove UNREAD label in the mail.
*
* @param string $mailId
* @return void
* @throws Exception
*/
public function markMailAsRead($mailId): void
{
// Build modify message request
$modifyMessageRequest = new Google_Service_Gmail_ModifyMessageRequest();
$modifyMessageRequest->setRemoveLabelIds(['UNREAD']);
// Modify the mail
try {
$this->service->users_messages->modify('me', $mailId, $modifyMessageRequest);
} catch (Exception $e) {
throw $e;
}
}
/**
* Get message html body and plain body
*
* @param object $part
* @return array
*/
private function getMessageBodyRecursive(object $part): array
{
if ($part->mimeType == 'text/html') {
return [
'html' => $this->base64UrlDecode($part->body->data)
];
} else if ($part->mimeType == 'text/plain') {
return [
'plain' => $this->base64UrlDecode($part->body->data)
];
} else if ($part->parts) {
$return = [];
foreach ($part->parts as $subPart) {
$result = $this->getMessageBodyRecursive($subPart);
$return = array_merge($return, $result);
if (array_key_exists('html', $return)) {
break;
}
}
return $return;
}
return [];
}
/**
* Returns a base64 decoded web safe string
*
* @param string $string
* @return string
*/
private function base64UrlDecode(string $string): string
{
return base64_decode(str_replace(['-', '_'], ['+', '/'], $string));
}
}

View File

@@ -0,0 +1,149 @@
<?php
namespace ProcessMaker\BusinessModel\ActionsByEmail;
use Exception;
use League\OAuth2\Client\Grant\RefreshToken;
use Microsoft\Graph\Graph;
use Microsoft\Graph\Model;
use ProcessMaker\Office365OAuth\Office365OAuth;
use stdClass;
/**
* Class Office365Mailbox
* @package ProcessMaker\BusinessModel\ActionsByEmail
*/
class Office365Mailbox
{
const SCOPE = 'https://graph.microsoft.com/Mail.ReadWrite';
private $service;
private $messages = [];
/**
* Office365Mailbox constructor.
* @param array $emailSetup
* @throws Exception
*/
public function __construct(array $emailSetup)
{
// Get client instance
$office365OAuth = new Office365OAuth();
$office365OAuth->setClientID($emailSetup['OAUTH_CLIENT_ID']);
$office365OAuth->setClientSecret($emailSetup['OAUTH_CLIENT_SECRET']);
$provider = $office365OAuth->getOffice365Client();
// Get fresh access token
try {
$accessToken = $provider->getAccessToken(
new RefreshToken(),
[
'refresh_token' => $emailSetup['OAUTH_REFRESH_TOKEN'],
'scope' => self::SCOPE
]
);
} catch (Exception $e) {
throw $e;
}
// Set Office365 service instance
$this->service = new Graph();
$this->service->setAccessToken($accessToken->getToken());
}
/**
* This function uses Office365 API to perform a search on the mailbox.
*
* @param string $criteria
* @return array
* @throws Exception
*/
public function searchMailbox(string $criteria = 'ALL'): array
{
// Transform criteria to values accepted by Office365 service
switch ($criteria) {
case 'UNSEEN':
$criteria = 'isRead eq false';
break;
case 'SEEN':
$criteria = 'isRead eq true';
break;
default:
$criteria = '';
}
// Initialize variables
$nextLink = '';
$mailsIds = [];
// Get unread user's messages
try {
do {
// First time the link is generated, by default 100 results per call
if (empty($nextLink)) {
$nextLink = '/me/messages?$filter=' . $criteria . '&$select=id,body,toRecipients,from,subject&$top=100';
}
// Get service response
$response = $this->service->createRequest('GET', $nextLink)->execute();
// Get the mails identifiers
$messages = $response->getResponseAsObject(Model\Message::class);
foreach ($messages as $message) {
// Collect the messages identifiers
$mailsIds[] = $message->getId();
// Create a simple message object
$simpleMessage= new stdClass();
$simpleMessage->textPlain = strip_tags($message->getBody()->getContent());
$simpleMessage->toString = $message->getToRecipients()[0]['emailAddress']['address'];
$simpleMessage->fromAddress = $message->getFrom()->getEmailAddress()->getAddress();
$simpleMessage->subject = $message->getSubject();
// Add the new message object to messages array
$this->messages[$message->getId()] = $simpleMessage;
}
// Get next link
$nextLink = $response->getNextLink();
} while (!is_null($nextLink));
} catch (Exception $e) {
throw $e;
}
return $mailsIds;
}
/**
* Get mail data.
*
* @param string $mailId ID of the mail
* @param bool $markAsSeen Mark the email as seen, maintained by compatibility reasons, currently not used
* @return object
*/
public function getMail(string $mailId, bool $markAsSeen = true): object
{
return $this->messages[$mailId] ?? null;
}
/**
* Set "Is Read" property to "true" in the mail.
*
* @param string $mailId
* @return void
* @throws Exception
*/
public function markMailAsRead($mailId): void
{
// Set "Is Read" property to "true"
$message = new Model\Message();
$message->setIsRead(true);
// Get service response
try {
$this->service->createRequest('PATCH', '/me/messages/' . $mailId)->attachBody($message)->execute();
} catch (Exception $e) {
throw $e;
}
}
}

View File

@@ -133,18 +133,35 @@ class ResponseReader
public function getAllEmails(array $dataAbe)
{
try {
// Get Email Server info
$emailServer = new EmailServer();
$emailSetup = (!is_null(EmailServerPeer::retrieveByPK($dataAbe['ABE_EMAIL_SERVER_RECEIVER_UID']))) ?
$emailServer->getEmailServer($dataAbe['ABE_EMAIL_SERVER_RECEIVER_UID'], true) :
$emailServer->getEmailServerDefault();
if (empty($emailSetup) || (empty($emailSetup['MESS_INCOMING_SERVER']) && $emailSetup['MESS_INCOMING_PORT'] == 0)) {
throw (new Exception(G::LoadTranslation('ID_ABE_LOG_CANNOT_READ'), 500));
// Create an instance according to the engine type of the email server
if ($emailSetup['MESS_ENGINE'] === 'IMAP') {
if (empty($emailSetup['MESS_INCOMING_SERVER']) && $emailSetup['MESS_INCOMING_PORT'] == 0) {
throw new Exception(G::LoadTranslation('ID_ABE_LOG_CANNOT_READ'), 500);
}
$mailbox = new Mailbox(
'{'. $emailSetup['MESS_INCOMING_SERVER'] . ':' . $emailSetup['MESS_INCOMING_PORT'] . '/imap/ssl/novalidate-cert}INBOX',
$emailSetup['MESS_ACCOUNT'],
$this->decryptPassword($emailSetup)
);
} else {
if (empty($emailSetup['OAUTH_CLIENT_ID']) || empty($emailSetup['OAUTH_CLIENT_SECRET']) || empty($emailSetup['OAUTH_REFRESH_TOKEN'])) {
throw new Exception(G::LoadTranslation('ID_ABE_LOG_CANNOT_READ'), 500);
}
if ($emailSetup['MESS_ENGINE'] === 'GMAILAPI') {
$mailbox = new GmailMailbox($emailSetup);
} else if ($emailSetup['MESS_ENGINE'] === 'OFFICE365API') {
$mailbox = new Office365Mailbox($emailSetup);
}
}
Log::channel(':' . $this->channel)->debug("Open mailbox", Bootstrap::context($emailSetup));
// Read all messages into an array
@@ -152,7 +169,6 @@ class ResponseReader
if ($mailsIds) {
// Get the first message and save its attachment(s) to disk:
foreach ($mailsIds as $key => $mailId) {
/** @var IncomingMail $mail */
$mail = $mailbox->getMail($mailId, false);
Log::channel(':' . $this->channel)->debug("Get mail", Bootstrap::context(['mailId' => $mailId]));
if (!empty($mail->textPlain)) {
@@ -260,11 +276,11 @@ class ResponseReader
/**
* Derivation of the case with the mail information
* @param array $caseInfo
* @param IncomingMail $mail
* @param object $mail
* @param array $dataAbe
* @throws Exception
*/
public function processABE(array $caseInfo, IncomingMail $mail, array $dataAbe = [])
public function processABE(array $caseInfo, object $mail, array $dataAbe = [])
{
try {
$actionsByEmail = new ActionsByEmail();
@@ -383,11 +399,11 @@ class ResponseReader
* Send an error message to the sender
* @param string $msgError
* @param array $caseInf
* @param IncomingMail $mail
* @param object $mail
* @param array $emailSetup
* @return \ProcessMaker\Util\Response|string|\WsResponse
*/
public function sendMessageError($msgError, array $caseInf, IncomingMail $mail, array $emailSetup)
public function sendMessageError($msgError, array $caseInf, object $mail, array $emailSetup)
{
$wsBase = new WsBase();
$result = $wsBase->sendMessage(

View File

@@ -308,7 +308,6 @@ class Home
->where('CAL_ID', '=', $id)
->join('ADDITIONAL_TABLES', 'ADDITIONAL_TABLES.ADD_TAB_UID', '=', 'CASE_LIST.ADD_TAB_UID')
->join('PROCESS', 'PROCESS.PRO_UID', '=', 'ADDITIONAL_TABLES.PRO_UID')
->get()
->first();
if (!empty($caseList)) {
$tableName = $caseList->ADD_TAB_NAME;

View File

@@ -268,7 +268,6 @@ class NotificationDevice
$dataGroupVariable = isset($appFields["APP_DATA"][$nextTaskGroupVariable]) ? $appFields["APP_DATA"][$nextTaskGroupVariable]
: (isset($appFields[$nextTaskGroupVariable]) ? $appFields[$nextTaskGroupVariable] : '');
if (!empty($dataGroupVariable)) {
$dataGroupVariable = $appFields["APP_DATA"][$nextTaskGroupVariable];
$dataGroupVariable = (is_array($dataGroupVariable))? $dataGroupVariable : trim($dataGroupVariable);
if (!empty($dataGroupVariable) && is_array($dataGroupVariable)){
$arrayTaskUser[] = $dataGroupVariable;

View File

@@ -350,7 +350,6 @@ class TaskSchedulerBM
$scheduler = TaskScheduler::select()
->where('title', '=', $service['title'])
->where('description', '=', $service['description'])
->get()
->first();
if (is_null($scheduler)) {
self::registerScheduledTask($service);

View File

@@ -1154,7 +1154,6 @@ class WebEntry
$result = true;
$webentry = WebEntryModel::select('WE_HIDE_ACTIVE_SESSION_WARNING', 'WE_AUTHENTICATION')
->where('WE_UID', '=', $weUid)
->get()
->first();
if ($webentry->WE_AUTHENTICATION === 'LOGIN_REQUIRED') {
$result = intval($webentry->WE_HIDE_ACTIVE_SESSION_WARNING) === 0;

View File

@@ -379,13 +379,17 @@ trait EmailBase
*/
public function sendTestMailWithPHPMailerOAuth($provider = 'League\OAuth2\Client\Provider\Google'): PHPMailerOAuth
{
$phpMailerOAuth = new PHPMailerOAuth([
'provider' => new $provider([
$options = [
'clientId' => $this->clientID,
'clientSecret' => $this->clientSecret,
'redirectUri' => $this->refreshToken,
'accessType' => 'offline'
]),
];
if ($provider === 'Stevenmaguire\OAuth2\Client\Provider\Microsoft') {
$options['urlAuthorize'] = self::URL_AUTHORIZE;
$options['urlAccessToken'] = self::URL_ACCESS_TOKEN;
}
$phpMailerOAuth = new PHPMailerOAuth([
'provider' => new $provider($options),
'clientId' => $this->clientID,
'clientSecret' => $this->clientSecret,
'refreshToken' => $this->refreshToken,

View File

@@ -93,7 +93,6 @@ class CaseList extends Model
'ADDITIONAL_TABLES.ADD_TAB_NAME',
'ADDITIONAL_TABLES.PRO_UID'
])
->get()
->first();
return $caseList;
@@ -176,7 +175,7 @@ class CaseList extends Model
$caseList = CaseList::where('CAL_ID', '=', $id);
$caseList->update($attributes);
$model = $caseList->get()->first();
$model = $caseList->first();
if (!is_null($model)) {
$model->CAL_COLUMNS = json_decode($model->CAL_COLUMNS);
}
@@ -190,7 +189,7 @@ class CaseList extends Model
* @param string $newColumns
* @return void
*/
private function checkColumnsConfigurationChanges(int $calId, string $type, string $newColumns): void
private static function checkColumnsConfigurationChanges(int $calId, string $type, string $newColumns): void
{
$caseList = CaseList::where('CAL_ID', '=', $calId)->first();
if ($caseList->CAL_COLUMNS === $newColumns) {
@@ -214,10 +213,7 @@ class CaseList extends Model
if (!property_exists($uscSetting->{$type}->customCaseList, $calId)) {
continue;
}
if (!property_exists($uscSetting->{$type}->customCaseList->{$calId}, 'columns')) {
continue;
}
$uscSetting->{$type}->customCaseList->{$calId}->columns = ['detail', 'actions'];
unset($uscSetting->{$type}->customCaseList->{$calId});
UserConfig::editSetting($userConfig->USR_ID, 'userConfig', (array) $uscSetting);
}
}
@@ -230,7 +226,7 @@ class CaseList extends Model
public static function deleteSetting(int $id)
{
$caseList = CaseList::where('CAL_ID', '=', $id);
$model = $caseList->get()->first();
$model = $caseList->first();
if (!is_null($model)) {
$caseList->delete();
$model->CAL_COLUMNS = json_decode($model->CAL_COLUMNS);
@@ -315,7 +311,6 @@ class CaseList extends Model
'CASE_LIST.*',
'ADDITIONAL_TABLES.ADD_TAB_NAME'
])
->get()
->first();
if (empty($model)) {
throw new Exception(G::LoadTranslation('ID_DOES_NOT_EXIST'));
@@ -363,7 +358,6 @@ class CaseList extends Model
//the pmtable not exist
$table = AdditionalTables::where('ADD_TAB_NAME', '=', $tableName)
->get()
->first();
if ($table === null) {
return [
@@ -393,7 +387,6 @@ class CaseList extends Model
//the name of the case list already exist
$list = CaseList::where('CAL_NAME', '=', $array['name'])
->get()
->first();
$requestData['duplicateName'] = $requestData['duplicateName'] ?? '';
if ($requestData['duplicateName'] !== 'continue') {

View File

@@ -67,6 +67,6 @@ class Groupwf extends Model
public static function getGroupId($grpUid)
{
$query = Groupwf::select('GRP_ID')->where('GRP_UID', $grpUid);
return $query->get()->first()->toArray();
return $query->first()->toArray();
}
}

View File

@@ -495,7 +495,6 @@ class Process extends Model
$process = Process::query()
->where($key, $proId)
->where('PRO_STATUS', 'ACTIVE')
->get()
->first();
return !empty($process);
}

View File

@@ -19,7 +19,7 @@ class RbacRoles extends Model
public static function getRolUidByCode($rolCode)
{
$query = RbacRoles::select('ROL_UID')->where('ROL_CODE', $rolCode);
$query = $query->get()->first();
$query = $query->first();
if (is_null($query)) {
return [];

View File

@@ -18,7 +18,6 @@ class Step extends Model
->where('TAS_UID', '=', $tasUid)
->where('STEP_TYPE_OBJ', '=', $stepTypeObj)
->where('STEP_UID_OBJ', '=', $stepUidObj)
->get()
->first();
return $step;
}

View File

@@ -29,7 +29,6 @@ class UserConfig extends Model
{
$userConfig = UserConfig::where('USR_ID', '=', $id)
->where('USC_NAME', '=', $name)
->get()
->first();
if (empty($userConfig)) {
return null;

View File

@@ -11,11 +11,16 @@ class Office365OAuth
{
use EmailBase;
const URL_AUTHORIZE = 'https://login.microsoftonline.com/common/oauth2/v2.0/authorize';
const URL_ACCESS_TOKEN = 'https://login.microsoftonline.com/common/oauth2/v2.0/token';
const SMTP_SCOPE = 'https://outlook.office.com/SMTP.Send';
private $options = [
'scope' => [
'wl.imap',
'wl.offline_access'
]
'response_mode' => 'query',
'prompt' => 'consent',
// Scopes requested in authentication
'scope' => 'offline_access https://outlook.office.com/SMTP.Send https://graph.microsoft.com/Mail.ReadWrite'
];
/**
@@ -46,8 +51,11 @@ class Office365OAuth
'clientId' => $this->getClientID(),
'clientSecret' => $this->getClientSecret(),
'redirectUri' => $this->getRedirectURI(),
'urlAuthorize' => self::URL_AUTHORIZE,
'urlAccessToken' => self::URL_ACCESS_TOKEN,
'accessType' => 'offline'
]);
$provider->defaultScopes = $this->options['scope'];
return $provider;
}
}

View File

@@ -0,0 +1,57 @@
<?php
namespace ProcessMaker\Util;
class BatchProcessWithIndexes
{
/**
* Start of the query.
* @var int
*/
private $start = 0;
/**
* Limit of the query.
* @var int
*/
private $limit = 1000;
/**
* Total size of the query.
* @var int
*/
private $size = 0;
/**
* Constructor of the class.
* @param int $size
*/
public function __construct(int $size)
{
$this->size = $size;
}
/**
* Set custom limit of the query.
* @param int $limit
* @return self
*/
public function setLimit(int $limit): self
{
$this->limit = $limit;
return $this;
}
/**
* Batch process returning the index for query.
* @param callable $callback
* @return void
*/
public function process(callable $callback): void
{
for ($batch = 1; $this->start < $this->size; $batch++) {
$callback($this->start, $this->limit);
$this->start = $batch * $this->limit;
}
}
}

View File

@@ -635,8 +635,8 @@ emailServer.application = {
["IMAP", "SMTP - IMAP (PHPMailer)"],
/*----------------------------------********---------------------------------*/
["MAIL", "Mail (PHP)"],
["GMAILAPI", "GMAIL API (PHPMailer)"],
["OFFICE365API", "OFFICE 365 API (PHPMailer)"]
["GMAILAPI", "GMAIL API SMTP-IMAP"],
["OFFICE365API", "OFFICE 365 API SMTP-IMAP"]
]
});