Skip to content

Commit f448dd3

Browse files
authored
Merge pull request #211 from globaldyne/v12.8
V12.8
2 parents 1579f2d + fd360ed commit f448dd3

26 files changed

+207
-184
lines changed

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,13 @@
11
# CHANGELOG
2+
### Version 12.8
3+
- Added links for PV apps
4+
- Fix ingredient import compounds failing to import
5+
- Fix AromaTrack app api
6+
- Fix JSON export from within the formula page
7+
- Minor cosmetic changes
8+
- Remove user session on logout even if the session delete query fails
9+
- Backwards compatibility db schema fix
10+
211
### Version 12.7
312
- Improved security for fetching ingredient providers
413
- FPDF lib update to 1.86

VERSION.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
12.7
1+
12.8

api-functions/aromatrack_get.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ function normalize_value($value, $type = 'string', $default = '-') {
3636
// Fetch supplier data
3737
$supplier_query = "SELECT ingSupplierID, price, size, stock, mUnit, status FROM suppliers WHERE ingID = '{$rx['id']}' AND preferred = 1 AND owner_id = '$userID'";
3838
$gSupQ = fetch_assoc($conn, $supplier_query);
39-
39+
error_log('PV API AROMATRACK QUERY: '.$supplier_query);
4040
// Fetch supplier name
4141
$supplier_name_query = "SELECT * FROM ingSuppliers WHERE id = '{$gSupQ['ingSupplierID']}' AND owner_id = '$userID'";
4242
$gSupN = fetch_assoc($conn, $supplier_name_query);
@@ -56,7 +56,7 @@ function normalize_value($value, $type = 'string', $default = '-') {
5656
$rx['price'] = normalize_value($price_per_unit, 'float', 0.0);
5757
$rx['stock'] = normalize_value($gSupQ['stock'], 'float', 0.0);
5858
$rx['mUnit'] = normalize_value($gSupQ['mUnit']);
59-
$rx['avilability'] = (int)normalize_value($gSupQ['status']) ?: 0;
59+
$rx['availability'] = (int)normalize_value($gSupQ['status']) ?: 0;
6060
$rx['updated_at'] = normalize_value(date(DATE_ISO8601, strtotime($rx['updated_at'])));
6161
$rx['created_at'] = normalize_value(date(DATE_ISO8601, strtotime($rx['created_at'])));
6262

@@ -75,12 +75,12 @@ function normalize_value($value, $type = 'string', $default = '-') {
7575
'created_at' => normalize_value($gSupN['created_at'] ? date(DATE_ISO8601, strtotime($gSupN['created_at'])) : date(DATE_ISO8601)),
7676
];
7777

78-
7978
$r[] = $rx;
8079
}
8180

8281
// Output JSON response
8382
$response = [
83+
"status" => "success",
8484
"ingredients" => $r,
8585
];
8686
echo json_encode($response, JSON_PRETTY_PRINT);

core/import_ingredients.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -204,9 +204,9 @@ function processIngredientCompounds($compounds) {
204204
return mysqli_real_escape_string($conn, $value);
205205
}, $cmp);
206206

207-
$query_check = "SELECT COUNT(*) FROM `ingredient_compounds` WHERE `name` = '{$cmp['name']}' AND `owner_id` = '$userID'";
207+
$query_check = "SELECT COUNT(*) FROM `ingredient_compounds` WHERE `name` = '{$cmp['name']}' AND `ing` = '{$cmp['ing']}' AND `owner_id` = '$userID'";
208208
$exists = mysqli_fetch_row(mysqli_query($conn, $query_check))[0];
209-
209+
// error_log("PV: Checking for existing compound: $query_check, exists: $exists");
210210
if ($exists == 0) {
211211
$query = "INSERT INTO `ingredient_compounds` (ing, name, cas, ec, min_percentage, max_percentage, GHS, toDeclare, created_at, owner_id)
212212
VALUES ('{$cmp['ing']}', '{$cmp['name']}', '{$cmp['cas']}', '{$cmp['ec']}', '{$cmp['min_percentage']}', '{$cmp['max_percentage']}', '{$cmp['GHS']}', '{$cmp['toDeclare']}', CURRENT_TIMESTAMP(), '$userID')";

css/select2.css

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -407,11 +407,16 @@
407407
.select2-container--classic .select2-selection--single .select2-selection__rendered {
408408
color: #444;
409409
line-height: 28px; }
410+
410411
.select2-container--classic .select2-selection--single .select2-selection__clear {
411412
cursor: pointer;
412413
float: right;
413414
font-weight: bold;
414-
margin-right: 10px; }
415+
margin-right: 10px;
416+
background-color: var(--bs-body-color);
417+
418+
}
419+
415420
.select2-container--classic .select2-selection--single .select2-selection__placeholder {
416421
color: #999; }
417422
.select2-container--classic .select2-selection--single .select2-selection__arrow {

css/vault.css

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1530,9 +1530,10 @@ th.dt-center, td.dt-center {
15301530
}
15311531

15321532
.pvScale-data-footer {
1533-
position: -webkit-sticky;
15341533
position: sticky;
1535-
bottom: 0;
1534+
bottom: 0;
1535+
background-color: var(--bs-primary-text-emphasis) !important;
1536+
color: var(--bs-light) !important;
15361537
}
15371538

15381539
.highlight {

db/schema.ver

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
12.7
1+
12.8

db/updates/update_12.6-12.7.sql

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
ALTER TABLE `ingredients` ADD `aromaTrackID` VARCHAR(255) NULL DEFAULT NULL AFTER `shelf_life`;
22
ALTER TABLE `ingSuppliers` ADD `currency` VARCHAR(255) NULL DEFAULT NULL AFTER `country`;
33
INSERT INTO `system_settings` (`key_name`, `value`, `slug`, `type`, `description`, `created_at`, `updated_at`) VALUES ('API_enabled', '0', 'API access', 'checkbox', 'Enable or disable API access globally', current_timestamp(), current_timestamp());
4-
UPDATE `ingTypes` SET `name` = 'Other/Unknown' WHERE `ingTypes`.`name` = 'Other/Uknown';
5-
6-
ALTER TABLE `batchIDHistory` CHANGE `created` `created_at` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP;
4+
UPDATE `ingTypes` SET `name` = 'Other/Unknown' WHERE `ingTypes`.`name` = 'Other/Uknown';

img/Pyramid/Pyramid_Slice_Base.png

1.31 MB
Loading

img/Pyramid/Pyramid_Slice_Heart.png

1.33 MB
Loading

img/Pyramid/Pyramid_Slice_Top.png

1.33 MB
Loading

img/Pyramid/Pyramid_Slice_Uknown.png

294 KB
Loading

img/appstore/get_aroma_track.png

39.4 KB
Loading

img/appstore/get_pv.png

36.2 KB
Loading

img/liquid.png

1.57 MB
Loading

img/solid.png

1.28 MB
Loading

js/fullformula.view.js

Lines changed: 41 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -594,22 +594,24 @@ $("#formula").on("click", ".open-quantity-dialog", function () {
594594
});
595595

596596

597-
$('.export_as').click(function() {
598-
var format = $(this).attr('data-format');
599-
$("#formula").tableHTMLExport({
600-
type: format,
601-
filename: myFNAME + "." + format,
602-
separator: ',',
603-
newline: '\r\n',
604-
trimContent: true,
605-
quoteFields: true,
606-
ignoreColumns: '.noexport',
607-
ignoreRows: '.noexport',
608-
htmlContent: false,
609-
orientation: 'l',
610-
subtitle: 'Created with Perfumer\'s Vault Pro',
611-
maintitle: myFNAME,
612-
});
597+
$('.export_as').click(function() {
598+
const format = $(this).data('format');
599+
const options = {
600+
type: format,
601+
filename: `${myFNAME}.${format}`,
602+
separator: ',',
603+
newline: '\r\n',
604+
trimContent: true,
605+
quoteFields: true,
606+
ignoreColumns: '.noexport',
607+
ignoreRows: '.noexport',
608+
htmlContent: false,
609+
orientation: 'l',
610+
subtitle: "Created with Perfumer's Vault Pro",
611+
maintitle: myFNAME,
612+
};
613+
614+
$("#formula").tableHTMLExport(options);
613615
});
614616

615617
$("#slvMeta, #slvMetaAdd").hide();
@@ -682,38 +684,34 @@ $('.table').on('hide.bs.dropdown', function () {
682684
});
683685

684686

685-
function update_bar(){
686-
$.getJSON("/core/full_formula_data.php?id="+myID+"&stats_only=1", function (json) {
687-
688-
$('#formula_name').html(json.stats.formula_name || "Unnamed");
689-
$('#formula_desc').html(json.stats.formula_description);
687+
function update_bar() {
688+
$.getJSON(`/core/full_formula_data.php?id=${myID}&stats_only=1`, function (json) {
689+
const stats = json.stats || {};
690+
const data = stats.data || {};
691+
692+
$('#formula_name').html(stats.formula_name || "Unnamed");
693+
$('#formula_desc').html(stats.formula_description || "");
690694

691-
if (json.stats.data) {
695+
if (data) {
692696
$('#progress-area').show();
693-
694-
var top = Math.round(json.stats.data.top.current);
695-
var top_max = Math.round(json.stats.data.top.max);
696-
697-
var heart = Math.round(json.stats.data.heart.current);
698-
var heart_max = Math.round(json.stats.data.heart.max);
699-
700-
var base = Math.round(json.stats.data.base.current);
701-
var base_max = Math.round(json.stats.data.base.max);
702-
703-
$('#top_bar').attr('aria-valuenow', top).css('width', top + '%').attr('aria-valuemax', top_max);
704-
$('#heart_bar').attr('aria-valuenow', heart).css('width', heart + '%').attr('aria-valuemax', heart_max);
705-
$('#base_bar').attr('aria-valuenow', base).css('width', base + '%').attr('aria-valuemax', base_max);
706-
707-
$('#top_label').html(top + "% Top Notes");
708-
$('#heart_label').html(heart + "% Heart Notes");
709-
$('#base_label').html(base + "% Base Notes");
710-
711697

698+
const updateProgressBar = (barId, labelId, value, max, labelText) => {
699+
const percentage = Math.round(value);
700+
const maxValue = Math.round(max);
701+
$(`#${barId}`)
702+
.attr('aria-valuenow', percentage)
703+
.css('width', `${percentage}%`)
704+
.attr('aria-valuemax', maxValue);
705+
$(`#${labelId}`).html(`${percentage}% ${labelText}`);
706+
};
707+
708+
updateProgressBar('top_bar', 'top_label', data.top.current, data.top.max, "Top Notes");
709+
updateProgressBar('heart_bar', 'heart_label', data.heart.current, data.heart.max, "Heart Notes");
710+
updateProgressBar('base_bar', 'base_label', data.base.current, data.base.max, "Base Notes");
712711
} else {
713712
$('#progress-area').hide();
714713
}
715-
716-
});
717-
};
714+
});
715+
}
718716

719717
update_bar();

js/import.ingredients.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ $('#btnRestoreIngredients').click(function (event) {
9797
$("#btnRestoreIngredients").hide();
9898
$("#backupArea").hide();
9999
$('#tdDataIng').DataTable().ajax.reload(null, false);
100+
$("#btnRestoreIngredientsCloseBK").prop("disabled", false);
100101
} else if (data.warning) {
101102
msg = `<div class="alert alert-warning"><i class="fa-solid fa-exclamation-circle mx-2"></i><strong>Import complete with warnings</strong> <br/>${data.warning}</div>`;
102103
} else if (data.error) {

login.php

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -337,21 +337,38 @@
337337
</div>
338338
<?php } ?>
339339
<?php if ($system_settings['USER_selfRegister'] == '1') { ?>
340-
<hr />
341340
<div class="text-center">
342341
<a class="small" href="/register.php">Create an Account!</a>
343342
</div>
344343
<?php
345344
}
346345
}
347346

348-
?>
349-
<hr />
350-
<div class="copyright text-center my-auto">
351-
<label class="small">Version: <?php echo $ver; ?> |<a
352-
href="https://www.perfumersvault.com/" class="mx-1"
353-
target="_blank"><?php echo $product; ?></a></label>
347+
?>
348+
<div class="container my-auto">
349+
<div class="copyright text-center my-auto">
350+
<hr/>
351+
<strong><a href="https://www.perfumersvault.com" target="_blank"><?php echo $product; ?></a></strong>
352+
<div id="footer_release" class="pv_point_gen"> Version: <strong><?php echo $ver ." ". $commit; ?></strong></div>
353+
<div><a href="https://discord.gg/WxNE8kR8ug" target="_blank"><strong>Discord Server</strong></a></div>
354+
<div class="mt-2" style="display: flex; justify-content: center; align-items: center; gap: 20px;">
355+
<div style="text-align: center;">
356+
<a href="https://apps.apple.com/us/app/perfumers-vault/id1525381567" target="_blank">
357+
<img src="/img/appstore/get_pv.png" alt="App Store" style="width: 150px;">
358+
</a>
359+
<div class="mt-1">Get the Perfumers Vault app</div>
360+
</div>
361+
<div style="text-align: center;">
362+
<a href="https://apps.apple.com/us/app/aromatrack/id6742348411" target="_blank">
363+
<img src="/img/appstore/get_aroma_track.png" alt="App Store" style="width: 150px;">
364+
</a>
365+
<div class="mt-1">Get the AromaTrack app</div>
366+
</div>
367+
</div>
368+
<div class="mt-2">Copyright &copy; 2017-<?php echo date('Y'); ?></div>
369+
</div>
354370
</div>
371+
355372
<?php if ($system_settings['USER_selfRegister'] == '1' && !empty($system_settings['USER_privacy_url'])) { ?>
356373
<div class="text-center">
357374
<a class="small"

logout.php

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,17 @@
1717
$userID = $_SESSION['userID'];
1818
error_log("User $userID logged out");
1919

20+
session_unset();
21+
session_destroy();
22+
2023
try {
2124
$conn = mysqli_connect($dbhost, $dbuser, $dbpass, $dbname);
2225
if (!$conn) {
2326
throw new Exception("Failed to connect to database: " . mysqli_connect_error());
2427
}
2528

2629
if (!mysqli_query($conn, "DELETE FROM session_info WHERE owner_id = '$userID'")) {
27-
throw new Exception("Failed to delete session info for user $userID: " . mysqli_error($conn));
30+
throw new Exception("Failed to delete session info");
2831
}
2932
} catch (Exception $e) {
3033
error_log($e->getMessage());
@@ -33,8 +36,7 @@
3336
exit();
3437
}
3538

36-
session_unset();
37-
session_destroy();
39+
3840

3941
if (ini_get("session.use_cookies")) {
4042
$params = session_get_cookie_params();

pages/export.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -863,7 +863,7 @@
863863

864864
while ($row = mysqli_fetch_assoc($compoundResult)) {
865865
$compositions[] = [
866-
'id' => (int)$row['id'],
866+
//'id' => (int)$row['id'],
867867
'ing' => (string)$row['ing'],
868868
'name' => (string)$row['name'],
869869
'cas' => (string)($row['cas'] ?: '-'),

pages/footer.php

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,24 @@
2626
<footer class="sticky-footer">
2727
<div class="container my-auto">
2828
<div class="copyright text-center my-auto">
29-
<hr/>
29+
<hr/>
3030
<strong><a href="https://www.perfumersvault.com" target="_blank"><?php echo $product; ?></a></strong>
3131
<div id="footer_release" class="pv_point_gen"> Version: <strong><?php echo $ver ." ". $commit; ?></strong></div>
3232
<div><a href="https://discord.gg/WxNE8kR8ug" target="_blank"><strong>Discord Server</strong></a></div>
33+
<div class="mt-2" style="display: flex; justify-content: center; align-items: center; gap: 20px;">
34+
<div style="text-align: center;">
35+
<a href="https://apps.apple.com/us/app/perfumers-vault/id1525381567" target="_blank">
36+
<img src="/img/appstore/get_pv.png" alt="App Store" style="width: 150px;">
37+
</a>
38+
<div class="mt-1">Get the Perfumers Vault app</div>
39+
</div>
40+
<div style="text-align: center;">
41+
<a href="https://apps.apple.com/us/app/aromatrack/id6742348411" target="_blank">
42+
<img src="/img/appstore/get_aroma_track.png" alt="App Store" style="width: 150px;">
43+
</a>
44+
<div class="mt-1">Get the AromaTrack app</div>
45+
</div>
46+
</div>
3347
<div class="mt-2">Copyright &copy; 2017-<?php echo date('Y'); ?></div>
3448
</div>
3549
</div>

0 commit comments

Comments
 (0)