Found issue in oc-includes/osclass/ItemActions.php: replaced this part and the issue with the expiration date is fixed.
// Manage expiration date
if($is_add || $this->is_admin) {
$dt_expiration = Params::getParam('dt_expiration');
if($dt_expiration == -1 || $dt_expiration == '') {
$aItem['dt_expiration'] = '';
} elseif (
$dt_expiration != ''
&& (
ctype_digit($dt_expiration)
|| preg_match('|^([0-9]{4})-([0-9]{2})-([0-9]{2}) ([0-9]{2}):([0-9]{2}):([0-9]{2})$|', $dt_expiration, $match)
|| preg_match('|^([0-9]{4})-([0-9]{2})-([0-9]{2})$|', $dt_expiration, $match)
)
) {
$aItem['dt_expiration'] = $dt_expiration;
$_category = osc_get_category_row($aItem['catId']);
if (ctype_digit($dt_expiration)) {
if (!$this->is_admin && $dt_expiration > $_category['i_expiration_days']) {
$aItem['dt_expiration'] = $_category['i_expiration_days'];
}
} else {
if(preg_match('|^([0-9]{4})-([0-9]{2})-([0-9]{2})$|', $dt_expiration, $match)) {
$aItem['dt_expiration'] .= ' 23:59:59';
}
if(!$this->is_admin && strtotime($dt_expiration) > (time() + $_category['i_expiration_days'] * 24 * 3600)) {
$aItem['dt_expiration'] = $_category['i_expiration_days'];
}
}
} else {
$_category = osc_get_category_row($aItem['catId']);
$aItem['dt_expiration'] = (isset($_category['i_expiration_days']) ? $_category['i_expiration_days'] : null);
}
unset($dt_expiration);
} else {
$aItem['dt_expiration'] = '';
}
Replace with:
// Manage expiration date
if($is_add || $this->is_admin) {
$dt_expiration = Params::getParam('dt_expiration');
$_category = Category::newInstance()->findByPrimaryKey($aItem['catId']);
$cat_days = isset($_category['i_expiration_days']) ? (int)$_category['i_expiration_days'] : 0;
if ($dt_expiration == -1) {
// Never expires
$aItem['dt_expiration'] = '';
} elseif ($dt_expiration != '' && (
ctype_digit($dt_expiration) ||
preg_match('|^([0-9]{4})-([0-9]{2})-([0-9]{2})$|', $dt_expiration) ||
preg_match('|^([0-9]{4})-([0-9]{2})-([0-9]{2}) ([0-9]{2}):([0-9]{2}):([0-9]{2})$|', $dt_expiration)
)) {
if (ctype_digit($dt_expiration)) {
// It's a number of days
$days = (int)$dt_expiration;
if (!$this->is_admin && $days > $cat_days) {
$days = $cat_days;
}
$aItem['dt_expiration'] = date('Y-m-d H:i:s', time() + ($days * 86400));
} else {
// It's a date or datetime string
if (preg_match('|^([0-9]{4})-([0-9]{2})-([0-9]{2})$|', $dt_expiration)) {
// Gebruik huidige tijd i.p.v. 23:59:59
$dt_expiration .= ' ' . date('H:i:s');
}
// Restrict if date is too far in the future for regular users
if (!$this->is_admin && strtotime($dt_expiration) > (time() + $cat_days * 86400)) {
$aItem['dt_expiration'] = date('Y-m-d H:i:s', time() + ($cat_days * 86400));
} else {
$aItem['dt_expiration'] = $dt_expiration;
}
}
} else {
// No valid date or days given, fallback to category limit
$aItem['dt_expiration'] = date('Y-m-d H:i:s', time() + ($cat_days * 86400));
}
unset($dt_expiration);
} else {
$aItem['dt_expiration'] = '';
}
When a number of days was submitted (e.g. 30), the code simply assigned it directly like this: $aItem['dt_expiration'] = $_category['i_expiration_days'];
When a full date or datetime string was passed, the code tried to add 23:59:59, but sometimes this got overwritten.
For numeric input (number of days), the code did not convert it into a proper datetime.
The category limit (i_expiration_days) was mixed in without clear structure.