Thanks to visit codestin.com
Credit goes to Github.com

Skip to content

fix: for custom time format store opening closing not working in vendor store settings#3090

Merged
MdAsifHossainNadim merged 9 commits intodevelopfrom
fix/store-openning-closing-time-not-working-for-custom-time-format
Feb 10, 2026
Merged

fix: for custom time format store opening closing not working in vendor store settings#3090
MdAsifHossainNadim merged 9 commits intodevelopfrom
fix/store-openning-closing-time-not-working-for-custom-time-format

Conversation

@juah255
Copy link
Contributor

@juah255 juah255 commented Jan 24, 2026

All Submissions:

  • My code follow the WordPress' coding standards
  • My code satisfies feature requirements
  • My code is tested
  • My code passes the PHPCS tests
  • My code has proper inline documentation
  • I've included related pull request(s) (optional)
  • I've included developer documentation (optional)
  • I've added proper labels to this pull request

Changes proposed in this Pull Request:

Related Pull Request(s)

Closes

How to test the changes in this Pull Request:

  • Steps or issue link

Changelog entry

Title

Detailed Description of the pull request. What was previous behaviour
and what will be changed in this PR.

Before Changes

Describe the issue before changes with screenshots(s).

After Changes

Describe the issue after changes with screenshot(s).

Feature Video (optional)

Link of detailed video if this PR is for a feature.

PR Self Review Checklist:

  • Code is not following code style guidelines
  • Bad naming: make sure you would understand your code if you read it a few months from now.
  • KISS: Keep it simple, Sweetie (not stupid!).
  • DRY: Don't Repeat Yourself.
  • Code that is not readable: too many nested 'if's are a bad sign.
  • Performance issues
  • Complicated constructions that need refactoring or comments: code should almost always be self-explanatory.
  • Grammar errors.

FOR PR REVIEWER ONLY:

As a reviewer, your feedback should be focused on the idea, not the person. Seek to understand, be respectful, and focus on constructive dialog.

As a contributor, your responsibility is to learn from suggestions and iterate your pull request should it be needed based on feedback. Seek to collaborate and produce the best possible contribution to the greater whole.

  • Correct โ€” Does the change do what itโ€™s supposed to? ie: code 100% fulfilling the requirements?
  • Secure โ€” Would a nefarious party find some way to exploit this change? ie: everything is sanitized/escaped appropriately for any SQL or XSS injection possibilities?
  • Readable โ€” Will your future self be able to understand this change months down the road?
  • Elegant โ€” Does the change fit aesthetically within the overall style and architecture?

Summary by CodeRabbit

  • Improvements
    • Consistent, localized time formatting for store open/close fields and pickers using a moment-compatible format.
    • Visible time inputs now mirror selections into hidden fields for reliable form submission.
    • Improved show/hide behavior, validation, error highlighting, and auto-focus on the first invalid time entry.
  • New Features
    • Helper to produce a moment.jsโ€“compatible i18n time format for parsing/formatting.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 24, 2026

๐Ÿ“ Walkthrough

Walkthrough

Server-side time conversions were simplified to pass only the time string; client templates separate visible time inputs from hidden submission inputs; client JS adds a Moment-compatible i18n time-format helper and uses it for timepicker parsing/formatting, validation, and populating hidden fields before submit.

Changes

Cohort / File(s) Summary
Server-side time parsing
includes/Dashboard/Templates/Settings.php
Simplified dokan_convert_date_format calls for opening_time and closing_time to pass only the time string (removed explicit input/output format args).
Client templates โ€” form & time inputs
templates/settings/store-form.php, templates/settings/store-time.php
Visible time inputs no longer have name attributes; added hidden inputs (opening_time, closing_time) to carry submitted values. Markup adjusted to support human-readable visible values while preserving submission values in hidden fields.
Client JS helper & validation
assets/src/js/helper.js, templates/settings/store-form.php (JS)
Added dokan_get_i18n_time_format_for_moment_js() to produce Moment.js-compatible time format; JS uses this format and a locale-normalizer to parse/format timepicker values, validate open/close ranges, and write human-readable times into hidden inputs before submit.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Browser as Client JS
    participant Server as PHP
    participant DB

    User->>Browser: Enter opening/closing times (visible inputs)
    Browser->>Browser: Map locale -> moment format\nParse & format times, populate hidden hidden inputs
    User->>Browser: Submit form
    Browser->>Server: POST with hidden time fields
    Server->>Server: Convert/validate times (dokan_convert_date_format)
    Server->>DB: Save timings
    DB-->>Server: Persisted
    Server-->>Browser: Response (saved)
    Browser-->>User: Show confirmation
Loading

Estimated code review effort

๐ŸŽฏ 3 (Moderate) | โฑ๏ธ ~25 minutes

Suggested labels

PM Dependency

Suggested reviewers

  • mrabbani
  • shohag121

Poem

๐Ÿฐ I hop and tweak each ticking chime,

Visible clocks for show, hidden ones keep time,
Moment molds the localeโ€™s song,
Server tucks the hours along,
A rabbit cheers โ€” all synced and fine.

๐Ÿšฅ Pre-merge checks | โœ… 2 | โŒ 1
โŒ Failed checks (1 warning)
Check name Status Explanation Resolution
Description check โš ๏ธ Warning The PR description is largely incomplete. While it includes the template structure with related PR/issue links, it lacks implementation details, testing steps, screenshots, and changelog content required by the template. Complete the missing sections: describe proposed changes, add testing steps, provide before/after screenshots, fill in the changelog entry, and complete the self-review checklist items.
โœ… Passed checks (2 passed)
Check name Status Explanation
Title check โœ… Passed The title clearly and specifically identifies the primary issue being fixed: custom time format handling for store opening/closing times in vendor settings.
Docstring Coverage โœ… Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

โœ๏ธ Tip: You can configure your own custom pre-merge checks in the settings.

โœจ Finishing touches
  • ๐Ÿ“ Generate docstrings
๐Ÿงช Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/store-openning-closing-time-not-working-for-custom-time-format

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

โค๏ธ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

๐Ÿค– Fix all issues with AI agents
In `@templates/settings/store-form.php`:
- Around line 340-344: The client-side time formatting currently uses
moment(...).format('hh:mm a') for openValueSelected and closeValueSelected which
produces leading zeros; update both calls to use format('h:mm a') to match the
server-side PHP expectation (ensure the two lines setting openValueSelected and
closeValueSelected are changed), so the values written via
$openInputHidden.val(...) and $closeInputHidden.val(...) will have no leading
zero.

In `@templates/settings/store-time.php`:
- Around line 26-32: The value attributes for the opening time inputs are
outputting the raw $opening_time variable and must be escaped to prevent XSS;
update both the visible input (id "opening-time[<?php echo esc_attr( $day_key );
?>]" / class "opening-time") and the hidden input (name "opening_time[<?php echo
esc_attr( $day_key ); ?>]" / class "opening-time-hidden") to wrap $opening_time
with esc_attr() so the attribute values are safely escaped before rendering.
๐Ÿงน Nitpick comments (1)
templates/settings/store-form.php (1)

378-385: Same format inconsistency and missing invalid date handling.

  1. Same 'hh:mm a' vs 'h:mm a' issue as the change handler.
  2. If moment() parsing fails (e.g., empty or malformed input after manual edit), format() returns "Invalid date" which would be submitted to the server.
Proposed fix
                 const formattedOpenValue  = moment( openValue, timeFormatMoment ).format( 'HH:mm' ),
                     formattedCloseValue = moment( closeValue, timeFormatMoment ).format( 'HH:mm' );

-                let openValueSelected  = moment(openValue, timeFormatMoment ).format('hh:mm a');
-                let closeValueSelected = moment(closeValue, timeFormatMoment ).format('hh:mm a');
+                const parsedOpen  = moment( openValue, timeFormatMoment );
+                const parsedClose = moment( closeValue, timeFormatMoment );
+
+                if ( ! parsedOpen.isValid() || ! parsedClose.isValid() ) {
+                    self.find( 'input.dokan-form-control' ).css({ 'border-color': '#F87171', 'color': '#F87171' });
+                    self.find( '.opening-time' ).focus();
+                    e.preventDefault();
+                    return false;
+                }
+
+                let openValueSelected  = parsedOpen.format( 'h:mm a' );
+                let closeValueSelected = parsedClose.format( 'h:mm a' );

                 $openInputHidden.val(openValueSelected);
                 $closeInputHidden.val(closeValueSelected);

Comment on lines 340 to 344
let openValueSelected = moment( openValue, timeFormatMoment ).format('hh:mm a' );
let closeValueSelected = moment( closeValue, timeFormatMoment ).format('hh:mm a' );

$openInputHidden.val( openValueSelected );
$closeInputHidden.val( closeValueSelected );
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

โš ๏ธ Potential issue | ๐ŸŸก Minor

Use 'h:mm a' format to match server-side expectations.

The 'hh:mm a' format outputs times with leading zeros (e.g., "09:30 am"), but the PHP backend uses 'g:i a' which expects no leading zeros (e.g., "9:30 am"). Use moment's single 'h' to avoid potential parsing issues.

Proposed fix
-                let openValueSelected  = moment( openValue, timeFormatMoment ).format('hh:mm a' );
-                let closeValueSelected = moment( closeValue, timeFormatMoment ).format('hh:mm a' );
+                let openValueSelected  = moment( openValue, timeFormatMoment ).format('h:mm a' );
+                let closeValueSelected = moment( closeValue, timeFormatMoment ).format('h:mm a' );
๐Ÿ“ Committable suggestion

โ€ผ๏ธ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
let openValueSelected = moment( openValue, timeFormatMoment ).format('hh:mm a' );
let closeValueSelected = moment( closeValue, timeFormatMoment ).format('hh:mm a' );
$openInputHidden.val( openValueSelected );
$closeInputHidden.val( closeValueSelected );
let openValueSelected = moment( openValue, timeFormatMoment ).format('h:mm a' );
let closeValueSelected = moment( closeValue, timeFormatMoment ).format('h:mm a' );
$openInputHidden.val( openValueSelected );
$closeInputHidden.val( closeValueSelected );
๐Ÿค– Prompt for AI Agents
In `@templates/settings/store-form.php` around lines 340 - 344, The client-side
time formatting currently uses moment(...).format('hh:mm a') for
openValueSelected and closeValueSelected which produces leading zeros; update
both calls to use format('h:mm a') to match the server-side PHP expectation
(ensure the two lines setting openValueSelected and closeValueSelected are
changed), so the values written via $openInputHidden.val(...) and
$closeInputHidden.val(...) will have no leading zero.

@juah255 juah255 requested a review from mrabbani January 24, 2026 11:05
@juah255 juah255 added the Needs: Dev Review It requires a developer review and approval label Jan 24, 2026
@MdAsifHossainNadim MdAsifHossainNadim added the Needs: Testing This requires further testing label Jan 26, 2026
@juah255 juah255 self-assigned this Jan 26, 2026
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

๐Ÿค– Fix all issues with AI agents
In `@templates/settings/store-form.php`:
- Around line 339-361: The change handler on
$('.dokan-store-times').on('change', '.dokan-form-group', ...) currently
compares formattedOpenValue > formattedCloseValue which permits equal open/close
times visually but the submit handler uses formattedOpenValue >=
formattedCloseValue and blocks equals; update the change handler's comparison to
formattedOpenValue >= formattedCloseValue (the same comparison used on submit)
so the error styling triggers immediately โ€” locate the handler by the selector
'.dokan-store-times' / '.dokan-form-group' and the variables formattedOpenValue
and formattedCloseValue and replace the '>' check with '>=' for consistency.

In `@templates/settings/store-time.php`:
- Around line 37-41: The template references an undefined variable $full_day and
uses the magic sentinel string '11:59 pm'; fix by pulling $full_day from the
incoming $args with a safe default (e.g. $full_day = isset($args['full_day']) ?
(bool)$args['full_day'] : false) in templates/settings/store-time.php so the
ternary on $closing_time won't error, and replace the literal '11:59 pm'
comparison with a named constant (e.g. define('STORE_FULL_DAY_SENTINEL', '11:59
pm') or use an existing class constant like Store_Settings::FULL_DAY_SENTINEL)
and use that constant in the closing_time hidden input value expression to avoid
brittle string comparisons; ensure any other uses of the sentinel across the
template or related store-form.php consume the same constant.
๐Ÿงน Nitpick comments (1)
templates/settings/store-form.php (1)

321-329: mapTimepickerLocaleToMoment performs sequential single-occurrence replacements โ€” beware of overlapping tokens.

The chained .replace() calls replace locale AM/PM strings one at a time. If a locale's PM string happens to be a substring of the AM string (or vice versa), or if the time value itself contains characters that match a locale token unexpectedly, the replacements can interfere with each other.

For typical locales this is fine, but consider guarding against it by only replacing the matched locale token (e.g., using a regex with word boundaries or replacing only the last token in the string).

Comment on lines +339 to 361
$('.dokan-store-times').on('change', '.dokan-form-group', function() {
const self = $(this),
openValue = self.find('.opening-time').val(),
closeValue = self.find('.closing-time').val(),
openInputHidden = self.find('.opening-time-hidden'),
closeInputHidden = self.find('.closing-time-hidden'),
formattedOpenValue = moment(mapTimepickerLocaleToMoment(openValue), timeFormatMoment).format('HH:mm'),
formattedCloseValue = moment(mapTimepickerLocaleToMoment(closeValue), timeFormatMoment).format('HH:mm');

let openValueSelected = moment(mapTimepickerLocaleToMoment(openValue), timeFormatMoment).locale('en').format('hh:mm a');
let closeValueSelected = moment(mapTimepickerLocaleToMoment(closeValue), timeFormatMoment).locale('en').format('hh:mm a');

openInputHidden.val(openValueSelected);
closeInputHidden.val(closeValueSelected);
if (formattedOpenValue > formattedCloseValue) {
self.find('input.dokan-form-control').css({
'border-color': '#F87171',
'color': '#F87171'
});
} else {
self.find( 'input.dokan-form-control' ).css({ 'border-color': '#bbb', 'color': '#4e4e4e' });
}
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

โš ๏ธ Potential issue | ๐ŸŸก Minor

Inconsistent validation: change handler uses > but submit handler uses >= for time comparison.

On line 353 (change handler), the comparison is formattedOpenValue > formattedCloseValue, which allows equal open/close times without flagging an error. On line 399 (submit handler), it's formattedOpenValue >= formattedCloseValue, which rejects equal times. This means a user can set equal open/close times, see no visual error feedback, but then be blocked on submit โ€” a confusing UX.

Use >= in both places so the error styling appears immediately.

Proposed fix (change handler, line 353)
-                if (formattedOpenValue > formattedCloseValue) {
+                if (formattedOpenValue >= formattedCloseValue) {

Also applies to: 363-411

๐Ÿค– Prompt for AI Agents
In `@templates/settings/store-form.php` around lines 339 - 361, The change handler
on $('.dokan-store-times').on('change', '.dokan-form-group', ...) currently
compares formattedOpenValue > formattedCloseValue which permits equal open/close
times visually but the submit handler uses formattedOpenValue >=
formattedCloseValue and blocks equals; update the change handler's comparison to
formattedOpenValue >= formattedCloseValue (the same comparison used on submit)
so the error styling triggers immediately โ€” locate the handler by the selector
'.dokan-store-times' / '.dokan-form-group' and the variables formattedOpenValue
and formattedCloseValue and replace the '>' check with '>=' for consistency.

Comment on lines 37 to 41
value="<?php echo esc_attr( ! $full_day ? dokan_convert_date_format( $closing_time, 'g:i A', 'H:i' ) : '' ); ?>" />
<input type="hidden"
name="closing_time[<?php echo esc_attr( $day_key ); ?>]"
class="closing-time-hidden"
value="<?php echo esc_attr( $closing_time === '11:59 pm' ? '11:30 pm' : $closing_time ); ?>" />
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

โš ๏ธ Potential issue | ๐Ÿ”ด Critical

๐Ÿงฉ Analysis chain

๐Ÿ Script executed:

#!/bin/bash
# First, locate the file and get its full context
find . -name "store-time.php" -type f

Repository: getdokan/dokan

Length of output: 93


๐Ÿ Script executed:

#!/bin/bash
# Search for $full_day definition/usage
rg -n '\$full_day' --type php -B3 -A3

Repository: getdokan/dokan

Length of output: 999


๐Ÿ Script executed:

#!/bin/bash
# Search for '11:59 pm' sentinel usage across the codebase
rg -n '11:59 pm' --type php

Repository: getdokan/dokan

Length of output: 214


๐Ÿ Script executed:

#!/bin/bash
# Also search for variations like uppercase/no space
rg -n '11:59' --type php | head -20

Repository: getdokan/dokan

Length of output: 214


๐Ÿ Script executed:

#!/bin/bash
# Get line count and read the entire template file
wc -l ./templates/settings/store-time.php
echo "---"
cat -n ./templates/settings/store-time.php

Repository: getdokan/dokan

Length of output: 3530


๐Ÿ Script executed:

#!/bin/bash
# Find where this template is included/required from
rg -n 'store-time.php' --type php

Repository: getdokan/dokan

Length of output: 40


๐Ÿ Script executed:

#!/bin/bash
# Search for where $full_day is SET (not just used)
rg -n '\$full_day\s*=' --type php -B2 -A2

Repository: getdokan/dokan

Length of output: 40


๐Ÿ Script executed:

#!/bin/bash
# Find where store-time.php is included/required
rg -n 'store-time' --type php -B2 -A2

Repository: getdokan/dokan

Length of output: 7814


๐Ÿ Script executed:

#!/bin/bash
# Search in the templates directory for includes and parent files
rg -n '\$full_day' --type php -B5 -A5 2>/dev/null | head -50

Repository: getdokan/dokan

Length of output: 1396


๐Ÿ Script executed:

#!/bin/bash
# Look for template loading in controller/view files
fd -name '*.php' -path '*/templates/*' | grep -i store | head -20

Repository: getdokan/dokan

Length of output: 288


๐Ÿ Script executed:

#!/bin/bash
# Read store-form.php to see how $args is built
wc -l ./templates/settings/store-form.php
echo "---"
sed -n '1,100p' ./templates/settings/store-form.php | cat -n

Repository: getdokan/dokan

Length of output: 6053


๐Ÿ Script executed:

#!/bin/bash
# Search for where the template is actually included/loaded in store-form.php
rg -n 'get_template_part|include|require' ./templates/settings/store-form.php

Repository: getdokan/dokan

Length of output: 360


๐Ÿ Script executed:

#!/bin/bash
# Search for $full_day assignment across the entire codebase
rg -n '\$full_day' --type php

Repository: getdokan/dokan

Length of output: 234


๐Ÿ Script executed:

#!/bin/bash
# Find the dokan_get_template_part function definition
rg -n 'function dokan_get_template_part' --type php -A10

Repository: getdokan/dokan

Length of output: 609


๐Ÿ Script executed:

#!/bin/bash
# Also search for where $full_day might be set via filter or other means
rg -n 'full_day' --type php

Repository: getdokan/dokan

Length of output: 234


๐Ÿ Script executed:

#!/bin/bash
# Check if there's extract() call in store-time.php or its parent
rg -n 'extract\(' --type php | grep -E '(store-time|store-form)'

Repository: getdokan/dokan

Length of output: 40


Fix the undefined $full_day variable and extract the '11:59 pm' sentinel to a named constant.

The $full_day variable referenced on line 37 is never passed in the $args array (defined in store-form.php lines 43-47) and doesn't exist anywhere else in the codebase. This will cause an undefined variable error when the template renders. The '11:59 pm' sentinel comparison on line 41 is brittleโ€”it should be defined as a class constant or configuration value to avoid silent failures if the stored time format ever changes.

๐Ÿค– Prompt for AI Agents
In `@templates/settings/store-time.php` around lines 37 - 41, The template
references an undefined variable $full_day and uses the magic sentinel string
'11:59 pm'; fix by pulling $full_day from the incoming $args with a safe default
(e.g. $full_day = isset($args['full_day']) ? (bool)$args['full_day'] : false) in
templates/settings/store-time.php so the ternary on $closing_time won't error,
and replace the literal '11:59 pm' comparison with a named constant (e.g.
define('STORE_FULL_DAY_SENTINEL', '11:59 pm') or use an existing class constant
like Store_Settings::FULL_DAY_SENTINEL) and use that constant in the
closing_time hidden input value expression to avoid brittle string comparisons;
ensure any other uses of the sentinel across the template or related
store-form.php consume the same constant.

@dev-shahed dev-shahed added ๐ŸŽ‰ QA Approved This PR is approved by the QA team and removed Needs: Testing This requires further testing labels Feb 9, 2026
@MdAsifHossainNadim MdAsifHossainNadim added Dev Review Done and removed Needs: Dev Review It requires a developer review and approval labels Feb 10, 2026
@MdAsifHossainNadim MdAsifHossainNadim merged commit 1c8262b into develop Feb 10, 2026
1 of 6 checks passed
@MdAsifHossainNadim MdAsifHossainNadim deleted the fix/store-openning-closing-time-not-working-for-custom-time-format branch February 10, 2026 10:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Dev Review Done ๐ŸŽ‰ QA Approved This PR is approved by the QA team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants