Skip to content

Commit e2b525c

Browse files
authored
Merge pull request #2422 from Blair2004/v6.0.x
V6.0.x
2 parents 9ed6b85 + 28118ef commit e2b525c

File tree

11 files changed

+374
-62
lines changed

11 files changed

+374
-62
lines changed

app/Http/Controllers/Dashboard/ModulesController.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,6 @@ public function downloadModule( $identifier )
6060
public function getModules( $argument = '' )
6161
{
6262
switch ( $argument ) {
63-
case '':
64-
$list = $this->modules->get();
65-
break;
6663
case 'enabled':
6764
$list = $this->modules->getEnabled();
6865
break;
@@ -72,6 +69,10 @@ public function getModules( $argument = '' )
7269
case 'invalid':
7370
$list = $this->modules->getInvalid();
7471
break;
72+
case '':
73+
default :
74+
$list = $this->modules->get();
75+
break;
7576
}
7677

7778
return [

app/Services/CoreService.php

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,33 @@ public function checkModulesSymbolicLinks(): void
371371
)->dispatchForGroup( Role::namespace( Role::ADMIN ) );
372372
}
373373
}
374+
375+
/**
376+
* We'll check if the links is broken
377+
*/
378+
if ( is_link( public_path( 'modules/' . $tolowercase ) ) ) {
379+
$notification = Notification::where( 'identifier', 'symlink-' . $tolowercase )->first();
380+
381+
if ( ! $notification instanceof Notification ) {
382+
$notificationService->create(
383+
title: sprintf( __( '%s: Symbolic Link Broken' ), $module[ 'name' ] ),
384+
identifier: 'symlink-' . $tolowercase,
385+
source: 'system',
386+
url: 'https://my.nexopos.com/en/documentation/troubleshooting/broken-media-images?utm_source=nexopos&utm_campaign=warning&utm_medium=app',
387+
description: sprintf(
388+
__( 'The symbolic link for the module %s is broken. The module assets might not load correctly.' ),
389+
$module[ 'name' ]
390+
),
391+
actions: [
392+
[
393+
'label' => __( 'Fix Symbolic Link' ),
394+
'url' => ns()->route( 'ns.dashboard.modules-symlink', [ 'namespace' => $tolowercase ] ),
395+
'data' => compact( 'module' ),
396+
]
397+
]
398+
)->dispatchForGroup( Role::namespace( Role::ADMIN ) );
399+
}
400+
}
374401
}
375402
}
376403

app/Services/ModulesService.php

Lines changed: 39 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -971,46 +971,60 @@ public function createSymLink( string $moduleNamespace ): void
971971
$this->checkManagementStatus();
972972

973973
if ( ! is_dir( base_path( 'public/modules' ) ) ) {
974-
Storage::disk( 'public' )->makeDirectory( 'modules', 0755, true );
974+
Storage::disk( 'ns-public' )->makeDirectory( 'modules', 0755, true );
975975
}
976976

977977
/**
978978
* checks if a public directory exists and create a
979979
* link for that directory
980980
*/
981-
if (
982-
Storage::disk( 'ns-modules' )->exists( $moduleNamespace . DIRECTORY_SEPARATOR . 'Public' ) &&
983-
! is_link( base_path( 'public' ) . DIRECTORY_SEPARATOR . 'modules' . DIRECTORY_SEPARATOR . strtolower( $moduleNamespace ) )
984-
) {
985-
$target = base_path( 'modules/' . $moduleNamespace . '/Public' );
981+
if ( Storage::disk( 'ns-modules' )->exists( $moduleNamespace . DIRECTORY_SEPARATOR . 'Public' ) ) {
982+
$linkPath = base_path( 'public' ) . DIRECTORY_SEPARATOR . 'modules' . DIRECTORY_SEPARATOR . strtolower( $moduleNamespace );
983+
984+
// Check if link exists and is broken, then remove it
985+
if ( is_link( $linkPath ) && ! file_exists( readlink( $linkPath ) ) ) {
986+
unlink( $linkPath );
987+
}
988+
989+
// Create symlink if it doesn't exist
990+
if ( ! is_link( $linkPath ) ) {
991+
$target = base_path( 'modules/' . $moduleNamespace . '/Public' );
986992

987-
if ( ! \windows_os() ) {
988-
$link = @\symlink( $target, public_path( '/modules/' . strtolower( $moduleNamespace ) ) );
989-
} else {
990-
$mode = 'J';
991-
$link = public_path( 'modules' . DIRECTORY_SEPARATOR . strtolower( $moduleNamespace ) );
992-
$target = base_path( 'modules' . DIRECTORY_SEPARATOR . $moduleNamespace . DIRECTORY_SEPARATOR . 'Public' );
993-
$link = exec( "mklink /{$mode} \"{$link}\" \"{$target}\"" );
993+
if ( ! \windows_os() ) {
994+
$link = @\symlink( $target, public_path( '/modules/' . strtolower( $moduleNamespace ) ) );
995+
} else {
996+
$mode = 'J';
997+
$link = public_path( 'modules' . DIRECTORY_SEPARATOR . strtolower( $moduleNamespace ) );
998+
$target = base_path( 'modules' . DIRECTORY_SEPARATOR . $moduleNamespace . DIRECTORY_SEPARATOR . 'Public' );
999+
$link = exec( "mklink /{$mode} \"{$link}\" \"{$target}\"" );
1000+
}
9941001
}
9951002
}
9961003

9971004
/**
9981005
* checks if a lang directory exists and create a
9991006
* link for that directory
10001007
*/
1001-
if (
1002-
Storage::disk( 'ns-modules' )->exists( $moduleNamespace . DIRECTORY_SEPARATOR . 'Lang' ) &&
1003-
! is_link( base_path( 'public' ) . DIRECTORY_SEPARATOR . 'modules-lang' . DIRECTORY_SEPARATOR . strtolower( $moduleNamespace ) )
1004-
) {
1005-
$target = base_path( 'modules/' . $moduleNamespace . '/Lang' );
1008+
if ( Storage::disk( 'ns-modules' )->exists( $moduleNamespace . DIRECTORY_SEPARATOR . 'Lang' ) ) {
1009+
$linkPath = base_path( 'public' ) . DIRECTORY_SEPARATOR . 'modules-lang' . DIRECTORY_SEPARATOR . strtolower( $moduleNamespace );
1010+
1011+
// Check if link exists and is broken, then remove it
1012+
if ( is_link( $linkPath ) && ! file_exists( readlink( $linkPath ) ) ) {
1013+
unlink( $linkPath );
1014+
}
1015+
1016+
// Create symlink if it doesn't exist
1017+
if ( ! is_link( $linkPath ) ) {
1018+
$target = base_path( 'modules/' . $moduleNamespace . '/Lang' );
10061019

1007-
if ( ! \windows_os() ) {
1008-
$link = @\symlink( $target, public_path( '/modules-lang/' . strtolower( $moduleNamespace ) ) );
1009-
} else {
1010-
$mode = 'J';
1011-
$link = public_path( 'modules-lang' . DIRECTORY_SEPARATOR . strtolower( $moduleNamespace ) );
1012-
$target = base_path( 'modules' . DIRECTORY_SEPARATOR . $moduleNamespace . DIRECTORY_SEPARATOR . 'Lang' );
1013-
$link = exec( "mklink /{$mode} \"{$link}\" \"{$target}\"" );
1020+
if ( ! \windows_os() ) {
1021+
$link = @\symlink( $target, public_path( '/modules-lang/' . strtolower( $moduleNamespace ) ) );
1022+
} else {
1023+
$mode = 'J';
1024+
$link = public_path( 'modules-lang' . DIRECTORY_SEPARATOR . strtolower( $moduleNamespace ) );
1025+
$target = base_path( 'modules' . DIRECTORY_SEPARATOR . $moduleNamespace . DIRECTORY_SEPARATOR . 'Lang' );
1026+
$link = exec( "mklink /{$mode} \"{$link}\" \"{$target}\"" );
1027+
}
10141028
}
10151029
}
10161030
}

config/nexopos.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
* This is the core version of NexoPOS. This is used to displays on the
1010
* dashboard and to ensure a compatibility with the modules.
1111
*/
12-
'version' => '6.0.1',
12+
'version' => '6.0.2',
1313

1414
/**
1515
* --------------------------------------------------------------------
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<template>
2+
<div class="ns-button">
3+
<button @click="openNotePopup()" class="w-full h-10 px-3 outline-hidden">
4+
<i class="las la-comment"></i>
5+
<span class="ml-1 hidden md:inline-block">{{ __( 'Comments' ) }}</span>
6+
</button>
7+
</div>
8+
</template>
9+
10+
<script lang="ts">
11+
import { Popup } from '~/libraries/popup';
12+
import { __ } from '~/libraries/lang';
13+
import { nsSnackBar } from '~/bootstrap';
14+
import nsPosNotePopupVue from '~/popups/ns-pos-note-popup.vue';
15+
import ActionPermissions from '~/libraries/action-permissions';
16+
17+
declare const POS;
18+
19+
export default {
20+
name: 'ns-pos-cart-comment-button',
21+
props: {
22+
order: {
23+
type: Object,
24+
required: true
25+
}
26+
},
27+
data() {
28+
return {
29+
__
30+
}
31+
},
32+
methods: {
33+
async openNotePopup() {
34+
/**
35+
* We'll ensure the user has the right to add comments to an order.
36+
*/
37+
await ActionPermissions.canProceed( 'nexopos.cart.comments' );
38+
39+
try {
40+
const response = await new Promise<{}>( ( resolve, reject ) => {
41+
const note = this.order.note;
42+
const note_visibility = this.order.note_visibility;
43+
Popup.show( nsPosNotePopupVue, { resolve, reject, note, note_visibility });
44+
});
45+
46+
const order = { ...this.order, ...response };
47+
POS.order.next( order );
48+
} catch( exception ) {
49+
if ( exception !== false ) {
50+
nsSnackBar.error( exception.message );
51+
}
52+
}
53+
}
54+
}
55+
}
56+
</script>
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<template>
2+
<div class="ns-button">
3+
<button @click="selectCoupon()" class="w-full h-10 px-3 outline-hidden flex items-center">
4+
<i class="las la-tags"></i>
5+
<span class="ml-1 hidden md:inline-block">{{ __( 'Coupons' ) }}</span>
6+
<span v-if="order.coupons && order.coupons.length > 0" class="ml-1 rounded-full flex items-center justify-center h-6 w-6 bg-info-secondary text-white">{{ order.coupons.length }}</span>
7+
</button>
8+
</div>
9+
</template>
10+
11+
<script lang="ts">
12+
import { Popup } from '~/libraries/popup';
13+
import { __ } from '~/libraries/lang';
14+
import nsPosCouponsLoadPopupVue from '~/popups/ns-pos-coupons-load-popup.vue';
15+
import ActionPermissions from '~/libraries/action-permissions';
16+
17+
export default {
18+
name: 'ns-pos-cart-coupons-button',
19+
props: {
20+
order: {
21+
type: Object,
22+
required: true
23+
}
24+
},
25+
data() {
26+
return {
27+
__
28+
}
29+
},
30+
methods: {
31+
async selectCoupon() {
32+
/**
33+
* We'll check if the user has the right to manage coupons.
34+
*/
35+
await ActionPermissions.canProceed( 'nexopos.cart.coupons' );
36+
37+
try {
38+
const response = await new Promise( ( resolve, reject ) => {
39+
Popup.show( nsPosCouponsLoadPopupVue, { resolve, reject })
40+
})
41+
} catch( exception ) {
42+
// something happened
43+
}
44+
}
45+
}
46+
}
47+
</script>
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<template>
2+
<div class="ns-button" v-if="options.ns_pos_quick_product === 'yes'">
3+
<button @click="openAddQuickProduct()" class="w-full h-10 px-3 outline-hidden flex items-center">
4+
<i class="las la-plus"></i>
5+
<span class="ml-1 hidden md:inline-block">{{ __( 'Product' ) }}</span>
6+
</button>
7+
</div>
8+
</template>
9+
10+
<script lang="ts">
11+
import { Popup } from '~/libraries/popup';
12+
import { __ } from '~/libraries/lang';
13+
import nsPosQuickProductPopupVue from '~/popups/ns-pos-quick-product-popup.vue';
14+
import ActionPermissions from '~/libraries/action-permissions';
15+
16+
export default {
17+
name: 'ns-pos-cart-quick-product-button',
18+
props: {
19+
order: {
20+
type: Object,
21+
required: true
22+
},
23+
options: {
24+
type: Object,
25+
required: true
26+
}
27+
},
28+
data() {
29+
return {
30+
__
31+
}
32+
},
33+
methods: {
34+
async openAddQuickProduct() {
35+
/**
36+
* We'll check if the user has the right to add a quick product.
37+
*/
38+
await ActionPermissions.canProceed( 'nexopos.cart.products' );
39+
40+
try {
41+
const promise = await new Promise( ( resolve, reject ) => {
42+
Popup.show( nsPosQuickProductPopupVue, { resolve, reject })
43+
});
44+
} catch( exception ) {
45+
// ...
46+
}
47+
}
48+
}
49+
}
50+
</script>
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
<template>
2+
<div class="ns-button">
3+
<button @click="defineOrderSettings()" class="w-full h-10 px-3 outline-hidden flex items-center">
4+
<i class="las la-tools"></i>
5+
<span class="ml-1 hidden md:inline-block">{{ __( 'Settings' ) }}</span>
6+
</button>
7+
</div>
8+
</template>
9+
10+
<script lang="ts">
11+
import { Popup } from '~/libraries/popup';
12+
import { __ } from '~/libraries/lang';
13+
import { nsSnackBar } from '~/bootstrap';
14+
import nsPosOrderSettingsVue from '~/popups/ns-pos-order-settings.vue';
15+
import ActionPermissions from '~/libraries/action-permissions';
16+
17+
declare const POS;
18+
19+
export default {
20+
name: 'ns-pos-cart-settings-button',
21+
props: {
22+
order: {
23+
type: Object,
24+
required: true
25+
},
26+
settings: {
27+
type: Object,
28+
required: true
29+
}
30+
},
31+
data() {
32+
return {
33+
__
34+
}
35+
},
36+
methods: {
37+
async defineOrderSettings() {
38+
if ( ! this.settings.edit_settings ) {
39+
return nsSnackBar.error( __( 'You\'re not allowed to edit the order settings.' ) );
40+
}
41+
42+
/**
43+
* We'll check if the user has the right to define order settings.
44+
*/
45+
await ActionPermissions.canProceed( 'defineOrderSettings' );
46+
47+
try {
48+
const response = await new Promise<{}>( ( resolve, reject) => {
49+
Popup.show( nsPosOrderSettingsVue, { resolve, reject, order : this.order });
50+
});
51+
52+
/**
53+
* We'll update the order
54+
*/
55+
POS.order.next({ ...this.order, ...response });
56+
57+
} catch( exception ) {
58+
// we shouldn't catch any exception here.
59+
}
60+
}
61+
}
62+
}
63+
</script>

0 commit comments

Comments
 (0)