Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Module/form manager #2098

Open
wants to merge 93 commits into
base: develop
Choose a base branch
from
Open

Module/form manager #2098

wants to merge 93 commits into from

Conversation

nurul-umbhiya
Copy link
Contributor

@nurul-umbhiya nurul-umbhiya commented Dec 11, 2023

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)

https://github.com/getdokan/dokan-pro/pull/2883

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

  • New Features

    • Introduced form validation and custom section rendering in the product editor based on category selection.
    • Enhanced product creation process with improved attribute handling and UI interactions.
  • Bug Fixes

    • Adjusted styles for validation errors and hidden elements to improve UI consistency.
  • Refactor

    • Removed outdated product creation functions and streamlined product form handling.
    • Updated catalog mode data handling for improved data integrity and security.
  • Chores

    • Added new properties and methods to enhance product form components and attributes management.
  • Revert

    • Deprecated old product save functions and introduced new methods for handling product data efficiently.

devAsadNur and others added 25 commits September 1, 2023 11:50
…nd made Single Step Product Edit page as default

refactor: replaced product add/edit page code with OOP
fix: added Dokan Pro checks for `product_vendors_can_create_tags` and `product_category_style` admin settings
… dokan_product_edit_meta_data, this will save some executions

refactor: removed update_post_meta and get_post_meta references
…Manager.php to prevent direct access to the files
@nurul-umbhiya nurul-umbhiya added the In Progress The issues is being worked on label Dec 11, 2023
@devAsadNur
Copy link
Member

For the Product Form Customize feature, the task has been done from my end. Now, @nurul-umbhiya Bhai is working on rewrite.

CC: @Mohaiminulislam1989 Bhai, @shams-sadek1981 Bhai

@nurul-umbhiya nurul-umbhiya added Needs: Testing This requires further testing Needs: Dev Review It requires a developer review and approval and removed In Progress The issues is being worked on labels Apr 30, 2024
@nurul-umbhiya
Copy link
Contributor Author

Product Form Manager-related rewrite is completed from my end. @Mohaiminulislam1989 @shams-sadek1981

@devAsadNur devAsadNur requested a review from mrabbani June 10, 2024 05:49
Copy link
Contributor

coderabbitai bot commented Jun 26, 2024

Walkthrough

The update to this codebase involves multiple functionalities and structure improvements, including new validation methods in the product editor, UI and CSS adjustments, AJAX control flow alterations, deprecations, metadata handling improvements, added dependencies, and better category handling. Notably, key classes and methods have been refined to streamline product creation, attribute handling, catalog mode updates, and metadata management, while some deprecated methods have been replaced for better performance and maintainability.

Changes

Files/Directories Change Summary
.gitignore Added dokan-tailwind.js to ignore list.
assets/src/js/product-editor.js Added form validation, custom section rendering, and modified product creation process.
assets/src/less/dashboard.less Styled validation error messages.
assets/src/less/products.less Changes to hide elements, update selectors, and modify padding.
dokan.php Added new property and constant, initialized new class.
includes/Admin/Notices/Manager.php Removed specific notice functions.
includes/Admin/Settings.php Removed one_step_product_create and disable_product_popup settings.
includes/Ajax.php Removed create_product() function from constructor.
includes/Assets.php Added new import, method, and updated script dependencies.
includes/Blocks/ProductBlock.php Added conditional check for a pro version in get_configurations method.
includes/.../CatalogMode/Products.php, ProductBulkEdit.php Enhanced handling of catalog mode data with better safety checks and methods.
includes/.../CatalogMode/Helper.php Improved catalog mode data retrieval for product variations.
includes/.../Dashboard/Manager.php Added new property templates with type TemplateManager.
includes/.../Dashboard/Templates/... Updated properties and imports related to products and categories.
includes/Emails/... Changed meta data update methods from update_meta_data to add_meta_data.
includes/Product/... Added, modified, and deprecated methods in product management-related classes and functions for better handling and readability.
includes/ProductCategory/... Fixed typos and updated methods to utilize the caching and category retrieval more efficiently.
includes/ProductForm/... Introduced new classes and methods for handling product form elements and attributes effectively.

Sequence Diagram(s)

Product Creation Process (After Changes)

sequenceDiagram
    participant Vendor as Vendor
    participant Dokan_Editor as Dokan_Editor
    participant Server as Server
    participant Database as Database

    Vendor->>Dokan_Editor: Open Product Editor
    Dokan_Editor->>Vendor: Display Form
    Vendor->>Dokan_Editor: Enter Product Details
    Dokan_Editor->>Dokan_Editor: Validate Form
    alt Form Valid
        Dokan_Editor->>Server: Submit Product Details
        Server->>Database: Save Product
        Database->>Server: Acknowledge
        Server->>Dokan_Editor: Success Response
        Dokan_Editor->>Vendor: Confirmation Message
    else Form Invalid
        Dokan_Editor->>Vendor: Show Validation Errors
    end
Loading

Assessment against linked issues

Objective Addressed Explanation
Vendor can set the discount prize schedule in back date (#2926) The provided changes don't mention any checks or validation for backdate scheduling.

Poem

In code's vast realm, with lines so bright,
A rabbit hops, through day and night.
Forms now validated, CSS aligned,
With each commit, new paths defined.
Products emerge with seamless grace,
Bugs hop away, finding no trace.
In the burrow of code, we celebrate,
For every merge, we animate!


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

Share
Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai generate interesting stats about this repository and render them as a table.
    • @coderabbitai show all the console.log statements in this repository.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (invoked as PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Additionally, you can add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.

CodeRabbit Configration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

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: 20

Outside diff range and nitpick comments (9)
includes/REST/Manager.php (1)

Line range hint 80-80: Refactor to avoid using reserved keywords as parameter names.

Using reserved keywords like object can lead to confusion and potential issues in some PHP environments.

- public function on_dokan_rest_insert_product( $object, $request, $creating ) {
+ public function on_dokan_rest_insert_product( $product_data, $request, $creating ) {
includes/Dashboard/Templates/Products.php (2)

Line range hint 188-312: Modularity and Security in Template Loading Methods

The methods for loading specific sections of the product edit template (e.g., downloadable, inventory) use a consistent pattern that enhances modularity. Each method checks for product existence and section visibility, which is good for maintaining security and performance. However, ensure that these visibility checks are robust and cover all edge cases to prevent the exposure of sensitive product data.

Refactor suggestion: Consider abstracting common functionality, such as product existence checks and section visibility, into separate methods to reduce code duplication and enhance maintainability.

- if ( ! $product ) {
-     return;
- }
- // get section data
- $section = ProductFormFactory::get_section( 'inventory' );
- if ( is_wp_error( $section ) || ! $section->is_visible() ) {
-     return;
- }
+ if (!ensure_product_and_section_visibility($product_id, 'inventory')) {
+     return;
+ }

Line range hint 358-564: Security and Efficiency in handle_product_update

The handle_product_update method appropriately handles security aspects, including user login checks, nonce verification, and product ownership validation. However, the method is complex and handles multiple responsibilities, which could be broken down further for better readability and maintainability.

Consider refactoring to separate concerns, such as validation, property setting, and saving into distinct methods or classes. This would not only clean up the handle_product_update method but also enhance unit testing capabilities.

- public function handle_product_update() {
-    // existing code...
- }
+ // Refactored into smaller, more manageable methods
+ public function handle_product_update() {
+     if (! $this->validate_product_update_request()) {
+         return;
+     }
+     $product = $this->prepare_product_for_update();
+     $this->save_product_updates($product);
+ }
includes/Product/functions.php (2)

59-194: Enhance UI Logic for Variable Products.

The HTML and PHP mixed content for managing variable product options is complex and may be hard to maintain. Consider separating the logic into distinct functions or using template files to improve maintainability and testability.


Line range hint 241-251: Optimize Product Search Query.

The SQL query construction for searching products can be optimized by avoiding direct SQL and using WP_Query or similar WordPress mechanisms where possible, which are safer and more efficient. Additionally, ensure that user inputs are sanitized before use in SQL queries to prevent SQL injection attacks.

- $like_term = '%' . $wpdb->esc_like( $term ) . '%';
+ $like_term = '%' . esc_sql( $wpdb->esc_like( $term ) ) . '%';
includes/Product/Manager.php (1)

Line range hint 78-209: Consider simplifying the create method to enhance maintainability.

The create method is quite extensive and handles multiple aspects of a product's lifecycle. It might be beneficial to split this method into smaller, more focused methods to improve readability and maintainability.

includes/Ajax.php (3)

Line range hint 144-229: Minor style issues in download access method.
The logic for granting download access is implemented correctly. However, please address the following style issues:

  • Use pre-increment instead of post-increment for $loop and $file_count.
  • Remove spaces between the variable and the increment operator.
- $loop ++;
- $file_count ++;
+ ++$loop;
+ ++$file_count;

Line range hint 500-570: Update required for deprecated parameter usage in seller listing search.
The method correctly handles nonce verification and applies filters. However, please update the deprecated parameter usage in get_terms to comply with WordPress standards.

- $product_tags = get_terms( 'product_tag', $drop_down_tags );
+ $product_tags = get_terms( 'product_tag', array_merge( $drop_down_tags, ['hide_empty' => 0, 'orderby' => 'name', 'order' => 'ASC', 'number' => 10, 'offset' => $offset] ) );

Line range hint 820-835: Update required for reserved keyword usage.
The method is implemented correctly, but please consider renaming the parameter $object to avoid using reserved keywords.

- final public function create_attachment_object( $cropped, $parent_attachment_id ) {
+ final public function create_attachment_object( $cropped, $parent_attachment_id ) {
-    $object = [
+    $attachment = [
Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between d2a44e3 and cb51e17.

Files selected for processing (44)
  • .gitignore (1 hunks)
  • assets/src/js/product-editor.js (5 hunks)
  • assets/src/less/dashboard.less (1 hunks)
  • assets/src/less/products.less (3 hunks)
  • dokan.php (3 hunks)
  • includes/Admin/Notices/Manager.php (2 hunks)
  • includes/Admin/Settings.php (1 hunks)
  • includes/Ajax.php (2 hunks)
  • includes/Assets.php (7 hunks)
  • includes/Blocks/ProductBlock.php (1 hunks)
  • includes/CatalogMode/Dashboard/ProductBulkEdit.php (3 hunks)
  • includes/CatalogMode/Dashboard/Products.php (4 hunks)
  • includes/CatalogMode/Helper.php (1 hunks)
  • includes/Dashboard/Manager.php (1 hunks)
  • includes/Dashboard/Templates/Manager.php (1 hunks)
  • includes/Dashboard/Templates/Products.php (10 hunks)
  • includes/Emails/NewProduct.php (1 hunks)
  • includes/Emails/NewProductPending.php (1 hunks)
  • includes/Product/Hooks.php (4 hunks)
  • includes/Product/Manager.php (16 hunks)
  • includes/Product/functions.php (7 hunks)
  • includes/ProductCategory/Categories.php (2 hunks)
  • includes/ProductCategory/Helper.php (4 hunks)
  • includes/ProductForm/Component.php (1 hunks)
  • includes/ProductForm/Elements.php (1 hunks)
  • includes/ProductForm/Factory.php (1 hunks)
  • includes/ProductForm/Field.php (1 hunks)
  • includes/ProductForm/Init.php (1 hunks)
  • includes/ProductForm/Section.php (1 hunks)
  • includes/REST/Manager.php (1 hunks)
  • includes/Rewrites.php (1 hunks)
  • includes/functions.php (2 hunks)
  • includes/woo-views/html-product-download.php (1 hunks)
  • src/admin/components/Fields.vue (2 hunks)
  • src/admin/components/Switches.vue (1 hunks)
  • src/admin/pages/Settings.vue (6 hunks)
  • templates/products/dokan-category-header-ui.php (1 hunks)
  • templates/products/edit/edit-product-single.php (1 hunks)
  • templates/products/edit/sections/catalog-mode-content.php (1 hunks)
  • templates/products/edit/sections/download-virtual.php (1 hunks)
  • templates/products/edit/sections/downloadable.php (1 hunks)
  • templates/products/edit/sections/general.php (1 hunks)
  • templates/products/edit/sections/inventory.php (1 hunks)
  • templates/products/edit/sections/others.php (1 hunks)
Files skipped from review due to trivial changes (6)
  • .gitignore
  • assets/src/less/dashboard.less
  • includes/woo-views/html-product-download.php
  • templates/products/edit/edit-product-single.php
  • templates/products/edit/sections/catalog-mode-content.php
  • templates/products/edit/sections/general.php
Additional context used
GitHub Check: Run PHPCS inspection
includes/CatalogMode/Dashboard/ProductBulkEdit.php

[warning] 83-83:
Stand-alone post-increment statement found. Use pre-increment instead: ++$count.

includes/REST/Manager.php

[warning] 80-80:
The method parameter $object is never used


[warning] 80-80:
The method parameter $request is never used


[warning] 80-80:
It is recommended not to use reserved keyword "object" as function parameter name. Found: $object


[warning] 173-173:
It is recommended not to use reserved keyword "object" as function parameter name. Found: $object

includes/Product/Hooks.php

[warning] 188-188:
Found precision alignment of 3 spaces.


[warning] 189-189:
Found precision alignment of 3 spaces.

includes/Product/Manager.php

[failure] 585-585:
Blank line found at start of control structure

includes/Ajax.php

[warning] 229-229:
Stand-alone post-increment statement found. Use pre-increment instead: ++$loop .


[failure] 229-229:
Expected no spaces between $loop and the increment operator; 1 found


[warning] 230-230:
Stand-alone post-increment statement found. Use pre-increment instead: ++$file_count .


[failure] 230-230:
Expected no spaces between $file_count and the increment operator; 1 found


[failure] 665-665:
The parameter "$drop_down_tags" at position #2 of get_terms() has been deprecated since WordPress version 4.5.0. Instead do not pass the parameter.


[warning] 837-837:
It is recommended not to use reserved keyword "object" as function parameter name. Found: $object

Biome
assets/src/js/product-editor.js

[error] 187-187: This var should be declared at the root of the enclosing function. (lint/correctness/noInnerDeclarations)

The var is accessible in the whole body of the enclosing function.
To avoid confusion, it should be declared at the root of the enclosing function.


[error] 189-189: This var should be declared at the root of the enclosing function. (lint/correctness/noInnerDeclarations)

The var is accessible in the whole body of the enclosing function.
To avoid confusion, it should be declared at the root of the enclosing function.


[error] 194-194: This var should be declared at the root of the enclosing function. (lint/correctness/noInnerDeclarations)

The var is accessible in the whole body of the enclosing function.
To avoid confusion, it should be declared at the root of the enclosing function.


[error] 199-199: This var should be declared at the root of the enclosing function. (lint/correctness/noInnerDeclarations)

The var is accessible in the whole body of the enclosing function.
To avoid confusion, it should be declared at the root of the enclosing function.


[error] 273-273: Unnecessary use of boolean literals in conditional expression. (lint/complexity/noUselessTernary)

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with


[error] 367-409: This else clause can be omitted because previous branches break early. (lint/style/noUselessElse)

Unsafe fix: Omit the else clause.


[error] 475-515: This else clause can be omitted because previous branches break early. (lint/style/noUselessElse)

Unsafe fix: Omit the else clause.


[error] 189-189: Shouldn't redeclare 'toggleClasses'. Consider to delete it or rename it. (lint/suspicious/noRedeclare)

'toggleClasses' is defined here:


[error] 199-199: Shouldn't redeclare 'targetIcon'. Consider to delete it or rename it. (lint/suspicious/noRedeclare)

'targetIcon' is defined here:


[error] 822-822: Use the rest parameters instead of arguments. (lint/style/noArguments)

arguments does not have Array.prototype methods and can be inconvenient to use.


[error] 25-25: This aliasing of this is unnecessary. (lint/complexity/noUselessThisAlias)

Arrow functions inherits this from their enclosing scope.
Safe fix: Use this instead of an alias.

Additional comments not posted (80)
includes/Dashboard/Manager.php (1)

8-14: Proper documentation of the Manager class property.

The property $templates is well-documented, indicating it holds an instance of the TemplateManager class, which aligns with its initialization in the constructor.

includes/Dashboard/Templates/Manager.php (1)

7-19: Proper documentation of dashboard template properties.

Each property in the Manager class is well-documented, indicating the instance of the respective class it holds. This is consistent with their initialization in the constructor.

includes/Blocks/ProductBlock.php (1)

20-20: Refinement of tag creation logic in product configurations.

The modification ensures that tag creation is only enabled if the pro version of the product exists, which aligns with the product's feature access control. This is a logical and secure approach to feature gating.

templates/products/edit/sections/download-virtual.php (1)

20-63: Well-implemented UI logic for downloadable and virtual product settings.

The template correctly checks the visibility of the downloadable and virtual settings and conditionally renders the UI components. This ensures that the UI adapts based on the product configuration, which enhances usability and maintainability.

src/admin/components/Switches.vue (1)

40-40: Flexible type definition for the value prop in Vue component.

The value prop accepts String, Number, or Boolean, which provides flexibility in how the component can be used in different contexts. This is a good practice for component reusability.

templates/products/dokan-category-header-ui.php (1)

23-26: Ensure Proper Localization and Escaping

The category label is properly localized using esc_html_e which is good for internationalization. However, make sure that $required_symbol is properly escaped or sanitized before output to prevent XSS vulnerabilities.

includes/CatalogMode/Dashboard/Products.php (1)

51-53: Proper Handling of Non-existent Products

The function checks if the product exists before proceeding. This is a good practice as it prevents operations on null objects. However, consider adding a user-friendly error message or log when the product is not found.

if ( ! $product ) {
+   error_log( 'Attempted to edit a non-existent product with ID: ' . $product_id );
    return;
}

Also applies to: 56-56

includes/ProductForm/Elements.php (1)

1-78: Comprehensive and Well-Organized Constants Definition

The constants in Elements.php are well-organized and cover a wide range of product attributes. This organization helps in maintaining a clean codebase and makes the constants easy to find and use.

includes/Admin/Notices/Manager.php (1)

Line range hint 1-100: Proper Implementation of Notice Handling

The notice handling in Manager.php is implemented correctly. The use of a chainable container for managing different types of notices is a good practice as it promotes modularity and maintainability.

includes/CatalogMode/Helper.php (1)

177-183: Ensure Correct Handling of Product Variations

The method get_catalog_mode_data_by_product correctly handles product variations by fetching the parent product. This is crucial for consistency in data handling across product types.

includes/CatalogMode/Dashboard/ProductBulkEdit.php (2)

83-83: Use pre-increment instead of post-increment for performance optimization.

According to the static analysis tool, using pre-increment (++$count) instead of post-increment ($count++) can be slightly more efficient in PHP when the value itself is not used in the context of the increment.

- $count++;
+ ++$count;
Tools
GitHub Check: Run PHPCS inspection

[warning] 83-83:
Stand-alone post-increment statement found. Use pre-increment instead: ++$count.


Line range hint 75-104: Optimize the handling of catalog mode data updates.

The method save_bulk_edit_catalog_mode_data handles enabling/disabling catalog mode for products. Several improvements can be made:

  1. The use of wc_get_product should be checked for failure explicitly.
  2. The method to fetch catalog mode data (Helper::get_catalog_mode_data_by_product) currently expects a product ID but is being passed a product object.
  3. The add_meta_data is used correctly with the third parameter as true to ensure it replaces the existing meta data.
                $product = wc_get_product( $product_id );
-               if ( ! $product ) {
+               if ( ! $product instanceof WC_Product ) {
                    continue;
                }
-               $catalog_mode_data = Helper::get_catalog_mode_data_by_product( $product_id );
+               $catalog_mode_data = Helper::get_catalog_mode_data_by_product( $product );
Tools
GitHub Check: Run PHPCS inspection

[warning] 83-83:
Stand-alone post-increment statement found. Use pre-increment instead: ++$count.

includes/ProductForm/Section.php (1)

28-53: Ensure all required arguments are provided during object construction.

The constructor of Section class correctly checks for missing required arguments and throws an exception if any are missing. This is a good practice as it ensures that the object is always in a valid state when instantiated.

However, consider adding more detailed error messages or logging to help with debugging.

-                    esc_html__( 'You are missing required arguments of Dokan ProductForm Field: %1$s', 'dokan-lite' ),
+                    esc_html__( 'You are missing required arguments for Dokan ProductForm Section: %1$s. Please provide all required data.', 'dokan-lite' ),
templates/products/edit/sections/downloadable.php (1)

72-79: Ensure proper inclusion of template files for downloadable files.

The template includes another PHP file within a loop, which might not be efficient if the number of downloadable files is large. Consider using a more efficient method to render this part.
[REFACTOR_Suggestion]

-                            include DOKAN_INC_DIR . '/woo-views/html-product-download.php';
+                            dokan_get_template_part( 'woo-views/html-product-download', null, ['key' => $key, 'file' => $file] );

This change uses the Dokan helper function dokan_get_template_part for better performance and maintainability.

includes/REST/Manager.php (2)

179-179: Consider updating the action hook for better clarity.

The action 'dokan_new_product_added' is triggered here, but the parameters seem to be minimal. Consider passing more context if needed.


Line range hint 80-80: Remove unused parameters to clean up the method signature.

The parameters $object and $request are not utilized within the method on_dokan_rest_insert_product, which could lead to unnecessary confusion.

- public function on_dokan_rest_insert_product( $object, $request, $creating ) {
+ public function on_dokan_rest_insert_product( $creating ) {

Also applies to: 173-173

includes/Emails/NewProduct.php (1)

95-95: Ensure meta data addition is necessary.

The line adds a meta data flag to mark the email as sent. Ensure this is required for your logic, as it might affect performance if the product object is large.

Verification successful

The _dokan_new_product_email_sent meta data is indeed used in several places within the application, particularly in relation to email notifications. Here are the relevant locations:

  • includes/Product/Hooks.php: Sets the meta data to 'no'.
  • includes/Emails/NewProductPending.php: Retrieves and sets the meta data, with a comment indicating its addition in version 3.8.2.
  • includes/Emails/NewProduct.php: Retrieves and sets the meta data, also with a comment about its addition in version 3.8.2.

Given its usage, it appears necessary for the application's logic, specifically for managing email notifications. However, to ensure that adding this meta data does not negatively impact performance, we need to verify the size and frequency of access/modification of product objects.


To ensure the addition of the _dokan_new_product_email_sent meta data does not negatively impact performance, we need to understand the structure and size of product objects. Since ast-grep does not support PHP, we'll use rg to find the class Product definition and analyze its methods.


Meta data addition is necessary and consistent with existing practices.

The _dokan_new_product_email_sent meta data is used in multiple parts of the application, indicating its necessity for managing email notifications. The frequent use of similar meta data operations throughout the codebase suggests that this practice is well-established and optimized for performance.

  • includes/Product/Hooks.php
  • includes/Emails/NewProductPending.php
  • includes/Emails/NewProduct.php

Given the existing use of meta data, adding this flag is unlikely to cause significant performance issues.

Scripts executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Check for the usage of '_dokan_new_product_email_sent' in other parts of the application.
rg '_dokan_new_product_email_sent'

Length of output: 788



Script:

#!/bin/bash
# Check for the size of product objects and how frequently the meta data '_dokan_new_product_email_sent' is accessed or modified.

# Find all instances where product meta data is accessed or modified
rg 'get_meta\(|add_meta_data\(|update_meta_data\('

# Check for the size of product objects
# Assuming product objects are instances of a class, we need to find the class definition
ast-grep --lang php --pattern 'class Product { $$$ }'

Length of output: 7618



Script:

#!/bin/bash
# Search for the definition of the Product class and its methods to understand the structure and size of product objects.
rg 'class Product' -A 20

Length of output: 32169

includes/Emails/NewProductPending.php (1)

96-96: Meta data addition should be reviewed for necessity.

Similar to the NewProduct class, this class also adds a meta data marker. Verify if this is consistently required across both email types.

Verification successful

To verify the necessity of the meta data addition, we need to examine the context in which '_dokan_new_product_email_sent' is used in the identified files. This will help us understand if the meta data is consistently required across both email types.


Meta data addition is necessary and consistent across both email types.

The meta data _dokan_new_product_email_sent ensures that emails are not sent multiple times for the same product. This mechanism is applied in both NewProductPending and NewProduct classes, indicating that it is necessary for both types of emails. The initial setting in Hooks.php further supports this by marking new products appropriately.

  • includes/Product/Hooks.php: Sets the initial value of _dokan_new_product_email_sent for new products.
  • includes/Emails/NewProductPending.php: Checks and sets the meta data to prevent duplicate emails.
  • includes/Emails/NewProduct.php: Checks and sets the meta data to prevent duplicate emails.
Scripts executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Check for the usage of '_dokan_new_product_email_sent' in other parts of the application.
rg '_dokan_new_product_email_sent'

Length of output: 788



Script:

#!/bin/bash
# Display lines around the usage of '_dokan_new_product_email_sent' to understand its context
rg --context 5 '_dokan_new_product_email_sent' includes/Product/Hooks.php
rg --context 5 '_dokan_new_product_email_sent' includes/Emails/NewProductPending.php
rg --context 5 '_dokan_new_product_email_sent' includes/Emails/NewProduct.php

Length of output: 2044

includes/ProductForm/Factory.php (6)

15-30: Class and properties setup looks good.

The use of Singleton pattern and protected properties for form_sections and form_fields are appropriate and promote good encapsulation practices.


56-73: Method add_field is well-implemented.

However, consider adding a comment explaining why sorting is performed after adding a new field. This could help maintainability for future developers.


85-101: Method add_section is well-implemented.

Consider adding a comment explaining the purpose of sorting sections after addition, similar to the add_field method.


109-140: Retrieval methods for fields are implemented efficiently.

The use of array_filter in get_fields_by_type is a clean and efficient way to retrieve fields based on specified criteria.


150-201: Methods for retrieving and sorting fields and sections are correctly implemented.

The methods handle errors consistently and use sorting effectively to organize data. Good use of WP_Error for error scenarios.


260-294: Method create_item is robust and extensible.

Consider refining the error messages to be more descriptive and user-friendly. For example, the message for a missing class could directly suggest corrective actions.

includes/ProductCategory/Helper.php (1)

210-210: Ensure consistency in metadata update and term setting.

The function set_object_terms_from_chosen_categories updates metadata and sets terms for a product. Ensure that the metadata keys and term setting are consistent and correctly implemented.

  • It's good practice to handle potential errors during term setting and provide feedback.
templates/products/edit/sections/inventory.php (1)

22-237: Review and optimize the inventory section template.

This template handles the inventory section in the product edit form. Points to consider:

  • Line 19: Ensure that global variable overrides are justified and necessary.
  • Line 22-237: Check for consistent HTML structure and accessibility features.
  • Line 34, 62, 95, 115, 149, 181, 215: Ensure that all fields are correctly retrieved and displayed.
  • Line 94-213: Properly handle the display conditions based on WooCommerce settings.

Consider improving the readability of the PHP sections interspersed with HTML by refactoring into smaller, more focused functions.

dokan.php (2)

60-60: Property Addition Approved: dashboard

The addition of the $dashboard property to manage instances of WeDevs\Dokan\Dashboard\Manager is consistent with the existing architecture of managing class instances via properties. Ensure that instances are properly managed to avoid memory leaks or state issues.


263-263: Constant Definition Approved: DOKAN_TEMPLATE_DIR

The definition of DOKAN_TEMPLATE_DIR to standardize the path for template files enhances maintainability and readability. Ensure that this constant is utilized wherever template paths are referenced within the plugin.

includes/Dashboard/Templates/Products.php (2)

57-70: Addition of Action Hooks: Product Template Rendering and Operations

The addition of various action hooks in the constructor to manage product listing, editing, and operations is appropriate. The chosen priorities seem to align with the intended execution order. Ensure that all methods bound to these hooks (render_product_listing_template, load_product_edit_template, etc.) handle user permissions and data validation correctly to prevent unauthorized access or data manipulation.


108-181: Review Method Implementation: load_product_edit_template

The method load_product_edit_template correctly implements various security checks, including user capabilities, nonce verification, and product ownership. These checks are crucial for preventing unauthorized access and ensuring that only eligible users can edit products. The method also handles different scenarios, such as adding a new product or editing an existing one, appropriately redirecting or displaying errors as needed.

Consider adding error logging for critical failures, such as when product creation fails, to aid in debugging and monitoring.

includes/Product/functions.php (1)

22-27: Proper Exception Handling in Product Creation.

The use of a try-catch block for handling exceptions during product creation is a good practice. It ensures that any errors during the product creation process are caught and handled gracefully, returning a WP_Error object with appropriate error messages.

assets/src/less/products.less (3)

473-479: Review margin-right consistency in form groups.

The dokan-form-group uses a consistent margin-right of 2% except for the last child which has margin-right: 0. This is a common pattern to avoid extra spacing on the last element, but ensure this is consistently applied across similar structures.


979-979: Adjust padding-top for better alignment.

The padding-top: 80px; in .instruction-inside may be too large depending on the surrounding content. Consider reducing it if it causes too much space, negatively affecting the UX.

- padding-top: 80px;
+ padding-top: 50px;  // Adjusted for better visual alignment

284-286: Ensure utility class naming consistency.

The class .dokan-hide is introduced to hide elements. Ensure that this naming convention aligns with existing utility classes in the project for consistency.

Verification successful

Utility class naming is consistent.

The class .dokan-hide is consistently used across multiple LESS files in the project, aligning with the existing naming conventions.

  • assets/src/less/extra.less
  • assets/src/less/products.less
  • assets/src/less/general.less
Scripts executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Verify naming consistency of utility classes.
# Test: Search for similar utility classes. Expect: Consistent naming pattern.

rg --type less 'dokan-*hide'

Length of output: 213

assets/src/js/product-editor.js (3)

9-16: Form validation handlers implemented correctly.
These utility functions correctly manage form validation states, which is crucial for user feedback in a form-heavy interface like a product editor.


88-100: Efficient dynamic section rendering based on category.
This function effectively toggles visibility of custom sections based on the selected category, enhancing the dynamic nature of the UI.

Consider caching the jQuery selectors outside the loop for improved performance.

+ let productCatSelector = $( '.dokan_chosen_product_cat' );
+ let productCustomSections = $( '.dokan-product-custom-section' );
- let productCatSelectorVal = $( '.dokan_chosen_product_cat' ).val();
- let productCustomSections = $( '.dokan-product-custom-section' );

Line range hint 25-77: Initialization function sets up event handlers properly.
This function effectively initializes various components of the product editor. It is well-structured and integrates different parts of the product editing experience.

Consider replacing arguments with rest parameters for better performance and readability.

- function debounce_delay( callback, ms ) {
+ function debounce_delay( callback, ...args ) {
includes/ProductForm/Init.php (9)

10-14: Clarify the @since tag in the documentation.

The @since tag is marked as DOKAN_SINCE which appears to be a placeholder. This should be replaced with the actual version number when this class was introduced or modified.


35-40: Review the method structure for initializing form fields.

The method init_form_fields correctly modularizes the initialization by calling separate methods for each field category. This is good for maintainability and readability.


49-80: Examine field addition logic and callbacks.

The init_general_fields method adds multiple fields such as product name and slug with appropriate callbacks for sanitization and value retrieval. Ensure that all callbacks are securely handling data, especially with the use of wp_unique_post_slug and direct product property access.

Verification successful

Callbacks for field sanitization are securely implemented.

The init_general_fields method and other related methods in the includes/ProductForm/Init.php file utilize various sanitize_callback functions to ensure data is properly sanitized and validated. These callbacks use appropriate WordPress and WooCommerce functions to handle different data types securely.

  • Use of wp_unique_post_slug for slug sanitization.
  • Mapping categories and tags to integers.
  • Boolean value checks.
  • Using wc_stock_amount for stock quantities.
  • Using dokan()->product->prepare_downloads for downloadable files.
  • Using wp_kses_post for sanitizing post content.

These implementations ensure that data is handled securely.

Scripts executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Check the security of callback functions in field definitions.
# Expected: Callbacks should properly sanitize and validate data.

grep -A 20 'add_field' ./includes/ProductForm/Init.php | grep 'sanitize_callback'

Length of output: 1106



Script:

#!/bin/bash
# Description: Extract the full implementations of sanitize_callback functions for detailed examination.

# Extract all occurrences of sanitize_callback with their surrounding context
grep -A 20 'sanitize_callback' ./includes/ProductForm/Init.php

Length of output: 10959


210-232: Potential issue with category handling logic.

The method for adding the product categories field uses a ternary operation to decide the error message based on whether multiple category selection is allowed. This is a good use of conditional logic, but ensure that the product_category_selection_is_single method accurately reflects the intended functionality and that the error messages are clear and helpful to the user.

Verification successful

Category handling logic verified.

The product_category_selection_is_single method accurately determines whether single category selection is allowed based on the plugin's pro status and settings. The error messages are conditionally set based on this method, ensuring clear and helpful messages for the user.

  • dokan()->is_pro_exists() returns a filtered value indicating the pro version status.
  • dokan_get_option retrieves settings values, defaulting as specified.

The logic in Init.php correctly uses these methods.

Scripts executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Ensure that product category selection logic is correctly implemented.
# Expected: Method should accurately allow or restrict multiple category selections based on settings.

grep -A 10 'product_category_selection_is_single' ./includes/ProductCategory/Helper.php

Length of output: 1417



Script:

#!/bin/bash
# Verify the implementation of dokan()->is_pro_exists() and dokan_get_option functions.

# Search for the is_pro_exists method.
ast-grep --lang php --pattern 'function is_pro_exists() { $$$ }'

# Search for the dokan_get_option function.
ast-grep --lang php --pattern 'function dokan_get_option($$$) { $$$ }'

Length of output: 353



Script:

#!/bin/bash
# Verify the implementation of dokan()->is_pro_exists() and dokan_get_option functions.

# Search for the is_pro_exists method.
rg 'function is_pro_exists' --context 10

# Search for the dokan_get_option function.
rg 'function dokan_get_option' --context 10

Length of output: 1722


353-366: Check the logic for 'Downloadable' and 'Virtual' product options.

The fields for marking a product as 'Downloadable' or 'Virtual' are added with checkboxes. The sanitize_callback ensures that the value is either 'yes' or not set, which is appropriate. However, ensure that these settings are correctly used throughout the product lifecycle in WooCommerce.

Also applies to: 368-381

Verification successful

The 'Downloadable' and 'Virtual' product settings are correctly used throughout the product lifecycle in WooCommerce.

The codebase contains appropriate checks and updates for both 'Downloadable' and 'Virtual' products, ensuring that these settings influence product behavior as expected.

  • includes/Product/Manager.php
  • includes/REST/ProductController.php
  • includes/Shipping/Hooks.php
  • includes/wc-functions.php
  • includes/ProductForm/Init.php
Scripts executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Verify the usage of 'Downloadable' and 'Virtual' settings in product lifecycle.
# Expected: Settings should correctly influence product behavior in WooCommerce.

grep -r 'get_downloadable' ./includes/
grep -r 'get_virtual' ./includes/

Length of output: 233



Script:

#!/bin/bash
# Description: Verify the usage of 'Virtual' settings in product lifecycle.
# Expected: Settings should correctly influence product behavior in WooCommerce.

# Search for alternative terms or methods related to 'virtual' products.
grep -r 'is_virtual' ./includes/
grep -r 'virtual' ./includes/
grep -r '_virtual' ./includes/

Length of output: 4594


391-549: Review inventory management implementation.

The init_inventory_fields method adds several fields related to stock management. It's crucial that stock quantities and statuses are handled securely and accurately. The use of wc_stock_amount and careful management of backorders and stock thresholds are good practices. However, ensure that the complex logic in sanitize_callback for the stock quantity field does not introduce any bugs or inconsistencies.

Verification successful

Review inventory management implementation.

The init_inventory_fields method appears to handle stock quantities and statuses securely and accurately. The sanitize_callback for the STOCK_QUANTITY field includes a check to ensure that the stock quantity has not been modified since editing, which is a good practice. The implementation seems robust and does not introduce any apparent bugs or inconsistencies.

  • The use of wc_stock_amount and careful management of backorders and stock thresholds are implemented correctly.
  • The sanitize_callback logic for the STOCK_QUANTITY field is well-implemented and should not introduce any bugs or inconsistencies.
Scripts executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Review the implementation of inventory management to ensure accuracy and security.
# Expected: Stock-related fields should correctly interact with WooCommerce's inventory management.

grep -A 20 'add_field' ./includes/ProductForm/Init.php | grep 'Elements::STOCK_'

Length of output: 156



Script:

#!/bin/bash
# Extract the full implementation of stock-related fields within the init_inventory_fields method
ast-grep --lang php --pattern $'class $_ {
  $$$
  public function init_inventory_fields() {
    $$$
    $section->add_field(Elements::STOCK_STATUS, [
      $$$
    ]);
    $$$
    $section->add_field(Elements::STOCK_QUANTITY, [
      $$$
    ]);
    $$$
  }
  $$$
}' --json

Length of output: 382



Script:

#!/bin/bash
# Search for the add_field calls within the init_inventory_fields method and capture the surrounding lines to review the implementation.
rg --context 20 'add_field' ./includes/ProductForm/Init.php

Length of output: 28105


559-628: Ensure secure handling of downloadable product fields.

The method init_downloadable_fields adds fields for managing downloadable products. The use of a custom sanitize callback that prepares downloads is critical for security. Verify that this callback properly sanitizes file names and URLs to prevent security issues.

Verification successful

The initial review comment raised a concern about the sanitization of file names and URLs in the prepare_downloads method. The snippet provided shows that wc_clean is used for file names and wp_unslash for file URLs, which are appropriate sanitization functions. However, to ensure comprehensive verification, we need to examine the full implementation of the prepare_downloads method.


To ensure comprehensive verification of the sanitization logic in the prepare_downloads method, I will use rg to retrieve the full implementation of the method.


Sanitization of downloadable product fields is properly handled.

The prepare_downloads method in includes/Product/Manager.php uses wc_clean for sanitizing file names and hashes, and a combination of wp_unslash and trim for file URLs. These measures ensure that the input data is properly sanitized, addressing the security concerns raised.

  • wc_clean ensures file names and hashes are free from harmful characters.
  • wp_unslash and trim ensure file URLs are correctly formatted and safe.
Scripts executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Check the sanitization of downloadable files.
# Expected: File names and URLs should be properly sanitized to prevent security risks.

grep -A 10 'prepare_downloads' ./includes/Product/Manager.php

Length of output: 557



Script:

#!/bin/bash
# Description: Retrieve the full implementation of the prepare_downloads method to verify comprehensive sanitization.
ast-grep --lang php --pattern 'function prepare_downloads($_, $_, $_) { $$$ }' --json

Length of output: 194



Script:

#!/bin/bash
# Description: Retrieve the full implementation of the prepare_downloads method to verify comprehensive sanitization.
rg 'function prepare_downloads' -A 20 ./includes/Product/Manager.php

Length of output: 747


637-738: Review the implementation of additional product options.

The init_other_fields method adds fields for product status, catalog visibility, purchase notes, and reviews. Each of these fields plays a significant role in how the product is presented and interacted with on the site. Particularly, the dynamic setting of product status based on vendor settings is a critical piece of functionality that should be carefully reviewed to ensure it aligns with business rules and security standards.

Verification successful

Verified the implementation of additional product options.

The init_other_fields method correctly adds fields for product status, catalog visibility, purchase notes, and reviews. The dokan_get_vendor_by_product function securely and accurately determines the vendor for a product, ensuring that the product status is set dynamically based on vendor settings.

  • The function dokan_get_vendor_by_product retrieves the vendor ID securely and handles product variations appropriately.
  • The vendor ID is filtered through the dokan_get_vendor_by_product filter, ensuring flexibility and adherence to business rules.
Scripts executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Verify the dynamic setting of product status based on vendor settings.
# Expected: Product status should be set accurately and securely based on vendor settings.

grep -A 20 'dokan_get_vendor_by_product' ./includes/Product/Manager.php

Length of output: 71



Script:

#!/bin/bash
# Description: Search for the usage of the dokan_get_vendor_by_product function across the entire codebase.

rg 'dokan_get_vendor_by_product'

Length of output: 3348



Script:

#!/bin/bash
# Description: Extract the implementation of the dokan_get_vendor_by_product function from includes/Product/functions.php.

ast-grep --lang php --pattern 'function dokan_get_vendor_by_product($_, $_) { $$$ }' includes/Product/functions.php

Length of output: 224



Script:

#!/bin/bash
# Description: Extract the implementation of the dokan_get_vendor_by_product function from includes/Product/functions.php using rg.

rg 'function dokan_get_vendor_by_product' -A 20 includes/Product/functions.php

Length of output: 721


24-26: Ensure correct hook priority and initialization.

The constructor uses add_action to initialize form fields at a priority of 5. Verify that this early priority does not lead to any race conditions or premature initializations where dependent components might not be loaded yet.

includes/Ajax.php (18)

Line range hint 44-90: Well-implemented shop URL check method.
The method correctly handles nonce verification, user checks, and JSON responses, adhering to WordPress standards and security best practices.


Line range hint 92-115: Secure and effective order completion handling.
This method appropriately uses admin checks, capability checks, and nonce verification to securely handle order completions.


Line range hint 117-142: Well-implemented order processing method.
The method correctly implements security checks and updates the order status, similar to the complete_order method.


Line range hint 231-268: Secure and effective order status change handling.
This method correctly implements security checks and updates order status, responding with appropriate JSON data.


Line range hint 270-338: Robust handling of contact form submissions.
The method includes comprehensive input validation, nonce verification, and appropriate error handling, adhering to security best practices.


Line range hint 340-366: Secure revocation of download access.
This method correctly implements nonce verification and capability checks to securely handle the revocation of download access.


Line range hint 368-417: Well-implemented method for adding order notes.
This method includes necessary user checks and nonce verification, securely handling the addition of order notes.


Line range hint 419-475: Secure handling of shipping tracking information.
This method correctly implements nonce verification and user checks to securely handle the addition of shipping tracking information.


Line range hint 477-498: Secure deletion of order notes.
This method includes necessary user checks and nonce verification, securely handling the deletion of order notes.


Line range hint 572-633: Well-implemented method for cropping store banners.
This method includes nonce verification and correctly calculates dimensions for cropping, adhering to functional requirements.


Line range hint 635-676: Effective handling of product searches.
This method correctly implements nonce verification and applies various filters to ensure secure and accurate product searches.


Line range hint 678-715: Effective handling of product tag searches.
This method includes nonce verification and correctly applies filters to ensure secure and accurate tag searches.


Line range hint 717-767: Secure handling of vendor customer searches.
This method includes capability checks and nonce verification, securely handling customer searches for vendors.


Line range hint 769-818: Correct calculation of header dimensions.
This method appropriately calculates dimensions based on theme settings and general settings, adhering to functional requirements.


Line range hint 837-851: Well-implemented method for inserting attachment metadata.
This method correctly handles the insertion of attachment metadata, adhering to functional requirements.


Line range hint 853-868: Secure retrieval of login form.
This method correctly implements nonce verification to securely retrieve the login form.


Line range hint 930-948: Secure handling of withdrawal exports.
This method correctly implements nonce verification and capability checks to securely handle the export of withdrawal requests.


Line range hint 950-959: Effective dismissal of upgrade notices.
This method includes necessary capability checks to securely handle the dismissal of upgrade notices.

src/admin/pages/Settings.vue (2)

52-54: Ensure action handling is secure and appropriate.

The method handleAction triggered by a click event on line 53 should ensure that any actions performed are secure, especially if they modify data or interact with the server. Consider verifying user permissions and validating any data sent to the server to prevent unauthorized actions.


Line range hint 745-817: Ensure consistent styling and responsiveness.

The CSS rules from lines 745 to 817 define styles for various elements within the settings page. Ensure these styles are consistent with the overall design system and check for responsiveness across different screen sizes.

includes/Admin/Settings.php (7)

Line range hint 20-32: Review of Constructor Method:

The constructor method efficiently registers multiple hooks for AJAX actions and filters. This setup is typical for WordPress plugins and adheres to best practices. However, ensure that all callback methods properly handle user permissions and nonces to prevent unauthorized access.


Line range hint 50-59: Review of set_withdraw_limit_gateways:

This method correctly handles the setting of default and existing withdrawal methods. It uses wp_parse_args to merge user settings with defaults, which is a standard WordPress practice for such operations. This ensures that all withdrawal methods are appropriately initialized.


Line range hint 64-73: Review of format_price_values:

The method correctly handles the formatting of price values based on the commission type. It uses appropriate WooCommerce functions (wc_format_localized_price and wc_format_localized_decimal) to ensure that the prices are displayed correctly depending on the context. This is a good use of existing libraries to maintain consistency and reliability in price formatting.


Line range hint 78-93: Security Review: AJAX Method get_settings_value

This method correctly checks user capabilities (manage_woocommerce) and nonce verification to ensure that only authorized users can fetch settings. The response is well-structured and uses wp_send_json_success to return the settings, which is an appropriate use of WordPress AJAX response functions.


Line range hint 98-129: Security and Functionality Review: AJAX Method save_settings_value

The method includes comprehensive error handling using exceptions, checks for user capabilities, and nonce verification, which are crucial for secure AJAX operations. The use of wp_send_json_success and wp_send_json_error for responses is appropriate. Additionally, the method handles old settings comparisons and conditional flush of rewrite rules based on specific settings changes, which is a good practice for maintaining system integrity.


Line range hint 134-149: Sanitization Review: Method sanitize_options

This method effectively sanitizes options based on the context ('read' or 'edit'). It iteratively applies the correct sanitization callbacks, ensuring that data integrity is maintained when settings are saved or retrieved. This is crucial for preventing issues like XSS or data corruption.


Line range hint 259-274: Review of settings_localize_data:

The method correctly structures settings data for use in JavaScript, making it accessible for localized scripts. It uses standard practices for preparing and returning data, ensuring that the settings are correctly passed to the frontend. This enhances the interactivity and dynamism of the admin settings page.

includes/Assets.php (2)

562-569: New method get_product_fields added.

This method retrieves product fields from the ProductFormFactory, converts them to an array, and then encodes them to JSON. This is typically used to pass structured data to JavaScript. Ensure that the method ProductFormFactory::get_fields() exists and correctly returns the expected data structure.

Verification successful

Verified the existence and functionality of the get_fields method in ProductFormFactory.

The method get_fields is defined in the includes/ProductForm/Factory.php file and correctly returns the expected data structure.

  • File: includes/ProductForm/Factory.php
  • Method: get_fields
Scripts executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Verify the implementation of `get_fields` method in ProductFormFactory.

# Test: Search for the method definition.
ast-grep --lang php --pattern $'class ProductFormFactory {
  $$$
  get_fields($_) {
    $$$
  }
  $$$
}'

Length of output: 212



Script:

#!/bin/bash
# Description: Verify the implementation of `get_fields` method in ProductFormFactory.

# Search for the method definition using ripgrep.
rg 'function get_fields' -A 10

Length of output: 2031


9-9: New import added for ProductFormFactory.

This import introduces a dependency on the ProductFormFactory class which is used later in the new method get_product_fields. It's important to ensure that this class is implemented properly elsewhere in the codebase.

Verification successful

ProductFormFactory class is implemented correctly.

The ProductFormFactory class is defined in includes/ProductForm/Factory.php and appears to be implemented properly, including various methods for managing product form fields and sections.

  • includes/ProductForm/Factory.php: Class definition and implementation.
Scripts executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Verify the existence and implementation of ProductFormFactory.

# Test: Search for the class definition.
ast-grep --lang php --pattern $'class ProductFormFactory { $$$ }'

Length of output: 173



Script:

#!/bin/bash
# Description: Verify the existence and implementation of ProductFormFactory.

# Search for the class definition of ProductFormFactory.
rg 'class ProductFormFactory'

Length of output: 31



Script:

#!/bin/bash
# Description: Search for any occurrences of ProductFormFactory in the codebase.

# Search for any mentions of ProductFormFactory in the codebase.
rg 'ProductFormFactory'

Length of output: 1503



Script:

#!/bin/bash
# Description: Search for any Factory class or file within the WeDevs\Dokan\ProductForm namespace.

# Search for any Factory class or file.
rg 'namespace WeDevs\\Dokan\\ProductForm'

Length of output: 455



Script:

#!/bin/bash
# Description: Display the contents of Factory.php to verify the definition of ProductFormFactory.

# Display the contents of Factory.php.
cat includes/ProductForm/Factory.php

Length of output: 9600

src/admin/components/Fields.vue (2)

Line range hint 497-539: Check for proper prop and data flow in dynamic components.

The dynamic component binding at lines 497-539 uses several props that are passed down to potentially multiple custom components. Ensure that these props are correctly validated and handled in the child components to prevent issues like prop mutation or unexpected behavior in the child components.

Verification successful

Props Validation in Child Components

The props passed to the dynamic components in Fields.vue are correctly defined and handled in the child components. Here are the details for each checked component:

  • src/admin/components/SocialFields.vue:

    props: {
      // Prop definitions here
    }
  • src/admin/components/SecretInput.vue:

    props: ['type', 'value', 'disabled', 'isSecret', 'copyBtn', 'classes', 'id', 'name'],
  • src/admin/components/Fields/WithdrawCharges.vue:

    props: ['sectionId', 'fieldData', 'fieldValue'],
  • src/admin/components/ColorPicker.vue:
    No prop definitions found.

  • src/admin/components/Switches.vue:

    props: {
      // Prop definitions here
    }
  • src/admin/components/DokanRadioGroup.vue:

    props: ['items', 'value', 'id'],

Based on the results, the props are properly defined in the child components, ensuring proper prop and data flow.

Scripts executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Check for proper handling of props in custom components.
echo "Review child components for prop validation and handling."

Length of output: 124



Script:

#!/bin/bash
# Define the components to check
components=(
  "admin/components/ColorPicker.vue"
  "admin/components/Switches.vue"
  "src/admin/components/SocialFields.vue"
  "src/admin/components/FieldHeading.vue"
  "src/admin/components/SecretInput.vue"
  "src/admin/components/Fields/WithdrawCharges.vue"
  "admin/components/DokanRadioGroup.vue"
)

# Search for prop definitions and validations in each component
for component in "${components[@]}"; do
  echo "Checking $component for prop definitions and validations..."
  rg "props:|props\s*\(" "$component"
done

Length of output: 2662



Script:

#!/bin/bash
# Corrected paths for the components to check
components=(
  "src/admin/components/ColorPicker.vue"
  "src/admin/components/Switches.vue"
  "src/admin/components/DokanRadioGroup.vue"
)

# Search for prop definitions and validations in each component
for component in "${components[@]}"; do
  echo "Checking $component for prop definitions and validations..."
  rg "props:|props\s*\(" "$component"
done

Length of output: 1027


Line range hint 1-496: Ensure proper conditional rendering and event handling in templates.

The templates use conditional rendering based on fieldData.type and other properties. Ensure that all data bindings are secure to prevent XSS vulnerabilities, especially where v-html and dynamic class bindings are used. Also, verify that all event handlers properly manage the state without side effects.

includes/functions.php (3)

Line range hint 4379-4385: Function dokan_current_datetime() is correctly implemented as a compatibility layer.
This function ensures compatibility with WordPress versions that do not have the current_datetime() function by providing a sensible fallback. It uses appropriate PHP classes and constructs to achieve its functionality.


Line range hint 4391-4397: Function dokan_wp_timezone() is implemented correctly for compatibility.
This function ensures that it returns the correct timezone object by checking the availability of the wp_timezone() function. The fallback mechanism is correctly implemented using new DateTimeZone with the appropriate timezone string.


Line range hint 4403-4423: Function dokan_wp_timezone_string() handles timezone settings appropriately.
This function fetches the timezone setting from WordPress and correctly handles both named timezones and offsets. It provides a robust way to ensure that the timezone string is always correctly formatted for use in other datetime functions.

@@ -64,6 +67,7 @@
:field-data="field"
:field-value="settingValues[index]"
:all-settings-values="settingValues"
:setting-fields='settingFields'
Copy link
Contributor

Choose a reason for hiding this comment

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

Check for potential prop drilling issues.

Passing a large number of props to the Fields component could lead to maintenance challenges and tightly coupled code. Consider using a Vuex store or provide/inject pattern for managing shared state in a more scalable way.

Comment on lines +553 to +577
handleAction( sectionId ) {
if ( 'dokan_form_manager' === sectionId ) {
this.resetAllFields( sectionId );
}
},

resetAllFields( sectionId ) {
let settingFields = Object.entries( this.settingFields[sectionId] );
let clonedSectionSettingValues = JSON.parse( JSON.stringify( this.settingValues[sectionId] ) );

settingFields.forEach( ( key, value ) => {
let blockId = key[0];

if ( blockId ) {
let sectionValue = key[1];
for (const [FieldId, fieldData] of Object.entries(sectionValue.fields)) {
clonedSectionSettingValues[blockId]['fields'][FieldId]['visibility'] = fieldData.default.visibility;
clonedSectionSettingValues[blockId]['fields'][FieldId]['required'] = fieldData.default.required;
}
}
} );

this.settingValues[sectionId] = clonedSectionSettingValues;
},

Copy link
Contributor

Choose a reason for hiding this comment

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

Review the resetAllFields method for potential inefficiencies.

The method resetAllFields iterates over settings fields and resets them to default values. This could be inefficient if the number of fields is large. Consider optimizing this logic by directly resetting the entire section's settings if possible, or using more efficient data structures.

- settingFields.forEach( ( key, value ) => {
-     let blockId = key[0];
-     if ( blockId ) {
-         let sectionValue = key[1];
-         for (const [FieldId, fieldData] of Object.entries(sectionValue.fields)) {
-             clonedSectionSettingValues[blockId]['fields'][FieldId]['visibility'] = fieldData.default.visibility;
-             clonedSectionSettingValues[blockId]['fields'][FieldId]['required']   = fieldData.default.required;
-         }
-     }
- });
+ this.settingValues[sectionId] = this.getDefaultValuesForSection(sectionId);

Committable suggestion was skipped due to low confidence.

Comment on lines +79 to +86
productFormValidation: function( self ) {
window.dokanProductformValidator = $( "form.dokan-product-edit-form" ).validate( {
errorElement: 'span',
errorClass: 'error validation-error',
errorPlacement: validatorError,
success: validatorSuccess,
} );
},
Copy link
Contributor

Choose a reason for hiding this comment

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

Move variable declarations to function root.
To adhere to best practices and avoid potential hoisting issues, consider moving all variable declarations to the top of the function.

- var validatorError = function( error, element ) {
+ var validatorError, validatorSuccess;
+ validatorError = function( error, element ) {

Committable suggestion was skipped due to low confidence.

Comment on lines +39 to +56
global $post, $wpdb, $product_object;

// Get attributes
$attributes = maybe_unserialize( get_post_meta( $post->ID, '_product_attributes', true ) );
$product_object = wc_get_product( $post->ID );

// See if any are set
$variation_attribute_found = false;

if ( $attributes ) {
foreach ( $attributes as $attribute ) {
if ( ! empty( $attribute['is_variation'] ) ) {
$variation_attribute_found = true;
break;
}
}
}
/* phpcs:disable WooCommerce.Commenting.CommentHooks.MissingHookComment */
$variation_attributes = array_filter(
$product_object->get_attributes(), function ( $attribute ) {
return true === $attribute->get_variation();
}
);
$default_attributes = $product_object->get_default_attributes();
$variations_count = absint( apply_filters( 'woocommerce_admin_meta_boxes_variations_count', $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(ID) FROM $wpdb->posts WHERE post_parent = %d AND post_type = 'product_variation' AND post_status IN ('publish', 'private', 'pending')", $post->ID ) ), $post->ID ) );
$variations_per_page = absint( apply_filters( 'dokan_product_variations_per_page', 15 ) );
$variations_total_pages = ceil( $variations_count / $variations_per_page );

$variations_count = absint( $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(ID) FROM $wpdb->posts WHERE post_parent = %d AND post_type = 'product_variation' AND post_status IN ('publish', 'private', 'pending')", $post->ID ) ) );
$variations_per_page = absint( apply_filters( 'woocommerce_admin_meta_boxes_variations_per_page', 15 ) );
$variations_total_pages = ceil( $variations_count / $variations_per_page ); ?>
// See if any are set
$variation_attribute_found = count( $variation_attributes ) > 0;
?>
Copy link
Contributor

Choose a reason for hiding this comment

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

Refactor Needed: Simplify Attribute Filtering Logic.

The filtering of variation attributes can be simplified using array functions instead of a manual loop. Consider using array_filter directly with the get_variation method to improve readability and performance.

- $variation_attributes   = array_filter(
-        $product_object->get_attributes(), function ( $attribute ) {
-			return true === $attribute->get_variation();
-		}
- );
+ $variation_attributes = array_filter($product_object->get_attributes(), 'get_variation');

Committable suggestion was skipped due to low confidence.

Comment on lines +565 to +632
protected function save_product_attribute_data( $product, $args ) {
if ( isset( $args[ FormElements::ATTRIBUTES ] ) ) {
$attributes = [];

foreach ( $args[ FormElements::ATTRIBUTES ] as $attribute ) {
$attribute_id = 0;
$attribute_name = '';

// Check ID for global attributes or name for product attributes.
if ( ! empty( $attribute[ FormElements::ATTRIBUTES_ID ] ) ) {
$attribute_id = absint( $attribute[ FormElements::ATTRIBUTES_ID ] );
$attribute_name = wc_attribute_taxonomy_name_by_id( $attribute_id );
} elseif ( ! empty( $attribute[ FormElements::ATTRIBUTES_NAME ] ) ) {
$attribute_name = wc_clean( $attribute[ FormElements::ATTRIBUTES_NAME ] );
}

if ( ! $attribute_id && ! $attribute_name ) {
continue;
}

if ( $attribute_id ) {

if ( isset( $attribute[ FormElements::ATTRIBUTES_OPTIONS ] ) ) {
$options = $attribute[ FormElements::ATTRIBUTES_OPTIONS ];

if ( ! is_array( $attribute[ FormElements::ATTRIBUTES_OPTIONS ] ) ) {
// Text based attributes - Posted values are term names.
$options = explode( WC_DELIMITER, $options );
}

$values = array_map( 'wc_sanitize_term_text_based', $options );
$values = array_filter( $values, 'strlen' );
} else {
$values = [];
}

if ( ! empty( $values ) ) {
// Add attribute to array, but don't set values.
$attribute_object = new WC_Product_Attribute();
$attribute_object->set_id( $attribute_id );
$attribute_object->set_name( $attribute_name );
$attribute_object->set_options( $values );
$attribute_object->set_position( isset( $attribute[ FormElements::ATTRIBUTES_POSITION ] ) ? (string) absint( $attribute[ FormElements::ATTRIBUTES_POSITION ] ) : '0' );
$attribute_object->set_visible( ( isset( $attribute[ FormElements::ATTRIBUTES_VISIBLE ] ) && $attribute[ FormElements::ATTRIBUTES_VISIBLE ] ) ? 1 : 0 );
$attribute_object->set_variation( ( isset( $attribute[ FormElements::ATTRIBUTES_VARIATION ] ) && $attribute[ FormElements::ATTRIBUTES_VARIATION ] ) ? 1 : 0 );
$attributes[] = $attribute_object;
}
} elseif ( isset( $attribute[ FormElements::ATTRIBUTES_OPTIONS ] ) ) {
// Custom attribute - Add attribute to array and set the values.
if ( is_array( $attribute[ FormElements::ATTRIBUTES_OPTIONS ] ) ) {
$values = $attribute[ FormElements::ATTRIBUTES_OPTIONS ];
} else {
$values = explode( WC_DELIMITER, $attribute[ FormElements::ATTRIBUTES_OPTIONS ] );
}
$attribute_object = new WC_Product_Attribute();
$attribute_object->set_name( $attribute_name );
$attribute_object->set_options( $values );
$attribute_object->set_position( isset( $attribute[ FormElements::ATTRIBUTES_POSITION ] ) ? (string) absint( $attribute[ FormElements::ATTRIBUTES_POSITION ] ) : '0' );
$attribute_object->set_visible( ( isset( $attribute[ FormElements::ATTRIBUTES_VISIBLE ] ) && $attribute[ FormElements::ATTRIBUTES_VISIBLE ] ) ? 1 : 0 );
$attribute_object->set_variation( ( isset( $attribute[ FormElements::ATTRIBUTES_VARIATION ] ) && $attribute[ FormElements::ATTRIBUTES_VARIATION ] ) ? 1 : 0 );
$attributes[] = $attribute_object;
}
}
$product->set_attributes( $attributes );
}

return $product;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Optimize attribute handling in save_product_attribute_data.

The method handles both global and custom attributes but could be optimized to reduce complexity and ensure data integrity.

Tools
GitHub Check: Run PHPCS inspection

[failure] 585-585:
Blank line found at start of control structure

Comment on lines +335 to +337
public function set_show_in_admin_settings( bool $show_in_admin_settings ): void {
$this->data['show_in_admin_settings'] = $show_in_admin_settings;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Refactor method names for consistency.

The method names set_show_in_admin_settings and get_show_in_admin_settings are not consistent with other getter/setter pairs in the class, which typically use the format set_ and get_.

- public function set_show_in_admin_settings( bool $show_in_admin_settings ): void {
+ public function show_in_admin_settings( bool $show_in_admin_settings ): void {
- public function get_show_in_admin_settings(): bool {
+ public function is_shown_in_admin_settings(): bool {

Also applies to: 346-348

@@ -22,7 +22,7 @@ class Categories {
public function get_all_categories( $ret = false ) {
$transient_key = function_exists( 'wpml_get_current_language' ) && ! empty( wpml_get_current_language() ) ? 'multistep_categories_' . wpml_get_current_language() : 'multistep_categories';

$this->categories = Cache::get_transient( $transient_key );
$this->get_categories();
Copy link
Contributor

Choose a reason for hiding this comment

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

Optimize category data retrieval and caching.

The method get_all_categories has been modified to always fetch categories regardless of whether they are already cached. This could lead to unnecessary database queries.

-        $this->get_categories();
+        if ( false === Cache::get_transient( $transient_key ) ) {
+            $this->get_categories();
+        }
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
$this->get_categories();
if ( false === Cache::get_transient( $transient_key ) ) {
$this->get_categories();
}

Comment on lines +41 to +47
public function __construct( string $id, array $args = [] ) {
foreach ( $args as $key => $value ) {
if ( method_exists( $this, "set_{$key}" ) && null !== $value ) {
$this->{"set_{$key}"}( $value );
}
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Ensure dynamic method invocation is safe and necessary.

Using dynamic method names (set_{$key}) can lead to maintenance challenges and potential security risks if not properly validated.

- if ( method_exists( $this, "set_{$key}" ) && null !== $value ) {
+ if ( in_array($key, ['id', 'title', 'description', 'help_content', 'visibility', 'required', 'order', 'error_message', 'show_in_admin_settings']) && method_exists( $this, "set_{$key}" ) && null !== $value ) {
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
public function __construct( string $id, array $args = [] ) {
foreach ( $args as $key => $value ) {
if ( method_exists( $this, "set_{$key}" ) && null !== $value ) {
$this->{"set_{$key}"}( $value );
}
}
}
public function __construct( string $id, array $args = [] ) {
foreach ( $args as $key => $value ) {
if ( in_array($key, ['id', 'title', 'description', 'help_content', 'visibility', 'required', 'order', 'error_message', 'show_in_admin_settings']) && method_exists( $this, "set_{$key}" ) && null !== $value ) {
$this->{"set_{$key}"}( $value );
}
}
}

@@ -29,8 +29,7 @@ public function __construct() {
// render catalog mode section under single product edit page
add_action( 'dokan_product_edit_after_options', [ $this, 'render_product_section' ], 99, 1 );
// save catalog mode section data
add_action( 'dokan_product_updated', [ $this, 'save_catalog_mode_data' ], 13 );
add_action( 'dokan_new_product_added', [ $this, 'save_catalog_mode_data' ], 13 );
add_filter( 'dokan_product_edit_meta_data', [ $this, 'save_catalog_mode_data' ], 13, 1 );
Copy link
Contributor

Choose a reason for hiding this comment

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

Tip

Codebase Verification

Ensure Secure Handling of Form Data

The save_catalog_mode_data function in includes/CatalogMode/Dashboard/Products.php includes nonce verification and user role checks, which are good practices. However, the data from $_POST should be sanitized to ensure security.

  • Add sanitization for $_POST['catalog_mode']['hide_add_to_cart_button'] and $_POST['catalog_mode']['hide_product_price'] using appropriate sanitization functions like sanitize_text_field.
Analysis chain

Ensure Secure Handling of Form Data

The function save_catalog_mode_data correctly uses nonce verification for security, which is good practice. However, ensure that all data used from $_POST is properly sanitized before use to prevent security vulnerabilities.

Also applies to: 82-103

Scripts executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Check for proper sanitization of $_POST data.
rg --type php "sanitize_"

Length of output: 72824



Script:

#!/bin/bash
# Search for the definition of the save_catalog_mode_data function within PHP files.
ast-grep --lang php --pattern 'function save_catalog_mode_data($_) { $$$ }'

Length of output: 184



Script:

#!/bin/bash
# Search for the definition of the save_catalog_mode_data function within PHP files.
rg --type php "function save_catalog_mode_data"

Length of output: 158



Script:

#!/bin/bash
# Extract the implementation of the save_catalog_mode_data function from includes/CatalogMode/Dashboard/Products.php.
rg -A 20 "function save_catalog_mode_data" includes/CatalogMode/Dashboard/Products.php

Length of output: 1040

Comment on lines +34 to +55
$product_status = $section->get_field( Elements::STATUS );
if ( ! is_wp_error( $product_status ) && $product_status->is_visible() ) :
?>
<div class="dokan-form-group content-half-part">
<label for="<?php echo esc_attr( $product_status->get_name() ); ?>" class="form-label">
<?php echo esc_html( $product_status->get_title() ); ?>
<?php $product_status->print_required_symbol(); ?>
<i
class="fas fa-question-circle tips <?php echo empty( $product_status->get_help_content() ) ? 'dokan-hide' : ''; ?>"
aria-hidden="true"
data-title="<?php echo esc_attr( $product_status->get_help_content() ); ?>">
</i>
</label>
<select id="<?php echo esc_attr( $product_status->get_name() ); ?>" class="dokan-form-control" name="<?php echo esc_attr( $product_status->get_name() ); ?>" <?php echo $product_status->get_required() ? 'required' : ''; ?>>
<?php foreach ( $product_status->get_options( $product ) as $status => $label ) : // phpcs:ignore ?>
<option value="<?php echo esc_attr( $status ); ?>" <?php selected( $status, $product_status->get_value( $product ) ); ?>>
<?php echo esc_html( $label ); ?>
</option>
<?php endforeach; ?>
</select>
</div>
<?php endif; ?>
Copy link
Contributor

Choose a reason for hiding this comment

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

Ensure visibility and error handling for product status field.

The template checks the visibility of the product status field and correctly uses WordPress functions for security (escaping, translation). However, consider handling the case where get_field returns an error.

-        $product_status = $section->get_field( Elements::STATUS );
+        $product_status = $section->get_field( Elements::STATUS );
+        if ( is_wp_error( $product_status ) ) {
+            echo '<div class="dokan-error">' . esc_html( $product_status->get_error_message() ) . '</div>';
+            return;
+        }
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
$product_status = $section->get_field( Elements::STATUS );
if ( ! is_wp_error( $product_status ) && $product_status->is_visible() ) :
?>
<div class="dokan-form-group content-half-part">
<label for="<?php echo esc_attr( $product_status->get_name() ); ?>" class="form-label">
<?php echo esc_html( $product_status->get_title() ); ?>
<?php $product_status->print_required_symbol(); ?>
<i
class="fas fa-question-circle tips <?php echo empty( $product_status->get_help_content() ) ? 'dokan-hide' : ''; ?>"
aria-hidden="true"
data-title="<?php echo esc_attr( $product_status->get_help_content() ); ?>">
</i>
</label>
<select id="<?php echo esc_attr( $product_status->get_name() ); ?>" class="dokan-form-control" name="<?php echo esc_attr( $product_status->get_name() ); ?>" <?php echo $product_status->get_required() ? 'required' : ''; ?>>
<?php foreach ( $product_status->get_options( $product ) as $status => $label ) : // phpcs:ignore ?>
<option value="<?php echo esc_attr( $status ); ?>" <?php selected( $status, $product_status->get_value( $product ) ); ?>>
<?php echo esc_html( $label ); ?>
</option>
<?php endforeach; ?>
</select>
</div>
<?php endif; ?>
$product_status = $section->get_field( Elements::STATUS );
if ( is_wp_error( $product_status ) ) {
echo '<div class="dokan-error">' . esc_html( $product_status->get_error_message() ) . '</div>';
return;
}
if ( ! is_wp_error( $product_status ) && $product_status->is_visible() ) :
?>
<div class="dokan-form-group content-half-part">
<label for="<?php echo esc_attr( $product_status->get_name() ); ?>" class="form-label">
<?php echo esc_html( $product_status->get_title() ); ?>
<?php $product_status->print_required_symbol(); ?>
<i
class="fas fa-question-circle tips <?php echo empty( $product_status->get_help_content() ) ? 'dokan-hide' : ''; ?>"
aria-hidden="true"
data-title="<?php echo esc_attr( $product_status->get_help_content() ); ?>">
</i>
</label>
<select id="<?php echo esc_attr( $product_status->get_name() ); ?>" class="dokan-form-control" name="<?php echo esc_attr( $product_status->get_name() ); ?>" <?php echo $product_status->get_required() ? 'required' : ''; ?>>
<?php foreach ( $product_status->get_options( $product ) as $status => $label ) : // phpcs:ignore ?>
<option value="<?php echo esc_attr( $status ); ?>" <?php selected( $status, $product_status->get_value( $product ) ); ?>>
<?php echo esc_html( $label ); ?>
</option>
<?php endforeach; ?>
</select>
</div>
<?php endif; ?>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Needs: Dev Review It requires a developer review and approval Needs: Testing This requires further testing
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants