-
Notifications
You must be signed in to change notification settings - Fork 200
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
Enhancement: Make analytics reports compatible with Dokan #2318
base: develop
Are you sure you want to change the base?
Changes from all commits
b65555e
4ee1255
f0b44e1
bab8fbf
0d9fb9d
2e22dd9
93a59aa
e271396
f9508ed
2094ee5
3cd5383
36e71ca
1856d99
5691487
b41df65
6a8ea9e
6f110e9
b00222e
d173d2a
840d5dd
e876902
1c23196
e554aa7
ce2a6e2
07a7362
9feebd1
81af1ca
cd6a0f6
6698ac0
9e80742
b8fa691
563f378
680faff
41f24ff
1374d98
05695f0
e0f2557
7a0428c
f3ee898
67898c5
b42cfc9
6b91a8d
5a889db
9c2a5d4
7e18fd4
f53868a
a9ccb38
29d6e12
b08b12a
a70e159
bf5b2ef
4c82265
d7b5c23
2e2c716
32ac352
992fcf3
16de598
707259d
18cd21a
524c5f5
97c3b32
f4e3118
afaa5bd
0176baf
d3fa0f1
7366a46
9a2878c
2c05bf0
30bc3c4
6f13a6e
c30f6aa
0bb18ad
c7e04b0
768e909
0d84346
67443f3
5a818a6
4b2e85f
65f8a97
97330e1
3334086
23064d3
ec84f3f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
- [Introduction](#introduction) | ||
- [Custom Products Stats Datastore](#custom-products-stats-datastore) | ||
|
||
## Introduction | ||
To handle **Dokan Orders**, we followed the [WooCommerce Admin Reports Extension Guidelines](https://github.com/woocommerce/woocommerce/blob/trunk/docs/reporting/extending-woocommerce-admin-reports.md#handle-currency-parameters-on-the-server). | ||
|
||
## Custom Stats Datastore | ||
|
||
We need to customize the default *WooCommerce Analytics Datastore* for some reports. For example, we replaced the [WC Products Stats DataStore](https://github.com/woocommerce/woocommerce/blob/9297409c5a705d1cd0ae65ec9b058271bd90851e/plugins/woocommerce/src/Admin/API/Reports/Products/Stats/DataStore.php#L170) with the [Dokan Product Stats Store](./../../includes/Analytics/Reports/Products/Stats/WcDataStore.php). This modification involves overriding the `$total_query` and `$interval_query` properties by substituting the `Automattic\WooCommerce\Admin\API\Reports\SqlQuery` class with `WeDevs\Dokan\Analytics\Reports\WcSqlQuery`. | ||
|
||
The primary change was to update the `get_sql_clause( $type, $handling = 'unfiltered' )` method to `get_sql_clause( $type, $handling = '' )`, allowing us to apply necessary filters for adding JOIN and WHERE clauses to the `dokan_order_stats` table. | ||
|
||
### Implementation Steps | ||
|
||
- **Step 1:** Create the [WcSqlQuery](./../../includes/Analytics/Reports/DataStoreModifier.php) class to override the `get_sql_clause( $type, $handling = 'unfiltered' )` method from the [WC SqlQuery](https://github.com/woocommerce/woocommerce/blob/9297409c5a705d1cd0ae65ec9b058271bd90851e/plugins/woocommerce/src/Admin/API/Reports/SqlQuery.php#L87) class. The new method should use `get_sql_clause( $type, $handling = '' )`. | ||
|
||
- **Step 2:** Implement the [WcDataStore](https://github.com/woocommerce/woocommerce/blob/9297409c5a705d1cd0ae65ec9b058271bd90851e/plugins/woocommerce/src/Admin/API/Reports/Products/Stats/DataStore.php#L170) class to set the `$total_query` and `$interval_query` properties with instance of **WcSqlQuery**. | ||
|
||
- **Step 3:** Use the `woocommerce_data_stores` filter within the [DataStoreModifier](./../../includes/Analytics/Reports/DataStoreModifier.php) class to replace the default WooCommerce Products Stats datastore with the custom Dokan Product Stats Store. |
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,129 @@ | ||||||||||||||||||||||||||||||||||
## Container Documentation | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
- [Register Service Provider](#register-service-provider) | ||||||||||||||||||||||||||||||||||
- [Register Services in the Service Provider](#register-services-in-the-service-provider) | ||||||||||||||||||||||||||||||||||
- [Add Services to the Container](#add-services-to-the-container) | ||||||||||||||||||||||||||||||||||
- [Get Service from the Container](#get-service-from-the-container) | ||||||||||||||||||||||||||||||||||
- [Override the Existing Service](#override-the-existing-service) | ||||||||||||||||||||||||||||||||||
- [Check if a Service is Registered](#check-service-is-registered-or-not) | ||||||||||||||||||||||||||||||||||
Comment on lines
+1
to
+8
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fix the invalid link fragment in the table of contents. The link fragment for "Check if a Service is Registered" doesn't match the corresponding section heading. Please update line 8 as follows: -- [Check if a Service is Registered](#check-service-is-registered-or-not)
++ [Check if a Service is Registered](#check-if-a-service-is-registered) 📝 Committable suggestion
Suggested change
🧰 Tools🪛 Markdownlint
|
||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
### Register Service Provider | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
1. **Step 1:** Create a service provider inside `includes/DependencyManagement/Providers` that extends `WeDevs\Dokan\DependencyManagement\BaseServiceProvider`. | ||||||||||||||||||||||||||||||||||
2. **Step 2:** Register the service provider in the `boot` method of `includes/DependencyManagement/Providers/ServiceProvider.php`. | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
You can see the already registered service providers inside the `boot` method of the [ServiceProvider](./../includes/DependencyManagement/Providers/ServiceProvider.php#L46) class. | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
### Register Services in the Service Provider | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
1. **Step 1:** Register the services inside the `register` method of your service provider. | ||||||||||||||||||||||||||||||||||
2. **Step 2:** Implement a `provides` method that returns `true` or `false` when the container invokes it with a service name. | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
```php | ||||||||||||||||||||||||||||||||||
namespace WeDevs\Dokan\DependencyManagement\Providers; | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
use WeDevs\Dokan\DependencyManagement\BaseServiceProvider; | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
class SomeServiceProvider extends BaseServiceProvider | ||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||
/** | ||||||||||||||||||||||||||||||||||
* The provides method lets the container know | ||||||||||||||||||||||||||||||||||
* which services are provided by this provider. | ||||||||||||||||||||||||||||||||||
* The alias must be added to this array or it will | ||||||||||||||||||||||||||||||||||
* be ignored. | ||||||||||||||||||||||||||||||||||
*/ | ||||||||||||||||||||||||||||||||||
public function provides(string $id): bool | ||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||
$services = [ | ||||||||||||||||||||||||||||||||||
'key', | ||||||||||||||||||||||||||||||||||
Some\Controller::class, | ||||||||||||||||||||||||||||||||||
Some\Model::class, | ||||||||||||||||||||||||||||||||||
Some\Request::class, | ||||||||||||||||||||||||||||||||||
]; | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
return in_array($id, $services); | ||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
/** | ||||||||||||||||||||||||||||||||||
* The register method defines services in the container. | ||||||||||||||||||||||||||||||||||
* Services must have an alias in the `provides` method | ||||||||||||||||||||||||||||||||||
* or they will be ignored. | ||||||||||||||||||||||||||||||||||
*/ | ||||||||||||||||||||||||||||||||||
public function register(): void | ||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||
$this->getContainer()->add('key', 'value'); | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
$this->getContainer() | ||||||||||||||||||||||||||||||||||
->add(Some\Controller::class) | ||||||||||||||||||||||||||||||||||
->addArgument(Some\Request::class) | ||||||||||||||||||||||||||||||||||
->addArgument(Some\Model::class); | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
$this->getContainer()->add(Some\Request::class); | ||||||||||||||||||||||||||||||||||
$this->getContainer()->add(Some\Model::class); | ||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||
``` | ||||||||||||||||||||||||||||||||||
Comment on lines
+17
to
+65
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Consider a more dynamic approach for the The current implementation of the Consider implementing a more dynamic approach, such as using reflection to automatically detect and register services. Here's an example: public function provides(string $id): bool
{
$reflection = new \ReflectionClass($this);
$methods = $reflection->getMethods(\ReflectionMethod::IS_PUBLIC);
$services = array_filter($methods, function($method) {
return strpos($method->getName(), 'provide') === 0;
});
$serviceNames = array_map(function($method) {
return lcfirst(substr($method->getName(), 7));
}, $services);
return in_array($id, $serviceNames);
} This approach automatically detects methods starting with "provide" and uses them to determine the available services. |
||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
### Add Services to the Container | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
- Add a service: | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
```php | ||||||||||||||||||||||||||||||||||
$this->getContainer()->add(ServiceClass::class); | ||||||||||||||||||||||||||||||||||
``` | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
- Add a shared service (one instance per request lifecycle): | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
```php | ||||||||||||||||||||||||||||||||||
$this->getContainer()->addShared(ServiceClass::class); | ||||||||||||||||||||||||||||||||||
``` | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
- Add a service with constructor parameters: | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
```php | ||||||||||||||||||||||||||||||||||
$this->getContainer()->addShared(ServiceClass::class, function () { | ||||||||||||||||||||||||||||||||||
return new ServiceClass($params); | ||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||
``` | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
- Add a shared service with constructor parameters and tag it: | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
```php | ||||||||||||||||||||||||||||||||||
$this->getContainer()->addShared(ServiceClass::class, function () { | ||||||||||||||||||||||||||||||||||
return new ServiceClass($params); | ||||||||||||||||||||||||||||||||||
})->addTag('tag_name'); | ||||||||||||||||||||||||||||||||||
``` | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
- Add a service and tag all implemented interfaces: | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
```php | ||||||||||||||||||||||||||||||||||
$this->getContainer()->share_with_implements_tags(ServiceClass::class); | ||||||||||||||||||||||||||||||||||
``` | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
### Get Service from the Container | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
- Get a single instance: | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
```php | ||||||||||||||||||||||||||||||||||
$service = dokan()->get_container()->get(ServiceClass::class); | ||||||||||||||||||||||||||||||||||
``` | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
- Get an array of instances by tag: | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
```php | ||||||||||||||||||||||||||||||||||
$service_list = dokan()->get_container()->get('tag-name'); | ||||||||||||||||||||||||||||||||||
``` | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
### Override the Existing Service | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
```php | ||||||||||||||||||||||||||||||||||
dokan()->get_container()->extend(ServiceClass::class)->setConcrete(new OtherServiceClass()); | ||||||||||||||||||||||||||||||||||
``` | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
### Check if a Service is Registered | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
```php | ||||||||||||||||||||||||||||||||||
$is_registered = dokan()->get_container()->has(ServiceClass::class); | ||||||||||||||||||||||||||||||||||
``` | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
For more details, visit the [League Container documentation](https://container.thephpleague.com/4.x/service-providers). |
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.
Fix the link fragment in the table of contents.
The link fragment for "Custom Products Stats Datastore" should match the section heading.
Committable suggestion
Tools
Markdownlint