-
Notifications
You must be signed in to change notification settings - Fork 194
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
base: develop
Are you sure you want to change the base?
Module/form manager #2098
Conversation
… block instead of generic sub section
…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
…o module/form_manager
…and discount related vendor dashboard product edit fields
…s based on default settngs
For the CC: @Mohaiminulislam1989 Bhai, @shams-sadek1981 Bhai |
…e field/section from admin settings
…roduct Attribute section were not loading if Product subscription module is enabled
Product Form Manager-related rewrite is completed from my end. @Mohaiminulislam1989 @shams-sadek1981 |
WalkthroughThe 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
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
Assessment against linked issues
Poem
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? TipsChatThere are 3 ways to chat with CodeRabbit:
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)
Additionally, you can add CodeRabbit Configration File (
|
There was a problem hiding this 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 MethodsThe 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 inhandle_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 thecreate
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 inget_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
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: $objectincludes/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 structureincludes/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 theManager
class property.The property
$templates
is well-documented, indicating it holds an instance of theTemplateManager
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
andvirtual
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 thevalue
prop in Vue component.The
value
prop acceptsString
,Number
, orBoolean
, 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 EscapingThe 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 ProductsThe 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 DefinitionThe 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 HandlingThe 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 VariationsThe 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:
- The use of
wc_get_product
should be checked for failure explicitly.- 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.- The
add_meta_data
is used correctly with the third parameter astrue
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 methodon_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. Sinceast-grep
does not support PHP, we'll userg
to find theclass 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 20Length 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 bothNewProductPending
andNewProduct
classes, indicating that it is necessary for both types of emails. The initial setting inHooks.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.phpLength 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
andform_fields
are appropriate and promote good encapsulation practices.
56-73
: Methodadd_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
: Methodadd_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
inget_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
: Methodcreate_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 ofWeDevs\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 OperationsThe 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 consistentmargin-right
of2%
except for the last child which hasmargin-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 asDOKAN_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 ofwp_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 theincludes/ProductForm/Init.php
file utilize varioussanitize_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.phpLength 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.phpLength 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 10Length 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 ofwc_stock_amount
and careful management of backorders and stock thresholds are good practices. However, ensure that the complex logic insanitize_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. Thesanitize_callback
for theSTOCK_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 theSTOCK_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, [ $$$ ]); $$$ } $$$ }' --jsonLength 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.phpLength 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 thatwc_clean
is used for file names andwp_unslash
for file URLs, which are appropriate sanitization functions. However, to ensure comprehensive verification, we need to examine the full implementation of theprepare_downloads
method.
To ensure comprehensive verification of the sanitization logic in the
prepare_downloads
method, I will userg
to retrieve the full implementation of the method.
Sanitization of downloadable product fields is properly handled.
The
prepare_downloads
method inincludes/Product/Manager.php
useswc_clean
for sanitizing file names and hashes, and a combination ofwp_unslash
andtrim
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
andtrim
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.phpLength 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($_, $_, $_) { $$$ }' --jsonLength 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.phpLength 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. Thedokan_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.phpLength 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.phpLength 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.phpLength 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 thecomplete_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 ofset_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 offormat_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
andwc_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 Methodget_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 useswp_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 Methodsave_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
andwp_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: Methodsanitize_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 ofsettings_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 methodget_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 methodProductFormFactory::get_fields()
exists and correctly returns the expected data structure.Verification successful
Verified the existence and functionality of the
get_fields
method inProductFormFactory
.The method
get_fields
is defined in theincludes/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 10Length 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 methodget_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 inincludes/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.phpLength 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" doneLength 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" doneLength 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 wherev-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
: Functiondokan_current_datetime()
is correctly implemented as a compatibility layer.
This function ensures compatibility with WordPress versions that do not have thecurrent_datetime()
function by providing a sensible fallback. It uses appropriate PHP classes and constructs to achieve its functionality.
Line range hint
4391-4397
: Functiondokan_wp_timezone()
is implemented correctly for compatibility.
This function ensures that it returns the correct timezone object by checking the availability of thewp_timezone()
function. The fallback mechanism is correctly implemented usingnew DateTimeZone
with the appropriate timezone string.
Line range hint
4403-4423
: Functiondokan_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' |
There was a problem hiding this comment.
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.
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; | ||
}, | ||
|
There was a problem hiding this comment.
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.
productFormValidation: function( self ) { | ||
window.dokanProductformValidator = $( "form.dokan-product-edit-form" ).validate( { | ||
errorElement: 'span', | ||
errorClass: 'error validation-error', | ||
errorPlacement: validatorError, | ||
success: validatorSuccess, | ||
} ); | ||
}, |
There was a problem hiding this comment.
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.
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; | ||
?> |
There was a problem hiding this comment.
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.
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; | ||
} |
There was a problem hiding this comment.
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
public function set_show_in_admin_settings( bool $show_in_admin_settings ): void { | ||
$this->data['show_in_admin_settings'] = $show_in_admin_settings; | ||
} |
There was a problem hiding this comment.
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(); |
There was a problem hiding this comment.
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.
$this->get_categories(); | |
if ( false === Cache::get_transient( $transient_key ) ) { | |
$this->get_categories(); | |
} |
public function __construct( string $id, array $args = [] ) { | ||
foreach ( $args as $key => $value ) { | ||
if ( method_exists( $this, "set_{$key}" ) && null !== $value ) { | ||
$this->{"set_{$key}"}( $value ); | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
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.
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 ); |
There was a problem hiding this comment.
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 likesanitize_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
$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; ?> |
There was a problem hiding this comment.
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.
$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; ?> |
All Submissions:
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:
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:
FOR PR REVIEWER ONLY:
Summary by CodeRabbit
New Features
Bug Fixes
Refactor
Chores
Revert