Version Description
- 2021-05-19 =
- New - Option to allow larger sites to opt-out of feed generation (product sync) job
- New - Log connection errors to allow easier troubleshooting
- Fix - Reduce default feed generation (product sync) interval to once per day to reduce overhead
- Fix - Trigger feed (product sync) job from to
admin_init
to reduce impact on front-end requests - Fix - Ensure variable product attribute values containing comma (
,
) sync correctly - Fix - Use existing / current tab for connection
Get Started
button - Dev - Require PHP version 7.0 or newer
- Dev - Adopt Composer autoloader to avoid manually
require
ing PHP class files - Dev - Adopt WooRelease release tool for deploying releases
- Dev - Use wp-scripts to build assets
- Dev - Add
phpcs
tooling to help standardise PHP code style - Dev - Add JobRegistry engine for managing periodic background batch jobs
Download this release
Release Info
Developer | automattic |
Plugin | Facebook for WooCommerce |
Version | 2.5.0 |
Comparing to | |
See all releases |
Code changes from version 2.4.1 to 2.5.0
- README.md +33 -0
- assets/build/admin/google-product-category-fields.asset.php +1 -0
- assets/build/admin/google-product-category-fields.js +1 -0
- assets/build/admin/index.asset.php +1 -0
- assets/build/admin/index.js +1 -0
- assets/build/admin/infobanner.asset.php +1 -0
- assets/build/admin/infobanner.js +1 -0
- assets/build/admin/metabox.asset.php +1 -0
- assets/build/admin/metabox.js +1 -0
- assets/build/admin/modal.asset.php +1 -0
- assets/build/admin/modal.js +1 -0
- assets/build/admin/orders.asset.php +1 -0
- assets/build/admin/orders.js +1 -0
- assets/build/admin/product-categories.asset.php +1 -0
- assets/build/admin/product-categories.js +1 -0
- assets/build/admin/product-sets-admin.asset.php +1 -0
- assets/build/admin/product-sets-admin.js +1 -0
- assets/build/admin/products-admin.asset.php +1 -0
- assets/build/admin/products-admin.js +1 -0
- assets/build/admin/settings-commerce.asset.php +1 -0
- assets/build/admin/settings-commerce.js +1 -0
- assets/build/admin/settings-sync.asset.php +1 -0
- assets/build/admin/settings-sync.js +1 -0
- assets/js/admin/facebook-for-woocommerce-product-sets-admin.min.js +0 -1
- assets/js/admin/facebook-for-woocommerce-products-admin.min.js +0 -1
- assets/js/admin/facebook-for-woocommerce-products-admin.min.old.js +0 -2
- assets/js/admin/facebook-for-woocommerce-products-admin.min.old.min.js +0 -1
- assets/js/admin/facebook-for-woocommerce-settings-messenger.js +0 -96
- assets/js/admin/facebook-for-woocommerce-settings-messenger.min.js +0 -1
- assets/js/admin/facebook-for-woocommerce-settings-sync.min.js +0 -1
- assets/js/admin/google-product-category-fields.min.js +0 -1
- assets/js/admin/index.js +1 -0
- assets/js/{facebook-infobanner.js → admin/infobanner.js} +0 -0
- assets/js/{facebook-metabox.js → admin/metabox.js} +0 -0
- assets/js/{facebook-for-woocommerce-modal.js → admin/modal.js} +0 -0
- assets/js/admin/orders.min.js +0 -1
- assets/js/admin/product-categories.min.js +0 -1
- assets/js/admin/{facebook-for-woocommerce-product-sets-admin.js → product-sets-admin.js} +0 -0
- assets/js/admin/{facebook-for-woocommerce-products-admin.js → products-admin.js} +0 -0
- assets/js/admin/settings-commerce.min.js +0 -1
- assets/js/admin/{facebook-for-woocommerce-settings-sync.js → settings-sync.js} +0 -0
- assets/js/facebook-for-woocommerce-modal.min.js +0 -1
- assets/js/facebook-infobanner.min.js +0 -1
- assets/js/facebook-metabox.min.js +0 -1
- assets/js/facebook-settings.min.js +0 -1
- changelog.txt +14 -0
- class-wc-facebookcommerce.php +101 -73
- facebook-commerce-events-tracker.php +113 -110
- facebook-commerce-messenger-chat.php +10 -2
- facebook-commerce-pixel-event.php +155 -82
- facebook-commerce.php +177 -163
- facebook-config-warmer.php +2 -2
- facebook-for-woocommerce.php +54 -30
- i18n/languages/facebook-for-woocommerce.pot +181 -181
- includes/AJAX.php +82 -71
- includes/API.php +74 -60
- includes/API/Catalog/Product_Group/Products/Read/Request.php +7 -5
- includes/API/Catalog/Product_Group/Products/Read/Response.php +1 -1
- includes/API/Catalog/Product_Item/Find/Request.php +1 -1
- includes/API/Catalog/Request.php +2 -2
- includes/API/Catalog/Send_Item_Updates/Request.php +5 -5
- includes/API/FBE/Configuration/Messenger.php +12 -9
- includes/API/FBE/Configuration/Read/Response.php +1 -1
- includes/API/FBE/Configuration/Request.php +3 -3
- includes/API/FBE/Configuration/Update/Request.php +3 -3
- includes/API/FBE/Installation/Read/Request.php +3 -3
- includes/API/FBE/Installation/Read/Response.php +3 -3
- includes/API/FBE/Installation/Request.php +1 -1
- includes/API/Orders/Acknowledge/Request.php +7 -5
- includes/API/Orders/Cancel/Request.php +11 -9
- includes/API/Orders/Fulfillment/Request.php +2 -2
- includes/API/Orders/Order.php +5 -5
- includes/API/Orders/Read/Request.php +21 -18
- includes/API/Orders/Refund/Request.php +2 -2
- includes/API/Orders/Request.php +21 -18
- includes/API/Orders/Response.php +1 -1
- includes/API/Pages/Read/Request.php +2 -2
- includes/API/Pages/Read/Response.php +1 -1
- includes/API/Pixel/Events/Request.php +5 -5
- includes/API/Request.php +1 -1
- includes/API/Traits/Paginated_Response.php +1 -1
- includes/API/Traits/Rate_Limited_API.php +2 -2
- includes/API/Traits/Rate_Limited_Response.php +1 -1
- includes/API/User/Permissions/Delete/Request.php +1 -1
- includes/API/User/Request.php +1 -1
- includes/Admin.php +98 -46
- includes/Admin/Abstract_Settings_Screen.php +1 -0
- includes/Admin/Enhanced_Catalog_Attribute_Fields.php +1 -1
- includes/Admin/Product_Categories.php +2 -2
- includes/Admin/Settings.php +25 -22
- includes/Admin/Settings_Screens/Advertise.php +14 -14
- includes/Admin/Settings_Screens/Connection.php +57 -46
- includes/Admin/Settings_Screens/Messenger.php +28 -21
- includes/Admin/Settings_Screens/Product_Sync.php +98 -74
- includes/Commerce/Orders.php +103 -84
- includes/Events/AAMSettings.php +20 -22
- includes/Events/Event.php +41 -36
- includes/Events/Normalizer.php +53 -56
- includes/Exceptions/ConnectWCAPIException.php +14 -0
- includes/Handlers/Connection.php +88 -61
- includes/Integrations/Bookings.php +7 -7
- includes/Integrations/Integrations.php +2 -2
- includes/Jobs/AbstractChainedJob.php +39 -0
- includes/Jobs/GenerateProductFeed.php +145 -0
- includes/Jobs/JobRegistry.php +31 -0
- includes/Jobs/LoggingTrait.php +38 -0
- includes/Lifecycle.php +29 -14
- includes/Locale.php +4 -5
- includes/ProductSets/Sync.php +2 -2
- includes/Product_Categories.php +1 -1
- includes/Products.php +8 -8
- includes/Products/FBCategories.php +2 -2
- includes/Products/Feed.php +19 -16
- includes/Products/Stock.php +11 -8
- includes/Products/Sync.php +11 -9
- includes/Products/Sync/Background.php +44 -25
- includes/Utilities/Background_Handle_Virtual_Products_Variations.php +3 -3
- includes/Utilities/Background_Remove_Duplicate_Visibility_Meta.php +8 -6
- includes/Utilities/Shipment.php +512 -512
- includes/Utilities/Tracker.php +1 -1
- includes/fbgraph.php +38 -36
- includes/fbproduct.php +6 -5
- includes/fbproductfeed.php +21 -24
- includes/fbutils.php +21 -21
- includes/fbwpml.php +2 -2
- includes/test/facebook-integration-test.php +1 -1
- readme.txt +16 -2
- vendor/autoload.php +7 -0
- vendor/composer/ClassLoader.php +445 -0
- vendor/composer/InstalledVersions.php +250 -0
- vendor/composer/LICENSE +21 -0
- vendor/composer/autoload_classmap.php +10 -0
- vendor/composer/autoload_namespaces.php +9 -0
- vendor/composer/autoload_psr4.php +12 -0
- vendor/composer/autoload_real.php +57 -0
- vendor/composer/autoload_static.php +52 -0
- vendor/composer/installed.json +231 -0
- vendor/composer/installed.php +65 -0
- vendor/composer/installers/LICENSE +19 -0
- vendor/composer/installers/phpstan.neon.dist +10 -0
- vendor/composer/installers/src/Composer/Installers/AglInstaller.php +21 -0
- vendor/composer/installers/src/Composer/Installers/AimeosInstaller.php +9 -0
- vendor/composer/installers/src/Composer/Installers/AnnotateCmsInstaller.php +11 -0
- vendor/composer/installers/src/Composer/Installers/AsgardInstaller.php +49 -0
- vendor/composer/installers/src/Composer/Installers/AttogramInstaller.php +9 -0
- vendor/composer/installers/src/Composer/Installers/BaseInstaller.php +137 -0
- vendor/composer/installers/src/Composer/Installers/BitrixInstaller.php +126 -0
- vendor/composer/installers/src/Composer/Installers/BonefishInstaller.php +9 -0
- vendor/composer/installers/src/Composer/Installers/CakePHPInstaller.php +65 -0
- vendor/composer/installers/src/Composer/Installers/ChefInstaller.php +11 -0
- vendor/composer/installers/src/Composer/Installers/CiviCrmInstaller.php +9 -0
- vendor/composer/installers/src/Composer/Installers/ClanCatsFrameworkInstaller.php +10 -0
- vendor/composer/installers/src/Composer/Installers/CockpitInstaller.php +32 -0
- vendor/composer/installers/src/Composer/Installers/CodeIgniterInstaller.php +11 -0
- vendor/composer/installers/src/Composer/Installers/Concrete5Installer.php +13 -0
- vendor/composer/installers/src/Composer/Installers/CraftInstaller.php +35 -0
- vendor/composer/installers/src/Composer/Installers/CroogoInstaller.php +21 -0
- vendor/composer/installers/src/Composer/Installers/DecibelInstaller.php +10 -0
- vendor/composer/installers/src/Composer/Installers/DframeInstaller.php +10 -0
- vendor/composer/installers/src/Composer/Installers/DokuWikiInstaller.php +50 -0
- vendor/composer/installers/src/Composer/Installers/DolibarrInstaller.php +16 -0
- vendor/composer/installers/src/Composer/Installers/DrupalInstaller.php +22 -0
- vendor/composer/installers/src/Composer/Installers/ElggInstaller.php +9 -0
- vendor/composer/installers/src/Composer/Installers/EliasisInstaller.php +12 -0
- vendor/composer/installers/src/Composer/Installers/ExpressionEngineInstaller.php +29 -0
- vendor/composer/installers/src/Composer/Installers/EzPlatformInstaller.php +10 -0
- vendor/composer/installers/src/Composer/Installers/FuelInstaller.php +11 -0
- vendor/composer/installers/src/Composer/Installers/FuelphpInstaller.php +9 -0
- vendor/composer/installers/src/Composer/Installers/GravInstaller.php +30 -0
- vendor/composer/installers/src/Composer/Installers/HuradInstaller.php +25 -0
- vendor/composer/installers/src/Composer/Installers/ImageCMSInstaller.php +11 -0
- vendor/composer/installers/src/Composer/Installers/Installer.php +297 -0
- vendor/composer/installers/src/Composer/Installers/ItopInstaller.php +9 -0
- vendor/composer/installers/src/Composer/Installers/JoomlaInstaller.php +15 -0
- vendor/composer/installers/src/Composer/Installers/KanboardInstaller.php +18 -0
- vendor/composer/installers/src/Composer/Installers/KirbyInstaller.php +11 -0
- vendor/composer/installers/src/Composer/Installers/KnownInstaller.php +11 -0
- vendor/composer/installers/src/Composer/Installers/KodiCMSInstaller.php +10 -0
- vendor/composer/installers/src/Composer/Installers/KohanaInstaller.php +9 -0
- vendor/composer/installers/src/Composer/Installers/LanManagementSystemInstaller.php +27 -0
- vendor/composer/installers/src/Composer/Installers/LaravelInstaller.php +9 -0
- vendor/composer/installers/src/Composer/Installers/LavaLiteInstaller.php +10 -0
- vendor/composer/installers/src/Composer/Installers/LithiumInstaller.php +10 -0
- vendor/composer/installers/src/Composer/Installers/MODULEWorkInstaller.php +9 -0
- vendor/composer/installers/src/Composer/Installers/MODXEvoInstaller.php +16 -0
- vendor/composer/installers/src/Composer/Installers/MagentoInstaller.php +11 -0
- vendor/composer/installers/src/Composer/Installers/MajimaInstaller.php +37 -0
- vendor/composer/installers/src/Composer/Installers/MakoInstaller.php +9 -0
- vendor/composer/installers/src/Composer/Installers/MantisBTInstaller.php +23 -0
- vendor/composer/installers/src/Composer/Installers/MauticInstaller.php +48 -0
- vendor/composer/installers/src/Composer/Installers/MayaInstaller.php +33 -0
- vendor/composer/installers/src/Composer/Installers/MediaWikiInstaller.php +51 -0
- vendor/composer/installers/src/Composer/Installers/MiaoxingInstaller.php +10 -0
- vendor/composer/installers/src/Composer/Installers/MicroweberInstaller.php +119 -0
- vendor/composer/installers/src/Composer/Installers/ModxInstaller.php +12 -0
- vendor/composer/installers/src/Composer/Installers/MoodleInstaller.php +59 -0
- vendor/composer/installers/src/Composer/Installers/OctoberInstaller.php +48 -0
- vendor/composer/installers/src/Composer/Installers/OntoWikiInstaller.php +24 -0
- vendor/composer/installers/src/Composer/Installers/OsclassInstaller.php +14 -0
- vendor/composer/installers/src/Composer/Installers/OxidInstaller.php +59 -0
- vendor/composer/installers/src/Composer/Installers/PPIInstaller.php +9 -0
- vendor/composer/installers/src/Composer/Installers/PhiftyInstaller.php +11 -0
- vendor/composer/installers/src/Composer/Installers/PhpBBInstaller.php +11 -0
- vendor/composer/installers/src/Composer/Installers/PimcoreInstaller.php +21 -0
- vendor/composer/installers/src/Composer/Installers/PiwikInstaller.php +32 -0
- vendor/composer/installers/src/Composer/Installers/PlentymarketsInstaller.php +29 -0
- vendor/composer/installers/src/Composer/Installers/Plugin.php +27 -0
- vendor/composer/installers/src/Composer/Installers/PortoInstaller.php +9 -0
- vendor/composer/installers/src/Composer/Installers/PrestashopInstaller.php +10 -0
- vendor/composer/installers/src/Composer/Installers/ProcessWireInstaller.php +22 -0
- vendor/composer/installers/src/Composer/Installers/PuppetInstaller.php +11 -0
- vendor/composer/installers/src/Composer/Installers/PxcmsInstaller.php +63 -0
- vendor/composer/installers/src/Composer/Installers/RadPHPInstaller.php +24 -0
- vendor/composer/installers/src/Composer/Installers/ReIndexInstaller.php +10 -0
- vendor/composer/installers/src/Composer/Installers/Redaxo5Installer.php +10 -0
- vendor/composer/installers/src/Composer/Installers/RedaxoInstaller.php +10 -0
- vendor/composer/installers/src/Composer/Installers/RoundcubeInstaller.php +22 -0
- vendor/composer/installers/src/Composer/Installers/SMFInstaller.php +10 -0
- vendor/composer/installers/src/Composer/Installers/ShopwareInstaller.php +60 -0
- vendor/composer/installers/src/Composer/Installers/SilverStripeInstaller.php +35 -0
- vendor/composer/installers/src/Composer/Installers/SiteDirectInstaller.php +25 -0
- vendor/composer/installers/src/Composer/Installers/StarbugInstaller.php +12 -0
- vendor/composer/installers/src/Composer/Installers/SyDESInstaller.php +47 -0
- vendor/composer/installers/src/Composer/Installers/SyliusInstaller.php +9 -0
- vendor/composer/installers/src/Composer/Installers/Symfony1Installer.php +26 -0
- vendor/composer/installers/src/Composer/Installers/TYPO3CmsInstaller.php +16 -0
- vendor/composer/installers/src/Composer/Installers/TYPO3FlowInstaller.php +38 -0
- vendor/composer/installers/src/Composer/Installers/TaoInstaller.php +30 -0
- vendor/composer/installers/src/Composer/Installers/TastyIgniterInstaller.php +32 -0
- vendor/composer/installers/src/Composer/Installers/TheliaInstaller.php +12 -0
- vendor/composer/installers/src/Composer/Installers/TuskInstaller.php +14 -0
- vendor/composer/installers/src/Composer/Installers/UserFrostingInstaller.php +9 -0
- vendor/composer/installers/src/Composer/Installers/VanillaInstaller.php +10 -0
- vendor/composer/installers/src/Composer/Installers/VgmcpInstaller.php +49 -0
- vendor/composer/installers/src/Composer/Installers/WHMCSInstaller.php +21 -0
- vendor/composer/installers/src/Composer/Installers/WinterInstaller.php +58 -0
- vendor/composer/installers/src/Composer/Installers/WolfCMSInstaller.php +9 -0
- vendor/composer/installers/src/Composer/Installers/WordPressInstaller.php +12 -0
- vendor/composer/installers/src/Composer/Installers/YawikInstaller.php +32 -0
- vendor/composer/installers/src/Composer/Installers/ZendInstaller.php +11 -0
- vendor/composer/installers/src/Composer/Installers/ZikulaInstaller.php +10 -0
- vendor/composer/installers/src/bootstrap.php +13 -0
- vendor/composer/platform_check.php +26 -0
- vendor/woocommerce/action-scheduler-job-framework/LICENSE +674 -0
- vendor/woocommerce/action-scheduler-job-framework/README.md +116 -0
- vendor/woocommerce/action-scheduler-job-framework/phpcs.xml.dist +57 -0
- vendor/woocommerce/action-scheduler-job-framework/src/AbstractChainedJob.php +251 -0
- vendor/woocommerce/action-scheduler-job-framework/src/AbstractJob.php +76 -0
- vendor/woocommerce/action-scheduler-job-framework/src/ChainedJobInterface.php +72 -0
- vendor/woocommerce/action-scheduler-job-framework/src/JobInterface.php +48 -0
- vendor/woocommerce/action-scheduler-job-framework/src/Proxies/ActionScheduler.php +97 -0
- vendor/woocommerce/action-scheduler-job-framework/src/Proxies/ActionSchedulerInterface.php +89 -0
- vendor/woocommerce/action-scheduler-job-framework/src/Utilities/BatchQueryOffset.php +26 -0
- vendor/woocommerce/action-scheduler-job-framework/src/Utilities/BatchSize.php +22 -0
- webpack.config.js +35 -0
README.md
ADDED
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Facebook for WooCommerce
|
2 |
+
|
3 |
+
This is the development repository for the Facebook for WooCommerce plugin.
|
4 |
+
|
5 |
+
- [WooCommerce.com product page](https://woocommerce.com/products/facebook)
|
6 |
+
- [WordPress.org plugin page](https://wordpress.org/plugins/facebook-for-woocommerce/)
|
7 |
+
- [User documentation](https://docs.woocommerce.com/document/facebook-for-woocommerce)
|
8 |
+
|
9 |
+
## Support
|
10 |
+
The best place to get support is the [WordPress.org Facebook for WooCommerce forum](https://wordpress.org/support/plugin/facebook-for-woocommerce/).
|
11 |
+
|
12 |
+
If you have a WooCommerce.com account, you can [start a chat or open a ticket on WooCommerce.com](https://woocommerce.com/my-account/create-a-ticket/).
|
13 |
+
|
14 |
+
## Development
|
15 |
+
### Developing
|
16 |
+
- Clone this repository into the `wp-content/plugins/` folder your WooCommerce development environment.
|
17 |
+
- Install dependencies:
|
18 |
+
- `npm install`
|
19 |
+
- `composer install`
|
20 |
+
- Build assets:
|
21 |
+
- `npm start` to build a development version
|
22 |
+
- Linting:
|
23 |
+
- `npm run lint:php` to run PHPCS linter on all PHP files
|
24 |
+
|
25 |
+
#### Production build
|
26 |
+
This plugin uses a custom build tool called [`sake`](https://github.com/skyverge/sake).
|
27 |
+
|
28 |
+
If you have `sake` set up on your system, these commands can be used to generate a production build.
|
29 |
+
|
30 |
+
- `npm run build` builds and zips to `/build/facebook-for-woocommerce.{version}.zip`.
|
31 |
+
|
32 |
+
### Releasing
|
33 |
+
Refer to the [wiki for details of how to build and release the plugin](https://github.com/woocommerce/facebook-for-woocommerce/wiki/Build-&-Release).
|
assets/build/admin/google-product-category-fields.asset.php
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
<?php return array('dependencies' => array('wp-polyfill'), 'version' => '00c66c0ea3ceb2d3751483c954e5a649');
|
assets/build/admin/google-product-category-fields.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
!function(e){var t={};function o(a){if(t[a])return t[a].exports;var n=t[a]={i:a,l:!1,exports:{}};return e[a].call(n.exports,n,n.exports,o),n.l=!0,n.exports}o.m=e,o.c=t,o.d=function(e,t,a){o.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:a})},o.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},o.t=function(e,t){if(1&t&&(e=o(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var a=Object.create(null);if(o.r(a),Object.defineProperty(a,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var n in e)o.d(a,n,function(t){return e[t]}.bind(null,n));return a},o.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return o.d(t,"a",t),t},o.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},o.p="",o(o.s=3)}([function(e,t){e.exports=function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}},function(e,t){function o(e,t){for(var o=0;o<t.length;o++){var a=t[o];a.enumerable=a.enumerable||!1,a.configurable=!0,"value"in a&&(a.writable=!0),Object.defineProperty(e,a.key,a)}}e.exports=function(e,t,a){return t&&o(e.prototype,t),a&&o(e,a),e}},,function(e,t,o){"use strict";o.r(t);var a=o(0),n=o.n(a),r=o(1),c=o.n(r);jQuery(document).ready((function(e){window.WC_Facebook_Google_Product_Category_Fields=function(){function t(o,a){var r=this;n()(this,t),this.categories=o,this.input_id=a;var c=e("#"+this.input_id);e('<div id="wc-facebook-google-product-category-fields"></div>').insertBefore(c).on("change","select.wc-facebook-google-product-category-select",(function(t){r.onChange(e(t.target))})),this.addInitialSelects(c.val());var i=this.globalsHolder().enhanced_attribute_optional_selector;void 0!==i&&e("#"+i).on("change",(function(){e(".wc-facebook-enhanced-catalog-attribute-optional-row").toggleClass("hidden",!e(this).prop("checked"))}))}return c()(t,[{key:"globalsHolder",value:function(){return"undefined"!=typeof facebook_for_woocommerce_product_categories?facebook_for_woocommerce_product_categories:"undefined"!=typeof facebook_for_woocommerce_settings_sync?facebook_for_woocommerce_settings_sync:facebook_for_woocommerce_products_admin}},{key:"getPageType",value:function(){return"undefined"!=typeof facebook_for_woocommerce_product_categories?0===e("input[name=tag_ID]").length?this.globalsHolder().enhanced_attribute_page_type_add_category:this.globalsHolder().enhanced_attribute_page_type_edit_category:this.globalsHolder().enhanced_attribute_page_type_edit_product}},{key:"addInitialSelects",value:function(e){var t=this;if(e){this.getSelectedCategoryIds(e).forEach((function(e){t.addSelect(t.getOptions(e[1]),e[0])}));var o=this.getOptions(e);Object.keys(o).length&&this.addSelect(o)}else this.addSelect(this.getOptions()),this.addSelect({})}},{key:"requestAttributesIfValid",value:function(){if("true"===e("#wc_facebook_can_show_enhanced_catalog_attributes_id").val()&&(e(".wc-facebook-enhanced-catalog-attribute-row").remove(),this.isValid())){var t="#"+this.input_id,o=e(t).parents("div.form-field"),a=this.globalsHolder().enhanced_attribute_optional_selector;this.getPageType()===this.globalsHolder().enhanced_attribute_page_type_edit_category?o=e(t).parents("tr.form-field"):this.getPageType()===this.globalsHolder().enhanced_attribute_page_type_edit_product&&(o=e(t).parents("p.form-field")),e.get(this.globalsHolder().ajax_url,{action:"wc_facebook_enhanced_catalog_attributes",security:"",selected_category:e(t).val(),tag_id:parseInt(e("input[name=tag_ID]").val(),10),taxonomy:e("input[name=taxonomy]").val(),item_id:parseInt(e("input[name=post_ID]").val(),10),page_type:this.getPageType()},(function(t){var n=e(t);e("#"+a,n).on("change",(function(){e(".wc-facebook-enhanced-catalog-attribute-optional-row").toggleClass("hidden",!e(this).prop("checked"))})),n.insertAfter(o),e(document.body).trigger("init_tooltips")}))}}},{key:"onChange",value:function(t){t.hasClass("locked")&&t.closest(".wc-facebook-google-product-category-field").nextAll().remove();var o=t.val();if(o){var a=this.getOptions(o);Object.keys(a).length&&this.addSelect(a)}else(o=t.closest("#wc-facebook-google-product-category-fields").find(".wc-facebook-google-product-category-select").not(t).last().val())||this.addSelect({});e("#"+this.input_id).val(o),this.requestAttributesIfValid()}},{key:"isValid",value:function(){return e(".wc-facebook-google-product-category-select").filter((function(t,o){return""!==e(o).val()})).length>=2}},{key:"addSelect",value:function(t,o){var a=e("#wc-facebook-google-product-category-fields"),n=a.find(".wc-facebook-google-product-category-select"),r=e('<select class="wc-enhanced-select wc-facebook-google-product-category-select"></select>');n.addClass("locked"),a.append(e('<div class="wc-facebook-google-product-category-field" style="margin-bottom: 16px">').append(r)),r.attr("data-placeholder",this.getSelectPlaceholder(n,t)).append(e('<option value=""></option>')),Object.keys(t).forEach((function(o){r.append(e('<option value="'+o+'">'+t[o]+"</option>"))})),r.val(o).select2({allowClear:!0})}},{key:"getSelectPlaceholder",value:function(e,t){return 0===e.length?facebook_for_woocommerce_google_product_category.i18n.top_level_dropdown_placeholder:1===e.length&&0===Object.keys(t).length?facebook_for_woocommerce_google_product_category.i18n.second_level_empty_dropdown_placeholder:facebook_for_woocommerce_google_product_category.i18n.general_dropdown_placeholder}},{key:"getOptions",value:function(e){return void 0===e||""===e?this.getTopLevelOptions():void 0===this.categories[e]||void 0===this.categories[e].options?[]:this.categories[e].options}},{key:"getTopLevelOptions",value:function(){var e=this,t={};return Object.keys(this.categories).forEach((function(o){e.categories[o].parent||(t[o]=e.categories[o].label)})),t}},{key:"getSelectedCategoryIds",value:function(e){var t=[];do{void 0!==this.categories[e]&&(t.push([e,this.categories[e].parent]),e=this.categories[e].parent)}while(""!==e);return t.reverse()}}]),t}()}))}]);
|
assets/build/admin/index.asset.php
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
<?php return array('dependencies' => array('wp-polyfill'), 'version' => '92d945b180080836a3157ac9b263c06c');
|
assets/build/admin/index.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
!function(e){var t={};function r(n){if(t[n])return t[n].exports;var o=t[n]={i:n,l:!1,exports:{}};return e[n].call(o.exports,o,o.exports,r),o.l=!0,o.exports}r.m=e,r.c=t,r.d=function(e,t,n){r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)r.d(n,o,function(t){return e[t]}.bind(null,o));return n},r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,"a",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p="",r(r.s=2)}({2:function(e,t){}});
|
assets/build/admin/infobanner.asset.php
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
<?php return array('dependencies' => array('wp-polyfill'), 'version' => '06a723733c2f5d1b1540bfd66802907d');
|
assets/build/admin/infobanner.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
!function(e){var t={};function r(n){if(t[n])return t[n].exports;var o=t[n]={i:n,l:!1,exports:{}};return e[n].call(o.exports,o,o.exports,r),o.l=!0,o.exports}r.m=e,r.c=t,r.d=function(e,t,n){r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)r.d(n,o,function(t){return e[t]}.bind(null,o));return n},r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,"a",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p="",r(r.s=4)}({4:function(e,t){}});
|
assets/build/admin/metabox.asset.php
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
<?php return array('dependencies' => array('wp-polyfill'), 'version' => '11491c9b1bc47798db6b39ee4dcc4f56');
|
assets/build/admin/metabox.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
!function(e){var t={};function r(n){if(t[n])return t[n].exports;var o=t[n]={i:n,l:!1,exports:{}};return e[n].call(o.exports,o,o.exports,r),o.l=!0,o.exports}r.m=e,r.c=t,r.d=function(e,t,n){r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)r.d(n,o,function(t){return e[t]}.bind(null,o));return n},r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,"a",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p="",r(r.s=5)}({5:function(e,t){}});
|
assets/build/admin/modal.asset.php
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
<?php return array('dependencies' => array('wp-polyfill'), 'version' => '5893f2331640da5de5c8690f39ba5f3e');
|
assets/build/admin/modal.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
!function(e){var n={};function o(t){if(n[t])return n[t].exports;var r=n[t]={i:t,l:!1,exports:{}};return e[t].call(r.exports,r,r.exports,o),r.l=!0,r.exports}o.m=e,o.c=n,o.d=function(e,n,t){o.o(e,n)||Object.defineProperty(e,n,{enumerable:!0,get:t})},o.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},o.t=function(e,n){if(1&n&&(e=o(e)),8&n)return e;if(4&n&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(o.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&n&&"string"!=typeof e)for(var r in e)o.d(t,r,function(n){return e[n]}.bind(null,r));return t},o.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return o.d(n,"a",n),n},o.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},o.p="",o(o.s=6)}({6:function(e,n){var o;o=jQuery,window.isModalBlocked=function(){var e=o(".wc-backbone-modal-content");return e.is(".processing")||e.parents(".processing").length},window.blockModal=function(){if(!isModalBlocked())return o(".wc-backbone-modal-content").addClass("processing").block({message:null,overlayCSS:{background:"#fff",opacity:.6}})},window.unBlockModal=function(){o(".wc-backbone-modal-content").removeClass("processing").unblock()},window.closeExistingModal=function(){o("#wc-backbone-modal-dialog .modal-close").trigger("click")}}});
|
assets/build/admin/orders.asset.php
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
<?php return array('dependencies' => array('wp-polyfill'), 'version' => '869fc31f506af286cd2b4e213105990a');
|
assets/build/admin/orders.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
!function(e){var o={};function r(c){if(o[c])return o[c].exports;var n=o[c]={i:c,l:!1,exports:{}};return e[c].call(n.exports,n,n.exports,r),n.l=!0,n.exports}r.m=e,r.c=o,r.d=function(e,o,c){r.o(e,o)||Object.defineProperty(e,o,{enumerable:!0,get:c})},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,o){if(1&o&&(e=r(e)),8&o)return e;if(4&o&&"object"==typeof e&&e&&e.__esModule)return e;var c=Object.create(null);if(r.r(c),Object.defineProperty(c,"default",{enumerable:!0,value:e}),2&o&&"string"!=typeof e)for(var n in e)r.d(c,n,function(o){return e[o]}.bind(null,n));return c},r.n=function(e){var o=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(o,"a",o),o},r.o=function(e,o){return Object.prototype.hasOwnProperty.call(e,o)},r.p="",r(r.s=7)}({7:function(e,o){jQuery(document).ready((function(e){"use strict";var o=Boolean(wc_facebook_commerce_orders.is_commerce_order),r={restrict_order_statuses:function(e){e.find("option").each((function(e,o){-1===wc_facebook_commerce_orders.allowed_commerce_statuses.indexOf(o.value)&&o.remove()}))},toggle_created_date_fields_status:function(o){r.toggle_field(e("#order_data").find("input[name*=order_date]"),o)},disable_order_status_field:function(e){r.toggle_field(e,!1)},toggle_order_customer_field:function(o){e("#order_data").find(".form-field.wc-customer-user").toggleClass("hidden",o)},toggle_billing_and_shipping_fields:function(o){e("#order_data").find("a.edit_address").toggleClass("hidden",o)},disable_pending_order_related_fields:function(e){r.toggle_created_date_fields_status(!1),r.disable_order_status_field(e),r.toggle_order_customer_field(!0),r.toggle_billing_and_shipping_fields(!0)},maybe_disable_refunds:function(){"completed"!==wc_facebook_commerce_orders.order_status&&e(".wc-order-bulk-actions .refund-items").hide()},toggle_field:function(e,o){e.hasClass("wc-enhanced-select")&&(e=e.next("span.select2-container")),o?e.css("pointer-events","all").css("opacity","1.0"):e.css("pointer-events","none").css("opacity","0.4")}},c=e('form[id="post"]'),n=e("#order_status"),a=n.val(),t=wc_facebook_commerce_orders.shipment_tracking,d="",_="",i="",s="";function l(o){unBlockModal(),e(".facebook-for-woocommerce-modal .wc-backbone-modal-content article").html("<p>"+o+"</p>"),e(".facebook-for-woocommerce-modal .wc-backbone-modal-content footer").remove()}function f(){var o=arguments.length>0&&void 0!==arguments[0]&&arguments[0],r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null;if(!r.length)return alert(wc_facebook_commerce_orders.i18n.missing_tracking_number_error),!1;o&&blockModal(),c.find("button[type=submit].save_order").prop("disabled",!0).append('<span class="spinner is-active"></span>'),e.post(ajaxurl,{action:wc_facebook_commerce_orders.complete_order_action,order_id:e("#post_ID").val(),tracking_number:r,carrier_code:n,nonce:wc_facebook_commerce_orders.complete_order_nonce},(function(e){if(o&&unBlockModal(),e&&e.success)c.data("allow-submit",!0).trigger("submit");else{var r=e&&e.data?e.data:wc_facebook_commerce_orders.i18n.unknown_error;alert(r)}})).fail((function(){l(wc_facebook_commerce_orders.i18n.unknown_error)})).always((function(){c.find("button[type=submit].save_order").prop("disabled",!1).find("span.spinner").remove()}))}function m(){var o=e("#refund_reason"),r=e("#wc_facebook_refund_reason").clone().css("width",o.css("width")),c=o.closest("tr"),n=c.clone();c.find("td.total").css("width","16em").end().find("#refund_reason").replaceWith(r.show()).end().find('label[for="refund_reason"]').attr("for","wc_facebook_refund_reason"),c.after(n),u(c,"wc_facebook_refund_reason",wc_facebook_commerce_orders.i18n.refund_reason_label,wc_facebook_commerce_orders.i18n.refund_reason_tooltip),u(n,"refund_reason",wc_facebook_commerce_orders.i18n.refund_description_label,wc_facebook_commerce_orders.i18n.refund_description_tooltip)}function u(e,o,r,c){var n=e.find('label[for="'+o+'"]'),a=n.find(".woocommerce-help-tip").clone();n.text(r),c&&a.length&&(n.prepend(a),a.attr("data-tip",c).tipTip({attribute:"data-tip",fadeIn:50,fadeOut:50,delay:200}))}Array.isArray(t)&&t[0]&&(d=t[0].tracking_number,_=t[0].carrier_code),o&&(r.restrict_order_statuses(n),"pending"===wc_facebook_commerce_orders.order_status&&r.disable_pending_order_related_fields(n),"cancelled"===wc_facebook_commerce_orders.order_status&&r.disable_order_status_field(n),r.maybe_disable_refunds()),o&&(m(),function(){if(void 0!==window.MutationObserver){var o=document.querySelector("#woocommerce-order-items .inside");o&&new MutationObserver((function(o){o.forEach((function(o){Array.prototype.forEach.call(o.addedNodes,(function(o){e(o).is(".wc-order-refund-items")&&m()}))}))})).observe(o,{childList:!0})}}()),c.on("submit",(function(r){if(!e("#post").data("skip-cancel-modal")&&"wc-cancelled"!==a&&o&&"wc-cancelled"===n.val())return function(o){return o.preventDefault(),e("#wc-backbone-modal-dialog .modal-close").trigger("click"),new e.WCBackboneModal.View({target:"facebook-for-woocommerce-modal",string:{message:wc_facebook_commerce_orders.cancel_modal_message,buttons:wc_facebook_commerce_orders.cancel_modal_buttons}}),e(".facebook-for-woocommerce-modal #btn-ok").off("click.facebook_for_commerce").on("click.facebook_for_commerce",(function(o){o.preventDefault(),o.stopPropagation(),blockModal(),e.post(ajaxurl,{action:wc_facebook_commerce_orders.cancel_order_action,order_id:e("#post_ID").val(),reason_code:e('.facebook-for-woocommerce-modal [name="wc_facebook_cancel_reason"]').val(),security:wc_facebook_commerce_orders.cancel_order_nonce},(function(o){o&&o.success?e("#post").data("skip-cancel-modal",!0).trigger("submit"):l(o&&o.data?o.data:wc_facebook_commerce_orders.i18n.unknown_error)})).fail((function(){l(wc_facebook_commerce_orders.i18n.unknown_error)}))})),!1}(r);if(o&&!c.data("allow-submit")){var t=n.val();"wc-refunded"===t&&a!==t&&function(o){o.preventDefault(),e("#wc-backbone-modal-dialog .modal-close").trigger("click"),new e.WCBackboneModal.View({target:"facebook-for-woocommerce-modal",string:{message:wc_facebook_commerce_orders.refund_modal_message,buttons:wc_facebook_commerce_orders.refund_modal_buttons}}),e(document.body).off("wc_backbone_modal_response.facebook_for_commerce").on("wc_backbone_modal_response.facebook_for_commerce",(function(){e("#refund_reason").val(e("#wc_facebook_refund_reason_modal").val()),c.data("allow-submit",!0).submit()}))}(r),"wc-completed"===t&&(r.preventDefault(),d||_?f(!1,d,_):(e("#wc-backbone-modal-dialog .modal-close").trigger("click"),(s||i)&&e(document.body).off("wc_backbone_modal_loaded").on("wc_backbone_modal_loaded",(function(){s&&e("#wc_facebook_carrier").val(s),i&&e("#wc_facebook_tracking_number").val(i)})),new e.WCBackboneModal.View({target:"facebook-for-woocommerce-modal",string:{message:wc_facebook_commerce_orders.complete_modal_message,buttons:wc_facebook_commerce_orders.complete_modal_buttons}}),e(".facebook-for-woocommerce-modal #btn-ok").off("click.facebook_for_commerce").on("click.facebook_for_commerce",(function(o){o.preventDefault(),o.stopPropagation(),s=e("#wc_facebook_carrier").val(),f(!0,i=e("#wc_facebook_tracking_number").val(),s)}))))}}))}))}});
|
assets/build/admin/product-categories.asset.php
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
<?php return array('dependencies' => array('wp-polyfill'), 'version' => '4bedc509a19a74c8c274f145cdaff75a');
|
assets/build/admin/product-categories.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
!function(e){var o={};function t(r){if(o[r])return o[r].exports;var n=o[r]={i:r,l:!1,exports:{}};return e[r].call(n.exports,n,n.exports,t),n.l=!0,n.exports}t.m=e,t.c=o,t.d=function(e,o,r){t.o(e,o)||Object.defineProperty(e,o,{enumerable:!0,get:r})},t.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},t.t=function(e,o){if(1&o&&(e=t(e)),8&o)return e;if(4&o&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(t.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&o&&"string"!=typeof e)for(var n in e)t.d(r,n,function(o){return e[o]}.bind(null,n));return r},t.n=function(e){var o=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(o,"a",o),o},t.o=function(e,o){return Object.prototype.hasOwnProperty.call(e,o)},t.p="",t(t.s=8)}({8:function(e,o){jQuery(document).ready((function(e){var o=e('form[id="edittag"]'),t=e("#wc_facebook_google_product_category_id"),r=t.val();o.on("submit",(function(n){o.data("allow-submit")||t.val()===r||(n.preventDefault(),e("#wc-backbone-modal-dialog .modal-close").trigger("click"),new e.WCBackboneModal.View({target:"facebook-for-woocommerce-modal",string:{message:facebook_for_woocommerce_product_categories.default_google_product_category_modal_message,buttons:facebook_for_woocommerce_product_categories.default_google_product_category_modal_buttons}}),e(document.body).off("wc_backbone_modal_response.facebook_for_commerce").on("wc_backbone_modal_response.facebook_for_commerce",(function(){o.data("allow-submit",!0).find(":submit").trigger("click")})))}))}))}});
|
assets/build/admin/product-sets-admin.asset.php
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
<?php return array('dependencies' => array('wp-polyfill'), 'version' => '98d555c2e6a0ef6072bdf3f337f9302c');
|
assets/build/admin/product-sets-admin.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
!function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=9)}({9:function(e,t){jQuery(document).ready((function(e){jQuery(".select2.wc-facebook").length&&(jQuery(".select2.wc-facebook").select2().addClass("visible").attr("disabled",!1),jQuery(".select2.updating-message").addClass("hidden"),jQuery(document).ajaxSuccess((function(e,t,n){var r=new URLSearchParams(n.data);r.has("action")&&"add-tag"===r.get("action")&&r.has("taxonomy")&&"fb_product_set"===r.get("taxonomy")&&jQuery(".select2.wc-facebook").select2().val(null).trigger("change")})))}))}});
|
assets/build/admin/products-admin.asset.php
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
<?php return array('dependencies' => array('wp-polyfill'), 'version' => 'c40e4d58318863c75d4136c0885d16ea');
|
assets/build/admin/products-admin.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
!function(o){var e={};function t(c){if(e[c])return e[c].exports;var n=e[c]={i:c,l:!1,exports:{}};return o[c].call(n.exports,n,n.exports,t),n.l=!0,n.exports}t.m=o,t.c=e,t.d=function(o,e,c){t.o(o,e)||Object.defineProperty(o,e,{enumerable:!0,get:c})},t.r=function(o){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(o,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(o,"__esModule",{value:!0})},t.t=function(o,e){if(1&e&&(o=t(o)),8&e)return o;if(4&e&&"object"==typeof o&&o&&o.__esModule)return o;var c=Object.create(null);if(t.r(c),Object.defineProperty(c,"default",{enumerable:!0,value:o}),2&e&&"string"!=typeof o)for(var n in o)t.d(c,n,function(e){return o[e]}.bind(null,n));return c},t.n=function(o){var e=o&&o.__esModule?function(){return o.default}:function(){return o};return t.d(e,"a",e),e},t.o=function(o,e){return Object.prototype.hasOwnProperty.call(o,e)},t.p="",t(t.s=10)}({10:function(o,e){jQuery(document).ready((function(o){var e=window.pagenow.length?window.pagenow:"";if(window.typenow.length&&window.typenow,"edit-product"===e){var t=!1;o("input#doaction, input#doaction2").on("click",(function(e){if(t)return!0;e.preventDefault();var c=o(this),n=c.prev("select").val();if("facebook_include"===n){var r=[];o.each(o('input[name="post[]"]:checked'),(function(){r.push(parseInt(o(this).val(),10))})),o.post(facebook_for_woocommerce_products_admin.ajax_url,{action:"facebook_for_woocommerce_set_product_sync_bulk_action_prompt",security:facebook_for_woocommerce_products_admin.set_product_sync_bulk_action_prompt_nonce,toggle:n,products:r},(function(e){e&&!e.success?(closeExistingModal(),new o.WCBackboneModal.View({target:"facebook-for-woocommerce-modal",string:e.data})):(t=!0,c.trigger("click"))}))}else t=!0,c.trigger("click")}))}if("product"===e){function c(o,e){e.find(".enable-if-sync-enabled").prop("disabled",!o)}function n(o,e){o?(e.find("option[value='sync_and_show']").show(),e.prop("original")&&e.val(e.prop("original"))):(e.find("option[value='sync_and_show']").hide(),"sync_and_show"===e.val()&&e.val("sync_and_hide"))}function r(o,e){var t=e.find("#wc_facebook_commerce_enabled"),c=t.prop("original");t.prop("checked",!!o&&c).prop("disabled",!o),t.trigger("change"),t.prop("original",c),e.find("#product-not-ready-notice, #variable-product-not-ready-notice").hide(),s()&&!i()?e.find("#variable-product-not-ready-notice").show():o||e.find("#product-not-ready-notice").show()}function a(){return!!(s()?i():"sync_disabled"!==v.val())&&!!(s()||(o("#_regular_price").val()||o("#fb_product_price").val()))&&!(!o("#_manage_stock").prop("checked")||!o("#_stock").val())}function i(){var e=o(".js-variable-fb-sync-toggle");return 0===e.length?!!facebook_for_woocommerce_products_admin.is_sync_enabled_for_product:!!e.map((function(e,t){return"sync_disabled"!==o(t).val()?t:null})).length}function s(){var e=o("select#product-type").val();return!(!e||!e.match(/variable/))}function d(o){o.attr("data-original-value",o.val())}function l(e){return e.map((function(e,t){var c=o(t),n=c.val();return"sync_disabled"===n&&n!==c.attr("data-original-value")})).toArray().indexOf(!0)>-1}function _(e){return v===e?o("input#post_ID").val():e.closest(".woocommerce_variation").find("input[name^=variable_post_id]").val()}function u(e){closeExistingModal(),m=e,g=_(e),new o.WCBackboneModal.View({target:"facebook-for-woocommerce-modal",string:{message:facebook_for_woocommerce_products_admin.product_removed_from_sync_confirm_modal_message,buttons:facebook_for_woocommerce_products_admin.product_removed_from_sync_confirm_modal_buttons}})}function f(){o(facebook_for_woocommerce_products_admin.product_removed_from_sync_field_id).val(b.join(","))}function p(o){b=b.filter((function(e){return e!==o})),f()}var m=null,g=null,b=[];o(document.body).on("click","button.button-product-removed-from-sync-delete",(function(){g&&(closeExistingModal(),b.push(g),f())})).on("click","button.button-product-removed-from-sync-cancel",(function(){var o;closeExistingModal(),m&&((o=m).val(o.attr("data-original-value")),m=null),f()})),o("#facebook_options #wc_facebook_commerce_enabled").on("change",(function(){var e=o(this).prop("checked");e?o(".wc_facebook_commerce_fields").show():o(".wc_facebook_commerce_fields").hide(),o(".product_attributes").find(".woocommerce_attribute").length?o(".show_if_has_attributes").show():o(".show_if_has_attributes").hide(),o(this).prop("original",e)})).trigger("change");var v=o("#wc_facebook_sync_mode"),h=v.closest(".woocommerce_options_panel");d(v),v.on("change",(function(){var o,e,t="sync_disabled"!==v.val();c(t,h),o=t,e=h.find(".wc-facebook-commerce-options-group"),o?e.show():e.hide(),t&&p(_(v)),v.prop("original",v.val()),l(v)&&u(v)})).trigger("change"),o("#_virtual").on("change",(function(){n(!o(this).prop("checked"),v)})).trigger("change");var w=o("#woocommerce-product-data");w.on("change","#_regular_price, #_manage_stock, #_stock, #wc_facebook_sync_mode, #fb_product_price",(function(e){setTimeout((function(){r(a(),o("#facebook_options"))}),1)})),o(".woocommerce_variations").on("change",".js-variable-fb-sync-toggle",(function(){var e=o(this),t="sync_disabled"!==e.val();c(t,e.closest(".wc-metabox-content")),r(a(),o("#facebook_options")),t&&p(_(e)),e.prop("original",e.val()),l(e)&&u(e)})),w.on("woocommerce_variations_loaded",(function(){w.find(".js-variable-fb-sync-toggle").each((function(e,t){var n=o(t);c("sync_disabled"!==n.val(),n.closest(".wc-metabox-content")),n.prop("original",n.val()),d(n)})),o(".variable_is_virtual").on("change",(function(){var e=o(this).closest(".wc-metabox-content").find(".js-variable-fb-sync-toggle");n(!o(this).prop("checked"),e)})),r(a(),o("#facebook_options"))})),w.on("change",".js-fb-product-image-source",(function(){var e=o(this).closest(".woocommerce_options_panel, .wc-metabox-content"),t=o(this).val();e.find(".product-image-source-field").closest(".form-field").hide(),e.find(".show-if-product-image-source-".concat(t)).closest(".form-field").show()})),o(".js-fb-product-image-source:checked:visible").trigger("change"),w.on("woocommerce_variations_loaded",(function(){o(".js-variable-fb-sync-toggle:visible").trigger("change"),o(".js-fb-product-image-source:checked:visible").trigger("change"),o(".variable_is_virtual:visible").trigger("change")})),o("#facebook_options").on("click","#product-not-ready-notice-open-modal",(function(e){e.preventDefault(),closeExistingModal(),new o.WCBackboneModal.View({target:"facebook-for-woocommerce-modal",string:{message:facebook_for_woocommerce_products_admin.product_not_ready_modal_message,buttons:facebook_for_woocommerce_products_admin.product_not_ready_modal_buttons}})})),r(a(),h);var y=!1;o('form#post input[type="submit"]').on("click",(function(e){if(o("#wc_facebook_commerce_enabled").prop("checked")&&a()&&o(".wc_facebook_commerce_fields .wc-facebook-google-product-category-select").map((function(e,t){return o(t).val()?o(t).val():null})).length<2)return e.preventDefault(),alert(facebook_for_woocommerce_products_admin.i18n.missing_google_product_category_message),!1;if(y)return!0;e.preventDefault();var t=o(this),c=parseInt(o("input#post_ID").val(),10),n=[],r=o('textarea[name="tax_input[product_tag]"]').length?o('textarea[name="tax_input[product_tag]"]').val().split(","):[],s="sync_disabled"!==v.val(),d=i();o('#taxonomy-product_cat input[name="tax_input[product_cat][]"]:checked').each((function(){n.push(parseInt(o(this).val(),10))})),o('#taxonomy-product_tag input[name="tax_input[product_tag][]"]:checked').each((function(){r.push(parseInt(o(this).val(),10))})),c>0?o.post(facebook_for_woocommerce_products_admin.ajax_url,{action:"facebook_for_woocommerce_set_product_sync_prompt",security:facebook_for_woocommerce_products_admin.set_product_sync_prompt_nonce,sync_enabled:s?"enabled":"disabled",var_sync_enabled:d?"enabled":"disabled",product:c,categories:n,tags:r},(function(e){e&&!e.success&&s?(closeExistingModal(),new o.WCBackboneModal.View({target:"facebook-for-woocommerce-modal",string:e.data})):(y=!0,t.trigger("click"))})):(y=!0,t.trigger("click"))}))}}))}});
|
assets/build/admin/settings-commerce.asset.php
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
<?php return array('dependencies' => array('wp-polyfill'), 'version' => '9513715b2a35d2eda9c958baf192798e');
|
assets/build/admin/settings-commerce.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
!function(e){var o={};function t(r){if(o[r])return o[r].exports;var c=o[r]={i:r,l:!1,exports:{}};return e[r].call(c.exports,c,c.exports,t),c.l=!0,c.exports}t.m=e,t.c=o,t.d=function(e,o,r){t.o(e,o)||Object.defineProperty(e,o,{enumerable:!0,get:r})},t.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},t.t=function(e,o){if(1&o&&(e=t(e)),8&o)return e;if(4&o&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(t.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&o&&"string"!=typeof e)for(var c in e)t.d(r,c,function(o){return e[o]}.bind(null,c));return r},t.n=function(e){var o=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(o,"a",o),o},t.o=function(e,o){return Object.prototype.hasOwnProperty.call(e,o)},t.p="",t(t.s=11)}({11:function(e,o){jQuery(document).ready((function(e){var o=e("form.wc-facebook-settings"),t=e("#wc_facebook_google_product_category_id"),r=t.val();o.on("submit",(function(c){o.data("allow-submit")||t.val()===r||(c.preventDefault(),e("#wc-backbone-modal-dialog .modal-close").trigger("click"),new e.WCBackboneModal.View({target:"facebook-for-woocommerce-modal",string:{message:t.val()?facebook_for_woocommerce_settings_commerce.default_google_product_category_modal_message:facebook_for_woocommerce_settings_commerce.default_google_product_category_modal_message_empty,buttons:facebook_for_woocommerce_settings_commerce.default_google_product_category_modal_buttons}}),e(document.body).off("wc_backbone_modal_response.facebook_for_commerce").on("wc_backbone_modal_response.facebook_for_commerce",(function(){o.data("allow-submit",!0).find(":submit").trigger("click")})))})),e(".woocommerce-help-tip").tipTip({attribute:"data-tip",fadeIn:50,fadeOut:50,delay:200})}))}});
|
assets/build/admin/settings-sync.asset.php
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
<?php return array('dependencies' => array('wp-polyfill'), 'version' => 'ca852c21b4cd9d57cc0fce8606957fc3');
|
assets/build/admin/settings-sync.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
!function(e){var o={};function c(n){if(o[n])return o[n].exports;var t=o[n]={i:n,l:!1,exports:{}};return e[n].call(t.exports,t,t.exports,c),t.l=!0,t.exports}c.m=e,c.c=o,c.d=function(e,o,n){c.o(e,o)||Object.defineProperty(e,o,{enumerable:!0,get:n})},c.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},c.t=function(e,o){if(1&o&&(e=c(e)),8&o)return e;if(4&o&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(c.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&o&&"string"!=typeof e)for(var t in e)c.d(n,t,function(o){return e[o]}.bind(null,t));return n},c.n=function(e){var o=e&&e.__esModule?function(){return e.default}:function(){return e};return c.d(o,"a",o),o},c.o=function(e,o){return Object.prototype.hasOwnProperty.call(e,o)},c.p="",c(c.s=12)}({12:function(e,o){jQuery(document).ready((function(e){function o(o){e(".product-sync-field").each((function(){var c=e(this);e(this).hasClass("wc-enhanced-select")&&(c=e(this).next("span.select2-container")),o?c.css("pointer-events","all").css("opacity","1.0"):c.css("pointer-events","none").css("opacity","0.4")}))}e(".woocommerce-help-tip").tipTip({attribute:"data-tip",fadeIn:50,fadeOut:50,delay:200}),e("form.wc-facebook-settings").hasClass("disconnected")&&o(!1),e("input#wc_facebook_enable_product_sync").on("change",(function(c){e("form.wc-facebook-settings").hasClass("disconnected")?e(this).css("pointer-events","none").css("opacity","0.4"):o(e(this).is(":checked"))})).trigger("change");var c=!1;function n(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null;t(e),window.syncStatusInterval||(window.syncStatusInterval=setInterval(r,1e4))}function t(){var c=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null;o(!1),e('input#wc_facebook_enable_product_sync, input[name="save_product_sync_settings"]').css("pointer-events","none").css("opacity","0.4");var n=facebook_for_woocommerce_settings_sync.i18n.sync_in_progress;c&&(n=(n+=c>1?facebook_for_woocommerce_settings_sync.i18n.sync_remaining_items_plural:facebook_for_woocommerce_settings_sync.i18n.sync_remaining_items_singular).replace("{count}",c)),e("#sync_progress").show().html(n).css("color","inherit"),facebook_for_woocommerce_settings_sync.sync_in_progress=!0}function s(){var c=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"";facebook_for_woocommerce_settings_sync.sync_in_progress=!1,clearInterval(window.syncStatusInterval),window.syncStatusInterval=null,o(!0),e('input#wc_facebook_enable_product_sync, input[name="save_product_sync_settings"]').css("pointer-events","all").css("opacity","1"),c?e("#sync_progress").show().html(c).css("color","#DC3232"):e("#sync_progress").hide()}function r(){facebook_for_woocommerce_settings_sync.sync_in_progress&&e.post(facebook_for_woocommerce_settings_sync.ajax_url,{action:"wc_facebook_get_sync_status",nonce:facebook_for_woocommerce_settings_sync.sync_status_nonce},(function(e){console.log(e),e.success&&(e.data>0?n(e.data):s())}))}e('input[name="save_product_sync_settings"]').on("click",(function(o){if(c)return!0;o.preventDefault();var n,t,s,r,_=e(this),i=(s=e("#wc_facebook_excluded_product_category_ids").val(),r=[],window.facebook_for_woocommerce_settings_sync&&window.facebook_for_woocommerce_settings_sync.excluded_category_ids&&(r=window.facebook_for_woocommerce_settings_sync.excluded_category_ids),e(s).not(r).get()),a=(n=e("#wc_facebook_excluded_product_tag_ids").val(),t=[],window.facebook_for_woocommerce_settings_sync&&window.facebook_for_woocommerce_settings_sync.excluded_tag_ids&&(t=window.facebook_for_woocommerce_settings_sync.excluded_tag_ids),e(n).not(t).get());i.length>0||a.length>0?e.post(facebook_for_woocommerce_settings_sync.ajax_url,{action:"facebook_for_woocommerce_set_excluded_terms_prompt",security:facebook_for_woocommerce_settings_sync.set_excluded_terms_prompt_nonce,categories:i,tags:a},(function(o){o&&!o.success?(e("#wc-backbone-modal-dialog .modal-close").trigger("click"),new e.WCBackboneModal.View({target:"facebook-for-woocommerce-modal",string:o.data}),e(".facebook-for-woocommerce-confirm-settings-change").on("click",(function(){blockModal(),c=!0,_.trigger("click")}))):(c=!0,_.trigger("click"))})):(c=!0,_.trigger("click"))})),facebook_for_woocommerce_settings_sync.sync_in_progress&&n(),e("#woocommerce-facebook-settings-sync-products").click((function(o){if(o.preventDefault(),confirm(facebook_for_woocommerce_settings_sync.i18n.confirm_sync)){t();var c=Date.now();e.post(facebook_for_woocommerce_settings_sync.ajax_url,{action:"wc_facebook_sync_products",nonce:facebook_for_woocommerce_settings_sync.sync_products_nonce},(function(e){if(console.log(e),e.success)setTimeout(r,Math.max(0,1e4-(Date.now()-c)));else{var o=facebook_for_woocommerce_settings_sync.i18n.general_error;e.data&&e.data.length>0&&(o=e.data),s(o)}})).fail((function(){s(facebook_for_woocommerce_settings_sync.i18n.general_error)}))}}))}))}});
|
assets/js/admin/facebook-for-woocommerce-product-sets-admin.min.js
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
"use strict";jQuery(document).ready(function(e){jQuery(".select2.wc-facebook").length&&(jQuery(".select2.wc-facebook").select2().addClass("visible").attr("disabled",!1),jQuery(".select2.updating-message").addClass("hidden"),jQuery(document).ajaxSuccess(function(e,a,t){t=new URLSearchParams(t.data);t.has("action")&&"add-tag"===t.get("action")&&t.has("taxonomy")&&"fb_product_set"===t.get("taxonomy")&&jQuery(".select2.wc-facebook").select2().val(null).trigger("change")}))});
|
|
assets/js/admin/facebook-for-woocommerce-products-admin.min.js
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
"use strict";jQuery(document).ready(function(r){var t,n,e,c,i,o,s,a,_,d,l,u,p,f,m,g,b,v,h,w,k,y,x,j,M,D,E=window.pagenow.length?window.pagenow:"";window.typenow.length&&window.typenow;"edit-product"===E&&(t=!1,r("input#doaction, input#doaction2").on("click",function(o){if(t)return!0;o.preventDefault();var e,c=r(this),o=c.prev("select").val();"facebook_include"===o?(e=[],r.each(r('input[name="post[]"]:checked'),function(){e.push(parseInt(r(this).val(),10))}),r.post(facebook_for_woocommerce_products_admin.ajax_url,{action:"facebook_for_woocommerce_set_product_sync_bulk_action_prompt",security:facebook_for_woocommerce_products_admin.set_product_sync_bulk_action_prompt_nonce,toggle:o,products:e},function(o){o&&!o.success?(closeExistingModal(),new r.WCBackboneModal.View({target:"facebook-for-woocommerce-modal",string:o.data})):(t=!0,c.trigger("click"))})):(t=!0,c.trigger("click"))})),"product"===E&&(n=function(o,e){e.find(".enable-if-sync-enabled").prop("disabled",!o)},e=function(o,e){o?(e.find("option[value='sync_and_show']").show(),e.prop("original")&&e.val(e.prop("original"))):(e.find("option[value='sync_and_show']").hide(),"sync_and_show"===e.val()&&e.val("sync_and_hide"))},c=function(o,e){var c=e.find("#wc_facebook_commerce_enabled"),t=c.prop("original");c.prop("checked",!!o&&t).prop("disabled",!o),c.trigger("change"),c.prop("original",t),e.find("#product-not-ready-notice, #variable-product-not-ready-notice").hide(),d()&&!s()?e.find("#variable-product-not-ready-notice").show():o||e.find("#product-not-ready-notice").show()},i=function(){return!!o()&&(!!_()&&!!u())},o=function(){return(d()?s:a)()},s=function(){var o=r(".js-variable-fb-sync-toggle");return 0===o.length?!!facebook_for_woocommerce_products_admin.is_sync_enabled_for_product:!!o.map(function(o,e){return"sync_disabled"!==r(e).val()?e:null}).length},a=function(){return"sync_disabled"!==x.val()},_=function(){return!!d()||l()},d=function(){var o=r("select#product-type").val();return!(!o||!o.match(/variable/))},l=function(){return!(!r("#_regular_price").val()&&!r("#fb_product_price").val())},u=function(){return p()},p=function(){return!(!r("#_manage_stock").prop("checked")||!r("#_stock").val())},f=function(o){o.attr("data-original-value",o.val())},m=function(o){return-1<o.map(function(o,e){var c=r(e),e=c.val();return"sync_disabled"===e&&e!==c.attr("data-original-value")}).toArray().indexOf(!0)},g=function(o){return(x===o?r("input#post_ID"):o.closest(".woocommerce_variation").find("input[name^=variable_post_id]")).val()},b=function(o){closeExistingModal(),k=g(w=o),new r.WCBackboneModal.View({target:"facebook-for-woocommerce-modal",string:{message:facebook_for_woocommerce_products_admin.product_removed_from_sync_confirm_modal_message,buttons:facebook_for_woocommerce_products_admin.product_removed_from_sync_confirm_modal_buttons}})},v=function(){r(facebook_for_woocommerce_products_admin.product_removed_from_sync_field_id).val(y.join(","))},h=function(e){y=y.filter(function(o){return o!==e}),v()},k=w=null,y=[],r(document.body).on("click","button.button-product-removed-from-sync-delete",function(){k&&(closeExistingModal(),y.push(k),v())}).on("click","button.button-product-removed-from-sync-cancel",function(){var o;closeExistingModal(),w&&((o=w).val(o.attr("data-original-value")),w=null),v()}),r("#facebook_options #wc_facebook_commerce_enabled").on("change",function(){var o=r(this).prop("checked");o?r(".wc_facebook_commerce_fields").show():r(".wc_facebook_commerce_fields").hide(),r(".product_attributes").find(".woocommerce_attribute").length?r(".show_if_has_attributes").show():r(".show_if_has_attributes").hide(),r(this).prop("original",o)}).trigger("change"),x=r("#wc_facebook_sync_mode"),j=x.closest(".woocommerce_options_panel"),f(x),x.on("change",function(){var o,e,c="sync_disabled"!==x.val();n(c,j),o=c,e=(e=j).find(".wc-facebook-commerce-options-group"),o?e.show():e.hide(),c&&h(g(x)),x.prop("original",x.val()),m(x)&&b(x)}).trigger("change"),r("#_virtual").on("change",function(){e(!r(this).prop("checked"),x)}).trigger("change"),(M=r("#woocommerce-product-data")).on("change","#_regular_price, #_manage_stock, #_stock, #wc_facebook_sync_mode, #fb_product_price",function(o){setTimeout(function(){c(i(),r("#facebook_options"))},1)}),r(".woocommerce_variations").on("change",".js-variable-fb-sync-toggle",function(){var o=r(this),e="sync_disabled"!==o.val();n(e,o.closest(".wc-metabox-content")),c(i(),r("#facebook_options")),e&&h(g(o)),o.prop("original",o.val()),m(o)&&b(o)}),M.on("woocommerce_variations_loaded",function(){M.find(".js-variable-fb-sync-toggle").each(function(o,e){e=r(e);n("sync_disabled"!==e.val(),e.closest(".wc-metabox-content")),e.prop("original",e.val()),f(e)}),r(".variable_is_virtual").on("change",function(){var o=r(this).closest(".wc-metabox-content").find(".js-variable-fb-sync-toggle");e(!r(this).prop("checked"),o)}),c(i(),r("#facebook_options"))}),M.on("change",".js-fb-product-image-source",function(){var o=r(this).closest(".woocommerce_options_panel, .wc-metabox-content"),e=r(this).val();o.find(".product-image-source-field").closest(".form-field").hide(),o.find(".show-if-product-image-source-"+e).closest(".form-field").show()}),r(".js-fb-product-image-source:checked:visible").trigger("change"),M.on("woocommerce_variations_loaded",function(){r(".js-variable-fb-sync-toggle:visible").trigger("change"),r(".js-fb-product-image-source:checked:visible").trigger("change"),r(".variable_is_virtual:visible").trigger("change")}),r("#facebook_options").on("click","#product-not-ready-notice-open-modal",function(o){o.preventDefault(),closeExistingModal(),new r.WCBackboneModal.View({target:"facebook-for-woocommerce-modal",string:{message:facebook_for_woocommerce_products_admin.product_not_ready_modal_message,buttons:facebook_for_woocommerce_products_admin.product_not_ready_modal_buttons}})}),c(i(),j),D=!1,r('form#post input[type="submit"]').on("click",function(o){if(!!r("#wc_facebook_commerce_enabled").prop("checked")&&(!!i()&&r(".wc_facebook_commerce_fields .wc-facebook-google-product-category-select").map(function(o,e){return r(e).val()?r(e).val():null}).length<2))return o.preventDefault(),alert(facebook_for_woocommerce_products_admin.i18n.missing_google_product_category_message),!1;if(D)return!0;o.preventDefault();var e=r(this),c=parseInt(r("input#post_ID").val(),10),t=[],n=r('textarea[name="tax_input[product_tag]"]').length?r('textarea[name="tax_input[product_tag]"]').val().split(","):[],a="sync_disabled"!==x.val(),o=s();r('#taxonomy-product_cat input[name="tax_input[product_cat][]"]:checked').each(function(){t.push(parseInt(r(this).val(),10))}),r('#taxonomy-product_tag input[name="tax_input[product_tag][]"]:checked').each(function(){n.push(parseInt(r(this).val(),10))}),0<c?r.post(facebook_for_woocommerce_products_admin.ajax_url,{action:"facebook_for_woocommerce_set_product_sync_prompt",security:facebook_for_woocommerce_products_admin.set_product_sync_prompt_nonce,sync_enabled:a?"enabled":"disabled",var_sync_enabled:o?"enabled":"disabled",product:c,categories:t,tags:n},function(o){o&&!o.success&&a?(closeExistingModal(),new r.WCBackboneModal.View({target:"facebook-for-woocommerce-modal",string:o.data})):(D=!0,e.trigger("click"))}):(D=!0,e.trigger("click"))}))});
|
|
assets/js/admin/facebook-for-woocommerce-products-admin.min.old.js
DELETED
@@ -1,2 +0,0 @@
|
|
1 |
-
"use strict";jQuery(document).ready(function(i){var o=window.pagenow.length?window.pagenow:"";window.typenow.length&&window.typenow;if("edit-product"===o){var a=!1;i("input#doaction, input#doaction2").on("click",function(o){if(a)return!0;o.preventDefault();var e=i(this),c=e.prev("select").val();if("facebook_include"===c){var t=[];i.each(i('input[name="post[]"]:checked'),function(){t.push(parseInt(i(this).val(),10))}),i.post(facebook_for_woocommerce_products_admin.ajax_url,{action:"facebook_for_woocommerce_set_product_sync_bulk_action_prompt",security:facebook_for_woocommerce_products_admin.set_product_sync_bulk_action_prompt_nonce,toggle:c,products:t},function(o){o&&!o.success?(i("#wc-backbone-modal-dialog .modal-close").trigger("click"),new i.WCBackboneModal.View({target:"facebook-for-woocommerce-modal",string:o.data})):(a=!0,e.trigger("click"))})}else a=!0,e.trigger("click")})}if("product"===o){var t=function(o,e){e.find(".enable-if-sync-enabled").prop("disabled",!o)},e=function(o,e){o?(e.find("option[value='sync_and_show']").show(),e.prop("original")&&e.val(e.prop("original"))):(e.find("option[value='sync_and_show']").hide(),"sync_and_show"===e.val()&&e.val("sync_and_hide"))},c=function(o,e){var c=e.find("#wc_facebook_commerce_enabled"),t=c.prop("original");c.prop("checked",!!o&&t).prop("disabled",!o),c.trigger("change"),c.prop("original",t),e.find("#product-not-ready-notice, #variable-product-not-ready-notice").hide(),i("select#product-type").val().match(/variable/)&&!r()?e.find("#variable-product-not-ready-notice").show():o||e.find("#product-not-ready-notice").show()},s=function(){return!!n()&&(!!_()&&!!u())},n=function(){return(i("select#product-type").val().match(/variable/)?r:d)()},r=function(){var o=i(".js-variable-fb-sync-toggle");return 0===o.length?!!facebook_for_woocommerce_products_admin.is_sync_enabled_for_product:!!o.map(function(o,e){return"sync_disabled"!==i(e).val()?e:null}).length},d=function(){return"sync_disabled"!==i("#wc_facebook_sync_mode").val()},_=function(){return!!i("select#product-type").val().match(/variable/)||l()},l=function(){return i("#_regular_price").val().length||i("#fb_product_price").val().length},u=function(){return p()},p=function(){return i("#_manage_stock").prop("checked")&&i("#_stock").val().length};i("#facebook_options #wc_facebook_commerce_enabled").on("change",function(){var o=i(this).prop("checked");o?i(".wc_facebook_commerce_fields").show():i(".wc_facebook_commerce_fields").hide(),i(".product_attributes").find(".woocommerce_attribute").length?i(".show_if_has_attributes").show():i(".show_if_has_attributes").hide(),i(this).prop("original",o)}).trigger("change");var f=i("#wc_facebook_sync_mode"),m=f.closest(".woocommerce_options_panel");f.on("change",function(){var o,e,c="sync_disabled"!==i(this).val();t(c,m),o=c,e=m.find(".wc-facebook-commerce-options-group"),o?e.show():e.hide(),f.prop("original",i(this).val())}).trigger("change"),i("#_virtual").on("change",function(){e(!i(this).prop("checked"),f)}).trigger("change"),i("#woocommerce-product-data").on("change","#_regular_price, #_manage_stock, #_stock, #wc_facebook_sync_mode, #fb_product_price",function(o){setTimeout(function(){c(s(),i("#facebook_options"))},1)}),i(".woocommerce_variations").on("change",".js-variable-fb-sync-toggle",function(){t("sync_disabled"!==i(this).val(),i(this).closest(".wc-metabox-content")),c(s(),i("#facebook_options")),i(this).prop("original",i(this).val())}),i("#woocommerce-product-data").on("woocommerce_variations_loaded",function(){i(".js-variable-fb-sync-toggle").each(function(){t("sync_disabled"!==i(this).val(),i(this).closest(".wc-metabox-content")),i(this).prop("original",i(this).val())}),i(".variable_is_virtual").on("change",function(){var o=i(this).closest(".wc-metabox-content").find(".js-variable-fb-sync-toggle");e(!i(this).prop("checked"),o)}),c(s(),i("#facebook_options"))}),i("#woocommerce-product-data").on("change",".js-fb-product-image-source",function(){var o=i(this).closest(".woocommerce_options_panel, .wc-metabox-content"),e=i(this).val();o.find(".product-image-source-field").closest(".form-field").hide(),o.find(".show-if-product-image-source-"+e).closest(".form-field").show()}),i(".js-fb-product-image-source:checked:visible").trigger("change"),i("#woocommerce-product-data").on("woocommerce_variations_loaded",function(){i(".js-variable-fb-sync-toggle:visible").trigger("change"),i(".js-fb-product-image-source:checked:visible").trigger("change"),i(".variable_is_virtual:visible").trigger("change")}),i("#facebook_options").on("click","#product-not-ready-notice-open-modal",function(o){o.preventDefault(),i("#wc-backbone-modal-dialog .modal-close").trigger("click"),new i.WCBackboneModal.View({target:"facebook-for-woocommerce-modal",string:{message:facebook_for_woocommerce_products_admin.product_not_ready_modal_message,buttons:facebook_for_woocommerce_products_admin.product_not_ready_modal_buttons}})}),c(s(),m);var g=!1;i('form#post input[type="submit"]').on("click",function(o){if(!!i("#wc_facebook_commerce_enabled").prop("checked")&&!!s()&&i(".wc_facebook_commerce_fields .wc-facebook-google-product-category-select").map(function(o,e){return i(e).val()?i(e).val():null}).length<2)return o.preventDefault(),alert(facebook_for_woocommerce_products_admin.i18n.missing_google_product_category_message),!1;if(g)return!0;o.preventDefault();var e=i(this),c=parseInt(i("input#post_ID").val(),10),t=[],a=i('textarea[name="tax_input[product_tag]"]').length?i('textarea[name="tax_input[product_tag]"]').val().split(","):[],n="sync_disabled"!==i("#wc_facebook_sync_mode").val(),r="sync_disabled"!==i(".js-variable-fb-sync-toggle").val();i('#taxonomy-product_cat input[name="tax_input[product_cat][]"]:checked').each(function(){t.push(parseInt(i(this).val(),10))}),i('#taxonomy-product_tag input[name="tax_input[product_tag][]"]:checked').each(function(){a.push(parseInt(i(this).val(),10))}),0<c?i.post(facebook_for_woocommerce_products_admin.ajax_url,{action:"facebook_for_woocommerce_set_product_sync_prompt",security:facebook_for_woocommerce_products_admin.set_product_sync_prompt_nonce,sync_enabled:n?"enabled":"disabled",var_sync_enabled:r?"enabled":"disabled",product:c,categories:t,tags:a},function(o){o&&!o.success&&n?(i("#wc-backbone-modal-dialog .modal-close").trigger("click"),new i.WCBackboneModal.View({target:"facebook-for-woocommerce-modal",string:o.data})):(g=!0,e.trigger("click"))}):(g=!0,e.trigger("click"))})}});
|
2 |
-
//# sourceMappingURL=facebook-for-woocommerce-products-admin.min.js.map
|
|
|
|
assets/js/admin/facebook-for-woocommerce-products-admin.min.old.min.js
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
"use strict";jQuery(document).ready(function(r){var t,c,e,a,i,o,n,s,d,_,l,u,p,f,m,g=window.pagenow.length?window.pagenow:"";window.typenow.length&&window.typenow,"edit-product"===g&&(t=!1,r("input#doaction, input#doaction2").on("click",function(o){if(t)return!0;o.preventDefault();var e,c=r(this),o=c.prev("select").val();"facebook_include"===o?(e=[],r.each(r('input[name="post[]"]:checked'),function(){e.push(parseInt(r(this).val(),10))}),r.post(facebook_for_woocommerce_products_admin.ajax_url,{action:"facebook_for_woocommerce_set_product_sync_bulk_action_prompt",security:facebook_for_woocommerce_products_admin.set_product_sync_bulk_action_prompt_nonce,toggle:o,products:e},function(o){o&&!o.success?(r("#wc-backbone-modal-dialog .modal-close").trigger("click"),new r.WCBackboneModal.View({target:"facebook-for-woocommerce-modal",string:o.data})):(t=!0,c.trigger("click"))})):(t=!0,c.trigger("click"))})),"product"===g&&(c=function(o,e){e.find(".enable-if-sync-enabled").prop("disabled",!o)},e=function(o,e){o?(e.find("option[value='sync_and_show']").show(),e.prop("original")&&e.val(e.prop("original"))):(e.find("option[value='sync_and_show']").hide(),"sync_and_show"===e.val()&&e.val("sync_and_hide"))},a=function(o,e){var c,t=(c=e.find("#wc_facebook_commerce_enabled")).prop("original");c.prop("checked",!!o&&t).prop("disabled",!o),c.trigger("change"),c.prop("original",t),e.find("#product-not-ready-notice, #variable-product-not-ready-notice").hide(),r("select#product-type").val().match(/variable/)&&!n()?e.find("#variable-product-not-ready-notice").show():o||e.find("#product-not-ready-notice").show()},i=function(){return!!o()&&!!d()&&!!l()},o=function(){return(r("select#product-type").val().match(/variable/)?n:s)()},n=function(){var o=r(".js-variable-fb-sync-toggle");return 0===o.length?!!facebook_for_woocommerce_products_admin.is_sync_enabled_for_product:!!o.map(function(o,e){return"sync_disabled"!==r(e).val()?e:null}).length},s=function(){return"sync_disabled"!==r("#wc_facebook_sync_mode").val()},d=function(){return!!r("select#product-type").val().match(/variable/)||_()},_=function(){return r("#_regular_price").val().length||r("#fb_product_price").val().length},l=function(){return u()},u=function(){return r("#_manage_stock").prop("checked")&&r("#_stock").val().length},r("#facebook_options #wc_facebook_commerce_enabled").on("change",function(){var o=r(this).prop("checked");o?r(".wc_facebook_commerce_fields").show():r(".wc_facebook_commerce_fields").hide(),r(".product_attributes").find(".woocommerce_attribute").length?r(".show_if_has_attributes").show():r(".show_if_has_attributes").hide(),r(this).prop("original",o)}).trigger("change"),p=r("#wc_facebook_sync_mode"),f=p.closest(".woocommerce_options_panel"),p.on("change",function(){var o,e="sync_disabled"!==r(this).val();c(e,f),o=e,e=f.find(".wc-facebook-commerce-options-group"),o?e.show():e.hide(),p.prop("original",r(this).val())}).trigger("change"),r("#_virtual").on("change",function(){e(!r(this).prop("checked"),p)}).trigger("change"),r("#woocommerce-product-data").on("change","#_regular_price, #_manage_stock, #_stock, #wc_facebook_sync_mode, #fb_product_price",function(o){setTimeout(function(){a(i(),r("#facebook_options"))},1)}),r(".woocommerce_variations").on("change",".js-variable-fb-sync-toggle",function(){c("sync_disabled"!==r(this).val(),r(this).closest(".wc-metabox-content")),a(i(),r("#facebook_options")),r(this).prop("original",r(this).val())}),r("#woocommerce-product-data").on("woocommerce_variations_loaded",function(){r(".js-variable-fb-sync-toggle").each(function(){c("sync_disabled"!==r(this).val(),r(this).closest(".wc-metabox-content")),r(this).prop("original",r(this).val())}),r(".variable_is_virtual").on("change",function(){var o=r(this).closest(".wc-metabox-content").find(".js-variable-fb-sync-toggle");e(!r(this).prop("checked"),o)}),a(i(),r("#facebook_options"))}),r("#woocommerce-product-data").on("change",".js-fb-product-image-source",function(){var o=r(this).closest(".woocommerce_options_panel, .wc-metabox-content"),e=r(this).val();o.find(".product-image-source-field").closest(".form-field").hide(),o.find(".show-if-product-image-source-"+e).closest(".form-field").show()}),r(".js-fb-product-image-source:checked:visible").trigger("change"),r("#woocommerce-product-data").on("woocommerce_variations_loaded",function(){r(".js-variable-fb-sync-toggle:visible").trigger("change"),r(".js-fb-product-image-source:checked:visible").trigger("change"),r(".variable_is_virtual:visible").trigger("change")}),r("#facebook_options").on("click","#product-not-ready-notice-open-modal",function(o){o.preventDefault(),r("#wc-backbone-modal-dialog .modal-close").trigger("click"),new r.WCBackboneModal.View({target:"facebook-for-woocommerce-modal",string:{message:facebook_for_woocommerce_products_admin.product_not_ready_modal_message,buttons:facebook_for_woocommerce_products_admin.product_not_ready_modal_buttons}})}),a(i(),f),m=!1,r('form#post input[type="submit"]').on("click",function(o){if(r("#wc_facebook_commerce_enabled").prop("checked")&&i()&&r(".wc_facebook_commerce_fields .wc-facebook-google-product-category-select").map(function(o,e){return r(e).val()?r(e).val():null}).length<2)return o.preventDefault(),alert(facebook_for_woocommerce_products_admin.i18n.missing_google_product_category_message),!1;if(m)return!0;o.preventDefault();var e=r(this),c=parseInt(r("input#post_ID").val(),10),t=[],a=r('textarea[name="tax_input[product_tag]"]').length?r('textarea[name="tax_input[product_tag]"]').val().split(","):[],n="sync_disabled"!==r("#wc_facebook_sync_mode").val(),o="sync_disabled"!==r(".js-variable-fb-sync-toggle").val();r('#taxonomy-product_cat input[name="tax_input[product_cat][]"]:checked').each(function(){t.push(parseInt(r(this).val(),10))}),r('#taxonomy-product_tag input[name="tax_input[product_tag][]"]:checked').each(function(){a.push(parseInt(r(this).val(),10))}),0<c?r.post(facebook_for_woocommerce_products_admin.ajax_url,{action:"facebook_for_woocommerce_set_product_sync_prompt",security:facebook_for_woocommerce_products_admin.set_product_sync_prompt_nonce,sync_enabled:n?"enabled":"disabled",var_sync_enabled:o?"enabled":"disabled",product:c,categories:t,tags:a},function(o){o&&!o.success&&n?(r("#wc-backbone-modal-dialog .modal-close").trigger("click"),new r.WCBackboneModal.View({target:"facebook-for-woocommerce-modal",string:o.data})):(m=!0,e.trigger("click"))}):(m=!0,e.trigger("click"))}))});
|
|
assets/js/admin/facebook-for-woocommerce-settings-messenger.js
DELETED
@@ -1,96 +0,0 @@
|
|
1 |
-
jQuery( document ).ready( function( $ ) {
|
2 |
-
|
3 |
-
/**
|
4 |
-
* Toggles availability of input in setting groups.
|
5 |
-
*
|
6 |
-
* @param {boolean} enable whether fields in this group should be enabled or not
|
7 |
-
*/
|
8 |
-
function toggleSettingOptions( enable ) {
|
9 |
-
|
10 |
-
$( '.messenger-field' ).each( function() {
|
11 |
-
|
12 |
-
let $element = $( this );
|
13 |
-
|
14 |
-
if ( $( this ).hasClass( 'wc-enhanced-select' ) ) {
|
15 |
-
$element = $( this ).next( 'span.select2-container' );
|
16 |
-
}
|
17 |
-
|
18 |
-
if ( enable ) {
|
19 |
-
$element.css( 'pointer-events', 'all' ).css( 'opacity', '1.0' );
|
20 |
-
} else {
|
21 |
-
$element.css( 'pointer-events', 'none' ).css( 'opacity', '0.4' );
|
22 |
-
}
|
23 |
-
} );
|
24 |
-
}
|
25 |
-
|
26 |
-
if ( $( 'form.wc-facebook-settings' ).hasClass( 'disconnected' ) ) {
|
27 |
-
toggleSettingOptions( false );
|
28 |
-
}
|
29 |
-
|
30 |
-
$( 'input#wc_facebook_enable_messenger' ).on( 'change', function ( e ) {
|
31 |
-
|
32 |
-
if ( $( 'form.wc-facebook-settings' ).hasClass( 'disconnected' ) ) {
|
33 |
-
$( this ).css( 'pointer-events', 'none' ).css( 'opacity', '0.4' );
|
34 |
-
return;
|
35 |
-
}
|
36 |
-
|
37 |
-
toggleSettingOptions( $( this ).is( ':checked' ) );
|
38 |
-
|
39 |
-
} ).trigger( 'change' );
|
40 |
-
|
41 |
-
// adds a character counter on the Messenger greeting textarea
|
42 |
-
$( 'textarea#wc_facebook_messenger_greeting' ).on( 'focus change keyup keydown keypress', function() {
|
43 |
-
|
44 |
-
const maxChars = parseInt( $( this ).attr( 'maxlength' ), 10 );
|
45 |
-
let chars = $( this ).val().length,
|
46 |
-
$counter = $( 'span.characters-counter' ),
|
47 |
-
$warning = $counter.find( 'span' );
|
48 |
-
|
49 |
-
$counter.html( chars + ' / ' + maxChars + '<br/>' ).append( $warning ).css( 'display', 'block' );
|
50 |
-
|
51 |
-
if ( chars > maxChars ) {
|
52 |
-
$counter.css( 'color', '#DC3232' ).find( 'span' ).show();
|
53 |
-
} else {
|
54 |
-
$counter.css( 'color', '#999999' ).find( 'span' ).hide();
|
55 |
-
}
|
56 |
-
|
57 |
-
} );
|
58 |
-
|
59 |
-
|
60 |
-
// init the color picker
|
61 |
-
$( '#wc_facebook_messenger_color_hex' )
|
62 |
-
|
63 |
-
.iris( {
|
64 |
-
change: function( event, ui ) {
|
65 |
-
$( this ).parent().find( '.colorpickpreview' ).css( { backgroundColor: ui.color.toString() } );
|
66 |
-
},
|
67 |
-
hide: true,
|
68 |
-
border: true
|
69 |
-
})
|
70 |
-
|
71 |
-
.on( 'click focus', function( event ) {
|
72 |
-
event.stopPropagation();
|
73 |
-
$( '.iris-picker' ).hide();
|
74 |
-
$( this ).closest( 'td' ).find( '.iris-picker' ).show();
|
75 |
-
$( this ).data( 'original-value', $( this ).val() );
|
76 |
-
} )
|
77 |
-
|
78 |
-
.on( 'change', function() {
|
79 |
-
|
80 |
-
if ( $( this ).is( '.iris-error' ) ) {
|
81 |
-
|
82 |
-
var original_value = $( this ).data( 'original-value' );
|
83 |
-
|
84 |
-
if ( original_value.match( /^\#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})$/ ) ) {
|
85 |
-
$( this ).val( $( this ).data( 'original-value' ) ).change();
|
86 |
-
} else {
|
87 |
-
$( this ).val( '' ).change();
|
88 |
-
}
|
89 |
-
}
|
90 |
-
} );
|
91 |
-
|
92 |
-
$( 'body' ).on( 'click', function() {
|
93 |
-
$( '.iris-picker' ).hide();
|
94 |
-
} );
|
95 |
-
|
96 |
-
} );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
assets/js/admin/facebook-for-woocommerce-settings-messenger.min.js
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
"use strict";jQuery(document).ready(function(c){function s(s){c(".messenger-field").each(function(){var e=c(this);c(this).hasClass("wc-enhanced-select")&&(e=c(this).next("span.select2-container")),s?e.css("pointer-events","all").css("opacity","1.0"):e.css("pointer-events","none").css("opacity","0.4")})}c("form.wc-facebook-settings").hasClass("disconnected")&&s(!1),c("input#wc_facebook_enable_messenger").on("change",function(e){c("form.wc-facebook-settings").hasClass("disconnected")?c(this).css("pointer-events","none").css("opacity","0.4"):s(c(this).is(":checked"))}).trigger("change"),c("textarea#wc_facebook_messenger_greeting").on("focus change keyup keydown keypress",function(){var e=parseInt(c(this).attr("maxlength"),10),s=c(this).val().length,n=c("span.characters-counter"),i=n.find("span");n.html(s+" / "+e+"<br/>").append(i).css("display","block"),e<s?n.css("color","#DC3232").find("span").show():n.css("color","#999999").find("span").hide()}),c("#wc_facebook_messenger_color_hex").iris({change:function(e,s){c(this).parent().find(".colorpickpreview").css({backgroundColor:s.color.toString()})},hide:!0,border:!0}).on("click focus",function(e){e.stopPropagation(),c(".iris-picker").hide(),c(this).closest("td").find(".iris-picker").show(),c(this).data("original-value",c(this).val())}).on("change",function(){c(this).is(".iris-error")&&(c(this).data("original-value").match(/^\#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})$/)?c(this).val(c(this).data("original-value")):c(this).val("")).change()}),c("body").on("click",function(){c(".iris-picker").hide()})});
|
|
assets/js/admin/facebook-for-woocommerce-settings-sync.min.js
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
"use strict";jQuery(document).ready(function(s){function c(e){s(".product-sync-field").each(function(){var o=s(this);s(this).hasClass("wc-enhanced-select")&&(o=s(this).next("span.select2-container")),e?o.css("pointer-events","all").css("opacity","1.0"):o.css("pointer-events","none").css("opacity","0.4")})}s(".woocommerce-help-tip").tipTip({attribute:"data-tip",fadeIn:50,fadeOut:50,delay:200}),s("form.wc-facebook-settings").hasClass("disconnected")&&c(!1),s("input#wc_facebook_enable_product_sync").on("change",function(o){s("form.wc-facebook-settings").hasClass("disconnected")?s(this).css("pointer-events","none").css("opacity","0.4"):c(s(this).is(":checked"))}).trigger("change");var t=!1;function e(o){n(0<arguments.length&&void 0!==o?o:null),window.syncStatusInterval||(window.syncStatusInterval=setInterval(r,1e4))}function n(o){var e=0<arguments.length&&void 0!==o?o:null;c(!1),s('input#wc_facebook_enable_product_sync, input[name="save_product_sync_settings"]').css("pointer-events","none").css("opacity","0.4");o=facebook_for_woocommerce_settings_sync.i18n.sync_in_progress;e&&(o=(o+=1<e?facebook_for_woocommerce_settings_sync.i18n.sync_remaining_items_plural:facebook_for_woocommerce_settings_sync.i18n.sync_remaining_items_singular).replace("{count}",e)),s("#sync_progress").show().html(o).css("color","inherit"),facebook_for_woocommerce_settings_sync.sync_in_progress=!0}function _(o){o=0<arguments.length&&void 0!==o?o:"";facebook_for_woocommerce_settings_sync.sync_in_progress=!1,clearInterval(window.syncStatusInterval),c(!(window.syncStatusInterval=null)),s('input#wc_facebook_enable_product_sync, input[name="save_product_sync_settings"]').css("pointer-events","all").css("opacity","1"),o?s("#sync_progress").show().html(o).css("color","#DC3232"):s("#sync_progress").hide()}function r(){facebook_for_woocommerce_settings_sync.sync_in_progress&&s.post(facebook_for_woocommerce_settings_sync.ajax_url,{action:"wc_facebook_get_sync_status",nonce:facebook_for_woocommerce_settings_sync.sync_status_nonce},function(o){console.log(o),o.success&&(0<o.data?e(o.data):_())})}s('input[name="save_product_sync_settings"]').on("click",function(o){if(t)return!0;o.preventDefault();var e,c,n=s(this),o=(e=s("#wc_facebook_excluded_product_category_ids").val(),c=[],window.facebook_for_woocommerce_settings_sync&&window.facebook_for_woocommerce_settings_sync.excluded_category_ids&&(c=window.facebook_for_woocommerce_settings_sync.excluded_category_ids),s(e).not(c).get()),c=(e=s("#wc_facebook_excluded_product_tag_ids").val(),c=[],window.facebook_for_woocommerce_settings_sync&&window.facebook_for_woocommerce_settings_sync.excluded_tag_ids&&(c=window.facebook_for_woocommerce_settings_sync.excluded_tag_ids),s(e).not(c).get());0<o.length||0<c.length?s.post(facebook_for_woocommerce_settings_sync.ajax_url,{action:"facebook_for_woocommerce_set_excluded_terms_prompt",security:facebook_for_woocommerce_settings_sync.set_excluded_terms_prompt_nonce,categories:o,tags:c},function(o){o&&!o.success?(s("#wc-backbone-modal-dialog .modal-close").trigger("click"),new s.WCBackboneModal.View({target:"facebook-for-woocommerce-modal",string:o.data}),s(".facebook-for-woocommerce-confirm-settings-change").on("click",function(){blockModal(),t=!0,n.trigger("click")})):(t=!0,n.trigger("click"))}):(t=!0,n.trigger("click"))}),facebook_for_woocommerce_settings_sync.sync_in_progress&&e(),s("#woocommerce-facebook-settings-sync-products").click(function(o){var c;o.preventDefault(),confirm(facebook_for_woocommerce_settings_sync.i18n.confirm_sync)&&(n(),c=Date.now(),s.post(facebook_for_woocommerce_settings_sync.ajax_url,{action:"wc_facebook_sync_products",nonce:facebook_for_woocommerce_settings_sync.sync_products_nonce},function(o){var e;console.log(o),o.success?setTimeout(r,Math.max(0,1e4-(Date.now()-c))):(e=facebook_for_woocommerce_settings_sync.i18n.general_error,_(e=o.data&&0<o.data.length?o.data:e))}).fail(function(){_(facebook_for_woocommerce_settings_sync.i18n.general_error)}))})});
|
|
assets/js/admin/google-product-category-fields.min.js
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
"use strict";var _createClass=function(){function a(e,t){for(var o=0;o<t.length;o++){var a=t[o];a.enumerable=a.enumerable||!1,a.configurable=!0,"value"in a&&(a.writable=!0),Object.defineProperty(e,a.key,a)}}return function(e,t,o){return t&&a(e.prototype,t),o&&a(e,o),e}}();function _classCallCheck(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}jQuery(document).ready(function(n){function a(e,t){var o=this;_classCallCheck(this,a),this.categories=e,this.input_id=t;t=n("#"+this.input_id);n('<div id="wc-facebook-google-product-category-fields"></div>').insertBefore(t).on("change","select.wc-facebook-google-product-category-select",function(e){o.onChange(n(e.target))}),this.addInitialSelects(t.val());t=this.globalsHolder().enhanced_attribute_optional_selector;void 0!==t&&n("#"+t).on("change",function(){n(".wc-facebook-enhanced-catalog-attribute-optional-row").toggleClass("hidden",!n(this).prop("checked"))})}window.WC_Facebook_Google_Product_Category_Fields=(_createClass(a,[{key:"globalsHolder",value:function(){return"undefined"!=typeof facebook_for_woocommerce_product_categories?facebook_for_woocommerce_product_categories:"undefined"!=typeof facebook_for_woocommerce_settings_sync?facebook_for_woocommerce_settings_sync:facebook_for_woocommerce_products_admin}},{key:"getPageType",value:function(){return"undefined"!=typeof facebook_for_woocommerce_product_categories?0===n("input[name=tag_ID]").length?this.globalsHolder().enhanced_attribute_page_type_add_category:this.globalsHolder().enhanced_attribute_page_type_edit_category:this.globalsHolder().enhanced_attribute_page_type_edit_product}},{key:"addInitialSelects",value:function(e){var t=this;e?(this.getSelectedCategoryIds(e).forEach(function(e){t.addSelect(t.getOptions(e[1]),e[0])}),e=this.getOptions(e),Object.keys(e).length&&this.addSelect(e)):(this.addSelect(this.getOptions()),this.addSelect({}))}},{key:"requestAttributesIfValid",value:function(){var e,t,o;"true"===n("#wc_facebook_can_show_enhanced_catalog_attributes_id").val()&&(n(".wc-facebook-enhanced-catalog-attribute-row").remove(),this.isValid()&&(e="#"+this.input_id,t=n(e).parents("div.form-field"),o=this.globalsHolder().enhanced_attribute_optional_selector,this.getPageType()===this.globalsHolder().enhanced_attribute_page_type_edit_category?t=n(e).parents("tr.form-field"):this.getPageType()===this.globalsHolder().enhanced_attribute_page_type_edit_product&&(t=n(e).parents("p.form-field")),n.get(this.globalsHolder().ajax_url,{action:"wc_facebook_enhanced_catalog_attributes",security:"",selected_category:n(e).val(),tag_id:parseInt(n("input[name=tag_ID]").val(),10),taxonomy:n("input[name=taxonomy]").val(),item_id:parseInt(n("input[name=post_ID]").val(),10),page_type:this.getPageType()},function(e){e=n(e);n("#"+o,e).on("change",function(){n(".wc-facebook-enhanced-catalog-attribute-optional-row").toggleClass("hidden",!n(this).prop("checked"))}),e.insertAfter(t),n(document.body).trigger("init_tooltips")})))}},{key:"onChange",value:function(e){e.hasClass("locked")&&e.closest(".wc-facebook-google-product-category-field").nextAll().remove();var t,o=e.val();o?(t=this.getOptions(o),Object.keys(t).length&&this.addSelect(t)):(o=e.closest("#wc-facebook-google-product-category-fields").find(".wc-facebook-google-product-category-select").not(e).last().val())||this.addSelect({}),n("#"+this.input_id).val(o),this.requestAttributesIfValid()}},{key:"isValid",value:function(){return 2<=n(".wc-facebook-google-product-category-select").filter(function(e,t){return""!==n(t).val()}).length}},{key:"addSelect",value:function(t,e){var o=n("#wc-facebook-google-product-category-fields"),a=o.find(".wc-facebook-google-product-category-select"),c=n('<select class="wc-enhanced-select wc-facebook-google-product-category-select"></select>');a.addClass("locked"),o.append(n('<div class="wc-facebook-google-product-category-field" style="margin-bottom: 16px">').append(c)),c.attr("data-placeholder",this.getSelectPlaceholder(a,t)).append(n('<option value=""></option>')),Object.keys(t).forEach(function(e){c.append(n('<option value="'+e+'">'+t[e]+"</option>"))}),c.val(e).select2({allowClear:!0})}},{key:"getSelectPlaceholder",value:function(e,t){return 0===e.length?facebook_for_woocommerce_google_product_category.i18n.top_level_dropdown_placeholder:1===e.length&&0===Object.keys(t).length?facebook_for_woocommerce_google_product_category.i18n.second_level_empty_dropdown_placeholder:facebook_for_woocommerce_google_product_category.i18n.general_dropdown_placeholder}},{key:"getOptions",value:function(e){return void 0===e||""===e?this.getTopLevelOptions():void 0===this.categories[e]||void 0===this.categories[e].options?[]:this.categories[e].options}},{key:"getTopLevelOptions",value:function(){var t=this,o={};return Object.keys(this.categories).forEach(function(e){t.categories[e].parent||(o[e]=t.categories[e].label)}),o}},{key:"getSelectedCategoryIds",value:function(e){for(var t=[];void 0!==this.categories[e]&&(t.push([e,this.categories[e].parent]),e=this.categories[e].parent),""!==e;);return t.reverse()}}]),a)});
|
|
assets/js/admin/index.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
// Add new any JS here
|
assets/js/{facebook-infobanner.js → admin/infobanner.js}
RENAMED
File without changes
|
assets/js/{facebook-metabox.js → admin/metabox.js}
RENAMED
File without changes
|
assets/js/{facebook-for-woocommerce-modal.js → admin/modal.js}
RENAMED
File without changes
|
assets/js/admin/orders.min.js
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
"use strict";jQuery(document).ready(function(a){var e,c=Boolean(wc_facebook_commerce_orders.is_commerce_order),o={restrict_order_statuses:function(e){e.find("option").each(function(e,o){-1===wc_facebook_commerce_orders.allowed_commerce_statuses.indexOf(o.value)&&o.remove()})},toggle_created_date_fields_status:function(e){o.toggle_field(a("#order_data").find("input[name*=order_date]"),e)},disable_order_status_field:function(e){o.toggle_field(e,!1)},toggle_order_customer_field:function(e){a("#order_data").find(".form-field.wc-customer-user").toggleClass("hidden",e)},toggle_billing_and_shipping_fields:function(e){a("#order_data").find("a.edit_address").toggleClass("hidden",e)},disable_pending_order_related_fields:function(e){o.toggle_created_date_fields_status(!1),o.disable_order_status_field(e),o.toggle_order_customer_field(!0),o.toggle_billing_and_shipping_fields(!0)},maybe_disable_refunds:function(){"completed"!==wc_facebook_commerce_orders.order_status&&a(".wc-order-bulk-actions .refund-items").hide()},toggle_field:function(e,o){e.hasClass("wc-enhanced-select")&&(e=e.next("span.select2-container")),o?e.css("pointer-events","all").css("opacity","1.0"):e.css("pointer-events","none").css("opacity","0.4")}},n=a('form[id="post"]'),r=a("#order_status"),t=r.val(),_=wc_facebook_commerce_orders.shipment_tracking,d="",s="",i="",l="";function m(e){unBlockModal(),a(".facebook-for-woocommerce-modal .wc-backbone-modal-content article").html("<p>"+e+"</p>"),a(".facebook-for-woocommerce-modal .wc-backbone-modal-content footer").remove()}function f(e,o,c){var r=0<arguments.length&&void 0!==e&&e,o=1<arguments.length&&void 0!==o?o:null,c=2<arguments.length&&void 0!==c?c:null;o.length?(r&&blockModal(),n.find("button[type=submit].save_order").prop("disabled",!0).append('<span class="spinner is-active"></span>'),a.post(ajaxurl,{action:wc_facebook_commerce_orders.complete_order_action,order_id:a("#post_ID").val(),tracking_number:o,carrier_code:c,nonce:wc_facebook_commerce_orders.complete_order_nonce},function(e){r&&unBlockModal(),e&&e.success?n.data("allow-submit",!0).trigger("submit"):(e=e&&e.data?e.data:wc_facebook_commerce_orders.i18n.unknown_error,alert(e))}).fail(function(){m(wc_facebook_commerce_orders.i18n.unknown_error)}).always(function(){n.find("button[type=submit].save_order").prop("disabled",!1).find("span.spinner").remove()})):alert(wc_facebook_commerce_orders.i18n.missing_tracking_number_error)}function b(){var e=a("#refund_reason"),o=a("#wc_facebook_refund_reason").clone().css("width",e.css("width")),c=e.closest("tr"),e=c.clone();c.find("td.total").css("width","16em").end().find("#refund_reason").replaceWith(o.show()).end().find('label[for="refund_reason"]').attr("for","wc_facebook_refund_reason"),c.after(e),u(c,"wc_facebook_refund_reason",wc_facebook_commerce_orders.i18n.refund_reason_label,wc_facebook_commerce_orders.i18n.refund_reason_tooltip),u(e,"refund_reason",wc_facebook_commerce_orders.i18n.refund_description_label,wc_facebook_commerce_orders.i18n.refund_description_tooltip)}function u(e,o,c,r){e=e.find('label[for="'+o+'"]'),o=e.find(".woocommerce-help-tip").clone();e.text(c),r&&o.length&&(e.prepend(o),o.attr("data-tip",r).tipTip({attribute:"data-tip",fadeIn:50,fadeOut:50,delay:200}))}Array.isArray(_)&&_[0]&&(d=_[0].tracking_number,s=_[0].carrier_code),c&&(o.restrict_order_statuses(r),"pending"===wc_facebook_commerce_orders.order_status&&o.disable_pending_order_related_fields(r),"cancelled"===wc_facebook_commerce_orders.order_status&&o.disable_order_status_field(r),o.maybe_disable_refunds()),c&&(b(),void 0===window.MutationObserver||(e=document.querySelector("#woocommerce-order-items .inside"))&&new MutationObserver(function(e){e.forEach(function(e){Array.prototype.forEach.call(e.addedNodes,function(e){a(e).is(".wc-order-refund-items")&&b()})})}).observe(e,{childList:!0})),n.on("submit",function(e){return!a("#post").data("skip-cancel-modal")&&"wc-cancelled"!==t&&(c&&"wc-cancelled"===r.val())?(e.preventDefault(),a("#wc-backbone-modal-dialog .modal-close").trigger("click"),new a.WCBackboneModal.View({target:"facebook-for-woocommerce-modal",string:{message:wc_facebook_commerce_orders.cancel_modal_message,buttons:wc_facebook_commerce_orders.cancel_modal_buttons}}),a(".facebook-for-woocommerce-modal #btn-ok").off("click.facebook_for_commerce").on("click.facebook_for_commerce",function(e){e.preventDefault(),e.stopPropagation(),blockModal(),a.post(ajaxurl,{action:wc_facebook_commerce_orders.cancel_order_action,order_id:a("#post_ID").val(),reason_code:a('.facebook-for-woocommerce-modal [name="wc_facebook_cancel_reason"]').val(),security:wc_facebook_commerce_orders.cancel_order_nonce},function(e){e&&e.success?a("#post").data("skip-cancel-modal",!0).trigger("submit"):m(e&&e.data?e.data:wc_facebook_commerce_orders.i18n.unknown_error)}).fail(function(){m(wc_facebook_commerce_orders.i18n.unknown_error)})}),!1):void(c&&!n.data("allow-submit")&&("wc-refunded"===(o=r.val())&&t!==o&&(e.preventDefault(),a("#wc-backbone-modal-dialog .modal-close").trigger("click"),new a.WCBackboneModal.View({target:"facebook-for-woocommerce-modal",string:{message:wc_facebook_commerce_orders.refund_modal_message,buttons:wc_facebook_commerce_orders.refund_modal_buttons}}),a(document.body).off("wc_backbone_modal_response.facebook_for_commerce").on("wc_backbone_modal_response.facebook_for_commerce",function(){a("#refund_reason").val(a("#wc_facebook_refund_reason_modal").val()),n.data("allow-submit",!0).submit()})),"wc-completed"===o&&(e.preventDefault(),d||s?f(!1,d,s):(a("#wc-backbone-modal-dialog .modal-close").trigger("click"),(l||i)&&a(document.body).off("wc_backbone_modal_loaded").on("wc_backbone_modal_loaded",function(){l&&a("#wc_facebook_carrier").val(l),i&&a("#wc_facebook_tracking_number").val(i)}),new a.WCBackboneModal.View({target:"facebook-for-woocommerce-modal",string:{message:wc_facebook_commerce_orders.complete_modal_message,buttons:wc_facebook_commerce_orders.complete_modal_buttons}}),a(".facebook-for-woocommerce-modal #btn-ok").off("click.facebook_for_commerce").on("click.facebook_for_commerce",function(e){e.preventDefault(),e.stopPropagation(),l=a("#wc_facebook_carrier").val(),f(!0,i=a("#wc_facebook_tracking_number").val(),l)})))));var o})});
|
|
assets/js/admin/product-categories.min.js
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
"use strict";jQuery(document).ready(function(e){var c=e('form[id="edittag"]'),a=e("#wc_facebook_google_product_category_id"),t=a.val();c.on("submit",function(o){c.data("allow-submit")||a.val()===t||(o.preventDefault(),e("#wc-backbone-modal-dialog .modal-close").trigger("click"),new e.WCBackboneModal.View({target:"facebook-for-woocommerce-modal",string:{message:facebook_for_woocommerce_product_categories.default_google_product_category_modal_message,buttons:facebook_for_woocommerce_product_categories.default_google_product_category_modal_buttons}}),e(document.body).off("wc_backbone_modal_response.facebook_for_commerce").on("wc_backbone_modal_response.facebook_for_commerce",function(){c.data("allow-submit",!0).find(":submit").trigger("click")}))})});
|
|
assets/js/admin/{facebook-for-woocommerce-product-sets-admin.js → product-sets-admin.js}
RENAMED
File without changes
|
assets/js/admin/{facebook-for-woocommerce-products-admin.js → products-admin.js}
RENAMED
File without changes
|
assets/js/admin/settings-commerce.min.js
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
"use strict";jQuery(document).ready(function(e){var c=e("form.wc-facebook-settings"),t=e("#wc_facebook_google_product_category_id"),a=t.val();c.on("submit",function(o){c.data("allow-submit")||t.val()===a||(o.preventDefault(),e("#wc-backbone-modal-dialog .modal-close").trigger("click"),new e.WCBackboneModal.View({target:"facebook-for-woocommerce-modal",string:{message:t.val()?facebook_for_woocommerce_settings_commerce.default_google_product_category_modal_message:facebook_for_woocommerce_settings_commerce.default_google_product_category_modal_message_empty,buttons:facebook_for_woocommerce_settings_commerce.default_google_product_category_modal_buttons}}),e(document.body).off("wc_backbone_modal_response.facebook_for_commerce").on("wc_backbone_modal_response.facebook_for_commerce",function(){c.data("allow-submit",!0).find(":submit").trigger("click")}))}),e(".woocommerce-help-tip").tipTip({attribute:"data-tip",fadeIn:50,fadeOut:50,delay:200})});
|
|
assets/js/admin/{facebook-for-woocommerce-settings-sync.js → settings-sync.js}
RENAMED
File without changes
|
assets/js/facebook-for-woocommerce-modal.min.js
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
"use strict";!function(n){window.isModalBlocked=function(){var o=n(".wc-backbone-modal-content");return o.is(".processing")||o.parents(".processing").length},window.blockModal=function(){if(!isModalBlocked())return n(".wc-backbone-modal-content").addClass("processing").block({message:null,overlayCSS:{background:"#fff",opacity:.6}})},window.unBlockModal=function(){n(".wc-backbone-modal-content").removeClass("processing").unblock()},window.closeExistingModal=function(){n("#wc-backbone-modal-dialog .modal-close").trigger("click")}}(jQuery);
|
|
assets/js/facebook-infobanner.min.js
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
"use strict";function ajax(n){var o=1<arguments.length&&void 0!==arguments[1]?arguments[1]:null,a=2<arguments.length&&void 0!==arguments[2]?arguments[2]:null,t=3<arguments.length&&void 0!==arguments[3]?arguments[3]:null,o=Object.assign({},{action:n},o);jQuery.post(ajaxurl,o,function(n){a&&a(n)}).fail(function(n){t&&t(n)})}function fb_woo_infobanner_post_click(){return console.log("Woo infobanner post tip click!"),ajax("ajax_woo_infobanner_post_click",{_ajax_nonce:wc_facebook_infobanner_jsx.nonce})}function fb_woo_infobanner_post_xout(){return console.log("Woo infobanner post tip xout!"),ajax("ajax_woo_infobanner_post_xout",{_ajax_nonce:wc_facebook_infobanner_jsx.nonce})}
|
|
assets/js/facebook-metabox.min.js
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
"use strict";function ajax(e){var o=1<arguments.length&&void 0!==arguments[1]?arguments[1]:null,t=2<arguments.length&&void 0!==arguments[2]?arguments[2]:null,a=3<arguments.length&&void 0!==arguments[3]?arguments[3]:null,o=Object.assign({},{action:e},o);jQuery.post(ajaxurl,o,function(e){t&&t(e)}).fail(function(e){a&&a(e)})}function fb_reset_product(e){if(confirm("Resetting Facebook metadata will not remove this product from your shop. If you have duplicated another product and are trying to publish a new Facebook product, click OK to proceed. Otherwise, Facebook metadata will be restored when this product is updated again.")){var o=document.querySelector("#fb_metadata");return o&&(o.innerHTML="<b>This product is not yet synced to Facebook.</b>"),ajax("ajax_reset_single_fb_product",{wp_id:e,_ajax_nonce:wc_facebook_metabox_jsx.nonce})}}function fb_delete_product(e){if(confirm('Are you sure you want to delete this product on Facebook? If you only want to "hide" the product, change the "Facebook sync" setting to "Sync and hide" and hit "Update". If you delete a product on Facebook and hit "Update" after, this product will be recreated. To permanently remove this product from Facebook, hit "OK" and close the window.This will not delete the product from WooCommerce.')){var o=document.querySelector("#fb_metadata");return o&&(o.innerHTML="<b>This product is not yet synced to Facebook.</b>"),ajax("ajax_delete_fb_product",{wp_id:e,_ajax_nonce:wc_facebook_metabox_jsx.nonce})}}
|
|
assets/js/facebook-settings.min.js
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
"use strict";var fb_sync_no_response_count=0,fb_show_advanced_options=!1;function openPopup(){var e,o=screen.height/2-404,n=screen.width/2-576.5;window.originParam=window.location.protocol+"//"+window.location.host,window.facebookAdsToolboxConfig.popupOrigin.includes("staticxx")&&(window.facebookAdsToolboxConfig.popupOrigin="https://www.facebook.com/"),window.facebookAdsToolboxConfig.popupOrigin=prepend_protocol(window.facebookAdsToolboxConfig.popupOrigin),e=window.facebookAdsToolboxConfig.popupOrigin;var t=window.open(e+"/login.php?display=popup&next="+encodeURIComponent(e+"/ads/dia?origin="+window.originParam+" &merchant_settings_id="+window.facebookAdsToolboxConfig.diaSettingId),"DiaWizard",["toolbar=no","location=no","directories=no","status=no","menubar=no","scrollbars=no","resizable=no","copyhistory=no","width=1153","height=808","top="+o,"left="+n].join(","));return function(e,o){t.postMessage({type:e,params:o},window.facebookAdsToolboxConfig.popupOrigin)}}function prepend_protocol(e){return 0===e.indexOf("//www.")&&(e="https:"+e),e}function get_pixel_id_box(){return document.querySelector("#woocommerce_facebookcommerce_facebook_pixel_id")}function get_pixel_use_pii_id_box(){return document.querySelector("#woocommerce_facebookcommerce_enable_advanced_matching")}function get_page_id_box(){return document.querySelector("#woocommerce_facebookcommerce_facebook_page_id")}function ajax(e){var o=1<arguments.length&&void 0!==arguments[1]?arguments[1]:null,n=2<arguments.length&&void 0!==arguments[2]?arguments[2]:null,t=3<arguments.length&&void 0!==arguments[3]?arguments[3]:null,s=Object.assign({},{action:e},o);jQuery.post(ajaxurl,s,function(e){n&&n(e)}).fail(function(e){t&&t(e)})}var settings={facebook_for_woocommerce:1},pixel_settings={facebook_for_woocommerce:1};function facebookConfig(){window.sendToFacebook=openPopup(),window.diaConfig={clientSetup:window.facebookAdsToolboxConfig}}function fb_flush(){return console.log("Removing all FBIDs from all products!"),ajax("ajax_reset_all_fb_products",{_ajax_nonce:wc_facebook_settings_jsx.nonce},null,function(){console.log("Failed to reset all FB products")})}function sync_confirm(){var e=0<arguments.length&&void 0!==arguments[0]?arguments[0]:null,o="";switch(e){case"fb_force_resync":o=facebook_for_woocommerce_settings_sync.i18n.confirm_resync;break;case"fb_test_product_sync":o=facebook_for_woocommerce_settings_sync.i18n.confirm_sync_test;break;default:o=facebook_for_woocommerce_settings_sync.i18n.confirm_sync}confirm(o)&&(sync_all_products(window.facebookAdsToolboxConfig.feed.hasClientSideFeedUpload,"fb_test_product_sync"==e),window.fb_sync_start_time=(new Date).getTime())}function sync_all_products(){var n=0<arguments.length&&void 0!==arguments[0]&&arguments[0],e=1<arguments.length&&void 0!==arguments[1]&&arguments[1];window.fb_connected=!0,sync_in_progress();var o={};o=n?(window.facebookAdsToolboxConfig.feed.hasClientSideFeedUpload=!0,window.feed_upload=!0,ping_feed_status_queue(),e?{action:"ajax_test_sync_products_using_feed"}:{action:"ajax_sync_all_fb_products_using_feed",_ajax_nonce:wc_facebook_settings_jsx.nonce}):(check_background_processor_status(),{action:"ajax_sync_all_fb_products",_ajax_nonce:wc_facebook_settings_jsx.nonce}),jQuery.post(ajaxurl,o).then(function(e){if(!e&&n||e&&!1===e.success){clearInterval(window.fb_pings),clearInterval(window.fb_feed_pings),jQuery("#woocommerce-facebook-settings-manage-connection, #woocommerce-facebook-settings-sync-products").css("pointer-events","auto");var o=void 0;o=e&&e.data&&e.data.error?e.data.error:facebook_for_woocommerce_settings_sync.i18n.general_error,jQuery("#sync_progress").show().html('<span style="color: #DC3232">'+o+"</span>")}})}function delete_all_settings(){var e=0<arguments.length&&void 0!==arguments[0]?arguments[0]:null,o=1<arguments.length&&void 0!==arguments[1]?arguments[1]:null;return get_pixel_id_box()&&(get_pixel_id_box().value=""),get_pixel_use_pii_id_box()&&(get_pixel_use_pii_id_box().checked=!1),get_page_id_box()&&(get_page_id_box().value=""),jQuery("#woocommerce_facebookcommerce_enable_messenger").prop("checked",!1).trigger("change"),jQuery(".messenger-field").each(function(){void 0!==jQuery(this).data("default")&&jQuery(this).val(jQuery(this).data("default")).trigger("change")}),window.facebookAdsToolboxConfig.pixel.pixelId="",window.facebookAdsToolboxConfig.diaSettingId="",window.fb_connected=!1,not_connected(),console.log("Deleting all settings and removing all FBIDs!"),ajax("ajax_delete_fb_settings",{_ajax_nonce:wc_facebook_settings_jsx.nonce},e,o)}function save_settings(){var o=0<arguments.length&&void 0!==arguments[0]?arguments[0]:null,n=1<arguments.length&&void 0!==arguments[1]?arguments[1]:null,e=2<arguments.length&&void 0!==arguments[2]?arguments[2]:null;(e=e||settings)._ajax_nonce=wc_facebook_settings_jsx.nonce,ajax("ajax_save_fb_settings",e,function(e){o&&o(e)},function(e){n&&n(e)})}function save_settings_for_plugin(o,n){save_settings(function(e){e&&!0===e.success?(console.log(e),o(e)):(console.log("Fail response on save_settings_for_plugin"),n(e))},function(e){console.log("Ajax error while saving settings:"+JSON.stringify(e)),n(e)})}function save_settings_and_sync(o){"api_key"in settings&&save_settings(function(e){e&&e.includes("settings_saved")?(console.log(e),window.sendToFacebook("ack set pixel",o.params),window.sendToFacebook("ack set page access token",o.params),window.sendToFacebook("ack set merchant settings",o.params)):(window.sendToFacebook("fail save_settings",e),console.log("Fail response on save_settings_and_sync"))},function(e){console.log("Ajax error while saving settings:"+JSON.stringify(e)),window.sendToFacebook("fail save_settings_ajax",JSON.stringify(e))})}function sync_in_progress(){jQuery("#woocommerce-facebook-settings-manage-connection, #woocommerce-facebook-settings-sync-products").css("pointer-events","none"),jQuery("#sync_progress").show().html(facebook_for_woocommerce_settings_sync.i18n.sync_in_progress)}function sync_not_in_progress(){jQuery("#woocommerce-facebook-settings-manage-connection, #woocommerce-facebook-settings-sync-products").css("pointer-events","auto"),jQuery("#sync_progress").empty().hide()}function not_connected(){jQuery("#fbsetup").show(),jQuery("#integration-settings").hide(),jQuery(".woocommerce-save-button").hide()}function addAnEventListener(e,o,n){"addEventListener"in e?e.addEventListener(o,n,!1):"attachEvent"in e&&e.attachEvent("on"+o,n)}function setMerchantSettings(e){if(!e.params.setting_id)return console.error("Facebook Extension Error: got no setting_id",e.params),void window.sendToFacebook("fail set merchant settings",e.params);settings.external_merchant_settings_id=e.params.setting_id,window.facebookAdsToolboxConfig.diaSettingId=e.params.setting_id}function setCatalog(e){if(!e.params.catalog_id)return console.error("Facebook Extension Error: got no catalog_id",e.params),void window.sendToFacebook("fail set catalog",e.params);settings.product_catalog_id=e.params.catalog_id,window.sendToFacebook("ack set catalog",e.params)}function setPixel(o){if(!o.params.pixel_id)return console.error("Facebook Ads Extension Error: got no pixel_id",o.params),void window.sendToFacebook("fail set pixel",o.params);get_pixel_id_box()&&(get_pixel_id_box().value=o.params.pixel_id),settings.pixel_id=o.params.pixel_id,pixel_settings.pixel_id=settings.pixel_id,void 0!==o.params.pixel_use_pii&&(get_pixel_use_pii_id_box()&&(get_pixel_use_pii_id_box().checked=!!o.params.pixel_use_pii),settings.pixel_use_pii=o.params.pixel_use_pii,pixel_settings.pixel_use_pii=settings.pixel_use_pii),save_settings(function(e){e&&!0===e.success&&window.sendToFacebook("ack set pixel",o.params)},function(e){console.log(e),window.sendToFacebook("fail set pixel",e)},pixel_settings)}function genFeed(t){console.log("generating feed"),jQuery.get(window.facebookAdsToolboxConfig.feedPrepared.feedUrl+"®enerate=true").done(function(e){window.sendToFacebook("ack feed",t.params)}).fail(function(e,o,n){window.sendToFacebook("fail feed",t.params)})}function setAccessTokenAndPageId(e){if(!e.params.page_token)return console.error("Facebook Ads Extension Error: got no page_token",e.params),void window.sendToFacebook("fail set page access token",e.params);get_page_id_box()&&(get_page_id_box().value=e.params.page_id),settings.api_key=e.params.page_token,settings.page_id=e.params.page_id,window.facebookAdsToolboxConfig.tokenExpired=!1,document.querySelector("#connection-message-invalid")&&(document.querySelector("#connection-message-invalid").style.display="none"),document.querySelector("#connection-message-refresh")&&(document.querySelector("#connection-message-refresh").style.display="block")}function setMsgerChatSetup(e){if(e.hasOwnProperty("is_messenger_chat_plugin_enabled")&&(settings.is_messenger_chat_plugin_enabled=e.is_messenger_chat_plugin_enabled,jQuery("#woocommerce_facebookcommerce_enable_messenger").prop("checked",e.is_messenger_chat_plugin_enabled).trigger("change")),e.hasOwnProperty("facebook_jssdk_version")&&(settings.facebook_jssdk_version=e.facebook_jssdk_version),e.hasOwnProperty("page_id")&&(settings.fb_page_id=e.page_id),e.hasOwnProperty("customization")){var o=e.customization;o.hasOwnProperty("greetingTextCode")&&(settings.msger_chat_customization_greeting_text_code=o.greetingTextCode,jQuery("#woocommerce_facebookcommerce_messenger_greeting").val(o.greetingTextCode).trigger("change")),o.hasOwnProperty("locale")&&(settings.msger_chat_customization_locale=o.locale,jQuery("#woocommerce_facebookcommerce_messenger_locale").val(o.locale).trigger("change")),o.hasOwnProperty("themeColorCode")&&(settings.msger_chat_customization_theme_color_code=o.themeColorCode,jQuery("#woocommerce_facebookcommerce_messenger_color_hex").val(o.themeColorCode).trigger("change"))}}function setFeedMigrated(e){if(!e.params.hasOwnProperty("feed_migrated"))return console.error("Facebook Extension Error: feed migrated not received",e.params),void window.sendToFacebook("fail set feed migrated",e.params);settings.feed_migrated=e.params.feed_migrated,window.facebookAdsToolboxConfig.feedPrepared.feedMigrated=e.params.feed_migrated,jQuery("#woocommerce-facebook-settings-sync-products").hide(),jQuery(".notice.wc-facebook-migrate-notice").hide(),save_settings_for_plugin(function(e){window.sendToFacebook("ack set feed migrated",event.data)},function(e){window.sendToFacebook("fail set feed migrated",event.data)})}function iFrameListener(o){var e=o.origin||o.originalEvent.origin;if(e!==window.facebookAdsToolboxConfig.popupOrigin){if(!urlFromSameDomain(e,window.facebookAdsToolboxConfig.popupOrigin))return;window.facebookAdsToolboxConfig.popupOrigin=e}switch(o.data.type){case"reset":delete_all_settings(function(e){e&&o.data.params?"Settings Deleted"===e?window.sendToFacebook("ack reset",o.data.params):(console.log(e),alert(e)):console.log("Got no response from delete_all_settings")},function(e){console.error(e)});break;case"get dia settings":window.sendToFacebook("dia settings",window.diaConfig);break;case"set catalog":setCatalog(o.data);break;case"set feed migrated":setFeedMigrated(o.data);break;case"set pixel":setPixel(o.data);break;case"gen feed":genFeed(o.data);break;case"set page access token":window.sendToFacebook("ack set page access token",o.data.params);break;case"set page":setPage(o.data);break;case"set merchant settings":setMerchantSettings(o.data),save_settings(function(e){console.log(e),e&&!0===e.success?(settings.pixel_id&&window.sendToFacebook("ack set pixel",o.data.params),settings.page_id&&window.sendToFacebook("ack set page",o.data.params),settings.external_merchant_settings_id&&(window.sendToFacebook("ack set merchant settings",o.data.params),jQuery("#fbsetup").hide(),jQuery("#integration-settings").show(),jQuery(".woocommerce-save-button").show())):(window.sendToFacebook("fail save_settings",e),console.log("Fail response on save_settings"))},function(e){console.log("Ajax error while saving settings:"+JSON.stringify(e)),window.sendToFacebook("fail save_settings_ajax",JSON.stringify(e))});break;case"set msger chat":setMsgerChatSetup(o.data.params),save_settings_for_plugin(function(e){window.sendToFacebook("ack msger chat",o.data)},function(e){window.sendToFacebook("fail msger chat",o.data)})}}function setPage(e){if(!e.params.hasOwnProperty("page_id"))return console.error("Facebook Extension Error: page ID not received",e.params),void window.sendToFacebook("fail set page",e.params);settings.page_id=e.params.page_id,jQuery("#woocommerce_facebookcommerce_facebook_page_id").val(settings.page_id)}function urlFromSameDomain(e,o){if(!e.startsWith("http")||!o.startsWith("http"))return!1;var n=parseURL(e),t=parseURL(o),s=n.host.replace(/^\w+\./,"www."),i=t.host.replace(/^\w+\./,"www.");return n.protocol===t.protocol&&s===i}function parseURL(e){var o=document.createElement("a");return o.href=e,o}function check_background_processor_status(){window.facebookAdsToolboxConfig.feed.hasClientSideFeedUpload||(clearInterval(window.fb_pings),window.fb_pings=setInterval(function(){console.log("Pinging queue..."),check_queues()},1e4))}function ping_feed_status_queue(){var e=0<arguments.length&&void 0!==arguments[0]?arguments[0]:0;clearInterval(window.fb_feed_pings),window.fb_feed_pings=setInterval(function(){console.log("Pinging feed uploading queue..."),check_feed_upload_queue(e)},3e4*(1<<e))}function product_sync_complete(e){sync_not_in_progress(),e.empty().hide(),clearInterval(window.fb_pings)}function check_queues(){ajax("ajax_fb_background_check_queue",{request_time:(new Date).getTime(),_ajax_nonce:wc_facebook_settings_jsx.nonce},function(e){if(window.feed_upload)clearInterval(window.fb_pings);else{var o=jQuery("#sync_progress"),n=parse_response_check_connection(e);if(n){if(fb_sync_no_response_count=0,n){n.background||(console.log("No background sync found, disabling pings"),clearInterval(window.fb_pings));var t=!!n.processing,s=n.remaining;if(t){var i="";i=1===s?facebook_for_woocommerce_settings_sync.i18n.sync_remaining_items_singular:facebook_for_woocommerce_settings_sync.i18n.sync_remaining_items_plural,o.show().html(i.replace("{count}",s)),0===s&&product_sync_complete(o)}else{if(window.fb_sync_start_time&&n.request_time){var a=new Date(parseInt(n.request_time));if(window.fb_sync_start_time>a)return void console.log("OLD PING")}0===s&&product_sync_complete(o)}}}else 5<fb_sync_no_response_count++&&clearInterval(window.fb_pings)}})}function parse_response_check_connection(e){if(e){console.log(e);var o=e.substring(e.indexOf("{"));return(o=JSON.parse(o)).connected||window.fb_connected?o:(not_connected(),null)}return null}function check_feed_upload_queue(t){ajax("ajax_check_feed_upload_status",{_ajax_nonce:wc_facebook_settings_jsx.nonce},function(e){var o=jQuery("#sync_progress"),n=parse_response_check_connection(e);if(clearInterval(window.fb_feed_pings),n)switch(n.status){case"complete":window.feed_upload=!1,window.is_test?display_test_result():product_sync_complete(o);break;case"in progress":o.show().html(facebook_for_woocommerce_settings_sync.i18n.sync_in_progress),ping_feed_status_queue(t+1);break;default:jQuery("#woocommerce-facebook-settings-manage-connection, #woocommerce-facebook-settings-sync-products").css("pointer-events","auto"),jQuery("#sync_progress").show().html('<span style="color: #DC3232">'+facebook_for_woocommerce_settings_sync.i18n.feed_upload_error+"</span>"),window.feed_upload=!1,window.is_test&&display_test_result()}})}function display_test_result(){ajax("ajax_display_test_result",{_ajax_nonce:wc_facebook_settings_jsx.nonce},function(e){var o=jQuery("#sync_progress"),n=document.querySelector("#sync_complete"),t=parse_response_check_connection(e);if(t)switch(t.pass){case"true":sync_not_in_progress(),n&&(n.style.display="",n.innerHTML=facebook_for_woocommerce_settings_sync.i18n.integration_test_sucessful),o.empty().hide(),window.is_test=!1;break;case"in progress":o.show().html(facebook_for_woocommerce_settings_sync.i18n.integration_test_in_progress),ping_feed_status_queue();break;default:window.debug_info=t.debug_info+"<br/>"+t.stack_trace,n&&(n.style.display="",n.innerHTML=facebook_for_woocommerce_settings_sync.i18n.integration_test_failed),o.empty().hide(),document.querySelector("#debug_info")&&(document.querySelector("#debug_info").style.display=""),window.is_test=!1}})}function show_debug_info(){var e=document.querySelector("#stack_trace");e&&(e.innerHTML=window.debug_info),document.querySelector("#debug_info")&&(document.querySelector("#debug_info").style.display="none"),window.debug_info=""}function fbe_init_nux_messages(){var r=window.jQuery;r(function(){r.each(r(".nux-message"),function(e,o){var n=r(o),t=n.data("target"),s=r("#"+t),i=s.position(),a=s.height()/2,c=s.outerWidth();n.css({top:Math.ceil(i.top+a)+"px",left:Math.ceil(i.left+c)+"px",display:"block"}),r(".nux-message-close-btn",n).click(function(){r(o).hide()})})})}function saveAutoSyncSchedule(){var e=document.getElementsByClassName("autosyncCheck")[0].checked,o=document.getElementsByClassName("autosyncTime")[0],n=(document.getElementsByClassName("autosyncSaveButton")[0],document.getElementsByClassName("autosyncSavedNotice")[0]);e?(o.removeAttribute("disabled"),n.style.transition="",n.style.opacity=1,setTimeout(function(){n.style.opacity=0,n.style.transition="opacity 5s"},3e3)):o.setAttribute("disabled",!0),ajax("ajax_schedule_force_resync",{enabled:e?1:0,time:o.value,_ajax_nonce:wc_facebook_settings_jsx.nonce})}function syncShortDescription(){var e=document.getElementsByClassName("syncShortDescription")[0].checked;ajax("ajax_update_fb_option",{option:"fb_sync_short_description",option_value:e?1:0,_ajax_nonce:wc_facebook_settings_jsx.nonce},null,function(){document.getElementsByClassName("syncShortDescription")[0].checked=!e,console.log("Failed to sync Short Description")})}addAnEventListener(window,"message",iFrameListener),jQuery(document).ready(function(e){e(".notice .wc-facebook-manage-connection").click(function(e){e.preventDefault(),facebookConfig()}),e("#woocommerce-facebook-settings-sync-products").click(function(e){e.preventDefault(),sync_confirm()})});
|
|
changelog.txt
CHANGED
@@ -1,5 +1,19 @@
|
|
1 |
*** Facebook for WooCommerce Changelog ***
|
2 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3 |
2021.04.29 - version 2.4.1
|
4 |
* Fix - PHP<7.1 incompatible code for Google Taxonomy Setting in products.
|
5 |
|
1 |
*** Facebook for WooCommerce Changelog ***
|
2 |
|
3 |
+
2021-05-19 - version 2.5.0
|
4 |
+
* New - Option to allow larger sites to opt-out of feed generation (product sync) job #1932
|
5 |
+
* New - Log connection errors to allow easier troubleshooting #1857
|
6 |
+
* Fix - Reduce default feed generation (product sync) interval to once per day to reduce overhead #1942
|
7 |
+
* Fix - Trigger feed (product sync) job from to `admin_init` to reduce impact on front-end requests #1939
|
8 |
+
* Fix - Ensure variable product attribute values containing comma (`,`) sync correctly #1922
|
9 |
+
* Fix - Use existing / current tab for connection `Get Started` button #1885
|
10 |
+
* Dev - Require PHP version 7.0 or newer #1908
|
11 |
+
* Dev - Adopt Composer autoloader to avoid manually `require`ing PHP class files #1919
|
12 |
+
* Dev - Adopt WooRelease release tool for deploying releases #1947
|
13 |
+
* Dev - Use wp-scripts to build assets #1826
|
14 |
+
* Dev - Add `phpcs` tooling to help standardise PHP code style #1911
|
15 |
+
* Dev - Add JobRegistry engine for managing periodic background batch jobs #1913
|
16 |
+
|
17 |
2021.04.29 - version 2.4.1
|
18 |
* Fix - PHP<7.1 incompatible code for Google Taxonomy Setting in products.
|
19 |
|
class-wc-facebookcommerce.php
CHANGED
@@ -22,7 +22,7 @@ if ( ! class_exists( 'WC_Facebookcommerce' ) ) :
|
|
22 |
|
23 |
|
24 |
/** @var string the plugin version */
|
25 |
-
const VERSION =
|
26 |
|
27 |
/** @var string for backwards compatibility TODO: remove this in v2.0.0 {CW 2020-02-06} */
|
28 |
const PLUGIN_VERSION = self::VERSION;
|
@@ -91,6 +91,9 @@ if ( ! class_exists( 'WC_Facebookcommerce' ) ) :
|
|
91 |
/** @var \SkyVerge\WooCommerce\Facebook\Tracker */
|
92 |
private $tracker;
|
93 |
|
|
|
|
|
|
|
94 |
/**
|
95 |
* Constructs the plugin.
|
96 |
*
|
@@ -101,9 +104,9 @@ if ( ! class_exists( 'WC_Facebookcommerce' ) ) :
|
|
101 |
parent::__construct(
|
102 |
self::PLUGIN_ID,
|
103 |
self::VERSION,
|
104 |
-
|
105 |
'text_domain' => 'facebook-for-woocommerce',
|
106 |
-
|
107 |
);
|
108 |
|
109 |
$this->init();
|
@@ -117,46 +120,27 @@ if ( ! class_exists( 'WC_Facebookcommerce' ) ) :
|
|
117 |
*/
|
118 |
public function init() {
|
119 |
|
120 |
-
add_action( 'init',
|
121 |
-
add_action( 'init',
|
122 |
-
add_action( 'add_meta_boxes_product'
|
123 |
-
add_filter( 'fb_product_set_row_actions',
|
124 |
-
add_filter( 'manage_edit-fb_product_set_columns',
|
125 |
|
126 |
// Product Set breadcrumb filters
|
127 |
-
add_filter( 'woocommerce_navigation_is_connected_page',
|
128 |
-
add_filter( 'woocommerce_navigation_get_breadcrumbs',
|
129 |
|
130 |
if ( \WC_Facebookcommerce_Utils::isWoocommerceIntegration() ) {
|
|
|
131 |
|
132 |
include_once 'facebook-commerce.php';
|
133 |
|
134 |
require_once $this->get_framework_path() . '/utilities/class-sv-wp-async-request.php';
|
135 |
require_once $this->get_framework_path() . '/utilities/class-sv-wp-background-job-handler.php';
|
136 |
|
137 |
-
require_once __DIR__ . '/includes/Locale.php';
|
138 |
-
require_once __DIR__ . '/includes/AJAX.php';
|
139 |
-
require_once __DIR__ . '/includes/Handlers/Connection.php';
|
140 |
-
require_once __DIR__ . '/includes/Handlers/WebHook.php';
|
141 |
-
require_once __DIR__ . '/includes/Integrations/Integrations.php';
|
142 |
-
require_once __DIR__ . '/includes/Product_Categories.php';
|
143 |
-
require_once __DIR__ . '/includes/Products.php';
|
144 |
-
require_once __DIR__ . '/includes/Products/Feed.php';
|
145 |
-
require_once __DIR__ . '/includes/Products/FBCategories.php';
|
146 |
-
require_once __DIR__ . '/includes/Products/Stock.php';
|
147 |
-
require_once __DIR__ . '/includes/Products/Sync.php';
|
148 |
-
require_once __DIR__ . '/includes/Products/Sync/Background.php';
|
149 |
-
require_once __DIR__ . '/includes/ProductSets/Sync.php';
|
150 |
require_once __DIR__ . '/includes/fbproductfeed.php';
|
151 |
require_once __DIR__ . '/facebook-commerce-messenger-chat.php';
|
152 |
-
require_once __DIR__ . '/includes/
|
153 |
-
require_once __DIR__ . '/includes/Events/Event.php';
|
154 |
-
require_once __DIR__ . '/includes/Events/Normalizer.php';
|
155 |
-
require_once __DIR__ . '/includes/Events/AAMSettings.php';
|
156 |
-
require_once __DIR__ . '/includes/Utilities/Shipment.php';
|
157 |
-
require_once __DIR__ . '/includes/Utilities/Tracker.php';
|
158 |
-
require_once __DIR__ . '/includes/Debug/ProfilingLogger.php';
|
159 |
-
require_once __DIR__ . '/includes/Debug/ProfilingLoggerProcess.php';
|
160 |
|
161 |
$this->product_feed = new \SkyVerge\WooCommerce\Facebook\Products\Feed();
|
162 |
$this->products_stock_handler = new \SkyVerge\WooCommerce\Facebook\Products\Stock();
|
@@ -188,10 +172,14 @@ if ( ! class_exists( 'WC_Facebookcommerce' ) ) :
|
|
188 |
}
|
189 |
|
190 |
$this->connection_handler = new \SkyVerge\WooCommerce\Facebook\Handlers\Connection( $this );
|
191 |
-
$this->webhook_handler
|
192 |
|
193 |
$this->tracker = new \SkyVerge\WooCommerce\Facebook\Utilities\Tracker();
|
194 |
|
|
|
|
|
|
|
|
|
195 |
// load admin handlers, before admin_init
|
196 |
if ( is_admin() ) {
|
197 |
|
@@ -235,12 +223,12 @@ if ( ! class_exists( 'WC_Facebookcommerce' ) ) :
|
|
235 |
*/
|
236 |
protected function get_deprecated_hooks() {
|
237 |
|
238 |
-
return
|
239 |
-
'wc_facebook_page_access_token' =>
|
240 |
'version' => '2.1.0',
|
241 |
'replacement' => false,
|
242 |
-
|
243 |
-
|
244 |
}
|
245 |
|
246 |
|
@@ -262,14 +250,20 @@ if ( ! class_exists( 'WC_Facebookcommerce' ) ) :
|
|
262 |
$message = sprintf(
|
263 |
/* translators: Placeholders %1$s - opening strong HTML tag, %2$s - closing strong HTML tag, %3$s - opening link HTML tag, %4$s - closing link HTML tag */
|
264 |
__( '%1$sHeads up!%2$s You\'re ready to migrate to a more secure, reliable Facebook for WooCommerce connection. Please %3$sclick here%4$s to reconnect!', 'facebook-for-woocommerce' ),
|
265 |
-
'<strong>',
|
266 |
-
'
|
|
|
|
|
267 |
);
|
268 |
|
269 |
-
$this->get_admin_notice_handler()->add_admin_notice(
|
270 |
-
|
271 |
-
|
272 |
-
|
|
|
|
|
|
|
|
|
273 |
|
274 |
// direct these users to the new plugin settings page
|
275 |
if ( ! $this->is_plugin_settings() ) {
|
@@ -277,16 +271,21 @@ if ( ! class_exists( 'WC_Facebookcommerce' ) ) :
|
|
277 |
$message = sprintf(
|
278 |
/* translators: Placeholders %1$s - opening link HTML tag, %2$s - closing link HTML tag */
|
279 |
__( 'For your convenience, the Facebook for WooCommerce settings are now located under %1$sWooCommerce > Facebook%2$s.', 'facebook-for-woocommerce' ),
|
280 |
-
'<a href="' . esc_url( facebook_for_woocommerce()->get_settings_url() ) . '">',
|
|
|
281 |
);
|
282 |
|
283 |
-
$this->get_admin_notice_handler()->add_admin_notice(
|
284 |
-
|
285 |
-
|
286 |
-
|
|
|
|
|
|
|
|
|
287 |
}
|
288 |
|
289 |
-
|
290 |
} elseif ( ! $this->is_plugin_settings() ) {
|
291 |
|
292 |
$message = sprintf(
|
@@ -301,33 +300,43 @@ if ( ! class_exists( 'WC_Facebookcommerce' ) ) :
|
|
301 |
'</a>'
|
302 |
);
|
303 |
|
304 |
-
$this->get_admin_notice_handler()->add_admin_notice(
|
305 |
-
|
306 |
-
|
307 |
-
|
|
|
|
|
|
|
|
|
308 |
}
|
309 |
|
310 |
-
|
311 |
} else {
|
312 |
|
313 |
// if upgraders had messenger enabled and one of the removed settings was customized, alert them to reconfigure
|
314 |
if (
|
315 |
$this->get_integration()->get_external_merchant_settings_id()
|
316 |
&& $this->get_integration()->is_messenger_enabled()
|
317 |
-
&& ( '#0084ff' !== $this->get_integration()->get_messenger_color_hex() || ! in_array( $this->get_integration()->get_messenger_greeting(),
|
318 |
) {
|
319 |
|
320 |
$message = sprintf(
|
321 |
/* translators: Placeholders: %1$s - <strong> tag, %2$s - </strong> tag, %3$s - <a> tag, %4$s - </a> tag */
|
322 |
__( '%1$sHeads up!%2$s If you\'ve customized your Facebook Messenger color or greeting settings, please update those settings again from the %3$sManage Connection%4$s area.', 'facebook-for-woocommerce' ),
|
323 |
-
'<strong>',
|
324 |
-
'
|
|
|
|
|
325 |
);
|
326 |
|
327 |
-
$this->get_admin_notice_handler()->add_admin_notice(
|
328 |
-
|
329 |
-
'
|
330 |
-
|
|
|
|
|
|
|
|
|
331 |
}
|
332 |
}
|
333 |
|
@@ -337,19 +346,25 @@ if ( ! class_exists( 'WC_Facebookcommerce' ) ) :
|
|
337 |
$message = sprintf(
|
338 |
/* translators: Placeholders: %1$s - <strong> tag, %2$s - </strong> tag, %3$s - <a> tag, %4$s - </a> tag */
|
339 |
__( '%1$sHeads up!%2$s Your connection to Facebook is no longer valid. Please %3$sclick here%4$s to securely reconnect your account and continue syncing products.', 'facebook-for-woocommerce' ),
|
340 |
-
'<strong>',
|
341 |
-
'
|
|
|
|
|
342 |
);
|
343 |
|
344 |
-
$this->get_admin_notice_handler()->add_admin_notice(
|
345 |
-
|
346 |
-
|
|
|
|
|
|
|
|
|
347 |
}
|
348 |
|
349 |
if ( Framework\SV_WC_Plugin_Compatibility::is_enhanced_admin_available() ) {
|
350 |
|
351 |
$is_marketing_enabled = is_callable( 'Automattic\WooCommerce\Admin\Loader::is_feature_enabled' )
|
352 |
-
|
353 |
|
354 |
if ( $is_marketing_enabled ) {
|
355 |
|
@@ -357,14 +372,15 @@ if ( ! class_exists( 'WC_Facebookcommerce' ) ) :
|
|
357 |
sprintf(
|
358 |
/* translators: Placeholders: %1$s - opening <a> HTML link tag, %2$s - closing </a> HTML link tag */
|
359 |
esc_html__( 'Heads up! The Facebook menu is now located under the %1$sMarketing%2$s menu.', 'facebook-for-woocommerce' ),
|
360 |
-
'<a href="' . esc_url( $this->get_settings_url() ) . '">',
|
|
|
361 |
),
|
362 |
'settings_moved_to_marketing',
|
363 |
-
|
364 |
'dismissible' => true,
|
365 |
'always_show_on_settings' => false,
|
366 |
'notice_class' => 'notice-info',
|
367 |
-
|
368 |
);
|
369 |
}
|
370 |
}
|
@@ -383,8 +399,9 @@ if ( ! class_exists( 'WC_Facebookcommerce' ) ) :
|
|
383 |
* @param string $log_id optional log id to segment the files by, defaults to plugin id
|
384 |
*/
|
385 |
public function log( $message, $log_id = null ) {
|
386 |
-
//
|
387 |
-
|
|
|
388 |
return;
|
389 |
}
|
390 |
|
@@ -398,7 +415,7 @@ if ( ! class_exists( 'WC_Facebookcommerce' ) ) :
|
|
398 |
*
|
399 |
* @param array $request request data
|
400 |
* @param array $response response data
|
401 |
-
* @param null
|
402 |
*/
|
403 |
public function log_api_request( $request, $response, $log_id = null ) {
|
404 |
|
@@ -901,7 +918,7 @@ if ( ! class_exists( 'WC_Facebookcommerce' ) ) :
|
|
901 |
static $instance = null;
|
902 |
if ( null === $instance ) {
|
903 |
$is_enabled = defined( 'FACEBOOK_FOR_WOOCOMMERCE_PROFILING_LOG_ENABLED' ) && FACEBOOK_FOR_WOOCOMMERCE_PROFILING_LOG_ENABLED;
|
904 |
-
$instance
|
905 |
}
|
906 |
|
907 |
return $instance;
|
@@ -985,6 +1002,17 @@ if ( ! class_exists( 'WC_Facebookcommerce' ) ) :
|
|
985 |
return __( 'Facebook for WooCommerce', 'facebook-for-woocommerce' );
|
986 |
}
|
987 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
988 |
|
989 |
/** Conditional methods ***************************************************************************************/
|
990 |
|
22 |
|
23 |
|
24 |
/** @var string the plugin version */
|
25 |
+
const VERSION = WC_Facebook_Loader::PLUGIN_VERSION;
|
26 |
|
27 |
/** @var string for backwards compatibility TODO: remove this in v2.0.0 {CW 2020-02-06} */
|
28 |
const PLUGIN_VERSION = self::VERSION;
|
91 |
/** @var \SkyVerge\WooCommerce\Facebook\Tracker */
|
92 |
private $tracker;
|
93 |
|
94 |
+
/** @var \SkyVerge\WooCommerce\Facebook\Jobs\JobRegistry */
|
95 |
+
public $job_registry;
|
96 |
+
|
97 |
/**
|
98 |
* Constructs the plugin.
|
99 |
*
|
104 |
parent::__construct(
|
105 |
self::PLUGIN_ID,
|
106 |
self::VERSION,
|
107 |
+
array(
|
108 |
'text_domain' => 'facebook-for-woocommerce',
|
109 |
+
)
|
110 |
);
|
111 |
|
112 |
$this->init();
|
120 |
*/
|
121 |
public function init() {
|
122 |
|
123 |
+
add_action( 'init', array( $this, 'get_integration' ) );
|
124 |
+
add_action( 'init', array( $this, 'register_custom_taxonomy' ) );
|
125 |
+
add_action( 'add_meta_boxes_product', array( $this, 'remove_product_fb_product_set_metabox' ), 50 );
|
126 |
+
add_filter( 'fb_product_set_row_actions', array( $this, 'product_set_links' ) );
|
127 |
+
add_filter( 'manage_edit-fb_product_set_columns', array( $this, 'manage_fb_product_set_columns' ) );
|
128 |
|
129 |
// Product Set breadcrumb filters
|
130 |
+
add_filter( 'woocommerce_navigation_is_connected_page', array( $this, 'is_current_page_conected_filter' ), 99, 2 );
|
131 |
+
add_filter( 'woocommerce_navigation_get_breadcrumbs', array( $this, 'wc_page_breadcrumbs_filter' ), 99 );
|
132 |
|
133 |
if ( \WC_Facebookcommerce_Utils::isWoocommerceIntegration() ) {
|
134 |
+
require_once __DIR__ . '/vendor/autoload.php';
|
135 |
|
136 |
include_once 'facebook-commerce.php';
|
137 |
|
138 |
require_once $this->get_framework_path() . '/utilities/class-sv-wp-async-request.php';
|
139 |
require_once $this->get_framework_path() . '/utilities/class-sv-wp-background-job-handler.php';
|
140 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
141 |
require_once __DIR__ . '/includes/fbproductfeed.php';
|
142 |
require_once __DIR__ . '/facebook-commerce-messenger-chat.php';
|
143 |
+
require_once __DIR__ . '/includes/Exceptions/ConnectWCAPIException.php';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
144 |
|
145 |
$this->product_feed = new \SkyVerge\WooCommerce\Facebook\Products\Feed();
|
146 |
$this->products_stock_handler = new \SkyVerge\WooCommerce\Facebook\Products\Stock();
|
172 |
}
|
173 |
|
174 |
$this->connection_handler = new \SkyVerge\WooCommerce\Facebook\Handlers\Connection( $this );
|
175 |
+
$this->webhook_handler = new \SkyVerge\WooCommerce\Facebook\Handlers\WebHook( $this );
|
176 |
|
177 |
$this->tracker = new \SkyVerge\WooCommerce\Facebook\Utilities\Tracker();
|
178 |
|
179 |
+
// Init jobs
|
180 |
+
$this->job_registry = new \SkyVerge\WooCommerce\Facebook\Jobs\JobRegistry();
|
181 |
+
add_action( 'init', [ $this->job_registry, 'init' ] );
|
182 |
+
|
183 |
// load admin handlers, before admin_init
|
184 |
if ( is_admin() ) {
|
185 |
|
223 |
*/
|
224 |
protected function get_deprecated_hooks() {
|
225 |
|
226 |
+
return array(
|
227 |
+
'wc_facebook_page_access_token' => array(
|
228 |
'version' => '2.1.0',
|
229 |
'replacement' => false,
|
230 |
+
),
|
231 |
+
);
|
232 |
}
|
233 |
|
234 |
|
250 |
$message = sprintf(
|
251 |
/* translators: Placeholders %1$s - opening strong HTML tag, %2$s - closing strong HTML tag, %3$s - opening link HTML tag, %4$s - closing link HTML tag */
|
252 |
__( '%1$sHeads up!%2$s You\'re ready to migrate to a more secure, reliable Facebook for WooCommerce connection. Please %3$sclick here%4$s to reconnect!', 'facebook-for-woocommerce' ),
|
253 |
+
'<strong>',
|
254 |
+
'</strong>',
|
255 |
+
'<a href="' . esc_url( $this->get_connection_handler()->get_connect_url() ) . '">',
|
256 |
+
'</a>'
|
257 |
);
|
258 |
|
259 |
+
$this->get_admin_notice_handler()->add_admin_notice(
|
260 |
+
$message,
|
261 |
+
self::PLUGIN_ID . '_migrate_to_v2_0',
|
262 |
+
array(
|
263 |
+
'dismissible' => false,
|
264 |
+
'notice_class' => 'notice-info',
|
265 |
+
)
|
266 |
+
);
|
267 |
|
268 |
// direct these users to the new plugin settings page
|
269 |
if ( ! $this->is_plugin_settings() ) {
|
271 |
$message = sprintf(
|
272 |
/* translators: Placeholders %1$s - opening link HTML tag, %2$s - closing link HTML tag */
|
273 |
__( 'For your convenience, the Facebook for WooCommerce settings are now located under %1$sWooCommerce > Facebook%2$s.', 'facebook-for-woocommerce' ),
|
274 |
+
'<a href="' . esc_url( facebook_for_woocommerce()->get_settings_url() ) . '">',
|
275 |
+
'</a>'
|
276 |
);
|
277 |
|
278 |
+
$this->get_admin_notice_handler()->add_admin_notice(
|
279 |
+
$message,
|
280 |
+
self::PLUGIN_ID . '_relocated_settings',
|
281 |
+
array(
|
282 |
+
'dismissible' => true,
|
283 |
+
'notice_class' => 'notice-info',
|
284 |
+
)
|
285 |
+
);
|
286 |
}
|
287 |
|
288 |
+
// otherwise, a general getting started message
|
289 |
} elseif ( ! $this->is_plugin_settings() ) {
|
290 |
|
291 |
$message = sprintf(
|
300 |
'</a>'
|
301 |
);
|
302 |
|
303 |
+
$this->get_admin_notice_handler()->add_admin_notice(
|
304 |
+
$message,
|
305 |
+
self::PLUGIN_ID . '_get_started',
|
306 |
+
array(
|
307 |
+
'dismissible' => true,
|
308 |
+
'notice_class' => 'notice-info',
|
309 |
+
)
|
310 |
+
);
|
311 |
}
|
312 |
|
313 |
+
// notices for those connected to FBE 2
|
314 |
} else {
|
315 |
|
316 |
// if upgraders had messenger enabled and one of the removed settings was customized, alert them to reconfigure
|
317 |
if (
|
318 |
$this->get_integration()->get_external_merchant_settings_id()
|
319 |
&& $this->get_integration()->is_messenger_enabled()
|
320 |
+
&& ( '#0084ff' !== $this->get_integration()->get_messenger_color_hex() || ! in_array( $this->get_integration()->get_messenger_greeting(), array( 'Hi! How can we help you?', "Hi! We're here to answer any questions you may have.", '' ), true ) )
|
321 |
) {
|
322 |
|
323 |
$message = sprintf(
|
324 |
/* translators: Placeholders: %1$s - <strong> tag, %2$s - </strong> tag, %3$s - <a> tag, %4$s - </a> tag */
|
325 |
__( '%1$sHeads up!%2$s If you\'ve customized your Facebook Messenger color or greeting settings, please update those settings again from the %3$sManage Connection%4$s area.', 'facebook-for-woocommerce' ),
|
326 |
+
'<strong>',
|
327 |
+
'</strong>',
|
328 |
+
'<a href="' . esc_url( $this->get_connection_handler()->get_manage_url() ) . '" target="_blank">',
|
329 |
+
'</a>'
|
330 |
);
|
331 |
|
332 |
+
$this->get_admin_notice_handler()->add_admin_notice(
|
333 |
+
$message,
|
334 |
+
'update_messenger',
|
335 |
+
array(
|
336 |
+
'always_show_on_settings' => false,
|
337 |
+
'notice_class' => 'notice-info',
|
338 |
+
)
|
339 |
+
);
|
340 |
}
|
341 |
}
|
342 |
|
346 |
$message = sprintf(
|
347 |
/* translators: Placeholders: %1$s - <strong> tag, %2$s - </strong> tag, %3$s - <a> tag, %4$s - </a> tag */
|
348 |
__( '%1$sHeads up!%2$s Your connection to Facebook is no longer valid. Please %3$sclick here%4$s to securely reconnect your account and continue syncing products.', 'facebook-for-woocommerce' ),
|
349 |
+
'<strong>',
|
350 |
+
'</strong>',
|
351 |
+
'<a href="' . esc_url( $this->get_connection_handler()->get_connect_url() ) . '">',
|
352 |
+
'</a>'
|
353 |
);
|
354 |
|
355 |
+
$this->get_admin_notice_handler()->add_admin_notice(
|
356 |
+
$message,
|
357 |
+
'connection_invalid',
|
358 |
+
array(
|
359 |
+
'notice_class' => 'notice-error',
|
360 |
+
)
|
361 |
+
);
|
362 |
}
|
363 |
|
364 |
if ( Framework\SV_WC_Plugin_Compatibility::is_enhanced_admin_available() ) {
|
365 |
|
366 |
$is_marketing_enabled = is_callable( 'Automattic\WooCommerce\Admin\Loader::is_feature_enabled' )
|
367 |
+
&& Automattic\WooCommerce\Admin\Loader::is_feature_enabled( 'marketing' );
|
368 |
|
369 |
if ( $is_marketing_enabled ) {
|
370 |
|
372 |
sprintf(
|
373 |
/* translators: Placeholders: %1$s - opening <a> HTML link tag, %2$s - closing </a> HTML link tag */
|
374 |
esc_html__( 'Heads up! The Facebook menu is now located under the %1$sMarketing%2$s menu.', 'facebook-for-woocommerce' ),
|
375 |
+
'<a href="' . esc_url( $this->get_settings_url() ) . '">',
|
376 |
+
'</a>'
|
377 |
),
|
378 |
'settings_moved_to_marketing',
|
379 |
+
array(
|
380 |
'dismissible' => true,
|
381 |
'always_show_on_settings' => false,
|
382 |
'notice_class' => 'notice-info',
|
383 |
+
)
|
384 |
);
|
385 |
}
|
386 |
}
|
399 |
* @param string $log_id optional log id to segment the files by, defaults to plugin id
|
400 |
*/
|
401 |
public function log( $message, $log_id = null ) {
|
402 |
+
// Bail if site is connected and user has disabled logging.
|
403 |
+
// If site is disconnected, force-enable logging so merchant can diagnose connection issues.
|
404 |
+
if ( ( ! $this->get_integration() || ! $this->get_integration()->is_debug_mode_enabled() ) && $this->get_connection_handler()->is_connected() ) {
|
405 |
return;
|
406 |
}
|
407 |
|
415 |
*
|
416 |
* @param array $request request data
|
417 |
* @param array $response response data
|
418 |
+
* @param null $log_id log ID
|
419 |
*/
|
420 |
public function log_api_request( $request, $response, $log_id = null ) {
|
421 |
|
918 |
static $instance = null;
|
919 |
if ( null === $instance ) {
|
920 |
$is_enabled = defined( 'FACEBOOK_FOR_WOOCOMMERCE_PROFILING_LOG_ENABLED' ) && FACEBOOK_FOR_WOOCOMMERCE_PROFILING_LOG_ENABLED;
|
921 |
+
$instance = new \SkyVerge\WooCommerce\Facebook\Debug\ProfilingLogger( $is_enabled );
|
922 |
}
|
923 |
|
924 |
return $instance;
|
1002 |
return __( 'Facebook for WooCommerce', 'facebook-for-woocommerce' );
|
1003 |
}
|
1004 |
|
1005 |
+
/**
|
1006 |
+
* Gets the url for the assets build directory.
|
1007 |
+
*
|
1008 |
+
* @since 2.3.4
|
1009 |
+
*
|
1010 |
+
* @return string
|
1011 |
+
*/
|
1012 |
+
public function get_asset_build_dir_url() {
|
1013 |
+
return $this->get_plugin_url() . '/assets/build';
|
1014 |
+
}
|
1015 |
+
|
1016 |
|
1017 |
/** Conditional methods ***************************************************************************************/
|
1018 |
|
facebook-commerce-events-tracker.php
CHANGED
@@ -63,7 +63,7 @@ if ( ! class_exists( 'WC_Facebookcommerce_EventsTracker' ) ) :
|
|
63 |
|
64 |
$this->pixel = new \WC_Facebookcommerce_Pixel( $user_info );
|
65 |
$this->aam_settings = $aam_settings;
|
66 |
-
$this->tracked_events =
|
67 |
|
68 |
$this->add_hooks();
|
69 |
}
|
@@ -100,37 +100,37 @@ if ( ! class_exists( 'WC_Facebookcommerce_EventsTracker' ) ) :
|
|
100 |
private function add_hooks() {
|
101 |
|
102 |
// inject Pixel
|
103 |
-
add_action( 'wp_head',
|
104 |
-
add_action( 'wp_footer',
|
105 |
|
106 |
// ViewContent for individual products
|
107 |
-
add_action( 'woocommerce_after_single_product',
|
108 |
-
add_action( 'woocommerce_after_single_product',
|
109 |
|
110 |
-
add_action( 'woocommerce_after_shop_loop',
|
111 |
|
112 |
-
add_action( 'pre_get_posts',
|
113 |
-
add_filter( 'woocommerce_redirect_single_search_result',
|
114 |
|
115 |
// AddToCart events
|
116 |
-
add_action( 'woocommerce_add_to_cart',
|
117 |
// AddToCart while AJAX is enabled
|
118 |
-
add_action( 'woocommerce_ajax_added_to_cart',
|
119 |
// AddToCart while using redirect to cart page
|
120 |
if ( 'yes' === get_option( 'woocommerce_cart_redirect_after_add' ) ) {
|
121 |
-
add_filter( 'woocommerce_add_to_cart_redirect',
|
122 |
-
add_action( 'woocommerce_ajax_added_to_cart',
|
123 |
-
add_action( 'woocommerce_after_cart',
|
124 |
}
|
125 |
|
126 |
// InitiateCheckout events
|
127 |
-
add_action( 'woocommerce_after_checkout_form',
|
128 |
// Purchase and Subscribe events
|
129 |
-
add_action( 'woocommerce_checkout_update_order_meta',
|
130 |
-
add_action( 'woocommerce_thankyou',
|
131 |
|
132 |
// TODO move this in some 3rd party plugin integrations handler at some point {FN 2020-03-20}
|
133 |
-
add_action( 'wpcf7_contact_form',
|
134 |
}
|
135 |
|
136 |
|
@@ -195,8 +195,8 @@ if ( ! class_exists( 'WC_Facebookcommerce_EventsTracker' ) ) :
|
|
195 |
// if any product is a variant, fire the pixel with
|
196 |
// content_type: product_group
|
197 |
$content_type = 'product';
|
198 |
-
$product_ids =
|
199 |
-
$contents =
|
200 |
|
201 |
foreach ( $products as $product ) {
|
202 |
|
@@ -204,10 +204,10 @@ if ( ! class_exists( 'WC_Facebookcommerce_EventsTracker' ) ) :
|
|
204 |
continue;
|
205 |
}
|
206 |
|
207 |
-
$contents[] =
|
208 |
'id' => \WC_Facebookcommerce_Utils::get_fb_retailer_id( $product ),
|
209 |
'quantity' => 1, // consider category results a quantity of 1
|
210 |
-
|
211 |
|
212 |
$product_ids = array_merge(
|
213 |
$product_ids,
|
@@ -221,17 +221,17 @@ if ( ! class_exists( 'WC_Facebookcommerce_EventsTracker' ) ) :
|
|
221 |
$categories = WC_Facebookcommerce_Utils::get_product_categories( get_the_ID() );
|
222 |
|
223 |
$event_name = 'ViewCategory';
|
224 |
-
$event_data =
|
225 |
-
'event_name'
|
226 |
-
'custom_data' =>
|
227 |
'content_name' => $categories['name'],
|
228 |
'content_category' => $categories['categories'],
|
229 |
'content_ids' => json_encode( array_slice( $product_ids, 0, 10 ) ),
|
230 |
'content_type' => $content_type,
|
231 |
'contents' => $contents,
|
232 |
-
|
233 |
-
'user_data'
|
234 |
-
|
235 |
|
236 |
$event = new Event( $event_data );
|
237 |
|
@@ -296,7 +296,7 @@ if ( ! class_exists( 'WC_Facebookcommerce_EventsTracker' ) ) :
|
|
296 |
*/
|
297 |
private function add_product_search_event_to_session( Event $event ) {
|
298 |
|
299 |
-
if ( isset( WC()->session ) && is_callable(
|
300 |
WC()->session->set( $this->search_event_data_session_variable, $event->get_data() );
|
301 |
}
|
302 |
}
|
@@ -317,7 +317,7 @@ if ( ! class_exists( 'WC_Facebookcommerce_EventsTracker' ) ) :
|
|
317 |
|
318 |
$this->search_event = $this->get_product_search_event_from_session();
|
319 |
|
320 |
-
if ( ! $this->search_event
|
321 |
return;
|
322 |
}
|
323 |
|
@@ -335,7 +335,7 @@ if ( ! class_exists( 'WC_Facebookcommerce_EventsTracker' ) ) :
|
|
335 |
*/
|
336 |
private function get_product_search_event_from_session() {
|
337 |
|
338 |
-
if ( ! isset( WC()->session ) || ! is_callable(
|
339 |
return null;
|
340 |
}
|
341 |
|
@@ -382,8 +382,8 @@ if ( ! class_exists( 'WC_Facebookcommerce_EventsTracker' ) ) :
|
|
382 |
}
|
383 |
|
384 |
// needs to run before wc_template_redirect, normally hooked with priority 10
|
385 |
-
add_action( 'template_redirect',
|
386 |
-
add_action( 'woocommerce_before_shop_loop',
|
387 |
}
|
388 |
}
|
389 |
|
@@ -417,8 +417,8 @@ if ( ! class_exists( 'WC_Facebookcommerce_EventsTracker' ) ) :
|
|
417 |
|
418 |
// if any product is a variant, fire the pixel with content_type: product_group
|
419 |
$content_type = 'product';
|
420 |
-
$product_ids =
|
421 |
-
$contents =
|
422 |
$total_value = 0.00;
|
423 |
|
424 |
foreach ( $wp_query->posts as $post ) {
|
@@ -431,10 +431,10 @@ if ( ! class_exists( 'WC_Facebookcommerce_EventsTracker' ) ) :
|
|
431 |
|
432 |
$product_ids = array_merge( $product_ids, WC_Facebookcommerce_Utils::get_fb_content_ids( $product ) );
|
433 |
|
434 |
-
$contents[] =
|
435 |
'id' => \WC_Facebookcommerce_Utils::get_fb_retailer_id( $product ),
|
436 |
'quantity' => 1, // consider the search results a quantity of 1
|
437 |
-
|
438 |
|
439 |
$total_value += (float) $product->get_price();
|
440 |
|
@@ -443,18 +443,18 @@ if ( ! class_exists( 'WC_Facebookcommerce_EventsTracker' ) ) :
|
|
443 |
}
|
444 |
}
|
445 |
|
446 |
-
$event_data =
|
447 |
'event_name' => 'Search',
|
448 |
-
'custom_data' =>
|
449 |
'content_type' => $content_type,
|
450 |
'content_ids' => json_encode( array_slice( $product_ids, 0, 10 ) ),
|
451 |
'contents' => $contents,
|
452 |
'search_string' => get_search_query(),
|
453 |
'value' => Framework\SV_WC_Helper::number_format( $total_value ),
|
454 |
'currency' => get_woocommerce_currency(),
|
455 |
-
|
456 |
-
'user_data'
|
457 |
-
|
458 |
|
459 |
$this->search_event = new Event( $event_data );
|
460 |
}
|
@@ -472,11 +472,14 @@ if ( ! class_exists( 'WC_Facebookcommerce_EventsTracker' ) ) :
|
|
472 |
|
473 |
$event = $this->get_search_event();
|
474 |
|
475 |
-
$this->pixel->inject_event(
|
476 |
-
|
477 |
-
|
478 |
-
|
479 |
-
|
|
|
|
|
|
|
480 |
}
|
481 |
|
482 |
|
@@ -499,7 +502,7 @@ if ( ! class_exists( 'WC_Facebookcommerce_EventsTracker' ) ) :
|
|
499 |
}
|
500 |
|
501 |
// if product is variable or grouped, fire the pixel with content_type: product_group
|
502 |
-
if ( $product->is_type(
|
503 |
$content_type = 'product_group';
|
504 |
} else {
|
505 |
$content_type = 'product';
|
@@ -507,26 +510,26 @@ if ( ! class_exists( 'WC_Facebookcommerce_EventsTracker' ) ) :
|
|
507 |
|
508 |
$categories = \WC_Facebookcommerce_Utils::get_product_categories( $product->get_id() );
|
509 |
|
510 |
-
$event_data =
|
511 |
'event_name' => 'ViewContent',
|
512 |
-
'custom_data' =>
|
513 |
'content_name' => $product->get_title(),
|
514 |
'content_ids' => wp_json_encode( \WC_Facebookcommerce_Utils::get_fb_content_ids( $product ) ),
|
515 |
'content_type' => $content_type,
|
516 |
'contents' => wp_json_encode(
|
517 |
-
|
518 |
-
|
519 |
'id' => \WC_Facebookcommerce_Utils::get_fb_retailer_id( $product ),
|
520 |
'quantity' => 1,
|
521 |
-
|
522 |
-
|
523 |
),
|
524 |
'content_category' => $categories['name'],
|
525 |
'value' => $product->get_price(),
|
526 |
'currency' => get_woocommerce_currency(),
|
527 |
-
|
528 |
-
'user_data'
|
529 |
-
|
530 |
|
531 |
$event = new Event( $event_data );
|
532 |
|
@@ -544,9 +547,9 @@ if ( ! class_exists( 'WC_Facebookcommerce_EventsTracker' ) ) :
|
|
544 |
* @internal
|
545 |
*
|
546 |
* @param string $cart_item_key the cart item key
|
547 |
-
* @param int
|
548 |
-
* @param int
|
549 |
-
* @param int
|
550 |
*/
|
551 |
public function inject_add_to_cart_event( $cart_item_key, $product_id, $quantity, $variation_id ) {
|
552 |
|
@@ -562,18 +565,18 @@ if ( ! class_exists( 'WC_Facebookcommerce_EventsTracker' ) ) :
|
|
562 |
return;
|
563 |
}
|
564 |
|
565 |
-
$event_data =
|
566 |
'event_name' => 'AddToCart',
|
567 |
-
'custom_data' =>
|
568 |
'content_ids' => $this->get_cart_content_ids(),
|
569 |
'content_name' => $this->get_cart_content_names(),
|
570 |
'content_type' => 'product',
|
571 |
'contents' => $this->get_cart_contents(),
|
572 |
'value' => $this->get_cart_total(),
|
573 |
'currency' => get_woocommerce_currency(),
|
574 |
-
|
575 |
-
'user_data'
|
576 |
-
|
577 |
|
578 |
$event = new SkyVerge\WooCommerce\Facebook\Events\Event( $event_data );
|
579 |
|
@@ -601,7 +604,7 @@ if ( ! class_exists( 'WC_Facebookcommerce_EventsTracker' ) ) :
|
|
601 |
public function add_filter_for_add_to_cart_fragments() {
|
602 |
|
603 |
if ( 'no' === get_option( 'woocommerce_cart_redirect_after_add' ) ) {
|
604 |
-
add_filter( 'woocommerce_add_to_cart_fragments',
|
605 |
}
|
606 |
}
|
607 |
|
@@ -620,17 +623,17 @@ if ( ! class_exists( 'WC_Facebookcommerce_EventsTracker' ) ) :
|
|
620 |
|
621 |
if ( $this->is_pixel_enabled() ) {
|
622 |
|
623 |
-
$params =
|
624 |
'content_ids' => $this->get_cart_content_ids(),
|
625 |
'content_name' => $this->get_cart_content_names(),
|
626 |
'content_type' => 'product',
|
627 |
'contents' => $this->get_cart_contents(),
|
628 |
'value' => $this->get_cart_total(),
|
629 |
'currency' => get_woocommerce_currency(),
|
630 |
-
|
631 |
|
632 |
// send the event ID to prevent duplication
|
633 |
-
if ( ! empty
|
634 |
|
635 |
$params['event_id'] = $event_id;
|
636 |
}
|
@@ -658,7 +661,7 @@ if ( ! class_exists( 'WC_Facebookcommerce_EventsTracker' ) ) :
|
|
658 |
public function add_filter_for_conditional_add_to_cart_fragment() {
|
659 |
|
660 |
if ( 'no' === get_option( 'woocommerce_cart_redirect_after_add' ) ) {
|
661 |
-
add_filter( 'woocommerce_add_to_cart_fragments',
|
662 |
}
|
663 |
}
|
664 |
|
@@ -677,17 +680,17 @@ if ( ! class_exists( 'WC_Facebookcommerce_EventsTracker' ) ) :
|
|
677 |
|
678 |
if ( $this->is_pixel_enabled() ) {
|
679 |
|
680 |
-
$params =
|
681 |
'content_ids' => $this->get_cart_content_ids(),
|
682 |
'content_name' => $this->get_cart_content_names(),
|
683 |
'content_type' => 'product',
|
684 |
'contents' => $this->get_cart_contents(),
|
685 |
'value' => $this->get_cart_total(),
|
686 |
'currency' => get_woocommerce_currency(),
|
687 |
-
|
688 |
|
689 |
// send the event ID to prevent duplication
|
690 |
-
if ( ! empty
|
691 |
|
692 |
$params['event_id'] = $event_id;
|
693 |
}
|
@@ -720,7 +723,7 @@ if ( ! class_exists( 'WC_Facebookcommerce_EventsTracker' ) ) :
|
|
720 |
*
|
721 |
* @since 1.10.2
|
722 |
*
|
723 |
-
* @param string
|
724 |
* @param null|\WC_Product $product the product just added to the cart
|
725 |
* @return string
|
726 |
*/
|
@@ -794,9 +797,9 @@ if ( ! class_exists( 'WC_Facebookcommerce_EventsTracker' ) ) :
|
|
794 |
}
|
795 |
|
796 |
$event_name = 'InitiateCheckout';
|
797 |
-
$event_data =
|
798 |
'event_name' => $event_name,
|
799 |
-
'custom_data' =>
|
800 |
'num_items' => $this->get_cart_num_items(),
|
801 |
'content_ids' => $this->get_cart_content_ids(),
|
802 |
'content_name' => $this->get_cart_content_names(),
|
@@ -804,9 +807,9 @@ if ( ! class_exists( 'WC_Facebookcommerce_EventsTracker' ) ) :
|
|
804 |
'contents' => $this->get_cart_contents(),
|
805 |
'value' => $this->get_cart_total(),
|
806 |
'currency' => get_woocommerce_currency(),
|
807 |
-
|
808 |
-
'user_data'
|
809 |
-
|
810 |
|
811 |
// if there is only one item in the cart, send its first category
|
812 |
if ( ( $cart = WC()->cart ) && count( $cart->get_cart() ) === 1 ) {
|
@@ -880,9 +883,9 @@ if ( ! class_exists( 'WC_Facebookcommerce_EventsTracker' ) ) :
|
|
880 |
}
|
881 |
|
882 |
$content_type = 'product';
|
883 |
-
$contents =
|
884 |
-
$product_ids =
|
885 |
-
$product_names =
|
886 |
|
887 |
foreach ( $order->get_items() as $item ) {
|
888 |
|
@@ -905,18 +908,18 @@ if ( ! class_exists( 'WC_Facebookcommerce_EventsTracker' ) ) :
|
|
905 |
}
|
906 |
}
|
907 |
// Advanced matching information is extracted from the order
|
908 |
-
$event_data =
|
909 |
'event_name' => $event_name,
|
910 |
-
'custom_data' =>
|
911 |
'content_ids' => wp_json_encode( array_merge( ... $product_ids ) ),
|
912 |
'content_name' => wp_json_encode( $product_names ),
|
913 |
'contents' => wp_json_encode( $contents ),
|
914 |
'content_type' => $content_type,
|
915 |
'value' => $order->get_total(),
|
916 |
'currency' => get_woocommerce_currency(),
|
917 |
-
|
918 |
-
'user_data'
|
919 |
-
|
920 |
|
921 |
$event = new Event( $event_data );
|
922 |
|
@@ -945,7 +948,7 @@ if ( ! class_exists( 'WC_Facebookcommerce_EventsTracker' ) ) :
|
|
945 |
*/
|
946 |
public function inject_subscribe_event( $order_id ) {
|
947 |
|
948 |
-
if ( ! function_exists( 'wcs_get_subscriptions_for_order' ) || ! $this->is_pixel_enabled() || $this->pixel->is_last_event( 'Subscribe' )
|
949 |
return;
|
950 |
}
|
951 |
|
@@ -955,15 +958,15 @@ if ( ! class_exists( 'WC_Facebookcommerce_EventsTracker' ) ) :
|
|
955 |
$event_name = 'Subscribe';
|
956 |
|
957 |
// TODO consider including (int|float) 'predicted_ltv': "Predicted lifetime value of a subscriber as defined by the advertiser and expressed as an exact value." {FN 2020-03-20}
|
958 |
-
$event_data =
|
959 |
'event_name' => $event_name,
|
960 |
-
'custom_data' =>
|
961 |
'sign_up_fee' => $subscription->get_sign_up_fee(),
|
962 |
'value' => $subscription->get_total(),
|
963 |
'currency' => get_woocommerce_currency(),
|
964 |
-
|
965 |
-
'user_data'
|
966 |
-
|
967 |
|
968 |
$event = new Event( $event_data );
|
969 |
|
@@ -1026,7 +1029,7 @@ if ( ! class_exists( 'WC_Facebookcommerce_EventsTracker' ) ) :
|
|
1026 |
|
1027 |
try {
|
1028 |
|
1029 |
-
facebook_for_woocommerce()->get_api()->send_pixel_events( facebook_for_woocommerce()->get_integration()->get_facebook_pixel_id(),
|
1030 |
|
1031 |
$success = true;
|
1032 |
|
@@ -1065,7 +1068,7 @@ if ( ! class_exists( 'WC_Facebookcommerce_EventsTracker' ) ) :
|
|
1065 |
*/
|
1066 |
private function get_cart_content_ids() {
|
1067 |
|
1068 |
-
$product_ids =
|
1069 |
|
1070 |
if ( $cart = WC()->cart ) {
|
1071 |
|
@@ -1091,7 +1094,7 @@ if ( ! class_exists( 'WC_Facebookcommerce_EventsTracker' ) ) :
|
|
1091 |
*/
|
1092 |
private function get_cart_content_names() {
|
1093 |
|
1094 |
-
$product_names =
|
1095 |
|
1096 |
if ( $cart = WC()->cart ) {
|
1097 |
|
@@ -1117,7 +1120,7 @@ if ( ! class_exists( 'WC_Facebookcommerce_EventsTracker' ) ) :
|
|
1117 |
*/
|
1118 |
private function get_cart_contents() {
|
1119 |
|
1120 |
-
$cart_contents =
|
1121 |
|
1122 |
if ( $cart = WC()->cart ) {
|
1123 |
|
@@ -1157,28 +1160,28 @@ if ( ! class_exists( 'WC_Facebookcommerce_EventsTracker' ) ) :
|
|
1157 |
*
|
1158 |
* @return array
|
1159 |
*/
|
1160 |
-
private function get_user_data_from_billing_address($order) {
|
1161 |
-
if($this->aam_settings == null ||
|
1162 |
return array();
|
1163 |
}
|
1164 |
-
$user_data= array();
|
1165 |
$user_data['fn'] = $order->get_billing_first_name();
|
1166 |
$user_data['ln'] = $order->get_billing_last_name();
|
1167 |
$user_data['em'] = $order->get_billing_email();
|
1168 |
// get_user_id() returns 0 if the current user is a guest
|
1169 |
-
$user_data['external_id'] = $order->get_user_id() === 0 ? null : strval($order->get_user_id());
|
1170 |
-
$user_data['zp']
|
1171 |
-
$user_data['st']
|
1172 |
// We can use country as key because this information is for CAPI events only
|
1173 |
$user_data['country'] = $order->get_billing_country();
|
1174 |
-
$user_data['ct']
|
1175 |
-
$user_data['ph']
|
1176 |
// The fields contain country, so we do not need to add a condition
|
1177 |
-
foreach ($user_data as $field => $value) {
|
1178 |
-
if( $value === null || $value === '' ||
|
1179 |
-
!in_array($field, $this->aam_settings->get_enabled_automatic_matching_fields())
|
1180 |
-
){
|
1181 |
-
unset($user_data[$field]);
|
1182 |
}
|
1183 |
}
|
1184 |
return $user_data;
|
@@ -1189,7 +1192,7 @@ if ( ! class_exists( 'WC_Facebookcommerce_EventsTracker' ) ) :
|
|
1189 |
*
|
1190 |
* @return array
|
1191 |
*/
|
1192 |
-
public function get_tracked_events(){
|
1193 |
return $this->tracked_events;
|
1194 |
}
|
1195 |
|
63 |
|
64 |
$this->pixel = new \WC_Facebookcommerce_Pixel( $user_info );
|
65 |
$this->aam_settings = $aam_settings;
|
66 |
+
$this->tracked_events = array();
|
67 |
|
68 |
$this->add_hooks();
|
69 |
}
|
100 |
private function add_hooks() {
|
101 |
|
102 |
// inject Pixel
|
103 |
+
add_action( 'wp_head', array( $this, 'inject_base_pixel' ) );
|
104 |
+
add_action( 'wp_footer', array( $this, 'inject_base_pixel_noscript' ) );
|
105 |
|
106 |
// ViewContent for individual products
|
107 |
+
add_action( 'woocommerce_after_single_product', array( $this, 'inject_view_content_event' ) );
|
108 |
+
add_action( 'woocommerce_after_single_product', array( $this, 'maybe_inject_search_event' ) );
|
109 |
|
110 |
+
add_action( 'woocommerce_after_shop_loop', array( $this, 'inject_view_category_event' ) );
|
111 |
|
112 |
+
add_action( 'pre_get_posts', array( $this, 'inject_search_event' ) );
|
113 |
+
add_filter( 'woocommerce_redirect_single_search_result', array( $this, 'maybe_add_product_search_event_to_session' ) );
|
114 |
|
115 |
// AddToCart events
|
116 |
+
add_action( 'woocommerce_add_to_cart', array( $this, 'inject_add_to_cart_event' ), 40, 4 );
|
117 |
// AddToCart while AJAX is enabled
|
118 |
+
add_action( 'woocommerce_ajax_added_to_cart', array( $this, 'add_filter_for_add_to_cart_fragments' ) );
|
119 |
// AddToCart while using redirect to cart page
|
120 |
if ( 'yes' === get_option( 'woocommerce_cart_redirect_after_add' ) ) {
|
121 |
+
add_filter( 'woocommerce_add_to_cart_redirect', array( $this, 'set_last_product_added_to_cart_upon_redirect' ), 10, 2 );
|
122 |
+
add_action( 'woocommerce_ajax_added_to_cart', array( $this, 'set_last_product_added_to_cart_upon_ajax_redirect' ) );
|
123 |
+
add_action( 'woocommerce_after_cart', array( $this, 'inject_add_to_cart_redirect_event' ), 10, 2 );
|
124 |
}
|
125 |
|
126 |
// InitiateCheckout events
|
127 |
+
add_action( 'woocommerce_after_checkout_form', array( $this, 'inject_initiate_checkout_event' ) );
|
128 |
// Purchase and Subscribe events
|
129 |
+
add_action( 'woocommerce_checkout_update_order_meta', array( $this, 'inject_purchase_event' ) );
|
130 |
+
add_action( 'woocommerce_thankyou', array( $this, 'inject_purchase_event' ), 40 );
|
131 |
|
132 |
// TODO move this in some 3rd party plugin integrations handler at some point {FN 2020-03-20}
|
133 |
+
add_action( 'wpcf7_contact_form', array( $this, 'inject_lead_event_hook' ), 11 );
|
134 |
}
|
135 |
|
136 |
|
195 |
// if any product is a variant, fire the pixel with
|
196 |
// content_type: product_group
|
197 |
$content_type = 'product';
|
198 |
+
$product_ids = array();
|
199 |
+
$contents = array();
|
200 |
|
201 |
foreach ( $products as $product ) {
|
202 |
|
204 |
continue;
|
205 |
}
|
206 |
|
207 |
+
$contents[] = array(
|
208 |
'id' => \WC_Facebookcommerce_Utils::get_fb_retailer_id( $product ),
|
209 |
'quantity' => 1, // consider category results a quantity of 1
|
210 |
+
);
|
211 |
|
212 |
$product_ids = array_merge(
|
213 |
$product_ids,
|
221 |
$categories = WC_Facebookcommerce_Utils::get_product_categories( get_the_ID() );
|
222 |
|
223 |
$event_name = 'ViewCategory';
|
224 |
+
$event_data = array(
|
225 |
+
'event_name' => $event_name,
|
226 |
+
'custom_data' => array(
|
227 |
'content_name' => $categories['name'],
|
228 |
'content_category' => $categories['categories'],
|
229 |
'content_ids' => json_encode( array_slice( $product_ids, 0, 10 ) ),
|
230 |
'content_type' => $content_type,
|
231 |
'contents' => $contents,
|
232 |
+
),
|
233 |
+
'user_data' => $this->pixel->get_user_info(),
|
234 |
+
);
|
235 |
|
236 |
$event = new Event( $event_data );
|
237 |
|
296 |
*/
|
297 |
private function add_product_search_event_to_session( Event $event ) {
|
298 |
|
299 |
+
if ( isset( WC()->session ) && is_callable( array( WC()->session, 'has_session' ) ) && WC()->session->has_session() ) {
|
300 |
WC()->session->set( $this->search_event_data_session_variable, $event->get_data() );
|
301 |
}
|
302 |
}
|
317 |
|
318 |
$this->search_event = $this->get_product_search_event_from_session();
|
319 |
|
320 |
+
if ( ! $this->search_event ) {
|
321 |
return;
|
322 |
}
|
323 |
|
335 |
*/
|
336 |
private function get_product_search_event_from_session() {
|
337 |
|
338 |
+
if ( ! isset( WC()->session ) || ! is_callable( array( WC()->session, 'get' ) ) ) {
|
339 |
return null;
|
340 |
}
|
341 |
|
382 |
}
|
383 |
|
384 |
// needs to run before wc_template_redirect, normally hooked with priority 10
|
385 |
+
add_action( 'template_redirect', array( $this, 'send_search_event' ), 5 );
|
386 |
+
add_action( 'woocommerce_before_shop_loop', array( $this, 'actually_inject_search_event' ) );
|
387 |
}
|
388 |
}
|
389 |
|
417 |
|
418 |
// if any product is a variant, fire the pixel with content_type: product_group
|
419 |
$content_type = 'product';
|
420 |
+
$product_ids = array();
|
421 |
+
$contents = array();
|
422 |
$total_value = 0.00;
|
423 |
|
424 |
foreach ( $wp_query->posts as $post ) {
|
431 |
|
432 |
$product_ids = array_merge( $product_ids, WC_Facebookcommerce_Utils::get_fb_content_ids( $product ) );
|
433 |
|
434 |
+
$contents[] = array(
|
435 |
'id' => \WC_Facebookcommerce_Utils::get_fb_retailer_id( $product ),
|
436 |
'quantity' => 1, // consider the search results a quantity of 1
|
437 |
+
);
|
438 |
|
439 |
$total_value += (float) $product->get_price();
|
440 |
|
443 |
}
|
444 |
}
|
445 |
|
446 |
+
$event_data = array(
|
447 |
'event_name' => 'Search',
|
448 |
+
'custom_data' => array(
|
449 |
'content_type' => $content_type,
|
450 |
'content_ids' => json_encode( array_slice( $product_ids, 0, 10 ) ),
|
451 |
'contents' => $contents,
|
452 |
'search_string' => get_search_query(),
|
453 |
'value' => Framework\SV_WC_Helper::number_format( $total_value ),
|
454 |
'currency' => get_woocommerce_currency(),
|
455 |
+
),
|
456 |
+
'user_data' => $this->pixel->get_user_info(),
|
457 |
+
);
|
458 |
|
459 |
$this->search_event = new Event( $event_data );
|
460 |
}
|
472 |
|
473 |
$event = $this->get_search_event();
|
474 |
|
475 |
+
$this->pixel->inject_event(
|
476 |
+
$event->get_name(),
|
477 |
+
array(
|
478 |
+
'event_id' => $event->get_id(),
|
479 |
+
'event_name' => $event->get_name(),
|
480 |
+
'custom_data' => $event->get_custom_data(),
|
481 |
+
)
|
482 |
+
);
|
483 |
}
|
484 |
|
485 |
|
502 |
}
|
503 |
|
504 |
// if product is variable or grouped, fire the pixel with content_type: product_group
|
505 |
+
if ( $product->is_type( array( 'variable', 'grouped' ) ) ) {
|
506 |
$content_type = 'product_group';
|
507 |
} else {
|
508 |
$content_type = 'product';
|
510 |
|
511 |
$categories = \WC_Facebookcommerce_Utils::get_product_categories( $product->get_id() );
|
512 |
|
513 |
+
$event_data = array(
|
514 |
'event_name' => 'ViewContent',
|
515 |
+
'custom_data' => array(
|
516 |
'content_name' => $product->get_title(),
|
517 |
'content_ids' => wp_json_encode( \WC_Facebookcommerce_Utils::get_fb_content_ids( $product ) ),
|
518 |
'content_type' => $content_type,
|
519 |
'contents' => wp_json_encode(
|
520 |
+
array(
|
521 |
+
array(
|
522 |
'id' => \WC_Facebookcommerce_Utils::get_fb_retailer_id( $product ),
|
523 |
'quantity' => 1,
|
524 |
+
),
|
525 |
+
)
|
526 |
),
|
527 |
'content_category' => $categories['name'],
|
528 |
'value' => $product->get_price(),
|
529 |
'currency' => get_woocommerce_currency(),
|
530 |
+
),
|
531 |
+
'user_data' => $this->pixel->get_user_info(),
|
532 |
+
);
|
533 |
|
534 |
$event = new Event( $event_data );
|
535 |
|
547 |
* @internal
|
548 |
*
|
549 |
* @param string $cart_item_key the cart item key
|
550 |
+
* @param int $product_id the product identifier
|
551 |
+
* @param int $quantity the added product quantity
|
552 |
+
* @param int $variation_id the product variation identifier
|
553 |
*/
|
554 |
public function inject_add_to_cart_event( $cart_item_key, $product_id, $quantity, $variation_id ) {
|
555 |
|
565 |
return;
|
566 |
}
|
567 |
|
568 |
+
$event_data = array(
|
569 |
'event_name' => 'AddToCart',
|
570 |
+
'custom_data' => array(
|
571 |
'content_ids' => $this->get_cart_content_ids(),
|
572 |
'content_name' => $this->get_cart_content_names(),
|
573 |
'content_type' => 'product',
|
574 |
'contents' => $this->get_cart_contents(),
|
575 |
'value' => $this->get_cart_total(),
|
576 |
'currency' => get_woocommerce_currency(),
|
577 |
+
),
|
578 |
+
'user_data' => $this->pixel->get_user_info(),
|
579 |
+
);
|
580 |
|
581 |
$event = new SkyVerge\WooCommerce\Facebook\Events\Event( $event_data );
|
582 |
|
604 |
public function add_filter_for_add_to_cart_fragments() {
|
605 |
|
606 |
if ( 'no' === get_option( 'woocommerce_cart_redirect_after_add' ) ) {
|
607 |
+
add_filter( 'woocommerce_add_to_cart_fragments', array( $this, 'add_add_to_cart_event_fragment' ) );
|
608 |
}
|
609 |
}
|
610 |
|
623 |
|
624 |
if ( $this->is_pixel_enabled() ) {
|
625 |
|
626 |
+
$params = array(
|
627 |
'content_ids' => $this->get_cart_content_ids(),
|
628 |
'content_name' => $this->get_cart_content_names(),
|
629 |
'content_type' => 'product',
|
630 |
'contents' => $this->get_cart_contents(),
|
631 |
'value' => $this->get_cart_total(),
|
632 |
'currency' => get_woocommerce_currency(),
|
633 |
+
);
|
634 |
|
635 |
// send the event ID to prevent duplication
|
636 |
+
if ( ! empty( $event_id = WC()->session->get( 'facebook_for_woocommerce_add_to_cart_event_id' ) ) ) {
|
637 |
|
638 |
$params['event_id'] = $event_id;
|
639 |
}
|
661 |
public function add_filter_for_conditional_add_to_cart_fragment() {
|
662 |
|
663 |
if ( 'no' === get_option( 'woocommerce_cart_redirect_after_add' ) ) {
|
664 |
+
add_filter( 'woocommerce_add_to_cart_fragments', array( $this, 'add_conditional_add_to_cart_event_fragment' ) );
|
665 |
}
|
666 |
}
|
667 |
|
680 |
|
681 |
if ( $this->is_pixel_enabled() ) {
|
682 |
|
683 |
+
$params = array(
|
684 |
'content_ids' => $this->get_cart_content_ids(),
|
685 |
'content_name' => $this->get_cart_content_names(),
|
686 |
'content_type' => 'product',
|
687 |
'contents' => $this->get_cart_contents(),
|
688 |
'value' => $this->get_cart_total(),
|
689 |
'currency' => get_woocommerce_currency(),
|
690 |
+
);
|
691 |
|
692 |
// send the event ID to prevent duplication
|
693 |
+
if ( ! empty( $event_id = WC()->session->get( 'facebook_for_woocommerce_add_to_cart_event_id' ) ) ) {
|
694 |
|
695 |
$params['event_id'] = $event_id;
|
696 |
}
|
723 |
*
|
724 |
* @since 1.10.2
|
725 |
*
|
726 |
+
* @param string $redirect URL redirecting to (usually cart)
|
727 |
* @param null|\WC_Product $product the product just added to the cart
|
728 |
* @return string
|
729 |
*/
|
797 |
}
|
798 |
|
799 |
$event_name = 'InitiateCheckout';
|
800 |
+
$event_data = array(
|
801 |
'event_name' => $event_name,
|
802 |
+
'custom_data' => array(
|
803 |
'num_items' => $this->get_cart_num_items(),
|
804 |
'content_ids' => $this->get_cart_content_ids(),
|
805 |
'content_name' => $this->get_cart_content_names(),
|
807 |
'contents' => $this->get_cart_contents(),
|
808 |
'value' => $this->get_cart_total(),
|
809 |
'currency' => get_woocommerce_currency(),
|
810 |
+
),
|
811 |
+
'user_data' => $this->pixel->get_user_info(),
|
812 |
+
);
|
813 |
|
814 |
// if there is only one item in the cart, send its first category
|
815 |
if ( ( $cart = WC()->cart ) && count( $cart->get_cart() ) === 1 ) {
|
883 |
}
|
884 |
|
885 |
$content_type = 'product';
|
886 |
+
$contents = array();
|
887 |
+
$product_ids = array( array() );
|
888 |
+
$product_names = array();
|
889 |
|
890 |
foreach ( $order->get_items() as $item ) {
|
891 |
|
908 |
}
|
909 |
}
|
910 |
// Advanced matching information is extracted from the order
|
911 |
+
$event_data = array(
|
912 |
'event_name' => $event_name,
|
913 |
+
'custom_data' => array(
|
914 |
'content_ids' => wp_json_encode( array_merge( ... $product_ids ) ),
|
915 |
'content_name' => wp_json_encode( $product_names ),
|
916 |
'contents' => wp_json_encode( $contents ),
|
917 |
'content_type' => $content_type,
|
918 |
'value' => $order->get_total(),
|
919 |
'currency' => get_woocommerce_currency(),
|
920 |
+
),
|
921 |
+
'user_data' => $this->get_user_data_from_billing_address( $order ),
|
922 |
+
);
|
923 |
|
924 |
$event = new Event( $event_data );
|
925 |
|
948 |
*/
|
949 |
public function inject_subscribe_event( $order_id ) {
|
950 |
|
951 |
+
if ( ! function_exists( 'wcs_get_subscriptions_for_order' ) || ! $this->is_pixel_enabled() || $this->pixel->is_last_event( 'Subscribe' ) ) {
|
952 |
return;
|
953 |
}
|
954 |
|
958 |
$event_name = 'Subscribe';
|
959 |
|
960 |
// TODO consider including (int|float) 'predicted_ltv': "Predicted lifetime value of a subscriber as defined by the advertiser and expressed as an exact value." {FN 2020-03-20}
|
961 |
+
$event_data = array(
|
962 |
'event_name' => $event_name,
|
963 |
+
'custom_data' => array(
|
964 |
'sign_up_fee' => $subscription->get_sign_up_fee(),
|
965 |
'value' => $subscription->get_total(),
|
966 |
'currency' => get_woocommerce_currency(),
|
967 |
+
),
|
968 |
+
'user_data' => $this->pixel->get_user_info(),
|
969 |
+
);
|
970 |
|
971 |
$event = new Event( $event_data );
|
972 |
|
1029 |
|
1030 |
try {
|
1031 |
|
1032 |
+
facebook_for_woocommerce()->get_api()->send_pixel_events( facebook_for_woocommerce()->get_integration()->get_facebook_pixel_id(), array( $event ) );
|
1033 |
|
1034 |
$success = true;
|
1035 |
|
1068 |
*/
|
1069 |
private function get_cart_content_ids() {
|
1070 |
|
1071 |
+
$product_ids = array( array() );
|
1072 |
|
1073 |
if ( $cart = WC()->cart ) {
|
1074 |
|
1094 |
*/
|
1095 |
private function get_cart_content_names() {
|
1096 |
|
1097 |
+
$product_names = array();
|
1098 |
|
1099 |
if ( $cart = WC()->cart ) {
|
1100 |
|
1120 |
*/
|
1121 |
private function get_cart_contents() {
|
1122 |
|
1123 |
+
$cart_contents = array();
|
1124 |
|
1125 |
if ( $cart = WC()->cart ) {
|
1126 |
|
1160 |
*
|
1161 |
* @return array
|
1162 |
*/
|
1163 |
+
private function get_user_data_from_billing_address( $order ) {
|
1164 |
+
if ( $this->aam_settings == null || ! $this->aam_settings->get_enable_automatic_matching() ) {
|
1165 |
return array();
|
1166 |
}
|
1167 |
+
$user_data = array();
|
1168 |
$user_data['fn'] = $order->get_billing_first_name();
|
1169 |
$user_data['ln'] = $order->get_billing_last_name();
|
1170 |
$user_data['em'] = $order->get_billing_email();
|
1171 |
// get_user_id() returns 0 if the current user is a guest
|
1172 |
+
$user_data['external_id'] = $order->get_user_id() === 0 ? null : strval( $order->get_user_id() );
|
1173 |
+
$user_data['zp'] = $order->get_billing_postcode();
|
1174 |
+
$user_data['st'] = $order->get_billing_state();
|
1175 |
// We can use country as key because this information is for CAPI events only
|
1176 |
$user_data['country'] = $order->get_billing_country();
|
1177 |
+
$user_data['ct'] = $order->get_billing_city();
|
1178 |
+
$user_data['ph'] = $order->get_billing_phone();
|
1179 |
// The fields contain country, so we do not need to add a condition
|
1180 |
+
foreach ( $user_data as $field => $value ) {
|
1181 |
+
if ( $value === null || $value === '' ||
|
1182 |
+
! in_array( $field, $this->aam_settings->get_enabled_automatic_matching_fields() )
|
1183 |
+
) {
|
1184 |
+
unset( $user_data[ $field ] );
|
1185 |
}
|
1186 |
}
|
1187 |
return $user_data;
|
1192 |
*
|
1193 |
* @return array
|
1194 |
*/
|
1195 |
+
public function get_tracked_events() {
|
1196 |
return $this->tracked_events;
|
1197 |
}
|
1198 |
|
facebook-commerce-messenger-chat.php
CHANGED
@@ -16,9 +16,16 @@ if ( ! class_exists( 'WC_Facebookcommerce_MessengerChat' ) ) :
|
|
16 |
include_once 'includes/fbutils.php';
|
17 |
}
|
18 |
|
|
|
|
|
|
|
19 |
class WC_Facebookcommerce_MessengerChat {
|
20 |
|
21 |
-
|
|
|
|
|
|
|
|
|
22 |
public function __construct( $settings ) {
|
23 |
|
24 |
$this->page_id = isset( $settings['fb_page_id'] )
|
@@ -42,7 +49,8 @@ if ( ! class_exists( 'WC_Facebookcommerce_MessengerChat' ) ) :
|
|
42 |
|
43 |
if ( facebook_for_woocommerce()->get_integration()->is_messenger_enabled() ) :
|
44 |
|
45 |
-
printf(
|
|
|
46 |
<div
|
47 |
attribution=\"fbe_woocommerce\"
|
48 |
class=\"fb-customerchat\"
|
16 |
include_once 'includes/fbutils.php';
|
17 |
}
|
18 |
|
19 |
+
/**
|
20 |
+
* Messenger chat handler class.
|
21 |
+
*/
|
22 |
class WC_Facebookcommerce_MessengerChat {
|
23 |
|
24 |
+
/**
|
25 |
+
* Class constructor.
|
26 |
+
*
|
27 |
+
* @param array $settings FB page settings array.
|
28 |
+
*/
|
29 |
public function __construct( $settings ) {
|
30 |
|
31 |
$this->page_id = isset( $settings['fb_page_id'] )
|
49 |
|
50 |
if ( facebook_for_woocommerce()->get_integration()->is_messenger_enabled() ) :
|
51 |
|
52 |
+
printf(
|
53 |
+
"
|
54 |
<div
|
55 |
attribution=\"fbe_woocommerce\"
|
56 |
class=\"fb-customerchat\"
|
facebook-commerce-pixel-event.php
CHANGED
@@ -16,38 +16,67 @@ if ( ! class_exists( 'WC_Facebookcommerce_Pixel' ) ) :
|
|
16 |
class WC_Facebookcommerce_Pixel {
|
17 |
|
18 |
|
19 |
-
const SETTINGS_KEY
|
20 |
-
const PIXEL_ID_KEY
|
21 |
-
const USE_PII_KEY
|
22 |
-
const USE_S2S_KEY= 'use_s2s';
|
23 |
const ACCESS_TOKEN_KEY = 'access_token';
|
24 |
|
25 |
-
/**
|
26 |
-
|
27 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
28 |
const NO_SCRIPT_RENDER = 'no_script_render';
|
29 |
|
30 |
-
/**
|
31 |
-
|
|
|
|
|
|
|
|
|
32 |
|
|
|
|
|
|
|
|
|
|
|
33 |
private $user_info;
|
34 |
|
|
|
|
|
|
|
|
|
|
|
35 |
private $last_event;
|
36 |
|
37 |
-
|
|
|
|
|
|
|
|
|
38 |
public function __construct( $user_info = array() ) {
|
39 |
|
40 |
$this->user_info = $user_info;
|
41 |
$this->last_event = '';
|
42 |
}
|
43 |
|
|
|
|
|
|
|
44 |
public static function initialize() {
|
45 |
if ( ! is_admin() ) {
|
46 |
return;
|
47 |
}
|
48 |
|
49 |
-
// Initialize PixelID in storage - this will only need to happen when the
|
50 |
-
// user is an admin
|
51 |
$pixel_id = self::get_pixel_id();
|
52 |
if ( ! WC_Facebookcommerce_Utils::is_valid_id( $pixel_id ) &&
|
53 |
class_exists( 'WC_Facebookcommerce_WarmConfig' ) ) {
|
@@ -61,7 +90,7 @@ if ( ! class_exists( 'WC_Facebookcommerce_Pixel' ) ) :
|
|
61 |
}
|
62 |
|
63 |
$is_advanced_matching_enabled = self::get_use_pii_key();
|
64 |
-
if (
|
65 |
class_exists( 'WC_Facebookcommerce_WarmConfig' ) ) {
|
66 |
$fb_warm_is_advanced_matching_enabled =
|
67 |
WC_Facebookcommerce_WarmConfig::$fb_warm_is_advanced_matching_enabled;
|
@@ -89,12 +118,15 @@ if ( ! class_exists( 'WC_Facebookcommerce_Pixel' ) ) :
|
|
89 |
*
|
90 |
* @param string $js_code
|
91 |
*/
|
92 |
-
return apply_filters(
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
|
|
|
|
|
|
98 |
}
|
99 |
|
100 |
|
@@ -107,8 +139,8 @@ if ( ! class_exists( 'WC_Facebookcommerce_Pixel' ) ) :
|
|
107 |
|
108 |
$pixel_id = self::get_pixel_id();
|
109 |
|
110 |
-
//
|
111 |
-
if ( empty( $pixel_id )|| ! empty( self::$render_cache[ self::PIXEL_RENDER ] ) ) {
|
112 |
return '';
|
113 |
}
|
114 |
|
@@ -129,11 +161,11 @@ if ( ! class_exists( 'WC_Facebookcommerce_Pixel' ) ) :
|
|
129 |
|
130 |
<?php echo $this->get_pixel_init_code(); ?>
|
131 |
|
132 |
-
fbq( 'track', 'PageView', <?php echo json_encode( self::build_params(
|
133 |
|
134 |
document.addEventListener( 'DOMContentLoaded', function() {
|
135 |
jQuery && jQuery( function( $ ) {
|
136 |
-
//
|
137 |
$( document.body ).append( '<div class=\"wc-facebook-pixel-event-placeholder\"></div>' );
|
138 |
} );
|
139 |
}, false );
|
@@ -198,11 +230,11 @@ if ( ! class_exists( 'WC_Facebookcommerce_Pixel' ) ) :
|
|
198 |
/**
|
199 |
* Determines if the last event in the current thread matches a given event.
|
200 |
*
|
201 |
-
* TODO remove this deprecated method by March 2020 or version 2.0.0 {FN 2020-03-25}
|
202 |
*
|
203 |
* @deprecated since 1.11.0
|
204 |
*
|
205 |
-
* @param string $event_name
|
206 |
* @return bool
|
207 |
*/
|
208 |
public function check_last_event( $event_name ) {
|
@@ -222,9 +254,9 @@ if ( ! class_exists( 'WC_Facebookcommerce_Pixel' ) ) :
|
|
222 |
*
|
223 |
* @since 1.10.2
|
224 |
*
|
225 |
-
* @param string $event_name
|
226 |
-
* @param array
|
227 |
-
* @param string $method
|
228 |
* @return string
|
229 |
*/
|
230 |
public function get_event_code( $event_name, $params, $method = 'track' ) {
|
@@ -242,9 +274,9 @@ if ( ! class_exists( 'WC_Facebookcommerce_Pixel' ) ) :
|
|
242 |
*
|
243 |
* @since 1.10.2
|
244 |
*
|
245 |
-
* @param string $event_name
|
246 |
-
* @param array
|
247 |
-
* @param string $method
|
248 |
* @return string
|
249 |
*/
|
250 |
public function get_event_script( $event_name, $params, $method = 'track' ) {
|
@@ -265,24 +297,20 @@ if ( ! class_exists( 'WC_Facebookcommerce_Pixel' ) ) :
|
|
265 |
|
266 |
/**
|
267 |
* Prints or enqueues the JavaScript code to track an event.
|
268 |
-
*
|
269 |
* Preferred method to inject events in a page.
|
|
|
270 |
* @see \WC_Facebookcommerce_Pixel::build_event()
|
271 |
*
|
272 |
-
* @param string $event_name
|
273 |
-
* @param array
|
274 |
-
* @param string $method
|
275 |
*/
|
276 |
public function inject_event( $event_name, $params, $method = 'track' ) {
|
277 |
|
278 |
if ( \WC_Facebookcommerce_Utils::isWoocommerceIntegration() ) {
|
279 |
-
|
280 |
\WC_Facebookcommerce_Utils::wc_enqueue_js( $this->get_event_code( $event_name, self::build_params( $params, $event_name ), $method ) );
|
281 |
-
|
282 |
} else {
|
283 |
-
|
284 |
-
// phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped
|
285 |
-
printf( $this->get_event_script( $event_name, self::build_params( $params, $event_name ), $method ) );
|
286 |
}
|
287 |
}
|
288 |
|
@@ -294,10 +322,10 @@ if ( ! class_exists( 'WC_Facebookcommerce_Pixel' ) ) :
|
|
294 |
*
|
295 |
* @since 1.10.2
|
296 |
*
|
297 |
-
* @param string $event_name
|
298 |
-
* @param array
|
299 |
-
* @param string $listener
|
300 |
-
* @param string $jsonified_pii JavaScript code representing an object of data for Advanced Matching
|
301 |
* @return string
|
302 |
*/
|
303 |
public function get_conditional_event_script( $event_name, $params, $listener, $jsonified_pii ) {
|
@@ -305,7 +333,12 @@ if ( ! class_exists( 'WC_Facebookcommerce_Pixel' ) ) :
|
|
305 |
$code = self::build_event( $event_name, $params, 'track' );
|
306 |
$this->last_event = $event_name;
|
307 |
|
308 |
-
/**
|
|
|
|
|
|
|
|
|
|
|
309 |
// Prepends fbq(...) with pii information to the injected code.
|
310 |
if ( $jsonified_pii && get_option( self::SETTINGS_KEY )[ self::USE_PII_KEY ] ) {
|
311 |
$this->user_info = '%s';
|
@@ -333,10 +366,10 @@ if ( ! class_exists( 'WC_Facebookcommerce_Pixel' ) ) :
|
|
333 |
*
|
334 |
* The tracking code will be executed when the given JavaScript event is triggered.
|
335 |
*
|
336 |
-
* @param string $event_name
|
337 |
-
* @param array
|
338 |
-
* @param string $listener
|
339 |
-
* @param string $jsonified_pii JavaScript code representing an object of data for Advanced Matching
|
340 |
* @return string
|
341 |
*/
|
342 |
public function inject_conditional_event( $event_name, $params, $listener, $jsonified_pii = '' ) {
|
@@ -353,9 +386,9 @@ if ( ! class_exists( 'WC_Facebookcommerce_Pixel' ) ) :
|
|
353 |
*
|
354 |
* @since 1.10.2
|
355 |
*
|
356 |
-
* @param string $event_name
|
357 |
-
* @param array
|
358 |
-
* @param string $listened_event
|
359 |
* @return string
|
360 |
*/
|
361 |
public function get_conditional_one_time_event_script( $event_name, $params, $listened_event ) {
|
@@ -369,7 +402,7 @@ if ( ! class_exists( 'WC_Facebookcommerce_Pixel' ) ) :
|
|
369 |
<script <?php echo self::get_script_attributes(); ?>>
|
370 |
function handle<?php echo $event_name; ?>Event() {
|
371 |
<?php echo $code; ?>
|
372 |
-
//
|
373 |
jQuery( document.body ).off( '<?php echo esc_js( $listened_event ); ?>', handle<?php echo $event_name; ?>Event );
|
374 |
}
|
375 |
|
@@ -387,28 +420,31 @@ if ( ! class_exists( 'WC_Facebookcommerce_Pixel' ) ) :
|
|
387 |
*
|
388 |
* @see \WC_Facebookcommerce_Pixel::inject_event() for the preferred method to inject an event.
|
389 |
*
|
390 |
-
* @param string $event_name
|
391 |
-
* @param array
|
392 |
-
* @param string $method
|
393 |
* @return string
|
394 |
*/
|
395 |
public static function build_event( $event_name, $params, $method = 'track' ) {
|
396 |
|
397 |
-
//
|
398 |
if ( isset( $params['event_name'] ) ) {
|
399 |
|
400 |
unset( $params['event_name'] );
|
401 |
}
|
402 |
|
403 |
-
|
404 |
-
|
|
|
|
|
|
|
405 |
if ( isset( $params['event_id'] ) ) {
|
406 |
|
407 |
$event_id = $params['event_id'];
|
408 |
unset( $params['event_id'] );
|
409 |
}
|
410 |
|
411 |
-
//
|
412 |
if ( isset( $params['custom_data'] ) ) {
|
413 |
|
414 |
$params = $params['custom_data'];
|
@@ -417,7 +453,7 @@ if ( ! class_exists( 'WC_Facebookcommerce_Pixel' ) ) :
|
|
417 |
if ( ! empty( $event_id ) ) {
|
418 |
$event = sprintf(
|
419 |
"/* %s Facebook Integration Event Tracking */\n" .
|
420 |
-
"fbq('set', 'agent', '%s', '%s');\n".
|
421 |
"fbq('%s', '%s', %s, %s);",
|
422 |
WC_Facebookcommerce_Utils::getIntegrationName(),
|
423 |
Event::get_platform_identifier(),
|
@@ -425,14 +461,14 @@ if ( ! class_exists( 'WC_Facebookcommerce_Pixel' ) ) :
|
|
425 |
esc_js( $method ),
|
426 |
esc_js( $event_name ),
|
427 |
json_encode( self::build_params( $params, $event_name ), JSON_PRETTY_PRINT | JSON_FORCE_OBJECT ),
|
428 |
-
json_encode(
|
429 |
);
|
430 |
|
431 |
} else {
|
432 |
|
433 |
$event = sprintf(
|
434 |
"/* %s Facebook Integration Event Tracking */\n" .
|
435 |
-
"fbq('set', 'agent', '%s', '%s');\n".
|
436 |
"fbq('%s', '%s', %s);",
|
437 |
WC_Facebookcommerce_Utils::getIntegrationName(),
|
438 |
Event::get_platform_identifier(),
|
@@ -454,11 +490,11 @@ if ( ! class_exists( 'WC_Facebookcommerce_Pixel' ) ) :
|
|
454 |
*
|
455 |
* @since 1.10.2
|
456 |
*
|
457 |
-
* @param array
|
458 |
-
* @param string $event
|
459 |
* @return array
|
460 |
*/
|
461 |
-
private static function build_params( $params =
|
462 |
|
463 |
$params = array_replace( Event::get_version_info(), $params );
|
464 |
|
@@ -467,8 +503,8 @@ if ( ! class_exists( 'WC_Facebookcommerce_Pixel' ) ) :
|
|
467 |
*
|
468 |
* @since 1.10.2
|
469 |
*
|
470 |
-
* @param array $params
|
471 |
-
* @param string $event
|
472 |
*/
|
473 |
return (array) apply_filters( 'wc_facebook_pixel_params', $params, $event );
|
474 |
}
|
@@ -492,7 +528,7 @@ if ( ! class_exists( 'WC_Facebookcommerce_Pixel' ) ) :
|
|
492 |
*
|
493 |
* @param array $custom_attributes
|
494 |
*/
|
495 |
-
$custom_attributes = (array) apply_filters( 'wc_facebook_pixel_script_attributes',
|
496 |
|
497 |
foreach ( $custom_attributes as $tag => $value ) {
|
498 |
$script_attributes .= ' ' . $tag . '="' . esc_attr( $value ) . '"';
|
@@ -501,21 +537,28 @@ if ( ! class_exists( 'WC_Facebookcommerce_Pixel' ) ) :
|
|
501 |
return $script_attributes;
|
502 |
}
|
503 |
|
504 |
-
|
|
|
|
|
505 |
public static function get_pixel_id() {
|
506 |
$fb_options = self::get_options();
|
507 |
if ( ! $fb_options ) {
|
508 |
return '';
|
509 |
}
|
510 |
return isset( $fb_options[ self::PIXEL_ID_KEY ] ) ?
|
511 |
-
|
512 |
}
|
513 |
|
|
|
|
|
|
|
|
|
|
|
514 |
public static function set_pixel_id( $pixel_id ) {
|
515 |
$fb_options = self::get_options();
|
516 |
|
517 |
if ( isset( $fb_options[ self::PIXEL_ID_KEY ] )
|
518 |
-
|
519 |
return;
|
520 |
}
|
521 |
|
@@ -523,20 +566,28 @@ if ( ! class_exists( 'WC_Facebookcommerce_Pixel' ) ) :
|
|
523 |
update_option( self::SETTINGS_KEY, $fb_options );
|
524 |
}
|
525 |
|
|
|
|
|
|
|
526 |
public static function get_use_pii_key() {
|
527 |
$fb_options = self::get_options();
|
528 |
if ( ! $fb_options ) {
|
529 |
return null;
|
530 |
}
|
531 |
return isset( $fb_options[ self::USE_PII_KEY ] ) ?
|
532 |
-
|
533 |
}
|
534 |
|
|
|
|
|
|
|
|
|
|
|
535 |
public static function set_use_pii_key( $use_pii ) {
|
536 |
$fb_options = self::get_options();
|
537 |
|
538 |
if ( isset( $fb_options[ self::USE_PII_KEY ] )
|
539 |
-
|
540 |
return;
|
541 |
}
|
542 |
|
@@ -544,20 +595,28 @@ if ( ! class_exists( 'WC_Facebookcommerce_Pixel' ) ) :
|
|
544 |
update_option( self::SETTINGS_KEY, $fb_options );
|
545 |
}
|
546 |
|
|
|
|
|
|
|
547 |
public static function get_use_s2s() {
|
548 |
$fb_options = self::get_options();
|
549 |
if ( ! $fb_options ) {
|
550 |
return false;
|
551 |
}
|
552 |
return isset( $fb_options[ self::USE_S2S_KEY ] ) ?
|
553 |
-
|
554 |
}
|
555 |
|
|
|
|
|
|
|
|
|
|
|
556 |
public static function set_use_s2s( $use_s2s ) {
|
557 |
$fb_options = self::get_options();
|
558 |
|
559 |
if ( isset( $fb_options[ self::USE_S2S_KEY ] )
|
560 |
-
|
561 |
return;
|
562 |
}
|
563 |
|
@@ -565,20 +624,28 @@ if ( ! class_exists( 'WC_Facebookcommerce_Pixel' ) ) :
|
|
565 |
update_option( self::SETTINGS_KEY, $fb_options );
|
566 |
}
|
567 |
|
|
|
|
|
|
|
568 |
public static function get_access_token() {
|
569 |
$fb_options = self::get_options();
|
570 |
if ( ! $fb_options ) {
|
571 |
return '';
|
572 |
}
|
573 |
return isset( $fb_options[ self::ACCESS_TOKEN_KEY ] ) ?
|
574 |
-
|
575 |
}
|
576 |
|
|
|
|
|
|
|
|
|
|
|
577 |
public static function set_access_token( $access_token ) {
|
578 |
$fb_options = self::get_options();
|
579 |
|
580 |
if ( isset( $fb_options[ self::ACCESS_TOKEN_KEY ] )
|
581 |
-
|
582 |
return;
|
583 |
}
|
584 |
|
@@ -586,6 +653,9 @@ if ( ! class_exists( 'WC_Facebookcommerce_Pixel' ) ) :
|
|
586 |
update_option( self::SETTINGS_KEY, $fb_options );
|
587 |
}
|
588 |
|
|
|
|
|
|
|
589 |
private static function get_version_info() {
|
590 |
global $wp_version;
|
591 |
|
@@ -604,13 +674,16 @@ if ( ! class_exists( 'WC_Facebookcommerce_Pixel' ) ) :
|
|
604 |
);
|
605 |
}
|
606 |
|
|
|
|
|
|
|
607 |
public static function get_options() {
|
608 |
return get_option(
|
609 |
self::SETTINGS_KEY,
|
610 |
array(
|
611 |
-
self::PIXEL_ID_KEY
|
612 |
-
self::USE_PII_KEY
|
613 |
-
self::USE_S2S_KEY
|
614 |
self::ACCESS_TOKEN_KEY => '',
|
615 |
)
|
616 |
);
|
@@ -636,7 +709,7 @@ if ( ! class_exists( 'WC_Facebookcommerce_Pixel' ) ) :
|
|
636 |
*
|
637 |
* @return string[]
|
638 |
*/
|
639 |
-
public function get_user_info(){
|
640 |
return $this->user_info;
|
641 |
}
|
642 |
}
|
16 |
class WC_Facebookcommerce_Pixel {
|
17 |
|
18 |
|
19 |
+
const SETTINGS_KEY = 'facebook_config';
|
20 |
+
const PIXEL_ID_KEY = 'pixel_id';
|
21 |
+
const USE_PII_KEY = 'use_pii';
|
22 |
+
const USE_S2S_KEY = 'use_s2s';
|
23 |
const ACCESS_TOKEN_KEY = 'access_token';
|
24 |
|
25 |
+
/**
|
26 |
+
* Cache key for pixel script block output.
|
27 |
+
*
|
28 |
+
* @var string cache key.
|
29 |
+
* */
|
30 |
+
const PIXEL_RENDER = 'pixel_render';
|
31 |
+
|
32 |
+
/**
|
33 |
+
* Cache key for pixel noscript block output.
|
34 |
+
*
|
35 |
+
* @var string cache key.
|
36 |
+
* */
|
37 |
const NO_SCRIPT_RENDER = 'no_script_render';
|
38 |
|
39 |
+
/**
|
40 |
+
* Script render memoization helper.
|
41 |
+
*
|
42 |
+
* @var array Cache array.
|
43 |
+
*/
|
44 |
+
public static $render_cache = array();
|
45 |
|
46 |
+
/**
|
47 |
+
* User information.
|
48 |
+
*
|
49 |
+
* @var array Information array.
|
50 |
+
*/
|
51 |
private $user_info;
|
52 |
|
53 |
+
/**
|
54 |
+
* The name of the last event.
|
55 |
+
*
|
56 |
+
* @var string Event name.
|
57 |
+
*/
|
58 |
private $last_event;
|
59 |
|
60 |
+
/**
|
61 |
+
* Class constructor.
|
62 |
+
*
|
63 |
+
* @param array $user_info User information array.
|
64 |
+
*/
|
65 |
public function __construct( $user_info = array() ) {
|
66 |
|
67 |
$this->user_info = $user_info;
|
68 |
$this->last_event = '';
|
69 |
}
|
70 |
|
71 |
+
/**
|
72 |
+
* Initialize pixelID.
|
73 |
+
*/
|
74 |
public static function initialize() {
|
75 |
if ( ! is_admin() ) {
|
76 |
return;
|
77 |
}
|
78 |
|
79 |
+
// Initialize PixelID in storage - this will only need to happen when the user is an admin.
|
|
|
80 |
$pixel_id = self::get_pixel_id();
|
81 |
if ( ! WC_Facebookcommerce_Utils::is_valid_id( $pixel_id ) &&
|
82 |
class_exists( 'WC_Facebookcommerce_WarmConfig' ) ) {
|
90 |
}
|
91 |
|
92 |
$is_advanced_matching_enabled = self::get_use_pii_key();
|
93 |
+
if ( null == $is_advanced_matching_enabled &&
|
94 |
class_exists( 'WC_Facebookcommerce_WarmConfig' ) ) {
|
95 |
$fb_warm_is_advanced_matching_enabled =
|
96 |
WC_Facebookcommerce_WarmConfig::$fb_warm_is_advanced_matching_enabled;
|
118 |
*
|
119 |
* @param string $js_code
|
120 |
*/
|
121 |
+
return apply_filters(
|
122 |
+
'facebook_woocommerce_pixel_init',
|
123 |
+
sprintf(
|
124 |
+
"fbq('init', '%s', %s, %s);\n",
|
125 |
+
esc_js( self::get_pixel_id() ),
|
126 |
+
json_encode( $this->user_info, JSON_PRETTY_PRINT | JSON_FORCE_OBJECT ),
|
127 |
+
json_encode( array( 'agent' => $agent_string ), JSON_PRETTY_PRINT | JSON_FORCE_OBJECT )
|
128 |
+
)
|
129 |
+
);
|
130 |
}
|
131 |
|
132 |
|
139 |
|
140 |
$pixel_id = self::get_pixel_id();
|
141 |
|
142 |
+
// Bail if no ID or already rendered.
|
143 |
+
if ( empty( $pixel_id ) || ! empty( self::$render_cache[ self::PIXEL_RENDER ] ) ) {
|
144 |
return '';
|
145 |
}
|
146 |
|
161 |
|
162 |
<?php echo $this->get_pixel_init_code(); ?>
|
163 |
|
164 |
+
fbq( 'track', 'PageView', <?php echo json_encode( self::build_params( array(), 'PageView' ), JSON_PRETTY_PRINT | JSON_FORCE_OBJECT ); ?> );
|
165 |
|
166 |
document.addEventListener( 'DOMContentLoaded', function() {
|
167 |
jQuery && jQuery( function( $ ) {
|
168 |
+
// Insert placeholder for events injected when a product is added to the cart through AJAX.
|
169 |
$( document.body ).append( '<div class=\"wc-facebook-pixel-event-placeholder\"></div>' );
|
170 |
} );
|
171 |
}, false );
|
230 |
/**
|
231 |
* Determines if the last event in the current thread matches a given event.
|
232 |
*
|
233 |
+
* TODO remove this deprecated method by March 2020 or version 2.0.0 {FN 2020-03-25}.
|
234 |
*
|
235 |
* @deprecated since 1.11.0
|
236 |
*
|
237 |
+
* @param string $event_name Name of the event.
|
238 |
* @return bool
|
239 |
*/
|
240 |
public function check_last_event( $event_name ) {
|
254 |
*
|
255 |
* @since 1.10.2
|
256 |
*
|
257 |
+
* @param string $event_name The name of the event to track.
|
258 |
+
* @param array $params Custom event parameters.
|
259 |
+
* @param string $method Name of the pixel's fbq() function to call.
|
260 |
* @return string
|
261 |
*/
|
262 |
public function get_event_code( $event_name, $params, $method = 'track' ) {
|
274 |
*
|
275 |
* @since 1.10.2
|
276 |
*
|
277 |
+
* @param string $event_name The name of the event to track.
|
278 |
+
* @param array $params Custom event parameters.
|
279 |
+
* @param string $method Name of the pixel's fbq() function to call.
|
280 |
* @return string
|
281 |
*/
|
282 |
public function get_event_script( $event_name, $params, $method = 'track' ) {
|
297 |
|
298 |
/**
|
299 |
* Prints or enqueues the JavaScript code to track an event.
|
|
|
300 |
* Preferred method to inject events in a page.
|
301 |
+
*
|
302 |
* @see \WC_Facebookcommerce_Pixel::build_event()
|
303 |
*
|
304 |
+
* @param string $event_name The name of the event to track.
|
305 |
+
* @param array $params Custom event parameters.
|
306 |
+
* @param string $method Name of the pixel's fbq() function to call.
|
307 |
*/
|
308 |
public function inject_event( $event_name, $params, $method = 'track' ) {
|
309 |
|
310 |
if ( \WC_Facebookcommerce_Utils::isWoocommerceIntegration() ) {
|
|
|
311 |
\WC_Facebookcommerce_Utils::wc_enqueue_js( $this->get_event_code( $event_name, self::build_params( $params, $event_name ), $method ) );
|
|
|
312 |
} else {
|
313 |
+
printf( $this->get_event_script( $event_name, self::build_params( $params, $event_name ), $method ) ); // phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped
|
|
|
|
|
314 |
}
|
315 |
}
|
316 |
|
322 |
*
|
323 |
* @since 1.10.2
|
324 |
*
|
325 |
+
* @param string $event_name The name of the event to track.
|
326 |
+
* @param array $params Custom event parameters.
|
327 |
+
* @param string $listener Name of the JavaScript event to listen for.
|
328 |
+
* @param string $jsonified_pii JavaScript code representing an object of data for Advanced Matching.
|
329 |
* @return string
|
330 |
*/
|
331 |
public function get_conditional_event_script( $event_name, $params, $listener, $jsonified_pii ) {
|
333 |
$code = self::build_event( $event_name, $params, 'track' );
|
334 |
$this->last_event = $event_name;
|
335 |
|
336 |
+
/**
|
337 |
+
* TODO: use the settings stored by {@see \WC_Facebookcommerce_Integration}.
|
338 |
+
* The use_pii setting here is currently always disabled regardless of
|
339 |
+
* the value configured in the plugin settings page {WV-2020-01-02}.
|
340 |
+
*/
|
341 |
+
|
342 |
// Prepends fbq(...) with pii information to the injected code.
|
343 |
if ( $jsonified_pii && get_option( self::SETTINGS_KEY )[ self::USE_PII_KEY ] ) {
|
344 |
$this->user_info = '%s';
|
366 |
*
|
367 |
* The tracking code will be executed when the given JavaScript event is triggered.
|
368 |
*
|
369 |
+
* @param string $event_name Name of the event.
|
370 |
+
* @param array $params Custom event parameters.
|
371 |
+
* @param string $listener Name of the JavaScript event to listen for.
|
372 |
+
* @param string $jsonified_pii JavaScript code representing an object of data for Advanced Matching.
|
373 |
* @return string
|
374 |
*/
|
375 |
public function inject_conditional_event( $event_name, $params, $listener, $jsonified_pii = '' ) {
|
386 |
*
|
387 |
* @since 1.10.2
|
388 |
*
|
389 |
+
* @param string $event_name The name of the event to track.
|
390 |
+
* @param array $params Custom event parameters.
|
391 |
+
* @param string $listened_event Name of the JavaScript event to listen for.
|
392 |
* @return string
|
393 |
*/
|
394 |
public function get_conditional_one_time_event_script( $event_name, $params, $listened_event ) {
|
402 |
<script <?php echo self::get_script_attributes(); ?>>
|
403 |
function handle<?php echo $event_name; ?>Event() {
|
404 |
<?php echo $code; ?>
|
405 |
+
// Some weird themes (hi, Basel) are running this script twice, so two listeners are added and we need to remove them after running one.
|
406 |
jQuery( document.body ).off( '<?php echo esc_js( $listened_event ); ?>', handle<?php echo $event_name; ?>Event );
|
407 |
}
|
408 |
|
420 |
*
|
421 |
* @see \WC_Facebookcommerce_Pixel::inject_event() for the preferred method to inject an event.
|
422 |
*
|
423 |
+
* @param string $event_name Event name.
|
424 |
+
* @param array $params Event params.
|
425 |
+
* @param string $method Optional, defaults to 'track'.
|
426 |
* @return string
|
427 |
*/
|
428 |
public static function build_event( $event_name, $params, $method = 'track' ) {
|
429 |
|
430 |
+
// Do not send the event name in the params.
|
431 |
if ( isset( $params['event_name'] ) ) {
|
432 |
|
433 |
unset( $params['event_name'] );
|
434 |
}
|
435 |
|
436 |
+
/**
|
437 |
+
* If possible, send the event ID to avoid duplication.
|
438 |
+
*
|
439 |
+
* @see https://developers.facebook.com/docs/marketing-api/server-side-api/deduplicate-pixel-and-server-side-events#deduplication-best-practices
|
440 |
+
*/
|
441 |
if ( isset( $params['event_id'] ) ) {
|
442 |
|
443 |
$event_id = $params['event_id'];
|
444 |
unset( $params['event_id'] );
|
445 |
}
|
446 |
|
447 |
+
// If custom data is set, send only the custom data.
|
448 |
if ( isset( $params['custom_data'] ) ) {
|
449 |
|
450 |
$params = $params['custom_data'];
|
453 |
if ( ! empty( $event_id ) ) {
|
454 |
$event = sprintf(
|
455 |
"/* %s Facebook Integration Event Tracking */\n" .
|
456 |
+
"fbq('set', 'agent', '%s', '%s');\n" .
|
457 |
"fbq('%s', '%s', %s, %s);",
|
458 |
WC_Facebookcommerce_Utils::getIntegrationName(),
|
459 |
Event::get_platform_identifier(),
|
461 |
esc_js( $method ),
|
462 |
esc_js( $event_name ),
|
463 |
json_encode( self::build_params( $params, $event_name ), JSON_PRETTY_PRINT | JSON_FORCE_OBJECT ),
|
464 |
+
json_encode( array( 'eventID' => $event_id ), JSON_PRETTY_PRINT | JSON_FORCE_OBJECT )
|
465 |
);
|
466 |
|
467 |
} else {
|
468 |
|
469 |
$event = sprintf(
|
470 |
"/* %s Facebook Integration Event Tracking */\n" .
|
471 |
+
"fbq('set', 'agent', '%s', '%s');\n" .
|
472 |
"fbq('%s', '%s', %s);",
|
473 |
WC_Facebookcommerce_Utils::getIntegrationName(),
|
474 |
Event::get_platform_identifier(),
|
490 |
*
|
491 |
* @since 1.10.2
|
492 |
*
|
493 |
+
* @param array $params User defined parameters.
|
494 |
+
* @param string $event The event name the params are for.
|
495 |
* @return array
|
496 |
*/
|
497 |
+
private static function build_params( $params = array(), $event = '' ) {
|
498 |
|
499 |
$params = array_replace( Event::get_version_info(), $params );
|
500 |
|
503 |
*
|
504 |
* @since 1.10.2
|
505 |
*
|
506 |
+
* @param array $params User defined parameters.
|
507 |
+
* @param string $event The event name.
|
508 |
*/
|
509 |
return (array) apply_filters( 'wc_facebook_pixel_params', $params, $event );
|
510 |
}
|
528 |
*
|
529 |
* @param array $custom_attributes
|
530 |
*/
|
531 |
+
$custom_attributes = (array) apply_filters( 'wc_facebook_pixel_script_attributes', array( 'type' => 'text/javascript' ) );
|
532 |
|
533 |
foreach ( $custom_attributes as $tag => $value ) {
|
534 |
$script_attributes .= ' ' . $tag . '="' . esc_attr( $value ) . '"';
|
537 |
return $script_attributes;
|
538 |
}
|
539 |
|
540 |
+
/**
|
541 |
+
* Get the PixelId.
|
542 |
+
*/
|
543 |
public static function get_pixel_id() {
|
544 |
$fb_options = self::get_options();
|
545 |
if ( ! $fb_options ) {
|
546 |
return '';
|
547 |
}
|
548 |
return isset( $fb_options[ self::PIXEL_ID_KEY ] ) ?
|
549 |
+
$fb_options[ self::PIXEL_ID_KEY ] : '';
|
550 |
}
|
551 |
|
552 |
+
/**
|
553 |
+
* Set the PixelId.
|
554 |
+
*
|
555 |
+
* @param string $pixel_id PixelId.
|
556 |
+
*/
|
557 |
public static function set_pixel_id( $pixel_id ) {
|
558 |
$fb_options = self::get_options();
|
559 |
|
560 |
if ( isset( $fb_options[ self::PIXEL_ID_KEY ] )
|
561 |
+
&& $fb_options[ self::PIXEL_ID_KEY ] == $pixel_id ) {
|
562 |
return;
|
563 |
}
|
564 |
|
566 |
update_option( self::SETTINGS_KEY, $fb_options );
|
567 |
}
|
568 |
|
569 |
+
/**
|
570 |
+
* Check if PII key use is enabled.
|
571 |
+
*/
|
572 |
public static function get_use_pii_key() {
|
573 |
$fb_options = self::get_options();
|
574 |
if ( ! $fb_options ) {
|
575 |
return null;
|
576 |
}
|
577 |
return isset( $fb_options[ self::USE_PII_KEY ] ) ?
|
578 |
+
$fb_options[ self::USE_PII_KEY ] : null;
|
579 |
}
|
580 |
|
581 |
+
/**
|
582 |
+
* Enable or disable use of PII key.
|
583 |
+
*
|
584 |
+
* @param string $use_pii PII key.
|
585 |
+
*/
|
586 |
public static function set_use_pii_key( $use_pii ) {
|
587 |
$fb_options = self::get_options();
|
588 |
|
589 |
if ( isset( $fb_options[ self::USE_PII_KEY ] )
|
590 |
+
&& $fb_options[ self::USE_PII_KEY ] == $use_pii ) {
|
591 |
return;
|
592 |
}
|
593 |
|
595 |
update_option( self::SETTINGS_KEY, $fb_options );
|
596 |
}
|
597 |
|
598 |
+
/**
|
599 |
+
* Check if S2S is set.
|
600 |
+
*/
|
601 |
public static function get_use_s2s() {
|
602 |
$fb_options = self::get_options();
|
603 |
if ( ! $fb_options ) {
|
604 |
return false;
|
605 |
}
|
606 |
return isset( $fb_options[ self::USE_S2S_KEY ] ) ?
|
607 |
+
$fb_options[ self::USE_S2S_KEY ] : false;
|
608 |
}
|
609 |
|
610 |
+
/**
|
611 |
+
* Enable or disable use of S2S key.
|
612 |
+
*
|
613 |
+
* @param string $use_s2s S2S setting.
|
614 |
+
*/
|
615 |
public static function set_use_s2s( $use_s2s ) {
|
616 |
$fb_options = self::get_options();
|
617 |
|
618 |
if ( isset( $fb_options[ self::USE_S2S_KEY ] )
|
619 |
+
&& $fb_options[ self::USE_S2S_KEY ] == $use_s2s ) {
|
620 |
return;
|
621 |
}
|
622 |
|
624 |
update_option( self::SETTINGS_KEY, $fb_options );
|
625 |
}
|
626 |
|
627 |
+
/**
|
628 |
+
* Get access token.
|
629 |
+
*/
|
630 |
public static function get_access_token() {
|
631 |
$fb_options = self::get_options();
|
632 |
if ( ! $fb_options ) {
|
633 |
return '';
|
634 |
}
|
635 |
return isset( $fb_options[ self::ACCESS_TOKEN_KEY ] ) ?
|
636 |
+
$fb_options[ self::ACCESS_TOKEN_KEY ] : '';
|
637 |
}
|
638 |
|
639 |
+
/**
|
640 |
+
* Set access token.
|
641 |
+
*
|
642 |
+
* @param string $access_token Access token.
|
643 |
+
*/
|
644 |
public static function set_access_token( $access_token ) {
|
645 |
$fb_options = self::get_options();
|
646 |
|
647 |
if ( isset( $fb_options[ self::ACCESS_TOKEN_KEY ] )
|
648 |
+
&& $fb_options[ self::ACCESS_TOKEN_KEY ] == $access_token ) {
|
649 |
return;
|
650 |
}
|
651 |
|
653 |
update_option( self::SETTINGS_KEY, $fb_options );
|
654 |
}
|
655 |
|
656 |
+
/**
|
657 |
+
* Get WooCommerce/Wordpress information.
|
658 |
+
*/
|
659 |
private static function get_version_info() {
|
660 |
global $wp_version;
|
661 |
|
674 |
);
|
675 |
}
|
676 |
|
677 |
+
/**
|
678 |
+
* Get PixelID related settings.
|
679 |
+
*/
|
680 |
public static function get_options() {
|
681 |
return get_option(
|
682 |
self::SETTINGS_KEY,
|
683 |
array(
|
684 |
+
self::PIXEL_ID_KEY => '0',
|
685 |
+
self::USE_PII_KEY => 0,
|
686 |
+
self::USE_S2S_KEY => false,
|
687 |
self::ACCESS_TOKEN_KEY => '',
|
688 |
)
|
689 |
);
|
709 |
*
|
710 |
* @return string[]
|
711 |
*/
|
712 |
+
public function get_user_info() {
|
713 |
return $this->user_info;
|
714 |
}
|
715 |
}
|
facebook-commerce.php
CHANGED
@@ -27,7 +27,9 @@ class WC_Facebookcommerce_Integration extends WC_Integration {
|
|
27 |
|
28 |
|
29 |
/**
|
30 |
-
*
|
|
|
|
|
31 |
* @deprecated 2.1.0
|
32 |
*/
|
33 |
const OPTION_PAGE_ACCESS_TOKEN = 'wc_facebook_page_access_token';
|
@@ -38,6 +40,9 @@ class WC_Facebookcommerce_Integration extends WC_Integration {
|
|
38 |
/** @var string the WordPress option name where the external merchant settings ID is stored */
|
39 |
const OPTION_EXTERNAL_MERCHANT_SETTINGS_ID = 'wc_facebook_external_merchant_settings_id';
|
40 |
|
|
|
|
|
|
|
41 |
/** @var string the WordPress option name where the feed ID is stored */
|
42 |
const OPTION_FEED_ID = 'wc_facebook_feed_id';
|
43 |
|
@@ -136,7 +141,7 @@ class WC_Facebookcommerce_Integration extends WC_Integration {
|
|
136 |
/** Legacy properties *********************************************************************************************/
|
137 |
|
138 |
|
139 |
-
// TODO probably some of these meta keys need to be moved to Facebook\Products {FN 2020-01-13}
|
140 |
const FB_PRODUCT_GROUP_ID = 'fb_product_group_id';
|
141 |
const FB_PRODUCT_ITEM_ID = 'fb_product_item_id';
|
142 |
const FB_PRODUCT_DESCRIPTION = 'fb_product_description';
|
@@ -155,7 +160,7 @@ class WC_Facebookcommerce_Integration extends WC_Integration {
|
|
155 |
// Number of days to query tip.
|
156 |
const FB_TIP_QUERY = 1;
|
157 |
|
158 |
-
// TODO: this constant is no longer used and can probably be removed {WV 2020-01-21}
|
159 |
const FB_VARIANT_IMAGE = 'fb_image';
|
160 |
|
161 |
const FB_ADMIN_MESSAGE_PREPEND = '<b>Facebook for WooCommerce</b><br/>';
|
@@ -171,9 +176,11 @@ class WC_Facebookcommerce_Integration extends WC_Integration {
|
|
171 |
public function init_pixel() {
|
172 |
WC_Facebookcommerce_Pixel::initialize();
|
173 |
|
174 |
-
|
175 |
-
|
176 |
-
|
|
|
|
|
177 |
if ( is_admin() ) {
|
178 |
|
179 |
$pixel_id = WC_Facebookcommerce_Pixel::get_pixel_id();
|
@@ -188,8 +195,10 @@ class WC_Facebookcommerce_Integration extends WC_Integration {
|
|
188 |
WC_Facebookcommerce_Pixel::set_pixel_id( $settings_pixel_id );
|
189 |
}
|
190 |
|
191 |
-
|
192 |
-
|
|
|
|
|
193 |
$settings_advanced_matching_enabled = $this->is_advanced_matching_enabled();
|
194 |
WC_Facebookcommerce_Pixel::set_use_pii_key( $settings_advanced_matching_enabled );
|
195 |
|
@@ -197,14 +206,13 @@ class WC_Facebookcommerce_Integration extends WC_Integration {
|
|
197 |
WC_Facebookcommerce_Pixel::set_use_s2s( $settings_use_s2s );
|
198 |
|
199 |
$settings_access_token = $this->get_access_token();
|
200 |
-
WC_Facebookcommerce_Pixel::set_access_token($settings_access_token);
|
201 |
}
|
202 |
}
|
203 |
|
204 |
/**
|
205 |
* Init and hook in the integration.
|
206 |
*
|
207 |
-
* @access public
|
208 |
* @return void
|
209 |
*/
|
210 |
public function __construct() {
|
@@ -215,11 +223,11 @@ class WC_Facebookcommerce_Integration extends WC_Integration {
|
|
215 |
$this->id = WC_Facebookcommerce::INTEGRATION_ID;
|
216 |
$this->method_title = __(
|
217 |
'Facebook for WooCommerce',
|
218 |
-
'facebook-for-
|
219 |
);
|
220 |
$this->method_description = __(
|
221 |
'Facebook Commerce and Dynamic Ads (Pixel) Extension',
|
222 |
-
'facebook-for-
|
223 |
);
|
224 |
|
225 |
// Load the settings.
|
@@ -227,25 +235,24 @@ class WC_Facebookcommerce_Integration extends WC_Integration {
|
|
227 |
|
228 |
$pixel_id = WC_Facebookcommerce_Pixel::get_pixel_id();
|
229 |
|
230 |
-
//
|
231 |
if ( $pixel_id && ! $this->get_facebook_pixel_id() ) {
|
232 |
$this->settings[ self::SETTING_FACEBOOK_PIXEL_ID ] = $pixel_id;
|
233 |
}
|
234 |
|
235 |
$advanced_matching_enabled = WC_Facebookcommerce_Pixel::get_use_pii_key();
|
236 |
|
237 |
-
//
|
238 |
-
// inherit the pixel option
|
239 |
if ( $advanced_matching_enabled && ! $this->is_advanced_matching_enabled() ) {
|
240 |
$this->settings[ self::SETTING_ENABLE_ADVANCED_MATCHING ] = $advanced_matching_enabled;
|
241 |
}
|
242 |
|
243 |
-
//For now, the values of use s2s and access token will be the ones returned from WC_Facebookcommerce_Pixel
|
244 |
-
$use_s2s
|
245 |
-
$this->settings[self::SETTING_USE_S2S] = $use_s2s;
|
246 |
|
247 |
-
$access_token
|
248 |
-
$this->settings[self::SETTING_ACCESS_TOKEN] = $access_token;
|
249 |
|
250 |
if ( ! class_exists( 'WC_Facebookcommerce_Utils' ) ) {
|
251 |
include_once 'includes/fbutils.php';
|
@@ -260,7 +267,6 @@ class WC_Facebookcommerce_Integration extends WC_Integration {
|
|
260 |
|
261 |
WC_Facebookcommerce_Utils::$fbgraph = $this->fbgraph;
|
262 |
|
263 |
-
// Hooks
|
264 |
if ( is_admin() ) {
|
265 |
|
266 |
$this->init_pixel();
|
@@ -340,30 +346,26 @@ class WC_Facebookcommerce_Integration extends WC_Integration {
|
|
340 |
self::FB_PRIORITY_MID
|
341 |
);
|
342 |
|
343 |
-
//
|
344 |
-
add_filter( 'woocommerce_duplicate_product_exclude_meta',
|
345 |
|
346 |
-
//
|
347 |
if ( $this->is_configured() && $this->get_product_catalog_id() ) {
|
348 |
|
349 |
-
//
|
350 |
-
add_action( 'woocommerce_process_product_meta',
|
351 |
|
352 |
add_action(
|
353 |
'woocommerce_product_quick_edit_save',
|
354 |
-
array( $this, 'on_quick_and_bulk_edit_save' )
|
355 |
-
10, // Action priority
|
356 |
-
1 // Args passed to on_quick_and_bulk_edit_save ('product')
|
357 |
);
|
358 |
|
359 |
add_action(
|
360 |
'woocommerce_product_bulk_edit_save',
|
361 |
-
array( $this, 'on_quick_and_bulk_edit_save' )
|
362 |
-
10, // Action priority
|
363 |
-
1 // Args passed to on_quick_and_bulk_edit_save ('product')
|
364 |
);
|
365 |
|
366 |
-
add_action( 'before_delete_post',
|
367 |
|
368 |
add_action( 'add_meta_boxes', array( $this, 'fb_product_metabox' ), 10, 1 );
|
369 |
|
@@ -396,13 +398,12 @@ class WC_Facebookcommerce_Integration extends WC_Integration {
|
|
396 |
|
397 |
add_action(
|
398 |
'wp_ajax_wpmelon_adv_bulk_edit',
|
399 |
-
|
400 |
self::FB_PRIORITY_MID
|
401 |
);
|
402 |
|
403 |
-
//
|
404 |
-
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
405 |
-
if ( isset( $_GET['remove_sticky'] ) ) {
|
406 |
$this->remove_sticky_message();
|
407 |
}
|
408 |
}
|
@@ -411,24 +412,26 @@ class WC_Facebookcommerce_Integration extends WC_Integration {
|
|
411 |
}
|
412 |
|
413 |
// Must be outside of admin for cron to schedule correctly.
|
414 |
-
add_action( 'sync_all_fb_products_using_feed',
|
415 |
|
416 |
-
//
|
417 |
-
add_action( 'wc_facebook_generate_product_catalog_feed',
|
418 |
|
419 |
if ( $this->get_facebook_pixel_id() ) {
|
420 |
-
$aam_settings
|
421 |
$user_info = WC_Facebookcommerce_Utils::get_user_info( $aam_settings );
|
422 |
$this->events_tracker = new WC_Facebookcommerce_EventsTracker( $user_info, $aam_settings );
|
423 |
}
|
424 |
|
425 |
-
//
|
426 |
-
$this->messenger_chat = new WC_Facebookcommerce_MessengerChat(
|
427 |
-
|
428 |
-
|
429 |
-
|
|
|
|
|
430 |
|
431 |
-
// Product Set hooks
|
432 |
add_action( 'fb_wc_product_set_sync', array( $this, 'create_or_update_product_set_item' ), 99, 2 );
|
433 |
add_action( 'fb_wc_product_set_delete', array( $this, 'delete_product_set_item' ), 99 );
|
434 |
}
|
@@ -442,41 +445,40 @@ class WC_Facebookcommerce_Integration extends WC_Integration {
|
|
442 |
*/
|
443 |
private function load_aam_settings_of_pixel() {
|
444 |
$installed_pixel = $this->get_facebook_pixel_id();
|
445 |
-
// If no pixel is installed, reading the DB is not needed
|
446 |
-
if(
|
447 |
return null;
|
448 |
}
|
449 |
-
$config_key
|
450 |
-
$saved_value
|
451 |
-
$refresh_interval = 20*MINUTE_IN_SECONDS;
|
452 |
-
$aam_settings
|
453 |
-
// If wc_facebook_aam_settings is present in the DB
|
454 |
-
|
455 |
-
|
456 |
-
$cached_aam_settings = new AAMSettings(json_decode($saved_value, true));
|
457 |
// This condition is added because
|
458 |
// it is possible that the AAMSettings saved do not belong to the current
|
459 |
// installed pixel
|
460 |
// because the admin could have changed the connection to Facebook
|
461 |
-
// during the refresh interval
|
462 |
-
if($cached_aam_settings->get_pixel_id() == $installed_pixel){
|
463 |
$aam_settings = $cached_aam_settings;
|
464 |
}
|
465 |
}
|
466 |
// If the settings are not present or invalid
|
467 |
// they are fetched from Facebook domain
|
468 |
-
// and cached in WP database if they are not null
|
469 |
-
if(
|
470 |
$aam_settings = AAMSettings::build_from_pixel_id( $installed_pixel );
|
471 |
-
if($aam_settings){
|
472 |
-
set_transient($config_key, strval($aam_settings), $refresh_interval);
|
473 |
}
|
474 |
}
|
475 |
return $aam_settings;
|
476 |
}
|
477 |
|
478 |
public function load_background_sync_process() {
|
479 |
-
// Attempt to load background processing (Woo 3.x.x only)
|
480 |
include_once 'includes/fbbackground.php';
|
481 |
if ( class_exists( 'WC_Facebookcommerce_Background_Process' ) ) {
|
482 |
if ( ! isset( $this->background_processor ) ) {
|
@@ -534,7 +536,7 @@ class WC_Facebookcommerce_Integration extends WC_Integration {
|
|
534 |
* @internal
|
535 |
* @deprecated since 1.10.0
|
536 |
*
|
537 |
-
* @param array $tabs
|
538 |
* @return array
|
539 |
*/
|
540 |
public function fb_new_product_tab( $tabs ) {
|
@@ -563,7 +565,7 @@ class WC_Facebookcommerce_Integration extends WC_Integration {
|
|
563 |
* @internal
|
564 |
* @deprecated since 1.10.0
|
565 |
*
|
566 |
-
* @param array $existing_columns
|
567 |
* @return array
|
568 |
*/
|
569 |
public function fb_product_columns( $existing_columns ) {
|
@@ -580,7 +582,7 @@ class WC_Facebookcommerce_Integration extends WC_Integration {
|
|
580 |
* @internal
|
581 |
* @deprecated since 1.10.0
|
582 |
*
|
583 |
-
* @param string $column
|
584 |
*/
|
585 |
public function fb_render_product_columns( $column ) {
|
586 |
|
@@ -594,11 +596,8 @@ class WC_Facebookcommerce_Integration extends WC_Integration {
|
|
594 |
);
|
595 |
wp_enqueue_script(
|
596 |
'wc_facebook_metabox_jsx',
|
597 |
-
|
598 |
-
|
599 |
-
__FILE__
|
600 |
-
),
|
601 |
-
[],
|
602 |
\WC_Facebookcommerce::PLUGIN_VERSION
|
603 |
);
|
604 |
wp_localize_script(
|
@@ -639,7 +638,7 @@ class WC_Facebookcommerce_Integration extends WC_Integration {
|
|
639 |
?>
|
640 |
|
641 |
<?php echo esc_html__( 'Facebook ID:', 'facebook-for-woocommerce' ); ?> <a href="https://facebook.com/<?php echo esc_attr( $fb_product_group_id ); ?>"
|
642 |
-
|
643 |
|
644 |
<?php if ( WC_Facebookcommerce_Utils::is_variable_type( $woo_product->get_type() ) ) : ?>
|
645 |
|
@@ -651,7 +650,7 @@ class WC_Facebookcommerce_Integration extends WC_Integration {
|
|
651 |
<?php foreach ( $product_item_ids_by_variation_id as $variation_id => $product_item_id ) : ?>
|
652 |
|
653 |
<?php echo esc_html( $variation_id ); ?>: <a href="https://facebook.com/<?php echo esc_attr( $product_item_id ); ?>"
|
654 |
-
|
655 |
|
656 |
<?php endforeach; ?>
|
657 |
</p>
|
@@ -697,8 +696,8 @@ class WC_Facebookcommerce_Integration extends WC_Integration {
|
|
697 |
*/
|
698 |
private function get_variation_product_item_ids( $product, $product_group_id ) {
|
699 |
|
700 |
-
$product_item_ids_by_variation_id =
|
701 |
-
$missing_product_item_ids =
|
702 |
|
703 |
// get the product item IDs from meta data and build a list of variations that don't have a product item ID stored
|
704 |
foreach ( $product->get_children() as $variation_id ) {
|
@@ -751,7 +750,7 @@ class WC_Facebookcommerce_Integration extends WC_Integration {
|
|
751 |
*/
|
752 |
private function find_variation_product_item_ids( $product_group_id ) {
|
753 |
|
754 |
-
$product_item_ids =
|
755 |
|
756 |
try {
|
757 |
|
@@ -761,7 +760,7 @@ class WC_Facebookcommerce_Integration extends WC_Integration {
|
|
761 |
|
762 |
$product_item_ids = array_merge( $product_item_ids, $response->get_ids() );
|
763 |
|
764 |
-
|
765 |
} while ( $response = facebook_for_woocommerce()->get_api()->next( $response, 2 ) );
|
766 |
|
767 |
} catch ( Framework\SV_WC_API_Exception $e ) {
|
@@ -782,12 +781,12 @@ class WC_Facebookcommerce_Integration extends WC_Integration {
|
|
782 |
*/
|
783 |
public function get_product_count() {
|
784 |
|
785 |
-
$args
|
786 |
'post_type' => 'product',
|
787 |
'post_status' => 'publish',
|
788 |
'posts_per_page' => -1,
|
789 |
'fields' => 'ids',
|
790 |
-
|
791 |
|
792 |
$products = new WP_Query( $args );
|
793 |
|
@@ -803,23 +802,20 @@ class WC_Facebookcommerce_Integration extends WC_Integration {
|
|
803 |
public function load_assets() {
|
804 |
|
805 |
$ajax_data = array(
|
806 |
-
|
807 |
-
|
808 |
// load banner assets
|
809 |
wp_enqueue_script(
|
810 |
'wc_facebook_infobanner_jsx',
|
811 |
-
|
812 |
-
|
813 |
-
__FILE__
|
814 |
-
),
|
815 |
-
[],
|
816 |
\WC_Facebookcommerce::PLUGIN_VERSION
|
817 |
);
|
818 |
wp_localize_script(
|
819 |
-
|
820 |
-
|
821 |
-
|
822 |
-
|
823 |
|
824 |
wp_enqueue_style(
|
825 |
'wc_facebook_infobanner_css',
|
@@ -827,7 +823,7 @@ class WC_Facebookcommerce_Integration extends WC_Integration {
|
|
827 |
'/assets/css/facebook-infobanner.css',
|
828 |
__FILE__
|
829 |
),
|
830 |
-
|
831 |
\WC_Facebookcommerce::PLUGIN_VERSION
|
832 |
);
|
833 |
|
@@ -855,7 +851,7 @@ class WC_Facebookcommerce_Integration extends WC_Integration {
|
|
855 |
baseCurrency:'<?php echo esc_js( WC_Admin_Settings::get_option( 'woocommerce_currency' ) ); ?>',
|
856 |
timezoneId: '<?php echo esc_js( date( 'Z' ) ); ?>',
|
857 |
storeName: '<?php echo esc_js( WC_Facebookcommerce_Utils::get_store_name() ); ?>',
|
858 |
-
version: '<?php echo esc_js( WC()->version )
|
859 |
php_version: '<?php echo PHP_VERSION; ?>',
|
860 |
plugin_version: '<?php echo esc_js( WC_Facebookcommerce_Utils::PLUGIN_VERSION ); ?>'
|
861 |
},
|
@@ -876,9 +872,9 @@ class WC_Facebookcommerce_Integration extends WC_Integration {
|
|
876 |
</script>
|
877 |
|
878 |
<?php
|
879 |
-
$ajax_data =
|
880 |
'nonce' => wp_create_nonce( 'wc_facebook_settings_jsx' ),
|
881 |
-
|
882 |
wp_localize_script(
|
883 |
'wc_facebook_settings_jsx',
|
884 |
'wc_facebook_settings_jsx',
|
@@ -890,7 +886,7 @@ class WC_Facebookcommerce_Integration extends WC_Integration {
|
|
890 |
'/assets/css/facebook.css',
|
891 |
__FILE__
|
892 |
),
|
893 |
-
|
894 |
\WC_Facebookcommerce::PLUGIN_VERSION
|
895 |
);
|
896 |
}
|
@@ -909,7 +905,7 @@ class WC_Facebookcommerce_Integration extends WC_Integration {
|
|
909 |
|
910 |
$posted_products = Framework\SV_WC_Helper::get_posted_value( WC_Facebook_Product::FB_REMOVE_FROM_SYNC );
|
911 |
if ( empty( $posted_products ) ) {
|
912 |
-
return
|
913 |
}
|
914 |
|
915 |
return array_map( 'absint', explode( ',', $posted_products ) );
|
@@ -960,12 +956,11 @@ class WC_Facebookcommerce_Integration extends WC_Integration {
|
|
960 |
|
961 |
$this->delete_fb_product( $delete_product );
|
962 |
}
|
963 |
-
|
964 |
} else {
|
965 |
|
966 |
if ( $sync_enabled ) {
|
967 |
|
968 |
-
Products::enable_sync_for_products(
|
969 |
Products::set_product_visibility( $product, Admin::SYNC_MODE_SYNC_AND_HIDE !== $sync_mode );
|
970 |
|
971 |
$this->save_product_settings( $product );
|
@@ -977,7 +972,7 @@ class WC_Facebookcommerce_Integration extends WC_Integration {
|
|
977 |
Admin::add_product_disabled_sync_notice();
|
978 |
}
|
979 |
|
980 |
-
Products::disable_sync_for_products(
|
981 |
|
982 |
if ( in_array( $wp_id, $products_to_delete_from_facebook, true ) ) {
|
983 |
|
@@ -997,17 +992,17 @@ class WC_Facebookcommerce_Integration extends WC_Integration {
|
|
997 |
case 'external':
|
998 |
case 'composite':
|
999 |
$this->on_simple_product_publish( $wp_id );
|
1000 |
-
|
1001 |
|
1002 |
case 'variable':
|
1003 |
$this->on_variable_product_publish( $wp_id );
|
1004 |
-
|
1005 |
|
1006 |
case 'subscription':
|
1007 |
case 'variable-subscription':
|
1008 |
case 'bundle':
|
1009 |
$this->on_product_publish( $wp_id );
|
1010 |
-
|
1011 |
}
|
1012 |
}
|
1013 |
}
|
@@ -1033,8 +1028,8 @@ class WC_Facebookcommerce_Integration extends WC_Integration {
|
|
1033 |
$woo_product->set_price( sanitize_text_field( wp_unslash( $_POST[ WC_Facebook_Product::FB_PRODUCT_PRICE ] ) ) );
|
1034 |
}
|
1035 |
|
1036 |
-
if ( isset( $_POST[
|
1037 |
-
$product->update_meta_data( Products::PRODUCT_IMAGE_SOURCE_META_KEY, sanitize_key( wp_unslash( $_POST[
|
1038 |
$product->save_meta_data();
|
1039 |
}
|
1040 |
|
@@ -1061,10 +1056,11 @@ class WC_Facebookcommerce_Integration extends WC_Integration {
|
|
1061 |
|
1062 |
/**
|
1063 |
* bail if not enabled for sync, except if explicitly deleting from the metabox
|
|
|
1064 |
* @see ajax_delete_fb_product()
|
1065 |
*/
|
1066 |
if ( ( ! is_ajax() || ! isset( $_POST['action'] ) || 'ajax_delete_fb_product' !== $_POST['action'] )
|
1067 |
-
|
1068 |
|
1069 |
return;
|
1070 |
}
|
@@ -1091,11 +1087,11 @@ class WC_Facebookcommerce_Integration extends WC_Integration {
|
|
1091 |
$retailer_id = \WC_Facebookcommerce_Utils::get_fb_retailer_id( $product );
|
1092 |
|
1093 |
// enqueue variation to be deleted in the background
|
1094 |
-
facebook_for_woocommerce()->get_products_sync_handler()->delete_products(
|
1095 |
|
1096 |
} elseif ( $product->is_type( 'variable' ) ) {
|
1097 |
|
1098 |
-
$retailer_ids =
|
1099 |
|
1100 |
foreach ( $product->get_children() as $variation_id ) {
|
1101 |
|
@@ -1128,8 +1124,8 @@ class WC_Facebookcommerce_Integration extends WC_Integration {
|
|
1128 |
*
|
1129 |
* @internal
|
1130 |
*
|
1131 |
-
* @param string
|
1132 |
-
* @param string
|
1133 |
* @param \WP_post $post
|
1134 |
*/
|
1135 |
public function fb_change_product_published_status( $new_status, $old_status, $post ) {
|
@@ -1227,7 +1223,7 @@ class WC_Facebookcommerce_Integration extends WC_Integration {
|
|
1227 |
/**
|
1228 |
* Syncs product to Facebook when saving a variable product.
|
1229 |
*
|
1230 |
-
* @param int
|
1231 |
* @param WC_Facebook_Product|null $woo_product product object
|
1232 |
*/
|
1233 |
function on_variable_product_publish( $wp_id, $woo_product = null ) {
|
@@ -1261,7 +1257,7 @@ class WC_Facebookcommerce_Integration extends WC_Integration {
|
|
1261 |
$this->create_product_group( $woo_product, $retailer_id, true );
|
1262 |
}
|
1263 |
|
1264 |
-
$variation_ids =
|
1265 |
|
1266 |
// scheduled update for each variation that should be synced
|
1267 |
foreach ( $woo_product->get_children() as $variation_id ) {
|
@@ -1280,7 +1276,7 @@ class WC_Facebookcommerce_Integration extends WC_Integration {
|
|
1280 |
/**
|
1281 |
* Syncs product to Facebook when saving a simple product.
|
1282 |
*
|
1283 |
-
* @param int
|
1284 |
* @param WC_Facebook_Product|null $woo_product product object
|
1285 |
* @param WC_Facebook_Product|null $parent_product parent object
|
1286 |
* @return int|mixed|void|null
|
@@ -1332,11 +1328,10 @@ class WC_Facebookcommerce_Integration extends WC_Integration {
|
|
1332 |
WC_Facebookcommerce_Utils::fblog(
|
1333 |
'Wrong! simple_product_publish called without group ID for
|
1334 |
a variable product!',
|
1335 |
-
|
1336 |
true
|
1337 |
);
|
1338 |
}
|
1339 |
-
|
1340 |
} else {
|
1341 |
|
1342 |
return $this->create_product_simple( $woo_product ); // new product
|
@@ -1514,9 +1509,9 @@ class WC_Facebookcommerce_Integration extends WC_Integration {
|
|
1514 |
);
|
1515 |
}
|
1516 |
|
1517 |
-
$product_group_data =
|
1518 |
'variants' => $variants,
|
1519 |
-
|
1520 |
|
1521 |
if ( $default_product_fbid ) {
|
1522 |
$product_group_data['default_product_id'] = $default_product_fbid;
|
@@ -1586,7 +1581,7 @@ class WC_Facebookcommerce_Integration extends WC_Integration {
|
|
1586 |
*/
|
1587 |
private function get_product_variation_attributes( $variation ) {
|
1588 |
|
1589 |
-
$final_attributes =
|
1590 |
$variation_attributes = $variation['attributes'];
|
1591 |
|
1592 |
foreach ( $variation_attributes as $attribute_name => $attribute_value ) {
|
@@ -1732,10 +1727,10 @@ class WC_Facebookcommerce_Integration extends WC_Integration {
|
|
1732 |
|
1733 |
if ( $this->is_configured() ) {
|
1734 |
|
1735 |
-
$response =
|
1736 |
'connected' => true,
|
1737 |
'status' => 'in progress',
|
1738 |
-
|
1739 |
|
1740 |
if ( ! empty( $this->get_upload_id() ) ) {
|
1741 |
|
@@ -1757,10 +1752,10 @@ class WC_Facebookcommerce_Integration extends WC_Integration {
|
|
1757 |
|
1758 |
} else {
|
1759 |
|
1760 |
-
$response =
|
1761 |
'connected' => true,
|
1762 |
'status' => 'error',
|
1763 |
-
|
1764 |
}
|
1765 |
|
1766 |
if ( 'complete' === $response['status'] ) {
|
@@ -1773,10 +1768,9 @@ class WC_Facebookcommerce_Integration extends WC_Integration {
|
|
1773 |
)
|
1774 |
);
|
1775 |
}
|
1776 |
-
|
1777 |
} else {
|
1778 |
|
1779 |
-
$response =
|
1780 |
}
|
1781 |
|
1782 |
printf( json_encode( $response ) );
|
@@ -1876,8 +1870,8 @@ class WC_Facebookcommerce_Integration extends WC_Integration {
|
|
1876 |
* Deals with FB API responses, displays error if FB API returns error.
|
1877 |
*
|
1878 |
* @param WP_Error|array $result API response
|
1879 |
-
* @param array|null
|
1880 |
-
* @param int|null
|
1881 |
* @return array|null|void result if response is 200, null otherwise
|
1882 |
*/
|
1883 |
function check_api_result( $result, $logdata = null, $wpid = null ) {
|
@@ -1919,7 +1913,6 @@ class WC_Facebookcommerce_Integration extends WC_Integration {
|
|
1919 |
return $result;
|
1920 |
}
|
1921 |
}
|
1922 |
-
|
1923 |
} else {
|
1924 |
|
1925 |
$this->display_error_message_from_result( $result );
|
@@ -1927,10 +1920,10 @@ class WC_Facebookcommerce_Integration extends WC_Integration {
|
|
1927 |
|
1928 |
WC_Facebookcommerce_Utils::log( $result );
|
1929 |
|
1930 |
-
$data =
|
1931 |
'result' => $result,
|
1932 |
'data' => $logdata,
|
1933 |
-
|
1934 |
WC_Facebookcommerce_Utils::fblog(
|
1935 |
'Non-200 error code from FB',
|
1936 |
$data,
|
@@ -2031,22 +2024,22 @@ class WC_Facebookcommerce_Integration extends WC_Integration {
|
|
2031 |
ob_start();
|
2032 |
|
2033 |
// get up to 12 published posts that are products
|
2034 |
-
$args =
|
2035 |
'post_type' => 'product',
|
2036 |
'post_status' => 'publish',
|
2037 |
'posts_per_page' => 12,
|
2038 |
'fields' => 'ids',
|
2039 |
-
|
2040 |
|
2041 |
$post_ids = get_posts( $args );
|
2042 |
-
$items =
|
2043 |
|
2044 |
foreach ( $post_ids as $post_id ) {
|
2045 |
|
2046 |
$woo_product = new WC_Facebook_Product( $post_id );
|
2047 |
$product_data = $woo_product->prepare_product();
|
2048 |
|
2049 |
-
$feed_item =
|
2050 |
'title' => strip_tags( $product_data['name'] ),
|
2051 |
'availability' => $woo_product->is_in_stock() ? 'in stock' :
|
2052 |
'out of stock',
|
@@ -2056,7 +2049,7 @@ class WC_Facebookcommerce_Integration extends WC_Integration {
|
|
2056 |
'brand' => Framework\SV_WC_Helper::str_truncate( wp_strip_all_tags( WC_Facebookcommerce_Utils::get_store_name() ), 100 ),
|
2057 |
'link' => $product_data['url'],
|
2058 |
'price' => $product_data['price'] . ' ' . get_woocommerce_currency(),
|
2059 |
-
|
2060 |
|
2061 |
array_push( $items, $feed_item );
|
2062 |
}
|
@@ -2066,7 +2059,7 @@ class WC_Facebookcommerce_Integration extends WC_Integration {
|
|
2066 |
|
2067 |
ob_end_clean();
|
2068 |
|
2069 |
-
return json_encode(
|
2070 |
}
|
2071 |
|
2072 |
/**
|
@@ -2236,7 +2229,7 @@ class WC_Facebookcommerce_Integration extends WC_Integration {
|
|
2236 |
$error_message
|
2237 |
);
|
2238 |
|
2239 |
-
wp_send_json_error(
|
2240 |
}
|
2241 |
}
|
2242 |
|
@@ -2471,7 +2464,7 @@ class WC_Facebookcommerce_Integration extends WC_Integration {
|
|
2471 |
|
2472 |
if ( ! $this->fbproductfeed->sync_all_products_using_feed() ) {
|
2473 |
|
2474 |
-
WC_Facebookcommerce_Utils::fblog( 'Sync all products using feed, curl failed',
|
2475 |
|
2476 |
throw new Framework\SV_WC_Plugin_Exception( __( "We couldn't create the feed or upload the product information.", 'facebook-for-woocommerce' ) );
|
2477 |
}
|
@@ -2830,7 +2823,7 @@ class WC_Facebookcommerce_Integration extends WC_Integration {
|
|
2830 |
* @param int[] $category_ids the configured excluded product category IDs
|
2831 |
* @param \WC_Facebookcommerce_Integration $integration the integration instance
|
2832 |
*/
|
2833 |
-
return (array) apply_filters( 'wc_facebook_excluded_product_category_ids', get_option( self::SETTING_EXCLUDED_PRODUCT_CATEGORY_IDS,
|
2834 |
}
|
2835 |
|
2836 |
|
@@ -2851,7 +2844,7 @@ class WC_Facebookcommerce_Integration extends WC_Integration {
|
|
2851 |
* @param int[] $tag_ids the configured excluded product tag IDs
|
2852 |
* @param \WC_Facebookcommerce_Integration $integration the integration instance
|
2853 |
*/
|
2854 |
-
return (array) apply_filters( 'wc_facebook_excluded_product_tag_ids', get_option( self::SETTING_EXCLUDED_PRODUCT_TAG_IDS,
|
2855 |
}
|
2856 |
|
2857 |
|
@@ -2874,10 +2867,10 @@ class WC_Facebookcommerce_Integration extends WC_Integration {
|
|
2874 |
*/
|
2875 |
$mode = (string) apply_filters( 'wc_facebook_product_description_mode', get_option( self::SETTING_PRODUCT_DESCRIPTION_MODE, self::PRODUCT_DESCRIPTION_MODE_STANDARD ), $this );
|
2876 |
|
2877 |
-
$valid_modes =
|
2878 |
self::PRODUCT_DESCRIPTION_MODE_STANDARD,
|
2879 |
self::PRODUCT_DESCRIPTION_MODE_SHORT,
|
2880 |
-
|
2881 |
|
2882 |
if ( ! in_array( $mode, $valid_modes, true ) ) {
|
2883 |
$mode = self::PRODUCT_DESCRIPTION_MODE_STANDARD;
|
@@ -3179,6 +3172,26 @@ class WC_Facebookcommerce_Integration extends WC_Integration {
|
|
3179 |
return (bool) apply_filters( 'wc_facebook_is_product_sync_enabled', 'yes' === get_option( self::SETTING_ENABLE_PRODUCT_SYNC, 'yes' ), $this );
|
3180 |
}
|
3181 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3182 |
|
3183 |
/**
|
3184 |
* Determines whether the scheduled re-sync is enabled.
|
@@ -3297,7 +3310,7 @@ class WC_Facebookcommerce_Integration extends WC_Integration {
|
|
3297 |
|
3298 |
WC_Facebookcommerce_Utils::fblog(
|
3299 |
$error_msg,
|
3300 |
-
|
3301 |
true
|
3302 |
);
|
3303 |
}
|
@@ -3359,16 +3372,16 @@ class WC_Facebookcommerce_Integration extends WC_Integration {
|
|
3359 |
|
3360 |
$response = facebook_for_woocommerce()->get_api()->get_page( $this->get_facebook_page_id() );
|
3361 |
|
3362 |
-
$this->page =
|
3363 |
'name' => $response->get_name(),
|
3364 |
'url' => $response->get_url(),
|
3365 |
-
|
3366 |
|
3367 |
} catch ( Framework\SV_WC_API_Exception $e ) {
|
3368 |
|
3369 |
// we intentionally set $this->page to an empty array if an error occurs to avoid additional API requests
|
3370 |
// it's unlikely that we will get a different result if the exception was caused by an expired token, incorrect page ID, or rate limiting error
|
3371 |
-
$this->page =
|
3372 |
|
3373 |
$message = sprintf( __( 'There was an error trying to retrieve information about the Facebook page: %s' ), $e->getMessage() );
|
3374 |
|
@@ -3376,7 +3389,7 @@ class WC_Facebookcommerce_Integration extends WC_Integration {
|
|
3376 |
}
|
3377 |
}
|
3378 |
|
3379 |
-
return is_array( $this->page ) ? $this->page :
|
3380 |
}
|
3381 |
|
3382 |
|
@@ -3415,15 +3428,15 @@ class WC_Facebookcommerce_Integration extends WC_Integration {
|
|
3415 |
*/
|
3416 |
function get_nux_message_ifexist() {
|
3417 |
|
3418 |
-
$nux_type_to_elemid_map =
|
3419 |
'messenger_chat' => 'connect_button',
|
3420 |
'instagram_shopping' => 'connect_button',
|
3421 |
-
|
3422 |
|
3423 |
-
$nux_type_to_message_map =
|
3424 |
'messenger_chat' => __( 'Get started with Messenger Customer Chat' ),
|
3425 |
'instagram_shopping' => __( 'Get started with Instagram Shopping' ),
|
3426 |
-
|
3427 |
|
3428 |
$message = '';
|
3429 |
|
@@ -3438,7 +3451,7 @@ class WC_Facebookcommerce_Integration extends WC_Integration {
|
|
3438 |
?>
|
3439 |
|
3440 |
<div class="nux-message" style="display: none;"
|
3441 |
-
|
3442 |
<div class="nux-message-text">
|
3443 |
<?php echo esc_attr( $nux_type_to_message_map[ $nux_type ] ); ?>
|
3444 |
</div>
|
@@ -3518,7 +3531,7 @@ class WC_Facebookcommerce_Integration extends WC_Integration {
|
|
3518 |
* Helper function to update FB visibility.
|
3519 |
*
|
3520 |
* @param int|\WC_Product $product_id product ID or product object
|
3521 |
-
* @param string
|
3522 |
*/
|
3523 |
function update_fb_visibility( $product_id, $visibility ) {
|
3524 |
|
@@ -3540,7 +3553,7 @@ class WC_Facebookcommerce_Integration extends WC_Integration {
|
|
3540 |
|
3541 |
Products::set_product_visibility( $product, $should_set_visible );
|
3542 |
|
3543 |
-
facebook_for_woocommerce()->get_products_sync_handler()->create_or_update_products(
|
3544 |
|
3545 |
} elseif ( $product->is_type( 'variable' ) ) {
|
3546 |
|
@@ -3550,7 +3563,7 @@ class WC_Facebookcommerce_Integration extends WC_Integration {
|
|
3550 |
// we should not add the parent product ID to the array of product IDs to be
|
3551 |
// updated because product groups, which are used to represent the parent product
|
3552 |
// for variable products, don't have the visibility property on Facebook
|
3553 |
-
$product_ids =
|
3554 |
|
3555 |
// set visibility for all children
|
3556 |
foreach ( $product->get_children() as $index => $id ) {
|
@@ -3558,7 +3571,7 @@ class WC_Facebookcommerce_Integration extends WC_Integration {
|
|
3558 |
$product = wc_get_product( $id );
|
3559 |
|
3560 |
if ( ! $product instanceof \WC_Product ) {
|
3561 |
-
|
3562 |
}
|
3563 |
|
3564 |
Products::set_product_visibility( $product, $should_set_visible );
|
@@ -3574,11 +3587,11 @@ class WC_Facebookcommerce_Integration extends WC_Integration {
|
|
3574 |
$fb_product_item_id = $this->get_product_fbid( self::FB_PRODUCT_ITEM_ID, $product_id );
|
3575 |
|
3576 |
if ( ! $fb_product_item_id ) {
|
3577 |
-
\WC_Facebookcommerce_Utils::fblog( $fb_product_item_id . " doesn't exist but underwent a visibility transform.",
|
3578 |
return;
|
3579 |
}
|
3580 |
|
3581 |
-
$set_visibility = $this->fbgraph->update_product_item( $fb_product_item_id,
|
3582 |
|
3583 |
if ( $this->check_api_result( $set_visibility ) ) {
|
3584 |
Products::set_product_visibility( $product, $should_set_visible );
|
@@ -3618,8 +3631,8 @@ class WC_Facebookcommerce_Integration extends WC_Integration {
|
|
3618 |
/**
|
3619 |
* Gets Facebook product ID from meta or from Facebook API.
|
3620 |
*
|
3621 |
-
* @param string
|
3622 |
-
* @param int
|
3623 |
* @param WC_Facebook_Product|null $woo_product product
|
3624 |
* @return mixed|void|null
|
3625 |
*/
|
@@ -3782,7 +3795,7 @@ class WC_Facebookcommerce_Integration extends WC_Integration {
|
|
3782 |
$timestamp = $first_scheduled_time >= $current_time ? $first_scheduled_time->getTimestamp() : $next_scheduled_time->getTimestamp();
|
3783 |
|
3784 |
// TODO: replace 'facebook-for-woocommerce' with the plugin ID once we stat using the Framework {WV 2020-01-30}
|
3785 |
-
as_schedule_single_action( $timestamp, self::ACTION_HOOK_SCHEDULED_RESYNC,
|
3786 |
}
|
3787 |
|
3788 |
|
@@ -3794,7 +3807,7 @@ class WC_Facebookcommerce_Integration extends WC_Integration {
|
|
3794 |
private function unschedule_resync() {
|
3795 |
|
3796 |
// TODO: replace 'facebook-for-woocommerce' with the plugin ID once we stat using the Framework {WV 2020-01-30}
|
3797 |
-
as_unschedule_all_actions( self::ACTION_HOOK_SCHEDULED_RESYNC,
|
3798 |
}
|
3799 |
|
3800 |
|
@@ -3810,7 +3823,7 @@ class WC_Facebookcommerce_Integration extends WC_Integration {
|
|
3810 |
public function is_resync_scheduled() {
|
3811 |
|
3812 |
// TODO: replace 'facebook-for-woocommerce' with the plugin ID once we stat using the Framework {WV 2020-01-30}
|
3813 |
-
return is_int( as_next_scheduled_action( self::ACTION_HOOK_SCHEDULED_RESYNC,
|
3814 |
}
|
3815 |
|
3816 |
|
@@ -3829,7 +3842,8 @@ class WC_Facebookcommerce_Integration extends WC_Integration {
|
|
3829 |
|
3830 |
try {
|
3831 |
$this->sync_facebook_products_using_feed();
|
3832 |
-
} catch ( Framework\SV_WC_Plugin_Exception $e ) {
|
|
|
3833 |
|
3834 |
$resync_offset = $this->get_scheduled_resync_offset();
|
3835 |
|
27 |
|
28 |
|
29 |
/**
|
30 |
+
* The WordPress option name where the page access token is stored.
|
31 |
+
*
|
32 |
+
* @var string option name.
|
33 |
* @deprecated 2.1.0
|
34 |
*/
|
35 |
const OPTION_PAGE_ACCESS_TOKEN = 'wc_facebook_page_access_token';
|
40 |
/** @var string the WordPress option name where the external merchant settings ID is stored */
|
41 |
const OPTION_EXTERNAL_MERCHANT_SETTINGS_ID = 'wc_facebook_external_merchant_settings_id';
|
42 |
|
43 |
+
/** @var string Option name for disabling feed. */
|
44 |
+
const OPTION_LEGACY_FEED_FILE_GENERATION_ENABLED = 'wc_facebook_legacy_feed_file_generation_enabled';
|
45 |
+
|
46 |
/** @var string the WordPress option name where the feed ID is stored */
|
47 |
const OPTION_FEED_ID = 'wc_facebook_feed_id';
|
48 |
|
141 |
/** Legacy properties *********************************************************************************************/
|
142 |
|
143 |
|
144 |
+
// TODO probably some of these meta keys need to be moved to Facebook\Products {FN 2020-01-13}.
|
145 |
const FB_PRODUCT_GROUP_ID = 'fb_product_group_id';
|
146 |
const FB_PRODUCT_ITEM_ID = 'fb_product_item_id';
|
147 |
const FB_PRODUCT_DESCRIPTION = 'fb_product_description';
|
160 |
// Number of days to query tip.
|
161 |
const FB_TIP_QUERY = 1;
|
162 |
|
163 |
+
// TODO: this constant is no longer used and can probably be removed {WV 2020-01-21}.
|
164 |
const FB_VARIANT_IMAGE = 'fb_image';
|
165 |
|
166 |
const FB_ADMIN_MESSAGE_PREPEND = '<b>Facebook for WooCommerce</b><br/>';
|
176 |
public function init_pixel() {
|
177 |
WC_Facebookcommerce_Pixel::initialize();
|
178 |
|
179 |
+
/**
|
180 |
+
* Migrate WC customer pixel_id from WC settings to WP options.
|
181 |
+
* This is part of a larger effort to consolidate all the FB-specific
|
182 |
+
* settings for all plugin integrations.
|
183 |
+
*/
|
184 |
if ( is_admin() ) {
|
185 |
|
186 |
$pixel_id = WC_Facebookcommerce_Pixel::get_pixel_id();
|
195 |
WC_Facebookcommerce_Pixel::set_pixel_id( $settings_pixel_id );
|
196 |
}
|
197 |
|
198 |
+
/**
|
199 |
+
* Migrate Advanced Matching enabled (use_pii) from the integration setting to the pixel option,
|
200 |
+
* so that it works the same way the pixel ID does
|
201 |
+
*/
|
202 |
$settings_advanced_matching_enabled = $this->is_advanced_matching_enabled();
|
203 |
WC_Facebookcommerce_Pixel::set_use_pii_key( $settings_advanced_matching_enabled );
|
204 |
|
206 |
WC_Facebookcommerce_Pixel::set_use_s2s( $settings_use_s2s );
|
207 |
|
208 |
$settings_access_token = $this->get_access_token();
|
209 |
+
WC_Facebookcommerce_Pixel::set_access_token( $settings_access_token );
|
210 |
}
|
211 |
}
|
212 |
|
213 |
/**
|
214 |
* Init and hook in the integration.
|
215 |
*
|
|
|
216 |
* @return void
|
217 |
*/
|
218 |
public function __construct() {
|
223 |
$this->id = WC_Facebookcommerce::INTEGRATION_ID;
|
224 |
$this->method_title = __(
|
225 |
'Facebook for WooCommerce',
|
226 |
+
'facebook-for-woocommerce'
|
227 |
);
|
228 |
$this->method_description = __(
|
229 |
'Facebook Commerce and Dynamic Ads (Pixel) Extension',
|
230 |
+
'facebook-for-woocommerce'
|
231 |
);
|
232 |
|
233 |
// Load the settings.
|
235 |
|
236 |
$pixel_id = WC_Facebookcommerce_Pixel::get_pixel_id();
|
237 |
|
238 |
+
// If there is a pixel option saved and no integration setting saved, inherit the pixel option.
|
239 |
if ( $pixel_id && ! $this->get_facebook_pixel_id() ) {
|
240 |
$this->settings[ self::SETTING_FACEBOOK_PIXEL_ID ] = $pixel_id;
|
241 |
}
|
242 |
|
243 |
$advanced_matching_enabled = WC_Facebookcommerce_Pixel::get_use_pii_key();
|
244 |
|
245 |
+
// If Advanced Matching (use_pii) is enabled on the saved pixel option and not on the saved integration setting, inherit the pixel option.
|
|
|
246 |
if ( $advanced_matching_enabled && ! $this->is_advanced_matching_enabled() ) {
|
247 |
$this->settings[ self::SETTING_ENABLE_ADVANCED_MATCHING ] = $advanced_matching_enabled;
|
248 |
}
|
249 |
|
250 |
+
// For now, the values of use s2s and access token will be the ones returned from WC_Facebookcommerce_Pixel.
|
251 |
+
$use_s2s = WC_Facebookcommerce_Pixel::get_use_s2s();
|
252 |
+
$this->settings[ self::SETTING_USE_S2S ] = $use_s2s;
|
253 |
|
254 |
+
$access_token = WC_Facebookcommerce_Pixel::get_access_token();
|
255 |
+
$this->settings[ self::SETTING_ACCESS_TOKEN ] = $access_token;
|
256 |
|
257 |
if ( ! class_exists( 'WC_Facebookcommerce_Utils' ) ) {
|
258 |
include_once 'includes/fbutils.php';
|
267 |
|
268 |
WC_Facebookcommerce_Utils::$fbgraph = $this->fbgraph;
|
269 |
|
|
|
270 |
if ( is_admin() ) {
|
271 |
|
272 |
$this->init_pixel();
|
346 |
self::FB_PRIORITY_MID
|
347 |
);
|
348 |
|
349 |
+
// Don't duplicate product FBID meta.
|
350 |
+
add_filter( 'woocommerce_duplicate_product_exclude_meta', array( $this, 'fb_duplicate_product_reset_meta' ) );
|
351 |
|
352 |
+
// Add product processing hooks if the plugin is configured only.
|
353 |
if ( $this->is_configured() && $this->get_product_catalog_id() ) {
|
354 |
|
355 |
+
// On_product_save() must run with priority larger than 20 to make sure WooCommerce has a chance to save the submitted product information.
|
356 |
+
add_action( 'woocommerce_process_product_meta', array( $this, 'on_product_save' ), 40 );
|
357 |
|
358 |
add_action(
|
359 |
'woocommerce_product_quick_edit_save',
|
360 |
+
array( $this, 'on_quick_and_bulk_edit_save' )
|
|
|
|
|
361 |
);
|
362 |
|
363 |
add_action(
|
364 |
'woocommerce_product_bulk_edit_save',
|
365 |
+
array( $this, 'on_quick_and_bulk_edit_save' )
|
|
|
|
|
366 |
);
|
367 |
|
368 |
+
add_action( 'before_delete_post', array( $this, 'on_product_delete' ) );
|
369 |
|
370 |
add_action( 'add_meta_boxes', array( $this, 'fb_product_metabox' ), 10, 1 );
|
371 |
|
398 |
|
399 |
add_action(
|
400 |
'wp_ajax_wpmelon_adv_bulk_edit',
|
401 |
+
array( $this, 'ajax_woo_adv_bulk_edit_compat' ),
|
402 |
self::FB_PRIORITY_MID
|
403 |
);
|
404 |
|
405 |
+
// Used to remove the 'you need to resync' message.
|
406 |
+
if ( isset( $_GET['remove_sticky'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
|
|
407 |
$this->remove_sticky_message();
|
408 |
}
|
409 |
}
|
412 |
}
|
413 |
|
414 |
// Must be outside of admin for cron to schedule correctly.
|
415 |
+
add_action( 'sync_all_fb_products_using_feed', array( $this, 'handle_scheduled_resync_action' ), self::FB_PRIORITY_MID );
|
416 |
|
417 |
+
// Handle the special background feed generation action.
|
418 |
+
add_action( 'wc_facebook_generate_product_catalog_feed', array( $this, 'handle_generate_product_catalog_feed' ) );
|
419 |
|
420 |
if ( $this->get_facebook_pixel_id() ) {
|
421 |
+
$aam_settings = $this->load_aam_settings_of_pixel();
|
422 |
$user_info = WC_Facebookcommerce_Utils::get_user_info( $aam_settings );
|
423 |
$this->events_tracker = new WC_Facebookcommerce_EventsTracker( $user_info, $aam_settings );
|
424 |
}
|
425 |
|
426 |
+
// Initialize the messenger chat features.
|
427 |
+
$this->messenger_chat = new WC_Facebookcommerce_MessengerChat(
|
428 |
+
array(
|
429 |
+
'fb_page_id' => $this->get_facebook_page_id(),
|
430 |
+
'facebook_jssdk_version' => $this->get_js_sdk_version(),
|
431 |
+
)
|
432 |
+
);
|
433 |
|
434 |
+
// Product Set hooks.
|
435 |
add_action( 'fb_wc_product_set_sync', array( $this, 'create_or_update_product_set_item' ), 99, 2 );
|
436 |
add_action( 'fb_wc_product_set_delete', array( $this, 'delete_product_set_item' ), 99 );
|
437 |
}
|
445 |
*/
|
446 |
private function load_aam_settings_of_pixel() {
|
447 |
$installed_pixel = $this->get_facebook_pixel_id();
|
448 |
+
// If no pixel is installed, reading the DB is not needed.
|
449 |
+
if ( ! $installed_pixel ) {
|
450 |
return null;
|
451 |
}
|
452 |
+
$config_key = 'wc_facebook_aam_settings';
|
453 |
+
$saved_value = get_transient( $config_key );
|
454 |
+
$refresh_interval = 20 * MINUTE_IN_SECONDS;
|
455 |
+
$aam_settings = null;
|
456 |
+
// If wc_facebook_aam_settings is present in the DB it is converted into an AAMSettings object.
|
457 |
+
if ( $saved_value !== false ) {
|
458 |
+
$cached_aam_settings = new AAMSettings( json_decode( $saved_value, true ) );
|
|
|
459 |
// This condition is added because
|
460 |
// it is possible that the AAMSettings saved do not belong to the current
|
461 |
// installed pixel
|
462 |
// because the admin could have changed the connection to Facebook
|
463 |
+
// during the refresh interval.
|
464 |
+
if ( $cached_aam_settings->get_pixel_id() == $installed_pixel ) {
|
465 |
$aam_settings = $cached_aam_settings;
|
466 |
}
|
467 |
}
|
468 |
// If the settings are not present or invalid
|
469 |
// they are fetched from Facebook domain
|
470 |
+
// and cached in WP database if they are not null.
|
471 |
+
if ( ! $aam_settings ) {
|
472 |
$aam_settings = AAMSettings::build_from_pixel_id( $installed_pixel );
|
473 |
+
if ( $aam_settings ) {
|
474 |
+
set_transient( $config_key, strval( $aam_settings ), $refresh_interval );
|
475 |
}
|
476 |
}
|
477 |
return $aam_settings;
|
478 |
}
|
479 |
|
480 |
public function load_background_sync_process() {
|
481 |
+
// Attempt to load background processing (Woo 3.x.x only).
|
482 |
include_once 'includes/fbbackground.php';
|
483 |
if ( class_exists( 'WC_Facebookcommerce_Background_Process' ) ) {
|
484 |
if ( ! isset( $this->background_processor ) ) {
|
536 |
* @internal
|
537 |
* @deprecated since 1.10.0
|
538 |
*
|
539 |
+
* @param array $tabs Array of tabs.
|
540 |
* @return array
|
541 |
*/
|
542 |
public function fb_new_product_tab( $tabs ) {
|
565 |
* @internal
|
566 |
* @deprecated since 1.10.0
|
567 |
*
|
568 |
+
* @param array $existing_columns Array of columns and labels.
|
569 |
* @return array
|
570 |
*/
|
571 |
public function fb_product_columns( $existing_columns ) {
|
582 |
* @internal
|
583 |
* @deprecated since 1.10.0
|
584 |
*
|
585 |
+
* @param string $column Name of the column to display.
|
586 |
*/
|
587 |
public function fb_render_product_columns( $column ) {
|
588 |
|
596 |
);
|
597 |
wp_enqueue_script(
|
598 |
'wc_facebook_metabox_jsx',
|
599 |
+
facebook_for_woocommerce()->get_asset_build_dir_url() . '/admin/metabox.js',
|
600 |
+
array(),
|
|
|
|
|
|
|
601 |
\WC_Facebookcommerce::PLUGIN_VERSION
|
602 |
);
|
603 |
wp_localize_script(
|
638 |
?>
|
639 |
|
640 |
<?php echo esc_html__( 'Facebook ID:', 'facebook-for-woocommerce' ); ?> <a href="https://facebook.com/<?php echo esc_attr( $fb_product_group_id ); ?>"
|
641 |
+
target="_blank"><?php echo esc_html( $fb_product_group_id ); ?></a>
|
642 |
|
643 |
<?php if ( WC_Facebookcommerce_Utils::is_variable_type( $woo_product->get_type() ) ) : ?>
|
644 |
|
650 |
<?php foreach ( $product_item_ids_by_variation_id as $variation_id => $product_item_id ) : ?>
|
651 |
|
652 |
<?php echo esc_html( $variation_id ); ?>: <a href="https://facebook.com/<?php echo esc_attr( $product_item_id ); ?>"
|
653 |
+
target="_blank"><?php echo esc_html( $product_item_id ); ?></a><br/>
|
654 |
|
655 |
<?php endforeach; ?>
|
656 |
</p>
|
696 |
*/
|
697 |
private function get_variation_product_item_ids( $product, $product_group_id ) {
|
698 |
|
699 |
+
$product_item_ids_by_variation_id = array();
|
700 |
+
$missing_product_item_ids = array();
|
701 |
|
702 |
// get the product item IDs from meta data and build a list of variations that don't have a product item ID stored
|
703 |
foreach ( $product->get_children() as $variation_id ) {
|
750 |
*/
|
751 |
private function find_variation_product_item_ids( $product_group_id ) {
|
752 |
|
753 |
+
$product_item_ids = array();
|
754 |
|
755 |
try {
|
756 |
|
760 |
|
761 |
$product_item_ids = array_merge( $product_item_ids, $response->get_ids() );
|
762 |
|
763 |
+
// get up to two additional pages of results
|
764 |
} while ( $response = facebook_for_woocommerce()->get_api()->next( $response, 2 ) );
|
765 |
|
766 |
} catch ( Framework\SV_WC_API_Exception $e ) {
|
781 |
*/
|
782 |
public function get_product_count() {
|
783 |
|
784 |
+
$args = array(
|
785 |
'post_type' => 'product',
|
786 |
'post_status' => 'publish',
|
787 |
'posts_per_page' => -1,
|
788 |
'fields' => 'ids',
|
789 |
+
);
|
790 |
|
791 |
$products = new WP_Query( $args );
|
792 |
|
802 |
public function load_assets() {
|
803 |
|
804 |
$ajax_data = array(
|
805 |
+
'nonce' => wp_create_nonce( 'wc_facebook_infobanner_jsx' ),
|
806 |
+
);
|
807 |
// load banner assets
|
808 |
wp_enqueue_script(
|
809 |
'wc_facebook_infobanner_jsx',
|
810 |
+
facebook_for_woocommerce()->get_asset_build_dir_url() . '/admin/infobanner.js',
|
811 |
+
array(),
|
|
|
|
|
|
|
812 |
\WC_Facebookcommerce::PLUGIN_VERSION
|
813 |
);
|
814 |
wp_localize_script(
|
815 |
+
'wc_facebook_infobanner_jsx',
|
816 |
+
'wc_facebook_infobanner_jsx',
|
817 |
+
$ajax_data
|
818 |
+
);
|
819 |
|
820 |
wp_enqueue_style(
|
821 |
'wc_facebook_infobanner_css',
|
823 |
'/assets/css/facebook-infobanner.css',
|
824 |
__FILE__
|
825 |
),
|
826 |
+
array(),
|
827 |
\WC_Facebookcommerce::PLUGIN_VERSION
|
828 |
);
|
829 |
|
851 |
baseCurrency:'<?php echo esc_js( WC_Admin_Settings::get_option( 'woocommerce_currency' ) ); ?>',
|
852 |
timezoneId: '<?php echo esc_js( date( 'Z' ) ); ?>',
|
853 |
storeName: '<?php echo esc_js( WC_Facebookcommerce_Utils::get_store_name() ); ?>',
|
854 |
+
version: '<?php echo esc_js( WC()->version ); ?>',
|
855 |
php_version: '<?php echo PHP_VERSION; ?>',
|
856 |
plugin_version: '<?php echo esc_js( WC_Facebookcommerce_Utils::PLUGIN_VERSION ); ?>'
|
857 |
},
|
872 |
</script>
|
873 |
|
874 |
<?php
|
875 |
+
$ajax_data = array(
|
876 |
'nonce' => wp_create_nonce( 'wc_facebook_settings_jsx' ),
|
877 |
+
);
|
878 |
wp_localize_script(
|
879 |
'wc_facebook_settings_jsx',
|
880 |
'wc_facebook_settings_jsx',
|
886 |
'/assets/css/facebook.css',
|
887 |
__FILE__
|
888 |
),
|
889 |
+
array(),
|
890 |
\WC_Facebookcommerce::PLUGIN_VERSION
|
891 |
);
|
892 |
}
|
905 |
|
906 |
$posted_products = Framework\SV_WC_Helper::get_posted_value( WC_Facebook_Product::FB_REMOVE_FROM_SYNC );
|
907 |
if ( empty( $posted_products ) ) {
|
908 |
+
return array();
|
909 |
}
|
910 |
|
911 |
return array_map( 'absint', explode( ',', $posted_products ) );
|
956 |
|
957 |
$this->delete_fb_product( $delete_product );
|
958 |
}
|
|
|
959 |
} else {
|
960 |
|
961 |
if ( $sync_enabled ) {
|
962 |
|
963 |
+
Products::enable_sync_for_products( array( $product ) );
|
964 |
Products::set_product_visibility( $product, Admin::SYNC_MODE_SYNC_AND_HIDE !== $sync_mode );
|
965 |
|
966 |
$this->save_product_settings( $product );
|
972 |
Admin::add_product_disabled_sync_notice();
|
973 |
}
|
974 |
|
975 |
+
Products::disable_sync_for_products( array( $product ) );
|
976 |
|
977 |
if ( in_array( $wp_id, $products_to_delete_from_facebook, true ) ) {
|
978 |
|
992 |
case 'external':
|
993 |
case 'composite':
|
994 |
$this->on_simple_product_publish( $wp_id );
|
995 |
+
break;
|
996 |
|
997 |
case 'variable':
|
998 |
$this->on_variable_product_publish( $wp_id );
|
999 |
+
break;
|
1000 |
|
1001 |
case 'subscription':
|
1002 |
case 'variable-subscription':
|
1003 |
case 'bundle':
|
1004 |
$this->on_product_publish( $wp_id );
|
1005 |
+
break;
|
1006 |
}
|
1007 |
}
|
1008 |
}
|
1028 |
$woo_product->set_price( sanitize_text_field( wp_unslash( $_POST[ WC_Facebook_Product::FB_PRODUCT_PRICE ] ) ) );
|
1029 |
}
|
1030 |
|
1031 |
+
if ( isset( $_POST['fb_product_image_source'] ) ) {
|
1032 |
+
$product->update_meta_data( Products::PRODUCT_IMAGE_SOURCE_META_KEY, sanitize_key( wp_unslash( $_POST['fb_product_image_source'] ) ) );
|
1033 |
$product->save_meta_data();
|
1034 |
}
|
1035 |
|
1056 |
|
1057 |
/**
|
1058 |
* bail if not enabled for sync, except if explicitly deleting from the metabox
|
1059 |
+
*
|
1060 |
* @see ajax_delete_fb_product()
|
1061 |
*/
|
1062 |
if ( ( ! is_ajax() || ! isset( $_POST['action'] ) || 'ajax_delete_fb_product' !== $_POST['action'] )
|
1063 |
+
&& ! Products::published_product_should_be_synced( $product ) ) {
|
1064 |
|
1065 |
return;
|
1066 |
}
|
1087 |
$retailer_id = \WC_Facebookcommerce_Utils::get_fb_retailer_id( $product );
|
1088 |
|
1089 |
// enqueue variation to be deleted in the background
|
1090 |
+
facebook_for_woocommerce()->get_products_sync_handler()->delete_products( array( $retailer_id ) );
|
1091 |
|
1092 |
} elseif ( $product->is_type( 'variable' ) ) {
|
1093 |
|
1094 |
+
$retailer_ids = array();
|
1095 |
|
1096 |
foreach ( $product->get_children() as $variation_id ) {
|
1097 |
|
1124 |
*
|
1125 |
* @internal
|
1126 |
*
|
1127 |
+
* @param string $new_status
|
1128 |
+
* @param string $old_status
|
1129 |
* @param \WP_post $post
|
1130 |
*/
|
1131 |
public function fb_change_product_published_status( $new_status, $old_status, $post ) {
|
1223 |
/**
|
1224 |
* Syncs product to Facebook when saving a variable product.
|
1225 |
*
|
1226 |
+
* @param int $wp_id product post ID
|
1227 |
* @param WC_Facebook_Product|null $woo_product product object
|
1228 |
*/
|
1229 |
function on_variable_product_publish( $wp_id, $woo_product = null ) {
|
1257 |
$this->create_product_group( $woo_product, $retailer_id, true );
|
1258 |
}
|
1259 |
|
1260 |
+
$variation_ids = array();
|
1261 |
|
1262 |
// scheduled update for each variation that should be synced
|
1263 |
foreach ( $woo_product->get_children() as $variation_id ) {
|
1276 |
/**
|
1277 |
* Syncs product to Facebook when saving a simple product.
|
1278 |
*
|
1279 |
+
* @param int $wp_id product post ID
|
1280 |
* @param WC_Facebook_Product|null $woo_product product object
|
1281 |
* @param WC_Facebook_Product|null $parent_product parent object
|
1282 |
* @return int|mixed|void|null
|
1328 |
WC_Facebookcommerce_Utils::fblog(
|
1329 |
'Wrong! simple_product_publish called without group ID for
|
1330 |
a variable product!',
|
1331 |
+
array(),
|
1332 |
true
|
1333 |
);
|
1334 |
}
|
|
|
1335 |
} else {
|
1336 |
|
1337 |
return $this->create_product_simple( $woo_product ); // new product
|
1509 |
);
|
1510 |
}
|
1511 |
|
1512 |
+
$product_group_data = array(
|
1513 |
'variants' => $variants,
|
1514 |
+
);
|
1515 |
|
1516 |
if ( $default_product_fbid ) {
|
1517 |
$product_group_data['default_product_id'] = $default_product_fbid;
|
1581 |
*/
|
1582 |
private function get_product_variation_attributes( $variation ) {
|
1583 |
|
1584 |
+
$final_attributes = array();
|
1585 |
$variation_attributes = $variation['attributes'];
|
1586 |
|
1587 |
foreach ( $variation_attributes as $attribute_name => $attribute_value ) {
|
1727 |
|
1728 |
if ( $this->is_configured() ) {
|
1729 |
|
1730 |
+
$response = array(
|
1731 |
'connected' => true,
|
1732 |
'status' => 'in progress',
|
1733 |
+
);
|
1734 |
|
1735 |
if ( ! empty( $this->get_upload_id() ) ) {
|
1736 |
|
1752 |
|
1753 |
} else {
|
1754 |
|
1755 |
+
$response = array(
|
1756 |
'connected' => true,
|
1757 |
'status' => 'error',
|
1758 |
+
);
|
1759 |
}
|
1760 |
|
1761 |
if ( 'complete' === $response['status'] ) {
|
1768 |
)
|
1769 |
);
|
1770 |
}
|
|
|
1771 |
} else {
|
1772 |
|
1773 |
+
$response = array( 'connected' => false );
|
1774 |
}
|
1775 |
|
1776 |
printf( json_encode( $response ) );
|
1870 |
* Deals with FB API responses, displays error if FB API returns error.
|
1871 |
*
|
1872 |
* @param WP_Error|array $result API response
|
1873 |
+
* @param array|null $logdata additional data for logging
|
1874 |
+
* @param int|null $wpid post ID
|
1875 |
* @return array|null|void result if response is 200, null otherwise
|
1876 |
*/
|
1877 |
function check_api_result( $result, $logdata = null, $wpid = null ) {
|
1913 |
return $result;
|
1914 |
}
|
1915 |
}
|
|
|
1916 |
} else {
|
1917 |
|
1918 |
$this->display_error_message_from_result( $result );
|
1920 |
|
1921 |
WC_Facebookcommerce_Utils::log( $result );
|
1922 |
|
1923 |
+
$data = array(
|
1924 |
'result' => $result,
|
1925 |
'data' => $logdata,
|
1926 |
+
);
|
1927 |
WC_Facebookcommerce_Utils::fblog(
|
1928 |
'Non-200 error code from FB',
|
1929 |
$data,
|
2024 |
ob_start();
|
2025 |
|
2026 |
// get up to 12 published posts that are products
|
2027 |
+
$args = array(
|
2028 |
'post_type' => 'product',
|
2029 |
'post_status' => 'publish',
|
2030 |
'posts_per_page' => 12,
|
2031 |
'fields' => 'ids',
|
2032 |
+
);
|
2033 |
|
2034 |
$post_ids = get_posts( $args );
|
2035 |
+
$items = array();
|
2036 |
|
2037 |
foreach ( $post_ids as $post_id ) {
|
2038 |
|
2039 |
$woo_product = new WC_Facebook_Product( $post_id );
|
2040 |
$product_data = $woo_product->prepare_product();
|
2041 |
|
2042 |
+
$feed_item = array(
|
2043 |
'title' => strip_tags( $product_data['name'] ),
|
2044 |
'availability' => $woo_product->is_in_stock() ? 'in stock' :
|
2045 |
'out of stock',
|
2049 |
'brand' => Framework\SV_WC_Helper::str_truncate( wp_strip_all_tags( WC_Facebookcommerce_Utils::get_store_name() ), 100 ),
|
2050 |
'link' => $product_data['url'],
|
2051 |
'price' => $product_data['price'] . ' ' . get_woocommerce_currency(),
|
2052 |
+
);
|
2053 |
|
2054 |
array_push( $items, $feed_item );
|
2055 |
}
|
2059 |
|
2060 |
ob_end_clean();
|
2061 |
|
2062 |
+
return json_encode( array( $items ) );
|
2063 |
}
|
2064 |
|
2065 |
/**
|
2229 |
$error_message
|
2230 |
);
|
2231 |
|
2232 |
+
wp_send_json_error( array( 'error' => $message ) );
|
2233 |
}
|
2234 |
}
|
2235 |
|
2464 |
|
2465 |
if ( ! $this->fbproductfeed->sync_all_products_using_feed() ) {
|
2466 |
|
2467 |
+
WC_Facebookcommerce_Utils::fblog( 'Sync all products using feed, curl failed', array(), true );
|
2468 |
|
2469 |
throw new Framework\SV_WC_Plugin_Exception( __( "We couldn't create the feed or upload the product information.", 'facebook-for-woocommerce' ) );
|
2470 |
}
|
2823 |
* @param int[] $category_ids the configured excluded product category IDs
|
2824 |
* @param \WC_Facebookcommerce_Integration $integration the integration instance
|
2825 |
*/
|
2826 |
+
return (array) apply_filters( 'wc_facebook_excluded_product_category_ids', get_option( self::SETTING_EXCLUDED_PRODUCT_CATEGORY_IDS, array() ), $this );
|
2827 |
}
|
2828 |
|
2829 |
|
2844 |
* @param int[] $tag_ids the configured excluded product tag IDs
|
2845 |
* @param \WC_Facebookcommerce_Integration $integration the integration instance
|
2846 |
*/
|
2847 |
+
return (array) apply_filters( 'wc_facebook_excluded_product_tag_ids', get_option( self::SETTING_EXCLUDED_PRODUCT_TAG_IDS, array() ), $this );
|
2848 |
}
|
2849 |
|
2850 |
|
2867 |
*/
|
2868 |
$mode = (string) apply_filters( 'wc_facebook_product_description_mode', get_option( self::SETTING_PRODUCT_DESCRIPTION_MODE, self::PRODUCT_DESCRIPTION_MODE_STANDARD ), $this );
|
2869 |
|
2870 |
+
$valid_modes = array(
|
2871 |
self::PRODUCT_DESCRIPTION_MODE_STANDARD,
|
2872 |
self::PRODUCT_DESCRIPTION_MODE_SHORT,
|
2873 |
+
);
|
2874 |
|
2875 |
if ( ! in_array( $mode, $valid_modes, true ) ) {
|
2876 |
$mode = self::PRODUCT_DESCRIPTION_MODE_STANDARD;
|
3172 |
return (bool) apply_filters( 'wc_facebook_is_product_sync_enabled', 'yes' === get_option( self::SETTING_ENABLE_PRODUCT_SYNC, 'yes' ), $this );
|
3173 |
}
|
3174 |
|
3175 |
+
/**
|
3176 |
+
* Return true if (legacy) feed generation is enabled.
|
3177 |
+
*
|
3178 |
+
* Feed generation for product sync is enabled by default, and generally recommended.
|
3179 |
+
* Large stores, or stores running on shared hosting (low resources) may have issues
|
3180 |
+
* with feed generation. This option allows those stores to disable generation to
|
3181 |
+
* work around the issue.
|
3182 |
+
*
|
3183 |
+
* Note - this is temporary. In a future release, an improved feed system will be
|
3184 |
+
* implemented, which should work well for all stores. This option will not disable
|
3185 |
+
* the new improved implementation.
|
3186 |
+
*
|
3187 |
+
* @since 2.5.0
|
3188 |
+
*
|
3189 |
+
* @return bool
|
3190 |
+
*/
|
3191 |
+
public function is_legacy_feed_file_generation_enabled() {
|
3192 |
+
return (bool) ( 'yes' === get_option( self::OPTION_LEGACY_FEED_FILE_GENERATION_ENABLED, 'yes' ) );
|
3193 |
+
}
|
3194 |
+
|
3195 |
|
3196 |
/**
|
3197 |
* Determines whether the scheduled re-sync is enabled.
|
3310 |
|
3311 |
WC_Facebookcommerce_Utils::fblog(
|
3312 |
$error_msg,
|
3313 |
+
array(),
|
3314 |
true
|
3315 |
);
|
3316 |
}
|
3372 |
|
3373 |
$response = facebook_for_woocommerce()->get_api()->get_page( $this->get_facebook_page_id() );
|
3374 |
|
3375 |
+
$this->page = array(
|
3376 |
'name' => $response->get_name(),
|
3377 |
'url' => $response->get_url(),
|
3378 |
+
);
|
3379 |
|
3380 |
} catch ( Framework\SV_WC_API_Exception $e ) {
|
3381 |
|
3382 |
// we intentionally set $this->page to an empty array if an error occurs to avoid additional API requests
|
3383 |
// it's unlikely that we will get a different result if the exception was caused by an expired token, incorrect page ID, or rate limiting error
|
3384 |
+
$this->page = array();
|
3385 |
|
3386 |
$message = sprintf( __( 'There was an error trying to retrieve information about the Facebook page: %s' ), $e->getMessage() );
|
3387 |
|
3389 |
}
|
3390 |
}
|
3391 |
|
3392 |
+
return is_array( $this->page ) ? $this->page : array();
|
3393 |
}
|
3394 |
|
3395 |
|
3428 |
*/
|
3429 |
function get_nux_message_ifexist() {
|
3430 |
|
3431 |
+
$nux_type_to_elemid_map = array(
|
3432 |
'messenger_chat' => 'connect_button',
|
3433 |
'instagram_shopping' => 'connect_button',
|
3434 |
+
);
|
3435 |
|
3436 |
+
$nux_type_to_message_map = array(
|
3437 |
'messenger_chat' => __( 'Get started with Messenger Customer Chat' ),
|
3438 |
'instagram_shopping' => __( 'Get started with Instagram Shopping' ),
|
3439 |
+
);
|
3440 |
|
3441 |
$message = '';
|
3442 |
|
3451 |
?>
|
3452 |
|
3453 |
<div class="nux-message" style="display: none;"
|
3454 |
+
data-target="<?php echo esc_attr( $nux_type_to_elemid_map[ $nux_type ] ); ?>">
|
3455 |
<div class="nux-message-text">
|
3456 |
<?php echo esc_attr( $nux_type_to_message_map[ $nux_type ] ); ?>
|
3457 |
</div>
|
3531 |
* Helper function to update FB visibility.
|
3532 |
*
|
3533 |
* @param int|\WC_Product $product_id product ID or product object
|
3534 |
+
* @param string $visibility visibility
|
3535 |
*/
|
3536 |
function update_fb_visibility( $product_id, $visibility ) {
|
3537 |
|
3553 |
|
3554 |
Products::set_product_visibility( $product, $should_set_visible );
|
3555 |
|
3556 |
+
facebook_for_woocommerce()->get_products_sync_handler()->create_or_update_products( array( $product->get_id() ) );
|
3557 |
|
3558 |
} elseif ( $product->is_type( 'variable' ) ) {
|
3559 |
|
3563 |
// we should not add the parent product ID to the array of product IDs to be
|
3564 |
// updated because product groups, which are used to represent the parent product
|
3565 |
// for variable products, don't have the visibility property on Facebook
|
3566 |
+
$product_ids = array();
|
3567 |
|
3568 |
// set visibility for all children
|
3569 |
foreach ( $product->get_children() as $index => $id ) {
|
3571 |
$product = wc_get_product( $id );
|
3572 |
|
3573 |
if ( ! $product instanceof \WC_Product ) {
|
3574 |
+
continue;
|
3575 |
}
|
3576 |
|
3577 |
Products::set_product_visibility( $product, $should_set_visible );
|
3587 |
$fb_product_item_id = $this->get_product_fbid( self::FB_PRODUCT_ITEM_ID, $product_id );
|
3588 |
|
3589 |
if ( ! $fb_product_item_id ) {
|
3590 |
+
\WC_Facebookcommerce_Utils::fblog( $fb_product_item_id . " doesn't exist but underwent a visibility transform.", array(), true );
|
3591 |
return;
|
3592 |
}
|
3593 |
|
3594 |
+
$set_visibility = $this->fbgraph->update_product_item( $fb_product_item_id, array( 'visibility' => $visibility ) );
|
3595 |
|
3596 |
if ( $this->check_api_result( $set_visibility ) ) {
|
3597 |
Products::set_product_visibility( $product, $should_set_visible );
|
3631 |
/**
|
3632 |
* Gets Facebook product ID from meta or from Facebook API.
|
3633 |
*
|
3634 |
+
* @param string $fbid_type ID type (group or item)
|
3635 |
+
* @param int $wp_id post ID
|
3636 |
* @param WC_Facebook_Product|null $woo_product product
|
3637 |
* @return mixed|void|null
|
3638 |
*/
|
3795 |
$timestamp = $first_scheduled_time >= $current_time ? $first_scheduled_time->getTimestamp() : $next_scheduled_time->getTimestamp();
|
3796 |
|
3797 |
// TODO: replace 'facebook-for-woocommerce' with the plugin ID once we stat using the Framework {WV 2020-01-30}
|
3798 |
+
as_schedule_single_action( $timestamp, self::ACTION_HOOK_SCHEDULED_RESYNC, array(), 'facebook-for-woocommerce' );
|
3799 |
}
|
3800 |
|
3801 |
|
3807 |
private function unschedule_resync() {
|
3808 |
|
3809 |
// TODO: replace 'facebook-for-woocommerce' with the plugin ID once we stat using the Framework {WV 2020-01-30}
|
3810 |
+
as_unschedule_all_actions( self::ACTION_HOOK_SCHEDULED_RESYNC, array(), 'facebook-for-woocommerce' );
|
3811 |
}
|
3812 |
|
3813 |
|
3823 |
public function is_resync_scheduled() {
|
3824 |
|
3825 |
// TODO: replace 'facebook-for-woocommerce' with the plugin ID once we stat using the Framework {WV 2020-01-30}
|
3826 |
+
return is_int( as_next_scheduled_action( self::ACTION_HOOK_SCHEDULED_RESYNC, array(), 'facebook-for-woocommerce' ) );
|
3827 |
}
|
3828 |
|
3829 |
|
3842 |
|
3843 |
try {
|
3844 |
$this->sync_facebook_products_using_feed();
|
3845 |
+
} catch ( Framework\SV_WC_Plugin_Exception $e ) {
|
3846 |
+
}
|
3847 |
|
3848 |
$resync_offset = $this->get_scheduled_resync_offset();
|
3849 |
|
facebook-config-warmer.php
CHANGED
@@ -18,8 +18,8 @@ if ( ! class_exists( 'WC_Facebookcommerce_WarmConfig' ) ) :
|
|
18 |
class WC_Facebookcommerce_WarmConfig {
|
19 |
static $fb_warm_pixel_id = null;
|
20 |
static $fb_warm_is_advanced_matching_enabled = null;
|
21 |
-
static $fb_warm_use_s2s
|
22 |
-
static $fb_warm_access_token
|
23 |
}
|
24 |
|
25 |
endif;
|
18 |
class WC_Facebookcommerce_WarmConfig {
|
19 |
static $fb_warm_pixel_id = null;
|
20 |
static $fb_warm_is_advanced_matching_enabled = null;
|
21 |
+
static $fb_warm_use_s2s = null;
|
22 |
+
static $fb_warm_access_token = null;
|
23 |
}
|
24 |
|
25 |
endif;
|
facebook-for-woocommerce.php
CHANGED
@@ -10,15 +10,16 @@
|
|
10 |
* Description: Grow your business on Facebook! Use this official plugin to help sell more of your products using Facebook. After completing the setup, you'll be ready to create ads that promote your products and you can also create a shop section on your Page where customers can browse your products on Facebook.
|
11 |
* Author: Facebook
|
12 |
* Author URI: https://www.facebook.com/
|
13 |
-
* Version: 2.
|
14 |
* Text Domain: facebook-for-woocommerce
|
15 |
* WC requires at least: 3.5.0
|
16 |
* WC tested up to: 5.2.2
|
|
|
17 |
*
|
18 |
* @package FacebookCommerce
|
19 |
*/
|
20 |
|
21 |
-
defined( 'ABSPATH' )
|
22 |
|
23 |
/**
|
24 |
* The plugin loader class.
|
@@ -27,27 +28,39 @@ defined( 'ABSPATH' ) or exit;
|
|
27 |
*/
|
28 |
class WC_Facebook_Loader {
|
29 |
|
|
|
|
|
|
|
|
|
30 |
|
31 |
-
|
32 |
-
const MINIMUM_PHP_VERSION = '
|
33 |
|
34 |
-
|
35 |
const MINIMUM_WP_VERSION = '4.4';
|
36 |
|
37 |
-
|
38 |
const MINIMUM_WC_VERSION = '3.5.0';
|
39 |
|
40 |
-
|
41 |
const FRAMEWORK_VERSION = '5.10.0';
|
42 |
|
43 |
-
|
44 |
const PLUGIN_NAME = 'Facebook for WooCommerce';
|
45 |
|
46 |
|
47 |
-
/**
|
|
|
|
|
|
|
|
|
48 |
private static $instance;
|
49 |
|
50 |
-
/**
|
|
|
|
|
|
|
|
|
51 |
private $notices = array();
|
52 |
|
53 |
|
@@ -65,7 +78,7 @@ class WC_Facebook_Loader {
|
|
65 |
|
66 |
add_action( 'admin_notices', array( $this, 'admin_notices' ), 15 );
|
67 |
|
68 |
-
//
|
69 |
if ( $this->is_environment_compatible() ) {
|
70 |
add_action( 'plugins_loaded', array( $this, 'init_plugin' ) );
|
71 |
}
|
@@ -107,7 +120,7 @@ class WC_Facebook_Loader {
|
|
107 |
|
108 |
$this->load_framework();
|
109 |
|
110 |
-
require_once
|
111 |
|
112 |
// fire it up!
|
113 |
if ( function_exists( 'facebook_for_woocommerce' ) ) {
|
@@ -124,7 +137,7 @@ class WC_Facebook_Loader {
|
|
124 |
private function load_framework() {
|
125 |
|
126 |
if ( ! class_exists( '\\SkyVerge\\WooCommerce\\PluginFramework\\' . $this->get_framework_version_namespace() . '\\SV_WC_Plugin' ) ) {
|
127 |
-
require_once
|
128 |
}
|
129 |
}
|
130 |
|
@@ -204,23 +217,34 @@ class WC_Facebook_Loader {
|
|
204 |
|
205 |
if ( ! $this->is_wp_compatible() ) {
|
206 |
|
207 |
-
$this->add_admin_notice(
|
208 |
-
'
|
209 |
-
'
|
210 |
-
|
211 |
-
|
212 |
-
|
|
|
|
|
|
|
|
|
|
|
213 |
}
|
214 |
|
215 |
if ( ! $this->is_wc_compatible() ) {
|
216 |
|
217 |
-
$this->add_admin_notice(
|
218 |
-
'
|
219 |
-
'
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
224 |
}
|
225 |
}
|
226 |
|
@@ -294,15 +318,15 @@ class WC_Facebook_Loader {
|
|
294 |
*
|
295 |
* @since 1.10.0
|
296 |
*
|
297 |
-
* @param string $slug
|
298 |
-
* @param string $class
|
299 |
-
* @param string $message
|
300 |
*/
|
301 |
private function add_admin_notice( $slug, $class, $message ) {
|
302 |
|
303 |
$this->notices[ $slug ] = array(
|
304 |
'class' => $class,
|
305 |
-
'message' => $message
|
306 |
);
|
307 |
}
|
308 |
|
10 |
* Description: Grow your business on Facebook! Use this official plugin to help sell more of your products using Facebook. After completing the setup, you'll be ready to create ads that promote your products and you can also create a shop section on your Page where customers can browse your products on Facebook.
|
11 |
* Author: Facebook
|
12 |
* Author URI: https://www.facebook.com/
|
13 |
+
* Version: 2.5.0
|
14 |
* Text Domain: facebook-for-woocommerce
|
15 |
* WC requires at least: 3.5.0
|
16 |
* WC tested up to: 5.2.2
|
17 |
+
* Requires PHP: 7.0
|
18 |
*
|
19 |
* @package FacebookCommerce
|
20 |
*/
|
21 |
|
22 |
+
defined( 'ABSPATH' ) || exit;
|
23 |
|
24 |
/**
|
25 |
* The plugin loader class.
|
28 |
*/
|
29 |
class WC_Facebook_Loader {
|
30 |
|
31 |
+
/**
|
32 |
+
* @var string the plugin version. This must be in the main plugin file to be automatically bumped by Woorelease.
|
33 |
+
*/
|
34 |
+
const PLUGIN_VERSION = '2.5.0'; // WRCS: DEFINED_VERSION.
|
35 |
|
36 |
+
// Minimum PHP version required by this plugin.
|
37 |
+
const MINIMUM_PHP_VERSION = '7.0.0';
|
38 |
|
39 |
+
// Minimum WordPress version required by this plugin.
|
40 |
const MINIMUM_WP_VERSION = '4.4';
|
41 |
|
42 |
+
// Minimum WooCommerce version required by this plugin.
|
43 |
const MINIMUM_WC_VERSION = '3.5.0';
|
44 |
|
45 |
+
// SkyVerge plugin framework version used by this plugin.
|
46 |
const FRAMEWORK_VERSION = '5.10.0';
|
47 |
|
48 |
+
// The plugin name, for displaying notices.
|
49 |
const PLUGIN_NAME = 'Facebook for WooCommerce';
|
50 |
|
51 |
|
52 |
+
/**
|
53 |
+
* This class instance.
|
54 |
+
*
|
55 |
+
* @var \WC_Facebook_Loader single instance of this class.
|
56 |
+
*/
|
57 |
private static $instance;
|
58 |
|
59 |
+
/**
|
60 |
+
* Admin notices to add.
|
61 |
+
*
|
62 |
+
* @var array Array of admin notices.
|
63 |
+
*/
|
64 |
private $notices = array();
|
65 |
|
66 |
|
78 |
|
79 |
add_action( 'admin_notices', array( $this, 'admin_notices' ), 15 );
|
80 |
|
81 |
+
// If the environment check fails, initialize the plugin.
|
82 |
if ( $this->is_environment_compatible() ) {
|
83 |
add_action( 'plugins_loaded', array( $this, 'init_plugin' ) );
|
84 |
}
|
120 |
|
121 |
$this->load_framework();
|
122 |
|
123 |
+
require_once plugin_dir_path( __FILE__ ) . 'class-wc-facebookcommerce.php';
|
124 |
|
125 |
// fire it up!
|
126 |
if ( function_exists( 'facebook_for_woocommerce' ) ) {
|
137 |
private function load_framework() {
|
138 |
|
139 |
if ( ! class_exists( '\\SkyVerge\\WooCommerce\\PluginFramework\\' . $this->get_framework_version_namespace() . '\\SV_WC_Plugin' ) ) {
|
140 |
+
require_once plugin_dir_path( __FILE__ ) . 'vendor/skyverge/wc-plugin-framework/woocommerce/class-sv-wc-plugin.php';
|
141 |
}
|
142 |
}
|
143 |
|
217 |
|
218 |
if ( ! $this->is_wp_compatible() ) {
|
219 |
|
220 |
+
$this->add_admin_notice(
|
221 |
+
'update_wordpress',
|
222 |
+
'error',
|
223 |
+
sprintf(
|
224 |
+
'%s requires WordPress version %s or higher. Please %supdate WordPress »%s',
|
225 |
+
'<strong>' . self::PLUGIN_NAME . '</strong>',
|
226 |
+
self::MINIMUM_WP_VERSION,
|
227 |
+
'<a href="' . esc_url( admin_url( 'update-core.php' ) ) . '">',
|
228 |
+
'</a>'
|
229 |
+
)
|
230 |
+
);
|
231 |
}
|
232 |
|
233 |
if ( ! $this->is_wc_compatible() ) {
|
234 |
|
235 |
+
$this->add_admin_notice(
|
236 |
+
'update_woocommerce',
|
237 |
+
'error',
|
238 |
+
sprintf(
|
239 |
+
'%1$s requires WooCommerce version %2$s or higher. Please %3$supdate WooCommerce%4$s to the latest version, or %5$sdownload the minimum required version »%6$s',
|
240 |
+
'<strong>' . self::PLUGIN_NAME . '</strong>',
|
241 |
+
self::MINIMUM_WC_VERSION,
|
242 |
+
'<a href="' . esc_url( admin_url( 'update-core.php' ) ) . '">',
|
243 |
+
'</a>',
|
244 |
+
'<a href="' . esc_url( 'https://downloads.wordpress.org/plugin/woocommerce.' . self::MINIMUM_WC_VERSION . '.zip' ) . '">',
|
245 |
+
'</a>'
|
246 |
+
)
|
247 |
+
);
|
248 |
}
|
249 |
}
|
250 |
|
318 |
*
|
319 |
* @since 1.10.0
|
320 |
*
|
321 |
+
* @param string $slug The slug for the notice.
|
322 |
+
* @param string $class The css class for the notice.
|
323 |
+
* @param string $message The notice message.
|
324 |
*/
|
325 |
private function add_admin_notice( $slug, $class, $message ) {
|
326 |
|
327 |
$this->notices[ $slug ] = array(
|
328 |
'class' => $class,
|
329 |
+
'message' => $message,
|
330 |
);
|
331 |
}
|
332 |
|
i18n/languages/facebook-for-woocommerce.pot
CHANGED
@@ -2,10 +2,10 @@
|
|
2 |
# This file is distributed under the same license as the Facebook for WooCommerce package.
|
3 |
msgid ""
|
4 |
msgstr ""
|
5 |
-
"Project-Id-Version: Facebook for WooCommerce 2.
|
6 |
"Report-Msgid-Bugs-To: "
|
7 |
"https://woocommerce.com/my-account/marketplace-ticket-form/\n"
|
8 |
-
"POT-Creation-Date: 2021-
|
9 |
"MIME-Version: 1.0\n"
|
10 |
"Content-Type: text/plain; charset=utf-8\n"
|
11 |
"Content-Transfer-Encoding: 8bit\n"
|
@@ -13,7 +13,7 @@ msgstr ""
|
|
13 |
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
14 |
"Language-Team: LANGUAGE <LL@li.org>\n"
|
15 |
|
16 |
-
#: class-wc-facebookcommerce.php:
|
17 |
#. translators: Placeholders %1$s - opening strong HTML tag, %2$s - closing
|
18 |
#. strong HTML tag, %3$s - opening link HTML tag, %4$s - closing link HTML tag
|
19 |
msgid ""
|
@@ -21,7 +21,7 @@ msgid ""
|
|
21 |
"Facebook for WooCommerce connection. Please %3$sclick here%4$s to reconnect!"
|
22 |
msgstr ""
|
23 |
|
24 |
-
#: class-wc-facebookcommerce.php:
|
25 |
#. translators: Placeholders %1$s - opening link HTML tag, %2$s - closing link
|
26 |
#. HTML tag
|
27 |
msgid ""
|
@@ -29,7 +29,7 @@ msgid ""
|
|
29 |
"under %1$sWooCommerce > Facebook%2$s."
|
30 |
msgstr ""
|
31 |
|
32 |
-
#: class-wc-facebookcommerce.php:
|
33 |
#. translators: Placeholders %1$s - opening strong HTML tag, %2$s - closing
|
34 |
#. strong HTML tag, %3$s - opening link HTML tag, %4$s - closing link HTML tag
|
35 |
msgid ""
|
@@ -37,7 +37,7 @@ msgid ""
|
|
37 |
"configuration, %3$scomplete the setup steps%4$s."
|
38 |
msgstr ""
|
39 |
|
40 |
-
#: class-wc-facebookcommerce.php:
|
41 |
#. translators: Placeholders: %1$s - <strong> tag, %2$s - </strong> tag, %3$s -
|
42 |
#. <a> tag, %4$s - </a> tag
|
43 |
msgid ""
|
@@ -46,7 +46,7 @@ msgid ""
|
|
46 |
"Connection%4$s area."
|
47 |
msgstr ""
|
48 |
|
49 |
-
#: class-wc-facebookcommerce.php:
|
50 |
#. translators: Placeholders: %1$s - <strong> tag, %2$s - </strong> tag, %3$s -
|
51 |
#. <a> tag, %4$s - </a> tag
|
52 |
msgid ""
|
@@ -55,51 +55,51 @@ msgid ""
|
|
55 |
"products."
|
56 |
msgstr ""
|
57 |
|
58 |
-
#: class-wc-facebookcommerce.php:
|
59 |
#. translators: Placeholders: %1$s - opening <a> HTML link tag, %2$s - closing
|
60 |
#. </a> HTML link tag
|
61 |
msgid "Heads up! The Facebook menu is now located under the %1$sMarketing%2$s menu."
|
62 |
msgstr ""
|
63 |
|
64 |
-
#: class-wc-facebookcommerce.php:
|
65 |
msgid "FB Product Sets"
|
66 |
msgstr ""
|
67 |
|
68 |
-
#: class-wc-facebookcommerce.php:
|
69 |
msgid "FB Product Set"
|
70 |
msgstr ""
|
71 |
|
72 |
-
#: class-wc-facebookcommerce.php:
|
73 |
#. translators: Edit item label
|
74 |
msgid "Edit %s"
|
75 |
msgstr ""
|
76 |
|
77 |
-
#: class-wc-facebookcommerce.php:
|
78 |
#. translators: Add new label
|
79 |
msgid "Add new %s"
|
80 |
msgstr ""
|
81 |
|
82 |
-
#: class-wc-facebookcommerce.php:
|
83 |
#. translators: No items found text
|
84 |
msgid "No %s found."
|
85 |
msgstr ""
|
86 |
|
87 |
-
#: class-wc-facebookcommerce.php:
|
88 |
#. translators: Search label
|
89 |
msgid "Search %s."
|
90 |
msgstr ""
|
91 |
|
92 |
-
#: class-wc-facebookcommerce.php:
|
93 |
#. translators: Text label
|
94 |
msgid "Separate %s with commas"
|
95 |
msgstr ""
|
96 |
|
97 |
-
#: class-wc-facebookcommerce.php:
|
98 |
#. translators: Text label
|
99 |
msgid "Choose from the most used %s"
|
100 |
msgstr ""
|
101 |
|
102 |
-
#: class-wc-facebookcommerce.php:
|
103 |
msgid "Cannot create the API instance because the access token is missing."
|
104 |
msgstr ""
|
105 |
|
@@ -107,69 +107,69 @@ msgstr ""
|
|
107 |
msgid "Facebook for WooCommerce"
|
108 |
msgstr ""
|
109 |
|
110 |
-
#: facebook-commerce.php:
|
111 |
msgid "Facebook Commerce and Dynamic Ads (Pixel) Extension"
|
112 |
msgstr ""
|
113 |
|
114 |
-
#: facebook-commerce.php:
|
115 |
msgid "Facebook ID:"
|
116 |
msgstr ""
|
117 |
|
118 |
-
#: facebook-commerce.php:
|
119 |
msgid "Variant IDs:"
|
120 |
msgstr ""
|
121 |
|
122 |
-
#: facebook-commerce.php:
|
123 |
msgid "Reset Facebook metadata"
|
124 |
msgstr ""
|
125 |
|
126 |
-
#: facebook-commerce.php:
|
127 |
msgid "Delete product(s) on Facebook"
|
128 |
msgstr ""
|
129 |
|
130 |
-
#: facebook-commerce.php:
|
131 |
msgid "This product is not yet synced to Facebook."
|
132 |
msgstr ""
|
133 |
|
134 |
-
#: facebook-commerce.php:
|
135 |
msgid "Nothing to update for product group for %1$s"
|
136 |
msgstr ""
|
137 |
|
138 |
-
#: facebook-commerce.php:
|
139 |
#. translators: Placeholders %1$s - original error message from Facebook API
|
140 |
msgid "There was an issue connecting to the Facebook API: %1$s"
|
141 |
msgstr ""
|
142 |
|
143 |
-
#: facebook-commerce.php:
|
144 |
msgid "Your connection has expired."
|
145 |
msgstr ""
|
146 |
|
147 |
-
#: facebook-commerce.php:
|
148 |
msgid ""
|
149 |
"Please click Manage connection > Advanced Options > Update Token to refresh "
|
150 |
"your connection to Facebook."
|
151 |
msgstr ""
|
152 |
|
153 |
-
#: facebook-commerce.php:
|
154 |
#. translators: Placeholders %s - error message
|
155 |
msgid "There was an error trying to sync the products to Facebook. %s"
|
156 |
msgstr ""
|
157 |
|
158 |
-
#: facebook-commerce.php:
|
159 |
msgid "Product sync is disabled."
|
160 |
msgstr ""
|
161 |
|
162 |
-
#: facebook-commerce.php:
|
163 |
msgid "The plugin is not configured or the Catalog ID is missing."
|
164 |
msgstr ""
|
165 |
|
166 |
-
#: facebook-commerce.php:
|
167 |
msgid ""
|
168 |
"A product sync is in progress. Please wait until the sync finishes before "
|
169 |
"starting a new one."
|
170 |
msgstr ""
|
171 |
|
172 |
-
#: facebook-commerce.php:
|
173 |
msgid ""
|
174 |
"We've detected that your Facebook Product Catalog is no longer valid. This "
|
175 |
"may happen if it was deleted, but could also be a temporary error. If the "
|
@@ -177,33 +177,33 @@ msgid ""
|
|
177 |
"and setup the plugin again."
|
178 |
msgstr ""
|
179 |
|
180 |
-
#: facebook-commerce.php:
|
181 |
msgid "We couldn't create the feed or upload the product information."
|
182 |
msgstr ""
|
183 |
|
184 |
-
#: facebook-commerce.php:
|
185 |
msgid "Hi! We're here to answer any questions you may have."
|
186 |
msgstr ""
|
187 |
|
188 |
-
#: facebook-commerce.php:
|
189 |
msgid "Facebook for WooCommerce error:"
|
190 |
msgstr ""
|
191 |
|
192 |
-
#: facebook-commerce.php:
|
193 |
msgid ""
|
194 |
"There was an error trying to retrieve information about the Facebook page: "
|
195 |
"%s"
|
196 |
msgstr ""
|
197 |
|
198 |
-
#: facebook-commerce.php:
|
199 |
msgid "Get started with Messenger Customer Chat"
|
200 |
msgstr ""
|
201 |
|
202 |
-
#: facebook-commerce.php:
|
203 |
msgid "Get started with Instagram Shopping"
|
204 |
msgstr ""
|
205 |
|
206 |
-
#: facebook-commerce.php:
|
207 |
#. translators: Placeholders %1$s - original error message from Facebook API
|
208 |
msgid "There was an issue connecting to the Facebook API: %s"
|
209 |
msgstr ""
|
@@ -224,33 +224,33 @@ msgstr ""
|
|
224 |
msgid "A valid Order ID is required."
|
225 |
msgstr ""
|
226 |
|
227 |
-
#: includes/AJAX.php:
|
228 |
msgid "Order ID is required"
|
229 |
msgstr ""
|
230 |
|
231 |
-
#: includes/AJAX.php:
|
232 |
msgid "Tracking number is required"
|
233 |
msgstr ""
|
234 |
|
235 |
-
#: includes/AJAX.php:
|
236 |
msgid "Carrier code is required"
|
237 |
msgstr ""
|
238 |
|
239 |
-
#: includes/AJAX.php:
|
240 |
msgid "Order not found"
|
241 |
msgstr ""
|
242 |
|
243 |
-
#: includes/AJAX.php:
|
244 |
msgid "Go to Settings"
|
245 |
msgstr ""
|
246 |
|
247 |
-
#: includes/AJAX.php:
|
248 |
#: includes/Admin/Product_Categories.php:118
|
249 |
-
#: includes/Admin/Settings_Screens/Product_Sync.php:
|
250 |
msgid "Cancel"
|
251 |
msgstr ""
|
252 |
|
253 |
-
#: includes/AJAX.php:
|
254 |
#. translators: Placeholder %s - <br/> tag
|
255 |
msgid ""
|
256 |
"This product belongs to a category or tag that is excluded from the "
|
@@ -259,7 +259,7 @@ msgid ""
|
|
259 |
"or click Cancel and update the product's category / tag assignments."
|
260 |
msgstr ""
|
261 |
|
262 |
-
#: includes/AJAX.php:
|
263 |
msgid ""
|
264 |
"One or more of the selected products belongs to a category or tag that is "
|
265 |
"excluded from the Facebook catalog sync. To sync these products to "
|
@@ -267,11 +267,11 @@ msgid ""
|
|
267 |
"settings."
|
268 |
msgstr ""
|
269 |
|
270 |
-
#: includes/AJAX.php:
|
271 |
msgid "Exclude Products"
|
272 |
msgstr ""
|
273 |
|
274 |
-
#: includes/AJAX.php:
|
275 |
#. translators: Placeholder %s - <br/> tags
|
276 |
msgid ""
|
277 |
"The categories and/or tags that you have selected to exclude from sync "
|
@@ -289,7 +289,7 @@ msgid "Show advanced options"
|
|
289 |
msgstr ""
|
290 |
|
291 |
#: includes/Admin/Product_Categories.php:99
|
292 |
-
#: includes/Admin/Settings_Screens/Product_Sync.php:
|
293 |
msgid ""
|
294 |
"Products and categories that inherit this global setting (i.e. they do not "
|
295 |
"have a specific Google product category set) will use the new default "
|
@@ -297,7 +297,7 @@ msgid ""
|
|
297 |
msgstr ""
|
298 |
|
299 |
#: includes/Admin/Product_Categories.php:122
|
300 |
-
#: includes/Admin/Settings_Screens/Product_Sync.php:
|
301 |
msgid "Update default Google product category"
|
302 |
msgstr ""
|
303 |
|
@@ -316,7 +316,7 @@ msgid ""
|
|
316 |
msgstr ""
|
317 |
|
318 |
#: includes/Admin/Product_Categories.php:232
|
319 |
-
#: includes/Admin/Settings_Screens/Product_Sync.php:
|
320 |
msgid "Default Google product category"
|
321 |
msgstr ""
|
322 |
|
@@ -381,42 +381,42 @@ msgstr ""
|
|
381 |
msgid "Facebook"
|
382 |
msgstr ""
|
383 |
|
384 |
-
#: includes/Admin/Settings.php:
|
385 |
#: includes/Admin/Settings_Screens/Connection.php:34
|
386 |
#: includes/Admin/Settings_Screens/Connection.php:35
|
387 |
msgid "Connection"
|
388 |
msgstr ""
|
389 |
|
390 |
-
#: includes/Admin/Settings.php:
|
391 |
#: includes/Admin/Settings_Screens/Messenger.php:40
|
392 |
#: includes/Admin/Settings_Screens/Messenger.php:41
|
393 |
-
#: includes/Admin/Settings_Screens/Messenger.php:
|
394 |
msgid "Messenger"
|
395 |
msgstr ""
|
396 |
|
397 |
-
#: includes/Admin/Settings.php:
|
398 |
#: includes/Admin/Settings_Screens/Product_Sync.php:42
|
399 |
#: includes/Admin/Settings_Screens/Product_Sync.php:43
|
400 |
-
#: includes/Admin/Settings_Screens/Product_Sync.php:
|
401 |
-
#: includes/Admin/Settings_Screens/Product_Sync.php:
|
402 |
msgid "Product sync"
|
403 |
msgstr ""
|
404 |
|
405 |
-
#: includes/Admin/Settings.php:
|
406 |
#: includes/Admin/Settings_Screens/Advertise.php:37
|
407 |
#: includes/Admin/Settings_Screens/Advertise.php:38
|
408 |
msgid "Advertise"
|
409 |
msgstr ""
|
410 |
|
411 |
-
#: includes/Admin/Settings.php:
|
412 |
msgid "You do not have permission to save these settings."
|
413 |
msgstr ""
|
414 |
|
415 |
-
#: includes/Admin/Settings.php:
|
416 |
msgid "Your settings have been saved."
|
417 |
msgstr ""
|
418 |
|
419 |
-
#: includes/Admin/Settings.php:
|
420 |
#. translators: Placeholders: %s - user-friendly error message
|
421 |
msgid "Your settings could not be saved. %s"
|
422 |
msgstr ""
|
@@ -442,120 +442,120 @@ msgid ""
|
|
442 |
"touch with our support team%6$s for assistance."
|
443 |
msgstr ""
|
444 |
|
445 |
-
#: includes/Admin/Settings_Screens/Connection.php:
|
446 |
msgid "Page"
|
447 |
msgstr ""
|
448 |
|
449 |
-
#: includes/Admin/Settings_Screens/Connection.php:
|
450 |
msgid "Pixel"
|
451 |
msgstr ""
|
452 |
|
453 |
-
#: includes/Admin/Settings_Screens/Connection.php:
|
454 |
msgid "Catalog"
|
455 |
msgstr ""
|
456 |
|
457 |
-
#: includes/Admin/Settings_Screens/Connection.php:
|
458 |
msgid "Business Manager account"
|
459 |
msgstr ""
|
460 |
|
461 |
-
#: includes/Admin/Settings_Screens/Connection.php:
|
462 |
msgid "Ad Manager account"
|
463 |
msgstr ""
|
464 |
|
465 |
-
#: includes/Admin/Settings_Screens/Connection.php:
|
466 |
msgid "Instagram Business ID"
|
467 |
msgstr ""
|
468 |
|
469 |
-
#: includes/Admin/Settings_Screens/Connection.php:
|
470 |
msgid "Commerce Merchant Settings ID"
|
471 |
msgstr ""
|
472 |
|
473 |
-
#: includes/Admin/Settings_Screens/Connection.php:
|
474 |
msgid "Reach the Right People and Sell More Online"
|
475 |
msgstr ""
|
476 |
|
477 |
-
#: includes/Admin/Settings_Screens/Connection.php:
|
478 |
msgid "Grow your business on Facebook"
|
479 |
msgstr ""
|
480 |
|
481 |
-
#: includes/Admin/Settings_Screens/Connection.php:
|
482 |
msgid "Use this WooCommerce and Facebook integration to:"
|
483 |
msgstr ""
|
484 |
|
485 |
-
#: includes/Admin/Settings_Screens/Connection.php:
|
486 |
msgid "Create an ad in a few steps"
|
487 |
msgstr ""
|
488 |
|
489 |
-
#: includes/Admin/Settings_Screens/Connection.php:
|
490 |
msgid "Use built-in best practices for online sales"
|
491 |
msgstr ""
|
492 |
|
493 |
-
#: includes/Admin/Settings_Screens/Connection.php:
|
494 |
msgid "Get reporting on sales and revenue"
|
495 |
msgstr ""
|
496 |
|
497 |
-
#: includes/Admin/Settings_Screens/Connection.php:
|
498 |
msgid "Manage Connection"
|
499 |
msgstr ""
|
500 |
|
501 |
-
#: includes/Admin/Settings_Screens/Connection.php:
|
502 |
msgid "Disconnect"
|
503 |
msgstr ""
|
504 |
|
505 |
-
#: includes/Admin/Settings_Screens/Connection.php:
|
506 |
msgid "Get Started"
|
507 |
msgstr ""
|
508 |
|
509 |
-
#: includes/Admin/Settings_Screens/Connection.php:
|
510 |
msgid "Debug"
|
511 |
msgstr ""
|
512 |
|
513 |
-
#: includes/Admin/Settings_Screens/Connection.php:
|
514 |
msgid "Enable debug mode"
|
515 |
msgstr ""
|
516 |
|
517 |
-
#: includes/Admin/Settings_Screens/Connection.php:
|
518 |
msgid "Log plugin events for debugging"
|
519 |
msgstr ""
|
520 |
|
521 |
-
#: includes/Admin/Settings_Screens/Connection.php:
|
522 |
msgid "Only enable this if you are experiencing problems with the plugin."
|
523 |
msgstr ""
|
524 |
|
525 |
-
#: includes/Admin/Settings_Screens/Messenger.php:
|
526 |
#. translators: Placeholders: %1$s - <a> tag, %2$s - </a> tag
|
527 |
msgid "%1$sClick here%2$s to manage your Messenger greeting and colors."
|
528 |
msgstr ""
|
529 |
|
530 |
-
#: includes/Admin/Settings_Screens/Messenger.php:
|
531 |
msgid "Enable Messenger"
|
532 |
msgstr ""
|
533 |
|
534 |
-
#: includes/Admin/Settings_Screens/Messenger.php:
|
535 |
msgid "Enable and customize Facebook Messenger on your store"
|
536 |
msgstr ""
|
537 |
|
538 |
-
#: includes/Admin/Settings_Screens/Messenger.php:
|
539 |
msgid "Language"
|
540 |
msgstr ""
|
541 |
|
542 |
-
#: includes/Admin/Settings_Screens/Messenger.php:
|
543 |
msgid "Greeting & Colors"
|
544 |
msgstr ""
|
545 |
|
546 |
-
#: includes/Admin/Settings_Screens/Messenger.php:
|
547 |
#. translators: Placeholders: %1$s - <a> tag, %2$s - </a> tag
|
548 |
msgid "Please %1$sconnect to Facebook%2$s to enable and manage Facebook Messenger."
|
549 |
msgstr ""
|
550 |
|
551 |
-
#: includes/Admin/Settings_Screens/Messenger.php:
|
552 |
#. translators: Placeholders: %1$s - <a> tag, %2$s - </a> tag
|
553 |
msgid ""
|
554 |
"There was an error communicating with the Facebook Business Extension. "
|
555 |
"%1$sClick here%2$s to manage your Messenger settings."
|
556 |
msgstr ""
|
557 |
|
558 |
-
#: includes/Admin/Settings_Screens/Messenger.php:
|
559 |
msgid "Please try again."
|
560 |
msgstr ""
|
561 |
|
@@ -564,19 +564,19 @@ msgstr ""
|
|
564 |
msgid "Product sets"
|
565 |
msgstr ""
|
566 |
|
567 |
-
#: includes/Admin/Settings_Screens/Product_Sync.php:
|
568 |
#. translators: Placeholders: {count} number of remaining items
|
569 |
msgid "{count} item remaining."
|
570 |
msgid_plural "{count} items remaining."
|
571 |
msgstr[0] ""
|
572 |
msgstr[1] ""
|
573 |
|
574 |
-
#: includes/Admin/Settings_Screens/Product_Sync.php:
|
575 |
#. translators: Placeholders %s - html code for a spinner icon
|
576 |
msgid "Your products will now be resynced to Facebook, this may take some time."
|
577 |
msgstr ""
|
578 |
|
579 |
-
#: includes/Admin/Settings_Screens/Product_Sync.php:
|
580 |
msgid ""
|
581 |
"Facebook for WooCommerce automatically syncs your products on "
|
582 |
"create/update. Are you sure you want to force product resync?\n"
|
@@ -586,21 +586,21 @@ msgid ""
|
|
586 |
"did not sync."
|
587 |
msgstr ""
|
588 |
|
589 |
-
#: includes/Admin/Settings_Screens/Product_Sync.php:
|
590 |
msgid "Your products are syncing - you may safely leave this page %s"
|
591 |
msgstr ""
|
592 |
|
593 |
-
#: includes/Admin/Settings_Screens/Product_Sync.php:
|
594 |
msgid "There was an error trying to sync the products to Facebook."
|
595 |
msgstr ""
|
596 |
|
597 |
-
#: includes/Admin/Settings_Screens/Product_Sync.php:
|
598 |
msgid ""
|
599 |
"Something went wrong while uploading the product information, please try "
|
600 |
"again."
|
601 |
msgstr ""
|
602 |
|
603 |
-
#: includes/Admin/Settings_Screens/Product_Sync.php:
|
604 |
#. translators: Placeholders: %1$s - <strong> tag, %2$s - </strong> tag
|
605 |
msgid ""
|
606 |
"Products and categories that inherit this global setting (they do not have "
|
@@ -610,62 +610,62 @@ msgid ""
|
|
610 |
"Are you sure you want to proceed?"
|
611 |
msgstr ""
|
612 |
|
613 |
-
#: includes/Admin/Settings_Screens/Product_Sync.php:
|
614 |
msgid "Sync products"
|
615 |
msgstr ""
|
616 |
|
617 |
-
#: includes/Admin/Settings_Screens/Product_Sync.php:
|
618 |
msgid "Enable product sync"
|
619 |
msgstr ""
|
620 |
|
621 |
-
#: includes/Admin/Settings_Screens/Product_Sync.php:
|
622 |
msgid "Exclude categories from sync"
|
623 |
msgstr ""
|
624 |
|
625 |
-
#: includes/Admin/Settings_Screens/Product_Sync.php:
|
626 |
msgid "Products in one or more of these categories will not sync to Facebook."
|
627 |
msgstr ""
|
628 |
|
629 |
-
#: includes/Admin/Settings_Screens/Product_Sync.php:
|
630 |
msgid "Search for a product category…"
|
631 |
msgstr ""
|
632 |
|
633 |
-
#: includes/Admin/Settings_Screens/Product_Sync.php:
|
634 |
msgid "Exclude tags from sync"
|
635 |
msgstr ""
|
636 |
|
637 |
-
#: includes/Admin/Settings_Screens/Product_Sync.php:
|
638 |
msgid "Products with one or more of these tags will not sync to Facebook."
|
639 |
msgstr ""
|
640 |
|
641 |
-
#: includes/Admin/Settings_Screens/Product_Sync.php:
|
642 |
msgid "Search for a product tag…"
|
643 |
msgstr ""
|
644 |
|
645 |
-
#: includes/Admin/Settings_Screens/Product_Sync.php:
|
646 |
msgid "Product description sync"
|
647 |
msgstr ""
|
648 |
|
649 |
-
#: includes/Admin/Settings_Screens/Product_Sync.php:
|
650 |
msgid "Choose which product description to display in the Facebook catalog."
|
651 |
msgstr ""
|
652 |
|
653 |
-
#: includes/Admin/Settings_Screens/Product_Sync.php:
|
654 |
msgid "Standard description"
|
655 |
msgstr ""
|
656 |
|
657 |
-
#: includes/Admin/Settings_Screens/Product_Sync.php:
|
658 |
msgid "Short description"
|
659 |
msgstr ""
|
660 |
|
661 |
-
#: includes/Admin/Settings_Screens/Product_Sync.php:
|
662 |
msgid ""
|
663 |
"Choose a default Google product category for your products. Defaults can "
|
664 |
"also be set for product categories. Products need at least two category "
|
665 |
"levels defined for tax to be correctly applied."
|
666 |
msgstr ""
|
667 |
|
668 |
-
#: includes/Admin/Settings_Screens/Product_Sync.php:
|
669 |
#. translators: Placeholders: %1$s - <a> tag, %2$s - </a> tag
|
670 |
msgid "Please %1$sconnect to Facebook%2$s to enable and manage product sync."
|
671 |
msgstr ""
|
@@ -674,41 +674,41 @@ msgstr ""
|
|
674 |
msgid "The name is how it appears on Facebook Catalog."
|
675 |
msgstr ""
|
676 |
|
677 |
-
#: includes/Admin.php:
|
678 |
msgid ""
|
679 |
"Please enter a Google product category and at least one sub-category to "
|
680 |
"sell this product on Instagram."
|
681 |
msgstr ""
|
682 |
|
683 |
-
#: includes/Admin.php:
|
684 |
msgid "Search main categories..."
|
685 |
msgstr ""
|
686 |
|
687 |
-
#: includes/Admin.php:
|
688 |
msgid "Choose a main category"
|
689 |
msgstr ""
|
690 |
|
691 |
-
#: includes/Admin.php:
|
692 |
msgid "Choose a category"
|
693 |
msgstr ""
|
694 |
|
695 |
-
#: includes/Admin.php:
|
696 |
msgid ""
|
697 |
"To sell this product on Instagram, please ensure it meets the following "
|
698 |
"requirements:"
|
699 |
msgstr ""
|
700 |
|
701 |
-
#: includes/Admin.php:
|
702 |
msgid "Has a price defined"
|
703 |
msgstr ""
|
704 |
|
705 |
-
#: includes/Admin.php:
|
706 |
#. translators: Placeholders: %1$s - <strong> opening HTML tag, %2$s -
|
707 |
#. </strong> closing HTML tag
|
708 |
msgid "Has %1$sManage Stock%2$s enabled on the %1$sInventory%2$s tab"
|
709 |
msgstr ""
|
710 |
|
711 |
-
#: includes/Admin.php:
|
712 |
#. translators: Placeholders: %1$s - <strong> opening HTML tag, %2$s -
|
713 |
#. </strong> closing HTML tag
|
714 |
msgid ""
|
@@ -716,11 +716,11 @@ msgid ""
|
|
716 |
"and hide\""
|
717 |
msgstr ""
|
718 |
|
719 |
-
#: includes/Admin.php:
|
720 |
msgid "Close"
|
721 |
msgstr ""
|
722 |
|
723 |
-
#: includes/Admin.php:
|
724 |
#. translators: Placeholders: %1$s - opening <a> link tag, %2$s - closing </a>
|
725 |
#. link tag
|
726 |
msgid ""
|
@@ -729,44 +729,44 @@ msgid ""
|
|
729 |
"the Facebook catalog as well?"
|
730 |
msgstr ""
|
731 |
|
732 |
-
#: includes/Admin.php:
|
733 |
msgid "Remove from sync only"
|
734 |
msgstr ""
|
735 |
|
736 |
-
#: includes/Admin.php:
|
737 |
msgid "Remove from sync and delete"
|
738 |
msgstr ""
|
739 |
|
740 |
-
#: includes/Admin.php:
|
741 |
msgid "Facebook sync"
|
742 |
msgstr ""
|
743 |
|
744 |
-
#: includes/Admin.php:
|
745 |
msgid "Sync and show"
|
746 |
msgstr ""
|
747 |
|
748 |
-
#: includes/Admin.php:
|
749 |
msgid "Sync and hide"
|
750 |
msgstr ""
|
751 |
|
752 |
-
#: includes/Admin.php:
|
753 |
-
#: includes/Admin.php:
|
754 |
msgid "Do not sync"
|
755 |
msgstr ""
|
756 |
|
757 |
-
#: includes/Admin.php:
|
758 |
msgid "Filter by Facebook sync setting"
|
759 |
msgstr ""
|
760 |
|
761 |
-
#: includes/Admin.php:
|
762 |
msgid "Include in Facebook sync"
|
763 |
msgstr ""
|
764 |
|
765 |
-
#: includes/Admin.php:
|
766 |
msgid "Exclude from Facebook sync"
|
767 |
msgstr ""
|
768 |
|
769 |
-
#: includes/Admin.php:
|
770 |
#. translators: Placeholders: %1$s - <strong> tag, %2$s - </strong> tag, %3$s -
|
771 |
#. <a> tag, %4$s - <a> tag
|
772 |
msgid ""
|
@@ -780,11 +780,11 @@ msgid_plural ""
|
|
780 |
msgstr[0] ""
|
781 |
msgstr[1] ""
|
782 |
|
783 |
-
#: includes/Admin.php:
|
784 |
msgid "Don't show this notice again"
|
785 |
msgstr ""
|
786 |
|
787 |
-
#: includes/Admin.php:
|
788 |
#. translators: Placeholders: %1$s - number of affected products, %2$s opening
|
789 |
#. HTML <a> tag, %3$s - closing HTML </a> tag, %4$s - opening HTML <a> tag,
|
790 |
#. %5$s - closing HTML </a> tag
|
@@ -801,7 +801,7 @@ msgid_plural ""
|
|
801 |
msgstr[0] ""
|
802 |
msgstr[1] ""
|
803 |
|
804 |
-
#: includes/Admin.php:
|
805 |
#. translators: Placeholders: %1$s - opening HTML <strong> tag, %2$s - closing
|
806 |
#. HTML </strong> tag, %3$s - opening HTML <a> tag, %4$s - closing HTML </a>
|
807 |
#. tag
|
@@ -811,176 +811,176 @@ msgid ""
|
|
811 |
"your Facebook catalog. You may still advertise Virtual products on Facebook."
|
812 |
msgstr ""
|
813 |
|
814 |
-
#: includes/Admin.php:
|
815 |
msgid "Sync and show in catalog"
|
816 |
msgstr ""
|
817 |
|
818 |
-
#: includes/Admin.php:
|
819 |
msgid "Sync and hide in catalog"
|
820 |
msgstr ""
|
821 |
|
822 |
-
#: includes/Admin.php:
|
823 |
msgid "Facebook Description"
|
824 |
msgstr ""
|
825 |
|
826 |
-
#: includes/Admin.php:
|
827 |
msgid ""
|
828 |
"Custom (plain-text only) description for product on Facebook. If blank, "
|
829 |
"product description will be used. If product description is blank, "
|
830 |
"shortname will be used."
|
831 |
msgstr ""
|
832 |
|
833 |
-
#: includes/Admin.php:
|
834 |
msgid "Facebook Product Image"
|
835 |
msgstr ""
|
836 |
|
837 |
-
#: includes/Admin.php:
|
838 |
msgid ""
|
839 |
"Choose the product image that should be synced to the Facebook catalog for "
|
840 |
"this product. If using a custom image, please enter an absolute URL (e.g. "
|
841 |
"https://domain.com/image.jpg)."
|
842 |
msgstr ""
|
843 |
|
844 |
-
#: includes/Admin.php:
|
845 |
msgid "Use WooCommerce image"
|
846 |
msgstr ""
|
847 |
|
848 |
-
#: includes/Admin.php:
|
849 |
msgid "Use custom image"
|
850 |
msgstr ""
|
851 |
|
852 |
-
#: includes/Admin.php:
|
853 |
msgid "Custom Image URL"
|
854 |
msgstr ""
|
855 |
|
856 |
-
#: includes/Admin.php:
|
857 |
#. translators: Placeholders %1$s - WC currency symbol
|
858 |
msgid "Facebook Price (%1$s)"
|
859 |
msgstr ""
|
860 |
|
861 |
-
#: includes/Admin.php:
|
862 |
msgid ""
|
863 |
"Custom price for product on Facebook. Please enter in monetary decimal (.) "
|
864 |
"format without thousand separators and currency symbols. If blank, product "
|
865 |
"price will be used."
|
866 |
msgstr ""
|
867 |
|
868 |
-
#: includes/Admin.php:
|
869 |
msgid "Use variation image"
|
870 |
msgstr ""
|
871 |
|
872 |
-
#: includes/Admin.php:
|
873 |
msgid "Use parent image"
|
874 |
msgstr ""
|
875 |
|
876 |
-
#: includes/Admin.php:
|
877 |
msgid "Close modal panel"
|
878 |
msgstr ""
|
879 |
|
880 |
-
#: includes/Commerce/Orders.php:
|
881 |
#. translators: Placeholders: %1$s - order remote id, %2$s - order created by
|
882 |
msgid "Order %1$s paid in %2$s"
|
883 |
msgstr ""
|
884 |
|
885 |
-
#: includes/Commerce/Orders.php:
|
886 |
msgid "Remote ID not found."
|
887 |
msgstr ""
|
888 |
|
889 |
-
#: includes/Commerce/Orders.php:
|
890 |
msgid "%s is not a valid shipping carrier code."
|
891 |
msgstr ""
|
892 |
|
893 |
-
#: includes/Commerce/Orders.php:
|
894 |
msgid "No valid Facebook products were found."
|
895 |
msgstr ""
|
896 |
|
897 |
-
#: includes/Commerce/Orders.php:
|
898 |
#. translators: Placeholder: %s - sales channel name, like Facebook or
|
899 |
#. Instagram
|
900 |
msgid "%s order fulfilled."
|
901 |
msgstr ""
|
902 |
|
903 |
-
#: includes/Commerce/Orders.php:
|
904 |
#. translators: Placeholders: %1$s - sales channel name, like Facebook or
|
905 |
#. Instagram, %2$s - error message
|
906 |
msgid "%1$s order could not be fulfilled. %2$s"
|
907 |
msgstr ""
|
908 |
|
909 |
-
#: includes/Commerce/Orders.php:
|
910 |
msgid "Parent order not found."
|
911 |
msgstr ""
|
912 |
|
913 |
-
#: includes/Commerce/Orders.php:
|
914 |
msgid "Remote ID for parent order not found."
|
915 |
msgstr ""
|
916 |
|
917 |
-
#: includes/Commerce/Orders.php:
|
918 |
#. translators: Placeholder: %s - sales channel name, like Facebook or
|
919 |
#. Instagram
|
920 |
msgid "Order refunded on %s."
|
921 |
msgstr ""
|
922 |
|
923 |
-
#: includes/Commerce/Orders.php:
|
924 |
#. translators: Placeholders: %1$s - sales channel name, like Facebook or
|
925 |
#. Instagram, %2$s - error message
|
926 |
msgid "Could not refund %1$s order: %2$s"
|
927 |
msgstr ""
|
928 |
|
929 |
-
#: includes/Commerce/Orders.php:
|
930 |
#. translators: Placeholder: %s - sales channel name, like Facebook or
|
931 |
#. Instagram
|
932 |
msgid "%s order cancelled."
|
933 |
msgstr ""
|
934 |
|
935 |
-
#: includes/Commerce/Orders.php:
|
936 |
#. translators: Placeholders: %1$s - sales channel name, like Facebook or
|
937 |
#. Instagram, %2$s - error message
|
938 |
msgid "%1$s order could not be cancelled. %2$s"
|
939 |
msgstr ""
|
940 |
|
941 |
-
#: includes/Commerce/Orders.php:
|
942 |
msgid "Customer requested cancellation"
|
943 |
msgstr ""
|
944 |
|
945 |
-
#: includes/Commerce/Orders.php:
|
946 |
msgid "Product(s) are out of stock"
|
947 |
msgstr ""
|
948 |
|
949 |
-
#: includes/Commerce/Orders.php:
|
950 |
msgid "Customer address is invalid"
|
951 |
msgstr ""
|
952 |
|
953 |
-
#: includes/Commerce/Orders.php:
|
954 |
msgid "Suspicious order"
|
955 |
msgstr ""
|
956 |
|
957 |
-
#: includes/Commerce/Orders.php:
|
958 |
msgid "Other"
|
959 |
msgstr ""
|
960 |
|
961 |
-
#: includes/Handlers/Connection.php:
|
962 |
msgid "Connection successful!"
|
963 |
msgstr ""
|
964 |
|
965 |
-
#: includes/Handlers/Connection.php:
|
966 |
msgid "You do not have permission to uninstall Facebook Business Extension."
|
967 |
msgstr ""
|
968 |
|
969 |
-
#: includes/Handlers/Connection.php:
|
970 |
msgid "Disconnection successful."
|
971 |
msgstr ""
|
972 |
|
973 |
-
#: includes/Handlers/Connection.php:
|
974 |
#. translators: Placeholders: %s - API error message
|
975 |
msgid "Could not retrieve page access data. %s"
|
976 |
msgstr ""
|
977 |
|
978 |
-
#: includes/Handlers/Connection.php:
|
979 |
#. translators: Placeholders: %s - Facebook page ID
|
980 |
msgid "Page %s not authorized."
|
981 |
msgstr ""
|
982 |
|
983 |
-
#: includes/Handlers/Connection.php:
|
984 |
msgid "You do not have permission to finish App Store login."
|
985 |
msgstr ""
|
986 |
|
@@ -992,14 +992,14 @@ msgstr ""
|
|
992 |
msgid "Job data key \"%s\" is not an array"
|
993 |
msgstr ""
|
994 |
|
995 |
-
#: includes/Products/Sync/Background.php:
|
996 |
msgid ""
|
997 |
"There was an error trying sync products using the Catalog Batch API for job "
|
998 |
-
"%s: %s"
|
999 |
msgstr ""
|
1000 |
|
1001 |
#: includes/fbgraph.php:105
|
1002 |
-
msgid "HTTP %s: %s"
|
1003 |
msgstr ""
|
1004 |
|
1005 |
#: includes/fbinfobanner.php:211
|
@@ -1014,19 +1014,19 @@ msgstr ""
|
|
1014 |
msgid "Dismiss"
|
1015 |
msgstr ""
|
1016 |
|
1017 |
-
#: includes/fbproductfeed.php:
|
1018 |
msgid "Could not create product catalog feed directory"
|
1019 |
msgstr ""
|
1020 |
|
1021 |
-
#: includes/fbproductfeed.php:
|
1022 |
msgid "Could not open the product catalog temporary feed file for writing"
|
1023 |
msgstr ""
|
1024 |
|
1025 |
-
#: includes/fbproductfeed.php:
|
1026 |
msgid "Could not open the product catalog feed file for writing"
|
1027 |
msgstr ""
|
1028 |
|
1029 |
-
#: includes/fbproductfeed.php:
|
1030 |
msgid "Could not rename the product catalog feed file"
|
1031 |
msgstr ""
|
1032 |
|
@@ -1067,7 +1067,7 @@ msgstr ""
|
|
1067 |
msgid "https://www.facebook.com/"
|
1068 |
msgstr ""
|
1069 |
|
1070 |
-
#: includes/Locale.php:
|
1071 |
msgctxt "language"
|
1072 |
msgid "English (United States)"
|
1073 |
msgstr ""
|
2 |
# This file is distributed under the same license as the Facebook for WooCommerce package.
|
3 |
msgid ""
|
4 |
msgstr ""
|
5 |
+
"Project-Id-Version: Facebook for WooCommerce 2.5.0\n"
|
6 |
"Report-Msgid-Bugs-To: "
|
7 |
"https://woocommerce.com/my-account/marketplace-ticket-form/\n"
|
8 |
+
"POT-Creation-Date: 2021-05-20 04:47:04+00:00\n"
|
9 |
"MIME-Version: 1.0\n"
|
10 |
"Content-Type: text/plain; charset=utf-8\n"
|
11 |
"Content-Transfer-Encoding: 8bit\n"
|
13 |
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
14 |
"Language-Team: LANGUAGE <LL@li.org>\n"
|
15 |
|
16 |
+
#: class-wc-facebookcommerce.php:252
|
17 |
#. translators: Placeholders %1$s - opening strong HTML tag, %2$s - closing
|
18 |
#. strong HTML tag, %3$s - opening link HTML tag, %4$s - closing link HTML tag
|
19 |
msgid ""
|
21 |
"Facebook for WooCommerce connection. Please %3$sclick here%4$s to reconnect!"
|
22 |
msgstr ""
|
23 |
|
24 |
+
#: class-wc-facebookcommerce.php:273
|
25 |
#. translators: Placeholders %1$s - opening link HTML tag, %2$s - closing link
|
26 |
#. HTML tag
|
27 |
msgid ""
|
29 |
"under %1$sWooCommerce > Facebook%2$s."
|
30 |
msgstr ""
|
31 |
|
32 |
+
#: class-wc-facebookcommerce.php:293
|
33 |
#. translators: Placeholders %1$s - opening strong HTML tag, %2$s - closing
|
34 |
#. strong HTML tag, %3$s - opening link HTML tag, %4$s - closing link HTML tag
|
35 |
msgid ""
|
37 |
"configuration, %3$scomplete the setup steps%4$s."
|
38 |
msgstr ""
|
39 |
|
40 |
+
#: class-wc-facebookcommerce.php:325
|
41 |
#. translators: Placeholders: %1$s - <strong> tag, %2$s - </strong> tag, %3$s -
|
42 |
#. <a> tag, %4$s - </a> tag
|
43 |
msgid ""
|
46 |
"Connection%4$s area."
|
47 |
msgstr ""
|
48 |
|
49 |
+
#: class-wc-facebookcommerce.php:348
|
50 |
#. translators: Placeholders: %1$s - <strong> tag, %2$s - </strong> tag, %3$s -
|
51 |
#. <a> tag, %4$s - </a> tag
|
52 |
msgid ""
|
55 |
"products."
|
56 |
msgstr ""
|
57 |
|
58 |
+
#: class-wc-facebookcommerce.php:374
|
59 |
#. translators: Placeholders: %1$s - opening <a> HTML link tag, %2$s - closing
|
60 |
#. </a> HTML link tag
|
61 |
msgid "Heads up! The Facebook menu is now located under the %1$sMarketing%2$s menu."
|
62 |
msgstr ""
|
63 |
|
64 |
+
#: class-wc-facebookcommerce.php:446
|
65 |
msgid "FB Product Sets"
|
66 |
msgstr ""
|
67 |
|
68 |
+
#: class-wc-facebookcommerce.php:447
|
69 |
msgid "FB Product Set"
|
70 |
msgstr ""
|
71 |
|
72 |
+
#: class-wc-facebookcommerce.php:455
|
73 |
#. translators: Edit item label
|
74 |
msgid "Edit %s"
|
75 |
msgstr ""
|
76 |
|
77 |
+
#: class-wc-facebookcommerce.php:457
|
78 |
#. translators: Add new label
|
79 |
msgid "Add new %s"
|
80 |
msgstr ""
|
81 |
|
82 |
+
#: class-wc-facebookcommerce.php:460
|
83 |
#. translators: No items found text
|
84 |
msgid "No %s found."
|
85 |
msgstr ""
|
86 |
|
87 |
+
#: class-wc-facebookcommerce.php:462
|
88 |
#. translators: Search label
|
89 |
msgid "Search %s."
|
90 |
msgstr ""
|
91 |
|
92 |
+
#: class-wc-facebookcommerce.php:464
|
93 |
#. translators: Text label
|
94 |
msgid "Separate %s with commas"
|
95 |
msgstr ""
|
96 |
|
97 |
+
#: class-wc-facebookcommerce.php:466
|
98 |
#. translators: Text label
|
99 |
msgid "Choose from the most used %s"
|
100 |
msgstr ""
|
101 |
|
102 |
+
#: class-wc-facebookcommerce.php:582
|
103 |
msgid "Cannot create the API instance because the access token is missing."
|
104 |
msgstr ""
|
105 |
|
107 |
msgid "Facebook for WooCommerce"
|
108 |
msgstr ""
|
109 |
|
110 |
+
#: facebook-commerce.php:228
|
111 |
msgid "Facebook Commerce and Dynamic Ads (Pixel) Extension"
|
112 |
msgstr ""
|
113 |
|
114 |
+
#: facebook-commerce.php:640
|
115 |
msgid "Facebook ID:"
|
116 |
msgstr ""
|
117 |
|
118 |
+
#: facebook-commerce.php:648
|
119 |
msgid "Variant IDs:"
|
120 |
msgstr ""
|
121 |
|
122 |
+
#: facebook-commerce.php:666
|
123 |
msgid "Reset Facebook metadata"
|
124 |
msgstr ""
|
125 |
|
126 |
+
#: facebook-commerce.php:671
|
127 |
msgid "Delete product(s) on Facebook"
|
128 |
msgstr ""
|
129 |
|
130 |
+
#: facebook-commerce.php:679
|
131 |
msgid "This product is not yet synced to Facebook."
|
132 |
msgstr ""
|
133 |
|
134 |
+
#: facebook-commerce.php:1491
|
135 |
msgid "Nothing to update for product group for %1$s"
|
136 |
msgstr ""
|
137 |
|
138 |
+
#: facebook-commerce.php:1885
|
139 |
#. translators: Placeholders %1$s - original error message from Facebook API
|
140 |
msgid "There was an issue connecting to the Facebook API: %1$s"
|
141 |
msgstr ""
|
142 |
|
143 |
+
#: facebook-commerce.php:2221
|
144 |
msgid "Your connection has expired."
|
145 |
msgstr ""
|
146 |
|
147 |
+
#: facebook-commerce.php:2221
|
148 |
msgid ""
|
149 |
"Please click Manage connection > Advanced Options > Update Token to refresh "
|
150 |
"your connection to Facebook."
|
151 |
msgstr ""
|
152 |
|
153 |
+
#: facebook-commerce.php:2228
|
154 |
#. translators: Placeholders %s - error message
|
155 |
msgid "There was an error trying to sync the products to Facebook. %s"
|
156 |
msgstr ""
|
157 |
|
158 |
+
#: facebook-commerce.php:2251 facebook-commerce.php:2424
|
159 |
msgid "Product sync is disabled."
|
160 |
msgstr ""
|
161 |
|
162 |
+
#: facebook-commerce.php:2258 facebook-commerce.php:2431
|
163 |
msgid "The plugin is not configured or the Catalog ID is missing."
|
164 |
msgstr ""
|
165 |
|
166 |
+
#: facebook-commerce.php:2281
|
167 |
msgid ""
|
168 |
"A product sync is in progress. Please wait until the sync finishes before "
|
169 |
"starting a new one."
|
170 |
msgstr ""
|
171 |
|
172 |
+
#: facebook-commerce.php:2293 facebook-commerce.php:2445
|
173 |
msgid ""
|
174 |
"We've detected that your Facebook Product Catalog is no longer valid. This "
|
175 |
"may happen if it was deleted, but could also be a temporary error. If the "
|
177 |
"and setup the plugin again."
|
178 |
msgstr ""
|
179 |
|
180 |
+
#: facebook-commerce.php:2469
|
181 |
msgid "We couldn't create the feed or upload the product information."
|
182 |
msgstr ""
|
183 |
|
184 |
+
#: facebook-commerce.php:2937
|
185 |
msgid "Hi! We're here to answer any questions you may have."
|
186 |
msgstr ""
|
187 |
|
188 |
+
#: facebook-commerce.php:3304
|
189 |
msgid "Facebook for WooCommerce error:"
|
190 |
msgstr ""
|
191 |
|
192 |
+
#: facebook-commerce.php:3386
|
193 |
msgid ""
|
194 |
"There was an error trying to retrieve information about the Facebook page: "
|
195 |
"%s"
|
196 |
msgstr ""
|
197 |
|
198 |
+
#: facebook-commerce.php:3437
|
199 |
msgid "Get started with Messenger Customer Chat"
|
200 |
msgstr ""
|
201 |
|
202 |
+
#: facebook-commerce.php:3438
|
203 |
msgid "Get started with Instagram Shopping"
|
204 |
msgstr ""
|
205 |
|
206 |
+
#: facebook-commerce.php:3673
|
207 |
#. translators: Placeholders %1$s - original error message from Facebook API
|
208 |
msgid "There was an issue connecting to the Facebook API: %s"
|
209 |
msgstr ""
|
224 |
msgid "A valid Order ID is required."
|
225 |
msgstr ""
|
226 |
|
227 |
+
#: includes/AJAX.php:181
|
228 |
msgid "Order ID is required"
|
229 |
msgstr ""
|
230 |
|
231 |
+
#: includes/AJAX.php:185
|
232 |
msgid "Tracking number is required"
|
233 |
msgstr ""
|
234 |
|
235 |
+
#: includes/AJAX.php:189
|
236 |
msgid "Carrier code is required"
|
237 |
msgstr ""
|
238 |
|
239 |
+
#: includes/AJAX.php:195
|
240 |
msgid "Order not found"
|
241 |
msgstr ""
|
242 |
|
243 |
+
#: includes/AJAX.php:337 includes/AJAX.php:408
|
244 |
msgid "Go to Settings"
|
245 |
msgstr ""
|
246 |
|
247 |
+
#: includes/AJAX.php:342 includes/AJAX.php:413 includes/AJAX.php:479
|
248 |
#: includes/Admin/Product_Categories.php:118
|
249 |
+
#: includes/Admin/Settings_Screens/Product_Sync.php:157 includes/Admin.php:391
|
250 |
msgid "Cancel"
|
251 |
msgstr ""
|
252 |
|
253 |
+
#: includes/AJAX.php:351
|
254 |
#. translators: Placeholder %s - <br/> tag
|
255 |
msgid ""
|
256 |
"This product belongs to a category or tag that is excluded from the "
|
259 |
"or click Cancel and update the product's category / tag assignments."
|
260 |
msgstr ""
|
261 |
|
262 |
+
#: includes/AJAX.php:420
|
263 |
msgid ""
|
264 |
"One or more of the selected products belongs to a category or tag that is "
|
265 |
"excluded from the Facebook catalog sync. To sync these products to "
|
267 |
"settings."
|
268 |
msgstr ""
|
269 |
|
270 |
+
#: includes/AJAX.php:473
|
271 |
msgid "Exclude Products"
|
272 |
msgstr ""
|
273 |
|
274 |
+
#: includes/AJAX.php:488
|
275 |
#. translators: Placeholder %s - <br/> tags
|
276 |
msgid ""
|
277 |
"The categories and/or tags that you have selected to exclude from sync "
|
289 |
msgstr ""
|
290 |
|
291 |
#: includes/Admin/Product_Categories.php:99
|
292 |
+
#: includes/Admin/Settings_Screens/Product_Sync.php:120
|
293 |
msgid ""
|
294 |
"Products and categories that inherit this global setting (i.e. they do not "
|
295 |
"have a specific Google product category set) will use the new default "
|
297 |
msgstr ""
|
298 |
|
299 |
#: includes/Admin/Product_Categories.php:122
|
300 |
+
#: includes/Admin/Settings_Screens/Product_Sync.php:161
|
301 |
msgid "Update default Google product category"
|
302 |
msgstr ""
|
303 |
|
316 |
msgstr ""
|
317 |
|
318 |
#: includes/Admin/Product_Categories.php:232
|
319 |
+
#: includes/Admin/Settings_Screens/Product_Sync.php:339
|
320 |
msgid "Default Google product category"
|
321 |
msgstr ""
|
322 |
|
381 |
msgid "Facebook"
|
382 |
msgstr ""
|
383 |
|
384 |
+
#: includes/Admin/Settings.php:120
|
385 |
#: includes/Admin/Settings_Screens/Connection.php:34
|
386 |
#: includes/Admin/Settings_Screens/Connection.php:35
|
387 |
msgid "Connection"
|
388 |
msgstr ""
|
389 |
|
390 |
+
#: includes/Admin/Settings.php:123
|
391 |
#: includes/Admin/Settings_Screens/Messenger.php:40
|
392 |
#: includes/Admin/Settings_Screens/Messenger.php:41
|
393 |
+
#: includes/Admin/Settings_Screens/Messenger.php:147
|
394 |
msgid "Messenger"
|
395 |
msgstr ""
|
396 |
|
397 |
+
#: includes/Admin/Settings.php:126
|
398 |
#: includes/Admin/Settings_Screens/Product_Sync.php:42
|
399 |
#: includes/Admin/Settings_Screens/Product_Sync.php:43
|
400 |
+
#: includes/Admin/Settings_Screens/Product_Sync.php:182
|
401 |
+
#: includes/Admin/Settings_Screens/Product_Sync.php:285
|
402 |
msgid "Product sync"
|
403 |
msgstr ""
|
404 |
|
405 |
+
#: includes/Admin/Settings.php:129
|
406 |
#: includes/Admin/Settings_Screens/Advertise.php:37
|
407 |
#: includes/Admin/Settings_Screens/Advertise.php:38
|
408 |
msgid "Advertise"
|
409 |
msgstr ""
|
410 |
|
411 |
+
#: includes/Admin/Settings.php:215
|
412 |
msgid "You do not have permission to save these settings."
|
413 |
msgstr ""
|
414 |
|
415 |
+
#: includes/Admin/Settings.php:224
|
416 |
msgid "Your settings have been saved."
|
417 |
msgstr ""
|
418 |
|
419 |
+
#: includes/Admin/Settings.php:231
|
420 |
#. translators: Placeholders: %s - user-friendly error message
|
421 |
msgid "Your settings could not be saved. %s"
|
422 |
msgstr ""
|
442 |
"touch with our support team%6$s for assistance."
|
443 |
msgstr ""
|
444 |
|
445 |
+
#: includes/Admin/Settings_Screens/Connection.php:130
|
446 |
msgid "Page"
|
447 |
msgstr ""
|
448 |
|
449 |
+
#: includes/Admin/Settings_Screens/Connection.php:134
|
450 |
msgid "Pixel"
|
451 |
msgstr ""
|
452 |
|
453 |
+
#: includes/Admin/Settings_Screens/Connection.php:138
|
454 |
msgid "Catalog"
|
455 |
msgstr ""
|
456 |
|
457 |
+
#: includes/Admin/Settings_Screens/Connection.php:143
|
458 |
msgid "Business Manager account"
|
459 |
msgstr ""
|
460 |
|
461 |
+
#: includes/Admin/Settings_Screens/Connection.php:147
|
462 |
msgid "Ad Manager account"
|
463 |
msgstr ""
|
464 |
|
465 |
+
#: includes/Admin/Settings_Screens/Connection.php:151
|
466 |
msgid "Instagram Business ID"
|
467 |
msgstr ""
|
468 |
|
469 |
+
#: includes/Admin/Settings_Screens/Connection.php:155
|
470 |
msgid "Commerce Merchant Settings ID"
|
471 |
msgstr ""
|
472 |
|
473 |
+
#: includes/Admin/Settings_Screens/Connection.php:254
|
474 |
msgid "Reach the Right People and Sell More Online"
|
475 |
msgstr ""
|
476 |
|
477 |
+
#: includes/Admin/Settings_Screens/Connection.php:256
|
478 |
msgid "Grow your business on Facebook"
|
479 |
msgstr ""
|
480 |
|
481 |
+
#: includes/Admin/Settings_Screens/Connection.php:259
|
482 |
msgid "Use this WooCommerce and Facebook integration to:"
|
483 |
msgstr ""
|
484 |
|
485 |
+
#: includes/Admin/Settings_Screens/Connection.php:261
|
486 |
msgid "Create an ad in a few steps"
|
487 |
msgstr ""
|
488 |
|
489 |
+
#: includes/Admin/Settings_Screens/Connection.php:262
|
490 |
msgid "Use built-in best practices for online sales"
|
491 |
msgstr ""
|
492 |
|
493 |
+
#: includes/Admin/Settings_Screens/Connection.php:263
|
494 |
msgid "Get reporting on sales and revenue"
|
495 |
msgstr ""
|
496 |
|
497 |
+
#: includes/Admin/Settings_Screens/Connection.php:286
|
498 |
msgid "Manage Connection"
|
499 |
msgstr ""
|
500 |
|
501 |
+
#: includes/Admin/Settings_Screens/Connection.php:290
|
502 |
msgid "Disconnect"
|
503 |
msgstr ""
|
504 |
|
505 |
+
#: includes/Admin/Settings_Screens/Connection.php:296
|
506 |
msgid "Get Started"
|
507 |
msgstr ""
|
508 |
|
509 |
+
#: includes/Admin/Settings_Screens/Connection.php:321
|
510 |
msgid "Debug"
|
511 |
msgstr ""
|
512 |
|
513 |
+
#: includes/Admin/Settings_Screens/Connection.php:327
|
514 |
msgid "Enable debug mode"
|
515 |
msgstr ""
|
516 |
|
517 |
+
#: includes/Admin/Settings_Screens/Connection.php:329
|
518 |
msgid "Log plugin events for debugging"
|
519 |
msgstr ""
|
520 |
|
521 |
+
#: includes/Admin/Settings_Screens/Connection.php:330
|
522 |
msgid "Only enable this if you are experiencing problems with the plugin."
|
523 |
msgstr ""
|
524 |
|
525 |
+
#: includes/Admin/Settings_Screens/Messenger.php:121
|
526 |
#. translators: Placeholders: %1$s - <a> tag, %2$s - </a> tag
|
527 |
msgid "%1$sClick here%2$s to manage your Messenger greeting and colors."
|
528 |
msgstr ""
|
529 |
|
530 |
+
#: includes/Admin/Settings_Screens/Messenger.php:153
|
531 |
msgid "Enable Messenger"
|
532 |
msgstr ""
|
533 |
|
534 |
+
#: includes/Admin/Settings_Screens/Messenger.php:155
|
535 |
msgid "Enable and customize Facebook Messenger on your store"
|
536 |
msgstr ""
|
537 |
|
538 |
+
#: includes/Admin/Settings_Screens/Messenger.php:165
|
539 |
msgid "Language"
|
540 |
msgstr ""
|
541 |
|
542 |
+
#: includes/Admin/Settings_Screens/Messenger.php:170
|
543 |
msgid "Greeting & Colors"
|
544 |
msgstr ""
|
545 |
|
546 |
+
#: includes/Admin/Settings_Screens/Messenger.php:192
|
547 |
#. translators: Placeholders: %1$s - <a> tag, %2$s - </a> tag
|
548 |
msgid "Please %1$sconnect to Facebook%2$s to enable and manage Facebook Messenger."
|
549 |
msgstr ""
|
550 |
|
551 |
+
#: includes/Admin/Settings_Screens/Messenger.php:245
|
552 |
#. translators: Placeholders: %1$s - <a> tag, %2$s - </a> tag
|
553 |
msgid ""
|
554 |
"There was an error communicating with the Facebook Business Extension. "
|
555 |
"%1$sClick here%2$s to manage your Messenger settings."
|
556 |
msgstr ""
|
557 |
|
558 |
+
#: includes/Admin/Settings_Screens/Messenger.php:317
|
559 |
msgid "Please try again."
|
560 |
msgstr ""
|
561 |
|
564 |
msgid "Product sets"
|
565 |
msgstr ""
|
566 |
|
567 |
+
#: includes/Admin/Settings_Screens/Product_Sync.php:81
|
568 |
#. translators: Placeholders: {count} number of remaining items
|
569 |
msgid "{count} item remaining."
|
570 |
msgid_plural "{count} items remaining."
|
571 |
msgstr[0] ""
|
572 |
msgstr[1] ""
|
573 |
|
574 |
+
#: includes/Admin/Settings_Screens/Product_Sync.php:96
|
575 |
#. translators: Placeholders %s - html code for a spinner icon
|
576 |
msgid "Your products will now be resynced to Facebook, this may take some time."
|
577 |
msgstr ""
|
578 |
|
579 |
+
#: includes/Admin/Settings_Screens/Product_Sync.php:97
|
580 |
msgid ""
|
581 |
"Facebook for WooCommerce automatically syncs your products on "
|
582 |
"create/update. Are you sure you want to force product resync?\n"
|
586 |
"did not sync."
|
587 |
msgstr ""
|
588 |
|
589 |
+
#: includes/Admin/Settings_Screens/Product_Sync.php:98
|
590 |
msgid "Your products are syncing - you may safely leave this page %s"
|
591 |
msgstr ""
|
592 |
|
593 |
+
#: includes/Admin/Settings_Screens/Product_Sync.php:101
|
594 |
msgid "There was an error trying to sync the products to Facebook."
|
595 |
msgstr ""
|
596 |
|
597 |
+
#: includes/Admin/Settings_Screens/Product_Sync.php:102
|
598 |
msgid ""
|
599 |
"Something went wrong while uploading the product information, please try "
|
600 |
"again."
|
601 |
msgstr ""
|
602 |
|
603 |
+
#: includes/Admin/Settings_Screens/Product_Sync.php:135
|
604 |
#. translators: Placeholders: %1$s - <strong> tag, %2$s - </strong> tag
|
605 |
msgid ""
|
606 |
"Products and categories that inherit this global setting (they do not have "
|
610 |
"Are you sure you want to proceed?"
|
611 |
msgstr ""
|
612 |
|
613 |
+
#: includes/Admin/Settings_Screens/Product_Sync.php:190
|
614 |
msgid "Sync products"
|
615 |
msgstr ""
|
616 |
|
617 |
+
#: includes/Admin/Settings_Screens/Product_Sync.php:290
|
618 |
msgid "Enable product sync"
|
619 |
msgstr ""
|
620 |
|
621 |
+
#: includes/Admin/Settings_Screens/Product_Sync.php:298
|
622 |
msgid "Exclude categories from sync"
|
623 |
msgstr ""
|
624 |
|
625 |
+
#: includes/Admin/Settings_Screens/Product_Sync.php:302
|
626 |
msgid "Products in one or more of these categories will not sync to Facebook."
|
627 |
msgstr ""
|
628 |
|
629 |
+
#: includes/Admin/Settings_Screens/Product_Sync.php:306
|
630 |
msgid "Search for a product category…"
|
631 |
msgstr ""
|
632 |
|
633 |
+
#: includes/Admin/Settings_Screens/Product_Sync.php:312
|
634 |
msgid "Exclude tags from sync"
|
635 |
msgstr ""
|
636 |
|
637 |
+
#: includes/Admin/Settings_Screens/Product_Sync.php:316
|
638 |
msgid "Products with one or more of these tags will not sync to Facebook."
|
639 |
msgstr ""
|
640 |
|
641 |
+
#: includes/Admin/Settings_Screens/Product_Sync.php:320
|
642 |
msgid "Search for a product tag…"
|
643 |
msgstr ""
|
644 |
|
645 |
+
#: includes/Admin/Settings_Screens/Product_Sync.php:326
|
646 |
msgid "Product description sync"
|
647 |
msgstr ""
|
648 |
|
649 |
+
#: includes/Admin/Settings_Screens/Product_Sync.php:329
|
650 |
msgid "Choose which product description to display in the Facebook catalog."
|
651 |
msgstr ""
|
652 |
|
653 |
+
#: includes/Admin/Settings_Screens/Product_Sync.php:332
|
654 |
msgid "Standard description"
|
655 |
msgstr ""
|
656 |
|
657 |
+
#: includes/Admin/Settings_Screens/Product_Sync.php:333
|
658 |
msgid "Short description"
|
659 |
msgstr ""
|
660 |
|
661 |
+
#: includes/Admin/Settings_Screens/Product_Sync.php:340
|
662 |
msgid ""
|
663 |
"Choose a default Google product category for your products. Defaults can "
|
664 |
"also be set for product categories. Products need at least two category "
|
665 |
"levels defined for tax to be correctly applied."
|
666 |
msgstr ""
|
667 |
|
668 |
+
#: includes/Admin/Settings_Screens/Product_Sync.php:386
|
669 |
#. translators: Placeholders: %1$s - <a> tag, %2$s - </a> tag
|
670 |
msgid "Please %1$sconnect to Facebook%2$s to enable and manage product sync."
|
671 |
msgstr ""
|
674 |
msgid "The name is how it appears on Facebook Catalog."
|
675 |
msgstr ""
|
676 |
|
677 |
+
#: includes/Admin.php:212
|
678 |
msgid ""
|
679 |
"Please enter a Google product category and at least one sub-category to "
|
680 |
"sell this product on Instagram."
|
681 |
msgstr ""
|
682 |
|
683 |
+
#: includes/Admin.php:238
|
684 |
msgid "Search main categories..."
|
685 |
msgstr ""
|
686 |
|
687 |
+
#: includes/Admin.php:239
|
688 |
msgid "Choose a main category"
|
689 |
msgstr ""
|
690 |
|
691 |
+
#: includes/Admin.php:240
|
692 |
msgid "Choose a category"
|
693 |
msgstr ""
|
694 |
|
695 |
+
#: includes/Admin.php:279
|
696 |
msgid ""
|
697 |
"To sell this product on Instagram, please ensure it meets the following "
|
698 |
"requirements:"
|
699 |
msgstr ""
|
700 |
|
701 |
+
#: includes/Admin.php:282
|
702 |
msgid "Has a price defined"
|
703 |
msgstr ""
|
704 |
|
705 |
+
#: includes/Admin.php:288
|
706 |
#. translators: Placeholders: %1$s - <strong> opening HTML tag, %2$s -
|
707 |
#. </strong> closing HTML tag
|
708 |
msgid "Has %1$sManage Stock%2$s enabled on the %1$sInventory%2$s tab"
|
709 |
msgstr ""
|
710 |
|
711 |
+
#: includes/Admin.php:300
|
712 |
#. translators: Placeholders: %1$s - <strong> opening HTML tag, %2$s -
|
713 |
#. </strong> closing HTML tag
|
714 |
msgid ""
|
716 |
"and hide\""
|
717 |
msgstr ""
|
718 |
|
719 |
+
#: includes/Admin.php:329
|
720 |
msgid "Close"
|
721 |
msgstr ""
|
722 |
|
723 |
+
#: includes/Admin.php:354
|
724 |
#. translators: Placeholders: %1$s - opening <a> link tag, %2$s - closing </a>
|
725 |
#. link tag
|
726 |
msgid ""
|
729 |
"the Facebook catalog as well?"
|
730 |
msgstr ""
|
731 |
|
732 |
+
#: includes/Admin.php:383
|
733 |
msgid "Remove from sync only"
|
734 |
msgstr ""
|
735 |
|
736 |
+
#: includes/Admin.php:387
|
737 |
msgid "Remove from sync and delete"
|
738 |
msgstr ""
|
739 |
|
740 |
+
#: includes/Admin.php:423 includes/Admin.php:1266 includes/Admin.php:1408
|
741 |
msgid "Facebook sync"
|
742 |
msgstr ""
|
743 |
|
744 |
+
#: includes/Admin.php:450 includes/Admin.php:481
|
745 |
msgid "Sync and show"
|
746 |
msgstr ""
|
747 |
|
748 |
+
#: includes/Admin.php:452 includes/Admin.php:482
|
749 |
msgid "Sync and hide"
|
750 |
msgstr ""
|
751 |
|
752 |
+
#: includes/Admin.php:456 includes/Admin.php:483 includes/Admin.php:1270
|
753 |
+
#: includes/Admin.php:1412
|
754 |
msgid "Do not sync"
|
755 |
msgstr ""
|
756 |
|
757 |
+
#: includes/Admin.php:480
|
758 |
msgid "Filter by Facebook sync setting"
|
759 |
msgstr ""
|
760 |
|
761 |
+
#: includes/Admin.php:893
|
762 |
msgid "Include in Facebook sync"
|
763 |
msgstr ""
|
764 |
|
765 |
+
#: includes/Admin.php:894
|
766 |
msgid "Exclude from Facebook sync"
|
767 |
msgstr ""
|
768 |
|
769 |
+
#: includes/Admin.php:1087
|
770 |
#. translators: Placeholders: %1$s - <strong> tag, %2$s - </strong> tag, %3$s -
|
771 |
#. <a> tag, %4$s - <a> tag
|
772 |
msgid ""
|
780 |
msgstr[0] ""
|
781 |
msgstr[1] ""
|
782 |
|
783 |
+
#: includes/Admin.php:1094
|
784 |
msgid "Don't show this notice again"
|
785 |
msgstr ""
|
786 |
|
787 |
+
#: includes/Admin.php:1128
|
788 |
#. translators: Placeholders: %1$s - number of affected products, %2$s opening
|
789 |
#. HTML <a> tag, %3$s - closing HTML </a> tag, %4$s - opening HTML <a> tag,
|
790 |
#. %5$s - closing HTML </a> tag
|
801 |
msgstr[0] ""
|
802 |
msgstr[1] ""
|
803 |
|
804 |
+
#: includes/Admin.php:1194
|
805 |
#. translators: Placeholders: %1$s - opening HTML <strong> tag, %2$s - closing
|
806 |
#. HTML </strong> tag, %3$s - opening HTML <a> tag, %4$s - closing HTML </a>
|
807 |
#. tag
|
811 |
"your Facebook catalog. You may still advertise Virtual products on Facebook."
|
812 |
msgstr ""
|
813 |
|
814 |
+
#: includes/Admin.php:1268 includes/Admin.php:1410
|
815 |
msgid "Sync and show in catalog"
|
816 |
msgstr ""
|
817 |
|
818 |
+
#: includes/Admin.php:1269 includes/Admin.php:1411
|
819 |
msgid "Sync and hide in catalog"
|
820 |
msgstr ""
|
821 |
|
822 |
+
#: includes/Admin.php:1279 includes/Admin.php:1424
|
823 |
msgid "Facebook Description"
|
824 |
msgstr ""
|
825 |
|
826 |
+
#: includes/Admin.php:1281 includes/Admin.php:1426
|
827 |
msgid ""
|
828 |
"Custom (plain-text only) description for product on Facebook. If blank, "
|
829 |
"product description will be used. If product description is blank, "
|
830 |
"shortname will be used."
|
831 |
msgstr ""
|
832 |
|
833 |
+
#: includes/Admin.php:1292 includes/Admin.php:1439
|
834 |
msgid "Facebook Product Image"
|
835 |
msgstr ""
|
836 |
|
837 |
+
#: includes/Admin.php:1294 includes/Admin.php:1441
|
838 |
msgid ""
|
839 |
"Choose the product image that should be synced to the Facebook catalog for "
|
840 |
"this product. If using a custom image, please enter an absolute URL (e.g. "
|
841 |
"https://domain.com/image.jpg)."
|
842 |
msgstr ""
|
843 |
|
844 |
+
#: includes/Admin.php:1296
|
845 |
msgid "Use WooCommerce image"
|
846 |
msgstr ""
|
847 |
|
848 |
+
#: includes/Admin.php:1297 includes/Admin.php:1445
|
849 |
msgid "Use custom image"
|
850 |
msgstr ""
|
851 |
|
852 |
+
#: includes/Admin.php:1308 includes/Admin.php:1457
|
853 |
msgid "Custom Image URL"
|
854 |
msgstr ""
|
855 |
|
856 |
+
#: includes/Admin.php:1319 includes/Admin.php:1470
|
857 |
#. translators: Placeholders %1$s - WC currency symbol
|
858 |
msgid "Facebook Price (%1$s)"
|
859 |
msgstr ""
|
860 |
|
861 |
+
#: includes/Admin.php:1323 includes/Admin.php:1474
|
862 |
msgid ""
|
863 |
"Custom price for product on Facebook. Please enter in monetary decimal (.) "
|
864 |
"format without thousand separators and currency symbols. If blank, product "
|
865 |
"price will be used."
|
866 |
msgstr ""
|
867 |
|
868 |
+
#: includes/Admin.php:1443
|
869 |
msgid "Use variation image"
|
870 |
msgstr ""
|
871 |
|
872 |
+
#: includes/Admin.php:1444
|
873 |
msgid "Use parent image"
|
874 |
msgstr ""
|
875 |
|
876 |
+
#: includes/Admin.php:1598
|
877 |
msgid "Close modal panel"
|
878 |
msgstr ""
|
879 |
|
880 |
+
#: includes/Commerce/Orders.php:432
|
881 |
#. translators: Placeholders: %1$s - order remote id, %2$s - order created by
|
882 |
msgid "Order %1$s paid in %2$s"
|
883 |
msgstr ""
|
884 |
|
885 |
+
#: includes/Commerce/Orders.php:584 includes/Commerce/Orders.php:819
|
886 |
msgid "Remote ID not found."
|
887 |
msgstr ""
|
888 |
|
889 |
+
#: includes/Commerce/Orders.php:591
|
890 |
msgid "%s is not a valid shipping carrier code."
|
891 |
msgstr ""
|
892 |
|
893 |
+
#: includes/Commerce/Orders.php:609 includes/Commerce/Orders.php:786
|
894 |
msgid "No valid Facebook products were found."
|
895 |
msgstr ""
|
896 |
|
897 |
+
#: includes/Commerce/Orders.php:627
|
898 |
#. translators: Placeholder: %s - sales channel name, like Facebook or
|
899 |
#. Instagram
|
900 |
msgid "%s order fulfilled."
|
901 |
msgstr ""
|
902 |
|
903 |
+
#: includes/Commerce/Orders.php:637
|
904 |
#. translators: Placeholders: %1$s - sales channel name, like Facebook or
|
905 |
#. Instagram, %2$s - error message
|
906 |
msgid "%1$s order could not be fulfilled. %2$s"
|
907 |
msgstr ""
|
908 |
|
909 |
+
#: includes/Commerce/Orders.php:681
|
910 |
msgid "Parent order not found."
|
911 |
msgstr ""
|
912 |
|
913 |
+
#: includes/Commerce/Orders.php:687
|
914 |
msgid "Remote ID for parent order not found."
|
915 |
msgstr ""
|
916 |
|
917 |
+
#: includes/Commerce/Orders.php:718
|
918 |
#. translators: Placeholder: %s - sales channel name, like Facebook or
|
919 |
#. Instagram
|
920 |
msgid "Order refunded on %s."
|
921 |
msgstr ""
|
922 |
|
923 |
+
#: includes/Commerce/Orders.php:730
|
924 |
#. translators: Placeholders: %1$s - sales channel name, like Facebook or
|
925 |
#. Instagram, %2$s - error message
|
926 |
msgid "Could not refund %1$s order: %2$s"
|
927 |
msgstr ""
|
928 |
|
929 |
+
#: includes/Commerce/Orders.php:827
|
930 |
#. translators: Placeholder: %s - sales channel name, like Facebook or
|
931 |
#. Instagram
|
932 |
msgid "%s order cancelled."
|
933 |
msgstr ""
|
934 |
|
935 |
+
#: includes/Commerce/Orders.php:837
|
936 |
#. translators: Placeholders: %1$s - sales channel name, like Facebook or
|
937 |
#. Instagram, %2$s - error message
|
938 |
msgid "%1$s order could not be cancelled. %2$s"
|
939 |
msgstr ""
|
940 |
|
941 |
+
#: includes/Commerce/Orders.php:859
|
942 |
msgid "Customer requested cancellation"
|
943 |
msgstr ""
|
944 |
|
945 |
+
#: includes/Commerce/Orders.php:860
|
946 |
msgid "Product(s) are out of stock"
|
947 |
msgstr ""
|
948 |
|
949 |
+
#: includes/Commerce/Orders.php:861
|
950 |
msgid "Customer address is invalid"
|
951 |
msgstr ""
|
952 |
|
953 |
+
#: includes/Commerce/Orders.php:862
|
954 |
msgid "Suspicious order"
|
955 |
msgstr ""
|
956 |
|
957 |
+
#: includes/Commerce/Orders.php:863
|
958 |
msgid "Other"
|
959 |
msgstr ""
|
960 |
|
961 |
+
#: includes/Handlers/Connection.php:316
|
962 |
msgid "Connection successful!"
|
963 |
msgstr ""
|
964 |
|
965 |
+
#: includes/Handlers/Connection.php:347
|
966 |
msgid "You do not have permission to uninstall Facebook Business Extension."
|
967 |
msgstr ""
|
968 |
|
969 |
+
#: includes/Handlers/Connection.php:357
|
970 |
msgid "Disconnection successful."
|
971 |
msgstr ""
|
972 |
|
973 |
+
#: includes/Handlers/Connection.php:422
|
974 |
#. translators: Placeholders: %s - API error message
|
975 |
msgid "Could not retrieve page access data. %s"
|
976 |
msgstr ""
|
977 |
|
978 |
+
#: includes/Handlers/Connection.php:436
|
979 |
#. translators: Placeholders: %s - Facebook page ID
|
980 |
msgid "Page %s not authorized."
|
981 |
msgstr ""
|
982 |
|
983 |
+
#: includes/Handlers/Connection.php:1385
|
984 |
msgid "You do not have permission to finish App Store login."
|
985 |
msgstr ""
|
986 |
|
992 |
msgid "Job data key \"%s\" is not an array"
|
993 |
msgstr ""
|
994 |
|
995 |
+
#: includes/Products/Sync/Background.php:157
|
996 |
msgid ""
|
997 |
"There was an error trying sync products using the Catalog Batch API for job "
|
998 |
+
"%1$s: %2$s"
|
999 |
msgstr ""
|
1000 |
|
1001 |
#: includes/fbgraph.php:105
|
1002 |
+
msgid "HTTP %1$s: %2$s"
|
1003 |
msgstr ""
|
1004 |
|
1005 |
#: includes/fbinfobanner.php:211
|
1014 |
msgid "Dismiss"
|
1015 |
msgstr ""
|
1016 |
|
1017 |
+
#: includes/fbproductfeed.php:465
|
1018 |
msgid "Could not create product catalog feed directory"
|
1019 |
msgstr ""
|
1020 |
|
1021 |
+
#: includes/fbproductfeed.php:530
|
1022 |
msgid "Could not open the product catalog temporary feed file for writing"
|
1023 |
msgstr ""
|
1024 |
|
1025 |
+
#: includes/fbproductfeed.php:537
|
1026 |
msgid "Could not open the product catalog feed file for writing"
|
1027 |
msgstr ""
|
1028 |
|
1029 |
+
#: includes/fbproductfeed.php:580
|
1030 |
msgid "Could not rename the product catalog feed file"
|
1031 |
msgstr ""
|
1032 |
|
1067 |
msgid "https://www.facebook.com/"
|
1068 |
msgstr ""
|
1069 |
|
1070 |
+
#: includes/Locale.php:180
|
1071 |
msgctxt "language"
|
1072 |
msgid "English (United States)"
|
1073 |
msgstr ""
|
includes/AJAX.php
CHANGED
@@ -41,26 +41,26 @@ class AJAX {
|
|
41 |
public function __construct() {
|
42 |
|
43 |
// maybe output a modal prompt when toggling product sync in bulk or individual product actions
|
44 |
-
add_action( 'wp_ajax_facebook_for_woocommerce_set_product_sync_prompt',
|
45 |
-
add_action( 'wp_ajax_facebook_for_woocommerce_set_product_sync_bulk_action_prompt',
|
46 |
|
47 |
// maybe output a modal prompt when setting excluded terms
|
48 |
-
add_action( 'wp_ajax_facebook_for_woocommerce_set_excluded_terms_prompt',
|
49 |
|
50 |
// sync all products via AJAX
|
51 |
-
add_action( 'wp_ajax_wc_facebook_sync_products',
|
52 |
|
53 |
// get the current sync status
|
54 |
-
add_action( 'wp_ajax_wc_facebook_get_sync_status',
|
55 |
|
56 |
// search a product's attributes for the given term
|
57 |
-
add_action( 'wp_ajax_' . self::ACTION_SEARCH_PRODUCT_ATTRIBUTES,
|
58 |
|
59 |
// complete a Facebook order for the given order ID
|
60 |
-
add_action( 'wp_ajax_' . self::ACTION_COMPLETE_ORDER,
|
61 |
|
62 |
// cancel facebook order by the given order ID
|
63 |
-
add_action( 'wp_ajax_' . self::ACTION_CANCEL_ORDER,
|
64 |
}
|
65 |
|
66 |
|
@@ -139,11 +139,15 @@ class AJAX {
|
|
139 |
$attributes = Admin\Products::get_available_product_attribute_names( $product );
|
140 |
|
141 |
// filter out any attributes whose slug or proper name don't at least partially match the search term
|
142 |
-
$results = array_filter(
|
|
|
|
|
143 |
|
144 |
-
|
145 |
|
146 |
-
|
|
|
|
|
147 |
|
148 |
wp_send_json( $results );
|
149 |
|
@@ -232,9 +236,11 @@ class AJAX {
|
|
232 |
|
233 |
$remaining_products = 0;
|
234 |
|
235 |
-
$jobs = facebook_for_woocommerce()->get_products_sync_background_handler()->get_jobs(
|
236 |
-
|
237 |
-
|
|
|
|
|
238 |
|
239 |
if ( ! empty( $jobs ) ) {
|
240 |
|
@@ -246,7 +252,6 @@ class AJAX {
|
|
246 |
if ( ! empty( $job->progress ) ) {
|
247 |
$remaining_products -= $job->progress;
|
248 |
}
|
249 |
-
|
250 |
}
|
251 |
|
252 |
wp_send_json_success( $remaining_products );
|
@@ -265,17 +270,17 @@ class AJAX {
|
|
265 |
check_ajax_referer( 'set-product-sync-prompt', 'security' );
|
266 |
|
267 |
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
268 |
-
$product_id
|
269 |
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
270 |
-
$sync_enabled
|
271 |
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
272 |
$var_sync_enabled = isset( $_POST['var_sync_enabled'] ) ? (string) $_POST['var_sync_enabled'] : '';
|
273 |
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
274 |
-
$product_cats
|
275 |
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
276 |
-
$product_tags
|
277 |
|
278 |
-
if ( $product_id > 0 && in_array( $var_sync_enabled,
|
279 |
|
280 |
$product = wc_get_product( $product_id );
|
281 |
|
@@ -296,7 +301,7 @@ class AJAX {
|
|
296 |
// try next with tags, but WordPress only gives us tag names
|
297 |
if ( ! $has_excluded_terms && ! empty( $product_tags ) ) {
|
298 |
|
299 |
-
$product_tag_ids =
|
300 |
|
301 |
foreach ( $product_tags as $product_tag_name_or_id ) {
|
302 |
|
@@ -339,14 +344,16 @@ class AJAX {
|
|
339 |
|
340 |
$buttons = ob_get_clean();
|
341 |
|
342 |
-
wp_send_json_error(
|
343 |
-
|
344 |
-
|
345 |
-
|
346 |
-
|
347 |
-
|
348 |
-
|
349 |
-
|
|
|
|
|
350 |
}
|
351 |
}
|
352 |
}
|
@@ -368,9 +375,9 @@ class AJAX {
|
|
368 |
check_ajax_referer( 'set-product-sync-bulk-action-prompt', 'security' );
|
369 |
|
370 |
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
371 |
-
$product_ids = isset( $_POST['products'] ) ? (array)
|
372 |
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
373 |
-
$toggle
|
374 |
|
375 |
if ( ! empty( $product_ids ) && ! empty( $toggle ) && 'facebook_include' === $toggle ) {
|
376 |
|
@@ -389,7 +396,7 @@ class AJAX {
|
|
389 |
}
|
390 |
|
391 |
// show modal if there's at least one product that belongs to an excluded term
|
392 |
-
if ( $has_excluded_term )
|
393 |
|
394 |
ob_start();
|
395 |
|
@@ -408,10 +415,12 @@ class AJAX {
|
|
408 |
|
409 |
$buttons = ob_get_clean();
|
410 |
|
411 |
-
wp_send_json_error(
|
412 |
-
|
413 |
-
|
414 |
-
|
|
|
|
|
415 |
}
|
416 |
}
|
417 |
|
@@ -431,12 +440,12 @@ class AJAX {
|
|
431 |
check_ajax_referer( 'set-excluded-terms-prompt', 'security' );
|
432 |
|
433 |
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
|
434 |
-
$posted_categories = isset( $_POST['categories'] ) ? wp_unslash( $_POST['categories'] ) :
|
435 |
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
|
436 |
-
$posted_tags = isset( $_POST['tags'] ) ? wp_unslash( $_POST['tags'] ) :
|
437 |
|
438 |
-
$new_category_ids =
|
439 |
-
$new_tag_ids =
|
440 |
|
441 |
if ( ! empty( $posted_categories ) ) {
|
442 |
foreach ( $posted_categories as $posted_category_id ) {
|
@@ -472,14 +481,16 @@ class AJAX {
|
|
472 |
|
473 |
$buttons = ob_get_clean();
|
474 |
|
475 |
-
wp_send_json_error(
|
476 |
-
|
477 |
-
|
478 |
-
|
479 |
-
|
480 |
-
|
481 |
-
|
482 |
-
|
|
|
|
|
483 |
|
484 |
} else {
|
485 |
|
@@ -501,34 +512,34 @@ class AJAX {
|
|
501 |
* @param string[] $new_excluded_tags
|
502 |
* @return int[]
|
503 |
*/
|
504 |
-
private function get_products_to_be_excluded( $new_excluded_categories =
|
505 |
|
506 |
// products with sync enabled
|
507 |
-
$sync_enabled_meta_query =
|
508 |
'relation' => 'OR',
|
509 |
-
|
510 |
'key' => Products::SYNC_ENABLED_META_KEY,
|
511 |
'value' => 'yes',
|
512 |
-
|
513 |
-
|
514 |
'key' => Products::SYNC_ENABLED_META_KEY,
|
515 |
'compare' => 'NOT EXISTS',
|
516 |
-
|
517 |
-
|
518 |
|
519 |
-
$products_query_vars =
|
520 |
'post_type' => 'product',
|
521 |
'fields' => 'ids',
|
522 |
'meta_query' => $sync_enabled_meta_query,
|
523 |
-
|
524 |
|
525 |
if ( ! empty( $new_excluded_categories ) ) {
|
526 |
|
527 |
// products that belong to the new excluded categories
|
528 |
-
$categories_tax_query =
|
529 |
'taxonomy' => 'product_cat',
|
530 |
'terms' => $new_excluded_categories,
|
531 |
-
|
532 |
|
533 |
if ( $integration = facebook_for_woocommerce()->get_integration() ) {
|
534 |
|
@@ -537,15 +548,15 @@ class AJAX {
|
|
537 |
|
538 |
if ( ! empty( $saved_excluded_categories ) ) {
|
539 |
|
540 |
-
$categories_tax_query =
|
541 |
'relation' => 'AND',
|
542 |
$categories_tax_query,
|
543 |
-
|
544 |
'taxonomy' => 'product_cat',
|
545 |
'terms' => $saved_excluded_categories,
|
546 |
'operator' => 'NOT IN',
|
547 |
-
|
548 |
-
|
549 |
}
|
550 |
}
|
551 |
|
@@ -555,10 +566,10 @@ class AJAX {
|
|
555 |
if ( ! empty( $new_excluded_tags ) ) {
|
556 |
|
557 |
// products that belong to the new excluded tags
|
558 |
-
$tags_tax_query =
|
559 |
'taxonomy' => 'product_tag',
|
560 |
'terms' => $new_excluded_tags,
|
561 |
-
|
562 |
|
563 |
if ( $integration = facebook_for_woocommerce()->get_integration() ) {
|
564 |
|
@@ -567,15 +578,15 @@ class AJAX {
|
|
567 |
if ( ! empty( $save_excluded_tags ) ) {
|
568 |
|
569 |
// products that do not belong to the saved excluded tags
|
570 |
-
$tags_tax_query =
|
571 |
'relation' => 'AND',
|
572 |
$tags_tax_query,
|
573 |
-
|
574 |
'taxonomy' => 'product_tag',
|
575 |
'terms' => $save_excluded_tags,
|
576 |
'operator' => 'NOT IN',
|
577 |
-
|
578 |
-
|
579 |
}
|
580 |
}
|
581 |
|
@@ -585,11 +596,11 @@ class AJAX {
|
|
585 |
|
586 |
} else {
|
587 |
|
588 |
-
$products_query_vars['tax_query'] =
|
589 |
'relation' => 'OR',
|
590 |
$products_query_vars,
|
591 |
$tags_tax_query,
|
592 |
-
|
593 |
}
|
594 |
}
|
595 |
|
41 |
public function __construct() {
|
42 |
|
43 |
// maybe output a modal prompt when toggling product sync in bulk or individual product actions
|
44 |
+
add_action( 'wp_ajax_facebook_for_woocommerce_set_product_sync_prompt', array( $this, 'handle_set_product_sync_prompt' ) );
|
45 |
+
add_action( 'wp_ajax_facebook_for_woocommerce_set_product_sync_bulk_action_prompt', array( $this, 'handle_set_product_sync_bulk_action_prompt' ) );
|
46 |
|
47 |
// maybe output a modal prompt when setting excluded terms
|
48 |
+
add_action( 'wp_ajax_facebook_for_woocommerce_set_excluded_terms_prompt', array( $this, 'handle_set_excluded_terms_prompt' ) );
|
49 |
|
50 |
// sync all products via AJAX
|
51 |
+
add_action( 'wp_ajax_wc_facebook_sync_products', array( $this, 'sync_products' ) );
|
52 |
|
53 |
// get the current sync status
|
54 |
+
add_action( 'wp_ajax_wc_facebook_get_sync_status', array( $this, 'get_sync_status' ) );
|
55 |
|
56 |
// search a product's attributes for the given term
|
57 |
+
add_action( 'wp_ajax_' . self::ACTION_SEARCH_PRODUCT_ATTRIBUTES, array( $this, 'admin_search_product_attributes' ) );
|
58 |
|
59 |
// complete a Facebook order for the given order ID
|
60 |
+
add_action( 'wp_ajax_' . self::ACTION_COMPLETE_ORDER, array( $this, 'admin_complete_order' ) );
|
61 |
|
62 |
// cancel facebook order by the given order ID
|
63 |
+
add_action( 'wp_ajax_' . self::ACTION_CANCEL_ORDER, array( $this, 'admin_cancel_order' ) );
|
64 |
}
|
65 |
|
66 |
|
139 |
$attributes = Admin\Products::get_available_product_attribute_names( $product );
|
140 |
|
141 |
// filter out any attributes whose slug or proper name don't at least partially match the search term
|
142 |
+
$results = array_filter(
|
143 |
+
$attributes,
|
144 |
+
function( $name, $slug ) use ( $term ) {
|
145 |
|
146 |
+
return false !== stripos( $name, $term ) || false !== stripos( $slug, $term );
|
147 |
|
148 |
+
},
|
149 |
+
ARRAY_FILTER_USE_BOTH
|
150 |
+
);
|
151 |
|
152 |
wp_send_json( $results );
|
153 |
|
236 |
|
237 |
$remaining_products = 0;
|
238 |
|
239 |
+
$jobs = facebook_for_woocommerce()->get_products_sync_background_handler()->get_jobs(
|
240 |
+
array(
|
241 |
+
'status' => 'processing',
|
242 |
+
)
|
243 |
+
);
|
244 |
|
245 |
if ( ! empty( $jobs ) ) {
|
246 |
|
252 |
if ( ! empty( $job->progress ) ) {
|
253 |
$remaining_products -= $job->progress;
|
254 |
}
|
|
|
255 |
}
|
256 |
|
257 |
wp_send_json_success( $remaining_products );
|
270 |
check_ajax_referer( 'set-product-sync-prompt', 'security' );
|
271 |
|
272 |
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
273 |
+
$product_id = isset( $_POST['product'] ) ? (int) $_POST['product'] : 0;
|
274 |
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
275 |
+
$sync_enabled = isset( $_POST['sync_enabled'] ) ? (string) $_POST['sync_enabled'] : '';
|
276 |
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
277 |
$var_sync_enabled = isset( $_POST['var_sync_enabled'] ) ? (string) $_POST['var_sync_enabled'] : '';
|
278 |
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
279 |
+
$product_cats = isset( $_POST['categories'] ) ? (array) $_POST['categories'] : array();
|
280 |
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
281 |
+
$product_tags = isset( $_POST['tags'] ) ? (array) $_POST['tags'] : array();
|
282 |
|
283 |
+
if ( $product_id > 0 && in_array( $var_sync_enabled, array( 'enabled', 'disabled' ), true ) && in_array( $sync_enabled, array( 'enabled', 'disabled' ), true ) ) {
|
284 |
|
285 |
$product = wc_get_product( $product_id );
|
286 |
|
301 |
// try next with tags, but WordPress only gives us tag names
|
302 |
if ( ! $has_excluded_terms && ! empty( $product_tags ) ) {
|
303 |
|
304 |
+
$product_tag_ids = array();
|
305 |
|
306 |
foreach ( $product_tags as $product_tag_name_or_id ) {
|
307 |
|
344 |
|
345 |
$buttons = ob_get_clean();
|
346 |
|
347 |
+
wp_send_json_error(
|
348 |
+
array(
|
349 |
+
'message' => sprintf(
|
350 |
+
/* translators: Placeholder %s - <br/> tag */
|
351 |
+
__( 'This product belongs to a category or tag that is excluded from the Facebook catalog sync. It will not sync to Facebook. %sTo sync this product to Facebook, click Go to Settings and remove the category or tag exclusion or click Cancel and update the product\'s category / tag assignments.', 'facebook-for-woocommerce' ),
|
352 |
+
'<br/><br/>'
|
353 |
+
),
|
354 |
+
'buttons' => $buttons,
|
355 |
+
)
|
356 |
+
);
|
357 |
}
|
358 |
}
|
359 |
}
|
375 |
check_ajax_referer( 'set-product-sync-bulk-action-prompt', 'security' );
|
376 |
|
377 |
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
378 |
+
$product_ids = isset( $_POST['products'] ) ? (array) $_POST['products'] : array();
|
379 |
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
380 |
+
$toggle = isset( $_POST['toggle'] ) ? (string) $_POST['toggle'] : '';
|
381 |
|
382 |
if ( ! empty( $product_ids ) && ! empty( $toggle ) && 'facebook_include' === $toggle ) {
|
383 |
|
396 |
}
|
397 |
|
398 |
// show modal if there's at least one product that belongs to an excluded term
|
399 |
+
if ( $has_excluded_term ) {
|
400 |
|
401 |
ob_start();
|
402 |
|
415 |
|
416 |
$buttons = ob_get_clean();
|
417 |
|
418 |
+
wp_send_json_error(
|
419 |
+
array(
|
420 |
+
'message' => __( 'One or more of the selected products belongs to a category or tag that is excluded from the Facebook catalog sync. To sync these products to Facebook, please remove the category or tag exclusion from the plugin settings.', 'facebook-for-woocommerce' ),
|
421 |
+
'buttons' => $buttons,
|
422 |
+
)
|
423 |
+
);
|
424 |
}
|
425 |
}
|
426 |
|
440 |
check_ajax_referer( 'set-excluded-terms-prompt', 'security' );
|
441 |
|
442 |
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
|
443 |
+
$posted_categories = isset( $_POST['categories'] ) ? wp_unslash( $_POST['categories'] ) : array();
|
444 |
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
|
445 |
+
$posted_tags = isset( $_POST['tags'] ) ? wp_unslash( $_POST['tags'] ) : array();
|
446 |
|
447 |
+
$new_category_ids = array();
|
448 |
+
$new_tag_ids = array();
|
449 |
|
450 |
if ( ! empty( $posted_categories ) ) {
|
451 |
foreach ( $posted_categories as $posted_category_id ) {
|
481 |
|
482 |
$buttons = ob_get_clean();
|
483 |
|
484 |
+
wp_send_json_error(
|
485 |
+
array(
|
486 |
+
'message' => sprintf(
|
487 |
+
/* translators: Placeholder %s - <br/> tags */
|
488 |
+
__( 'The categories and/or tags that you have selected to exclude from sync contain products that are currently synced to Facebook.%sTo exclude these products from the Facebook sync, click Exclude Products. To review the category / tag exclusion settings, click Cancel.', 'facebook-for-woocommerce' ),
|
489 |
+
'<br/><br/>'
|
490 |
+
),
|
491 |
+
'buttons' => $buttons,
|
492 |
+
)
|
493 |
+
);
|
494 |
|
495 |
} else {
|
496 |
|
512 |
* @param string[] $new_excluded_tags
|
513 |
* @return int[]
|
514 |
*/
|
515 |
+
private function get_products_to_be_excluded( $new_excluded_categories = array(), $new_excluded_tags = array() ) {
|
516 |
|
517 |
// products with sync enabled
|
518 |
+
$sync_enabled_meta_query = array(
|
519 |
'relation' => 'OR',
|
520 |
+
array(
|
521 |
'key' => Products::SYNC_ENABLED_META_KEY,
|
522 |
'value' => 'yes',
|
523 |
+
),
|
524 |
+
array(
|
525 |
'key' => Products::SYNC_ENABLED_META_KEY,
|
526 |
'compare' => 'NOT EXISTS',
|
527 |
+
),
|
528 |
+
);
|
529 |
|
530 |
+
$products_query_vars = array(
|
531 |
'post_type' => 'product',
|
532 |
'fields' => 'ids',
|
533 |
'meta_query' => $sync_enabled_meta_query,
|
534 |
+
);
|
535 |
|
536 |
if ( ! empty( $new_excluded_categories ) ) {
|
537 |
|
538 |
// products that belong to the new excluded categories
|
539 |
+
$categories_tax_query = array(
|
540 |
'taxonomy' => 'product_cat',
|
541 |
'terms' => $new_excluded_categories,
|
542 |
+
);
|
543 |
|
544 |
if ( $integration = facebook_for_woocommerce()->get_integration() ) {
|
545 |
|
548 |
|
549 |
if ( ! empty( $saved_excluded_categories ) ) {
|
550 |
|
551 |
+
$categories_tax_query = array(
|
552 |
'relation' => 'AND',
|
553 |
$categories_tax_query,
|
554 |
+
array(
|
555 |
'taxonomy' => 'product_cat',
|
556 |
'terms' => $saved_excluded_categories,
|
557 |
'operator' => 'NOT IN',
|
558 |
+
),
|
559 |
+
);
|
560 |
}
|
561 |
}
|
562 |
|
566 |
if ( ! empty( $new_excluded_tags ) ) {
|
567 |
|
568 |
// products that belong to the new excluded tags
|
569 |
+
$tags_tax_query = array(
|
570 |
'taxonomy' => 'product_tag',
|
571 |
'terms' => $new_excluded_tags,
|
572 |
+
);
|
573 |
|
574 |
if ( $integration = facebook_for_woocommerce()->get_integration() ) {
|
575 |
|
578 |
if ( ! empty( $save_excluded_tags ) ) {
|
579 |
|
580 |
// products that do not belong to the saved excluded tags
|
581 |
+
$tags_tax_query = array(
|
582 |
'relation' => 'AND',
|
583 |
$tags_tax_query,
|
584 |
+
array(
|
585 |
'taxonomy' => 'product_tag',
|
586 |
'terms' => $save_excluded_tags,
|
587 |
'operator' => 'NOT IN',
|
588 |
+
),
|
589 |
+
);
|
590 |
}
|
591 |
}
|
592 |
|
596 |
|
597 |
} else {
|
598 |
|
599 |
+
$products_query_vars['tax_query'] = array(
|
600 |
'relation' => 'OR',
|
601 |
$products_query_vars,
|
602 |
$tags_tax_query,
|
603 |
+
);
|
604 |
}
|
605 |
}
|
606 |
|
includes/API.php
CHANGED
@@ -49,9 +49,9 @@ class API extends Framework\SV_WC_API_Base {
|
|
49 |
|
50 |
$this->access_token = $access_token;
|
51 |
|
52 |
-
$this->request_headers =
|
53 |
'Authorization' => "Bearer {$access_token}",
|
54 |
-
|
55 |
|
56 |
$this->set_request_content_type_header( 'application/json' );
|
57 |
$this->set_request_accept_header( 'application/json' );
|
@@ -148,7 +148,7 @@ class API extends Framework\SV_WC_API_Base {
|
|
148 |
* @link https://developers.facebook.com/docs/graph-api/using-graph-api/error-handling#rate-limiting-error-codes
|
149 |
* @link https://developers.facebook.com/docs/marketing-api/reference/product-catalog/batch/#validation-rules
|
150 |
*/
|
151 |
-
if ( in_array( $code,
|
152 |
|
153 |
$delay_in_seconds = $this->calculate_rate_limit_delay( $response, $this->get_response_headers() );
|
154 |
|
@@ -172,7 +172,7 @@ class API extends Framework\SV_WC_API_Base {
|
|
172 |
*
|
173 |
* @link https://developers.facebook.com/docs/graph-api/using-graph-api/error-handling#errorcodes
|
174 |
*/
|
175 |
-
if ( ( $code >= 200 && $code < 300 ) || in_array( $code,
|
176 |
set_transient( 'wc_facebook_connection_invalid', time(), DAY_IN_SECONDS );
|
177 |
} else {
|
178 |
// this was an unrelated error, so the OAuth connection may still be valid
|
@@ -203,7 +203,7 @@ class API extends Framework\SV_WC_API_Base {
|
|
203 |
* @since 2.1.0
|
204 |
*
|
205 |
* @param string $rate_limit_id ID for the API request
|
206 |
-
* @param int
|
207 |
* @throws API\Exceptions\Request_Limit_Reached
|
208 |
*/
|
209 |
private function handle_throttled_request( $rate_limit_id, $timestamp ) {
|
@@ -345,12 +345,12 @@ class API extends Framework\SV_WC_API_Base {
|
|
345 |
*
|
346 |
* @since 2.0.0
|
347 |
*
|
348 |
-
* @param string
|
349 |
* @param API\FBE\Configuration\Messenger $configuration messenger configuration
|
350 |
* @return Response
|
351 |
* @throws Framework\SV_WC_API_Exception
|
352 |
*/
|
353 |
-
public function update_messenger_configuration(
|
354 |
|
355 |
$request = new API\FBE\Configuration\Update\Request( $external_business_id );
|
356 |
|
@@ -370,8 +370,8 @@ class API extends Framework\SV_WC_API_Base {
|
|
370 |
* @since 2.0.0
|
371 |
*
|
372 |
* @param string $catalog_id catalog ID
|
373 |
-
* @param array
|
374 |
-
* @param bool
|
375 |
* @return \SkyVerge\WooCommerce\Facebook\API\Catalog\Send_Item_Updates\Response
|
376 |
* @throws Framework\SV_WC_API_Exception
|
377 |
*/
|
@@ -394,16 +394,18 @@ class API extends Framework\SV_WC_API_Base {
|
|
394 |
* @since 2.0.0
|
395 |
*
|
396 |
* @param string $catalog_id catalog ID
|
397 |
-
* @param array
|
398 |
* @return Response
|
399 |
* @throws Framework\SV_WC_API_Exception
|
400 |
*/
|
401 |
public function create_product_group( $catalog_id, $data ) {
|
402 |
|
403 |
-
$request = $this->get_new_request(
|
404 |
-
|
405 |
-
|
406 |
-
|
|
|
|
|
407 |
|
408 |
$request->set_data( $data );
|
409 |
|
@@ -419,16 +421,18 @@ class API extends Framework\SV_WC_API_Base {
|
|
419 |
* @since 2.0.0
|
420 |
*
|
421 |
* @param string $product_group_id product group ID
|
422 |
-
* @param array
|
423 |
* @return Response
|
424 |
* @throws Framework\SV_WC_API_Exception
|
425 |
*/
|
426 |
public function update_product_group( $product_group_id, $data ) {
|
427 |
|
428 |
-
$request = $this->get_new_request(
|
429 |
-
|
430 |
-
|
431 |
-
|
|
|
|
|
432 |
|
433 |
$request->set_data( $data );
|
434 |
|
@@ -449,10 +453,12 @@ class API extends Framework\SV_WC_API_Base {
|
|
449 |
*/
|
450 |
public function delete_product_group( $product_group_id ) {
|
451 |
|
452 |
-
$request = $this->get_new_request(
|
453 |
-
|
454 |
-
|
455 |
-
|
|
|
|
|
456 |
|
457 |
$this->set_response_handler( Response::class );
|
458 |
|
@@ -466,7 +472,7 @@ class API extends Framework\SV_WC_API_Base {
|
|
466 |
* @since 2.0.0
|
467 |
*
|
468 |
* @param string $product_group_id product group ID
|
469 |
-
* @param int
|
470 |
* @return API\Catalog\Product_Group\Products\Read\Response
|
471 |
* @throws Framework\SV_WC_API_Exception
|
472 |
*/
|
@@ -506,16 +512,18 @@ class API extends Framework\SV_WC_API_Base {
|
|
506 |
* @since 2.0.0
|
507 |
*
|
508 |
* @param string $product_group_id parent product ID
|
509 |
-
* @param array
|
510 |
* @return Response
|
511 |
* @throws Framework\SV_WC_API_Exception
|
512 |
*/
|
513 |
public function create_product_item( $product_group_id, $data ) {
|
514 |
|
515 |
-
$request = $this->get_new_request(
|
516 |
-
|
517 |
-
|
518 |
-
|
|
|
|
|
519 |
|
520 |
$request->set_data( $data );
|
521 |
|
@@ -531,16 +539,18 @@ class API extends Framework\SV_WC_API_Base {
|
|
531 |
* @since 2.0.0
|
532 |
*
|
533 |
* @param string $product_item_id product item ID
|
534 |
-
* @param array
|
535 |
* @return Response
|
536 |
* @throws Framework\SV_WC_API_Exception
|
537 |
*/
|
538 |
public function update_product_item( $product_item_id, $data ) {
|
539 |
|
540 |
-
$request = $this->get_new_request(
|
541 |
-
|
542 |
-
|
543 |
-
|
|
|
|
|
544 |
|
545 |
$request->set_data( $data );
|
546 |
|
@@ -561,10 +571,12 @@ class API extends Framework\SV_WC_API_Base {
|
|
561 |
*/
|
562 |
public function delete_product_item( $product_item_id ) {
|
563 |
|
564 |
-
$request = $this->get_new_request(
|
565 |
-
|
566 |
-
|
567 |
-
|
|
|
|
|
568 |
|
569 |
$this->set_response_handler( Response::class );
|
570 |
|
@@ -577,7 +589,7 @@ class API extends Framework\SV_WC_API_Base {
|
|
577 |
*
|
578 |
* @since 2.0.0
|
579 |
*
|
580 |
-
* @param string
|
581 |
* @param Event[] $events events to send
|
582 |
* @return Response
|
583 |
* @throws Framework\SV_WC_API_Exception
|
@@ -598,7 +610,7 @@ class API extends Framework\SV_WC_API_Base {
|
|
598 |
* @since 2.0.0
|
599 |
*
|
600 |
* @param API\Response $response previous response object
|
601 |
-
* @param int
|
602 |
* @return API\Response|null
|
603 |
* @throws Framework\SV_WC_API_Exception
|
604 |
*/
|
@@ -611,11 +623,13 @@ class API extends Framework\SV_WC_API_Base {
|
|
611 |
|
612 |
$components = parse_url( str_replace( $this->request_uri, '', $response->get_next_page_endpoint() ) );
|
613 |
|
614 |
-
$request = $this->get_new_request(
|
615 |
-
|
616 |
-
|
617 |
-
|
618 |
-
|
|
|
|
|
619 |
|
620 |
$this->set_response_handler( get_class( $response ) );
|
621 |
|
@@ -640,12 +654,12 @@ class API extends Framework\SV_WC_API_Base {
|
|
640 |
*/
|
641 |
public function get_new_orders( $page_id ) {
|
642 |
|
643 |
-
$request_args =
|
644 |
-
'state' =>
|
645 |
Order::STATUS_PROCESSING,
|
646 |
Order::STATUS_CREATED,
|
647 |
-
|
648 |
-
|
649 |
|
650 |
$request = new API\Orders\Request( $page_id, $request_args );
|
651 |
|
@@ -666,13 +680,13 @@ class API extends Framework\SV_WC_API_Base {
|
|
666 |
*/
|
667 |
public function get_cancelled_orders( $page_id ) {
|
668 |
|
669 |
-
$request_args =
|
670 |
-
'state'
|
671 |
Order::STATUS_COMPLETED,
|
672 |
-
|
673 |
'updated_after' => time() - facebook_for_woocommerce()->get_commerce_handler()->get_orders_handler()->get_order_update_interval(),
|
674 |
'filters' => 'has_cancellations',
|
675 |
-
|
676 |
|
677 |
$request = new API\Orders\Request( $page_id, $request_args );
|
678 |
|
@@ -729,7 +743,7 @@ class API extends Framework\SV_WC_API_Base {
|
|
729 |
* @since 2.1.0
|
730 |
*
|
731 |
* @param string $remote_id remote order ID
|
732 |
-
* @param array
|
733 |
* @return API\Response
|
734 |
* @throws Framework\SV_WC_API_Exception
|
735 |
*/
|
@@ -750,7 +764,7 @@ class API extends Framework\SV_WC_API_Base {
|
|
750 |
*
|
751 |
* @param string $remote_id remote order ID
|
752 |
* @param string $reason cancellation reason
|
753 |
-
* @param bool
|
754 |
* @return API\Response
|
755 |
* @throws Framework\SV_WC_API_Exception
|
756 |
*/
|
@@ -772,7 +786,7 @@ class API extends Framework\SV_WC_API_Base {
|
|
772 |
* @since 2.1.0
|
773 |
*
|
774 |
* @param string $remote_id remote order ID
|
775 |
-
* @param array
|
776 |
* @return API\Response
|
777 |
* @throws Framework\SV_WC_API_Exception
|
778 |
*/
|
@@ -800,13 +814,13 @@ class API extends Framework\SV_WC_API_Base {
|
|
800 |
* }
|
801 |
* @return Request
|
802 |
*/
|
803 |
-
protected function get_new_request( $args =
|
804 |
|
805 |
-
$defaults =
|
806 |
'path' => '/',
|
807 |
'method' => 'GET',
|
808 |
-
'params' =>
|
809 |
-
|
810 |
|
811 |
$args = wp_parse_args( $args, $defaults );
|
812 |
$request = new Request( $args['path'], $args['method'] );
|
49 |
|
50 |
$this->access_token = $access_token;
|
51 |
|
52 |
+
$this->request_headers = array(
|
53 |
'Authorization' => "Bearer {$access_token}",
|
54 |
+
);
|
55 |
|
56 |
$this->set_request_content_type_header( 'application/json' );
|
57 |
$this->set_request_accept_header( 'application/json' );
|
148 |
* @link https://developers.facebook.com/docs/graph-api/using-graph-api/error-handling#rate-limiting-error-codes
|
149 |
* @link https://developers.facebook.com/docs/marketing-api/reference/product-catalog/batch/#validation-rules
|
150 |
*/
|
151 |
+
if ( in_array( $code, array( 4, 17, 32, 613, 80001, 80004 ), true ) ) {
|
152 |
|
153 |
$delay_in_seconds = $this->calculate_rate_limit_delay( $response, $this->get_response_headers() );
|
154 |
|
172 |
*
|
173 |
* @link https://developers.facebook.com/docs/graph-api/using-graph-api/error-handling#errorcodes
|
174 |
*/
|
175 |
+
if ( ( $code >= 200 && $code < 300 ) || in_array( $code, array( 10, 102, 190 ), false ) ) {
|
176 |
set_transient( 'wc_facebook_connection_invalid', time(), DAY_IN_SECONDS );
|
177 |
} else {
|
178 |
// this was an unrelated error, so the OAuth connection may still be valid
|
203 |
* @since 2.1.0
|
204 |
*
|
205 |
* @param string $rate_limit_id ID for the API request
|
206 |
+
* @param int $timestamp timestamp until the delay is over
|
207 |
* @throws API\Exceptions\Request_Limit_Reached
|
208 |
*/
|
209 |
private function handle_throttled_request( $rate_limit_id, $timestamp ) {
|
345 |
*
|
346 |
* @since 2.0.0
|
347 |
*
|
348 |
+
* @param string $external_business_id external business ID
|
349 |
* @param API\FBE\Configuration\Messenger $configuration messenger configuration
|
350 |
* @return Response
|
351 |
* @throws Framework\SV_WC_API_Exception
|
352 |
*/
|
353 |
+
public function update_messenger_configuration( $external_business_id, API\FBE\Configuration\Messenger $configuration ) {
|
354 |
|
355 |
$request = new API\FBE\Configuration\Update\Request( $external_business_id );
|
356 |
|
370 |
* @since 2.0.0
|
371 |
*
|
372 |
* @param string $catalog_id catalog ID
|
373 |
+
* @param array $requests array of prefixed product IDs to create, update or remove
|
374 |
+
* @param bool $allow_upsert whether to allow updates to insert new items
|
375 |
* @return \SkyVerge\WooCommerce\Facebook\API\Catalog\Send_Item_Updates\Response
|
376 |
* @throws Framework\SV_WC_API_Exception
|
377 |
*/
|
394 |
* @since 2.0.0
|
395 |
*
|
396 |
* @param string $catalog_id catalog ID
|
397 |
+
* @param array $data product group data
|
398 |
* @return Response
|
399 |
* @throws Framework\SV_WC_API_Exception
|
400 |
*/
|
401 |
public function create_product_group( $catalog_id, $data ) {
|
402 |
|
403 |
+
$request = $this->get_new_request(
|
404 |
+
array(
|
405 |
+
'path' => "/{$catalog_id}/product_groups",
|
406 |
+
'method' => 'POST',
|
407 |
+
)
|
408 |
+
);
|
409 |
|
410 |
$request->set_data( $data );
|
411 |
|
421 |
* @since 2.0.0
|
422 |
*
|
423 |
* @param string $product_group_id product group ID
|
424 |
+
* @param array $data product group data
|
425 |
* @return Response
|
426 |
* @throws Framework\SV_WC_API_Exception
|
427 |
*/
|
428 |
public function update_product_group( $product_group_id, $data ) {
|
429 |
|
430 |
+
$request = $this->get_new_request(
|
431 |
+
array(
|
432 |
+
'path' => "/{$product_group_id}",
|
433 |
+
'method' => 'POST',
|
434 |
+
)
|
435 |
+
);
|
436 |
|
437 |
$request->set_data( $data );
|
438 |
|
453 |
*/
|
454 |
public function delete_product_group( $product_group_id ) {
|
455 |
|
456 |
+
$request = $this->get_new_request(
|
457 |
+
array(
|
458 |
+
'path' => "/{$product_group_id}",
|
459 |
+
'method' => 'DELETE',
|
460 |
+
)
|
461 |
+
);
|
462 |
|
463 |
$this->set_response_handler( Response::class );
|
464 |
|
472 |
* @since 2.0.0
|
473 |
*
|
474 |
* @param string $product_group_id product group ID
|
475 |
+
* @param int $limit max number of results returned per page of data
|
476 |
* @return API\Catalog\Product_Group\Products\Read\Response
|
477 |
* @throws Framework\SV_WC_API_Exception
|
478 |
*/
|
512 |
* @since 2.0.0
|
513 |
*
|
514 |
* @param string $product_group_id parent product ID
|
515 |
+
* @param array $data product data
|
516 |
* @return Response
|
517 |
* @throws Framework\SV_WC_API_Exception
|
518 |
*/
|
519 |
public function create_product_item( $product_group_id, $data ) {
|
520 |
|
521 |
+
$request = $this->get_new_request(
|
522 |
+
array(
|
523 |
+
'path' => "/{$product_group_id}/products",
|
524 |
+
'method' => 'POST',
|
525 |
+
)
|
526 |
+
);
|
527 |
|
528 |
$request->set_data( $data );
|
529 |
|
539 |
* @since 2.0.0
|
540 |
*
|
541 |
* @param string $product_item_id product item ID
|
542 |
+
* @param array $data product data
|
543 |
* @return Response
|
544 |
* @throws Framework\SV_WC_API_Exception
|
545 |
*/
|
546 |
public function update_product_item( $product_item_id, $data ) {
|
547 |
|
548 |
+
$request = $this->get_new_request(
|
549 |
+
array(
|
550 |
+
'path' => "/{$product_item_id}",
|
551 |
+
'method' => 'POST',
|
552 |
+
)
|
553 |
+
);
|
554 |
|
555 |
$request->set_data( $data );
|
556 |
|
571 |
*/
|
572 |
public function delete_product_item( $product_item_id ) {
|
573 |
|
574 |
+
$request = $this->get_new_request(
|
575 |
+
array(
|
576 |
+
'path' => "/{$product_item_id}",
|
577 |
+
'method' => 'DELETE',
|
578 |
+
)
|
579 |
+
);
|
580 |
|
581 |
$this->set_response_handler( Response::class );
|
582 |
|
589 |
*
|
590 |
* @since 2.0.0
|
591 |
*
|
592 |
+
* @param string $pixel_id pixel ID
|
593 |
* @param Event[] $events events to send
|
594 |
* @return Response
|
595 |
* @throws Framework\SV_WC_API_Exception
|
610 |
* @since 2.0.0
|
611 |
*
|
612 |
* @param API\Response $response previous response object
|
613 |
+
* @param int $additional_pages number of additional pages of results to retrieve
|
614 |
* @return API\Response|null
|
615 |
* @throws Framework\SV_WC_API_Exception
|
616 |
*/
|
623 |
|
624 |
$components = parse_url( str_replace( $this->request_uri, '', $response->get_next_page_endpoint() ) );
|
625 |
|
626 |
+
$request = $this->get_new_request(
|
627 |
+
array(
|
628 |
+
'path' => isset( $components['path'] ) ? $components['path'] : '',
|
629 |
+
'method' => 'GET',
|
630 |
+
'params' => isset( $components['query'] ) ? wp_parse_args( $components['query'] ) : array(),
|
631 |
+
)
|
632 |
+
);
|
633 |
|
634 |
$this->set_response_handler( get_class( $response ) );
|
635 |
|
654 |
*/
|
655 |
public function get_new_orders( $page_id ) {
|
656 |
|
657 |
+
$request_args = array(
|
658 |
+
'state' => array(
|
659 |
Order::STATUS_PROCESSING,
|
660 |
Order::STATUS_CREATED,
|
661 |
+
),
|
662 |
+
);
|
663 |
|
664 |
$request = new API\Orders\Request( $page_id, $request_args );
|
665 |
|
680 |
*/
|
681 |
public function get_cancelled_orders( $page_id ) {
|
682 |
|
683 |
+
$request_args = array(
|
684 |
+
'state' => array(
|
685 |
Order::STATUS_COMPLETED,
|
686 |
+
),
|
687 |
'updated_after' => time() - facebook_for_woocommerce()->get_commerce_handler()->get_orders_handler()->get_order_update_interval(),
|
688 |
'filters' => 'has_cancellations',
|
689 |
+
);
|
690 |
|
691 |
$request = new API\Orders\Request( $page_id, $request_args );
|
692 |
|
743 |
* @since 2.1.0
|
744 |
*
|
745 |
* @param string $remote_id remote order ID
|
746 |
+
* @param array $fulfillment_data fulfillment data to be sent on the request
|
747 |
* @return API\Response
|
748 |
* @throws Framework\SV_WC_API_Exception
|
749 |
*/
|
764 |
*
|
765 |
* @param string $remote_id remote order ID
|
766 |
* @param string $reason cancellation reason
|
767 |
+
* @param bool $restock_items whether to restock items remotely
|
768 |
* @return API\Response
|
769 |
* @throws Framework\SV_WC_API_Exception
|
770 |
*/
|
786 |
* @since 2.1.0
|
787 |
*
|
788 |
* @param string $remote_id remote order ID
|
789 |
+
* @param array $refund_data refund data to be sent on the request
|
790 |
* @return API\Response
|
791 |
* @throws Framework\SV_WC_API_Exception
|
792 |
*/
|
814 |
* }
|
815 |
* @return Request
|
816 |
*/
|
817 |
+
protected function get_new_request( $args = array() ) {
|
818 |
|
819 |
+
$defaults = array(
|
820 |
'path' => '/',
|
821 |
'method' => 'GET',
|
822 |
+
'params' => array(),
|
823 |
+
);
|
824 |
|
825 |
$args = wp_parse_args( $args, $defaults );
|
826 |
$request = new Request( $args['path'], $args['method'] );
|
includes/API/Catalog/Product_Group/Products/Read/Request.php
CHANGED
@@ -28,16 +28,18 @@ class Request extends API\Request {
|
|
28 |
* @since 2.0.0
|
29 |
*
|
30 |
* @param string $product_group_id product group ID
|
31 |
-
* @param int
|
32 |
*/
|
33 |
public function __construct( $product_group_id, $limit ) {
|
34 |
|
35 |
parent::__construct( "/{$product_group_id}/products", 'GET' );
|
36 |
|
37 |
-
$this->set_params(
|
38 |
-
|
39 |
-
|
40 |
-
|
|
|
|
|
41 |
}
|
42 |
|
43 |
|
28 |
* @since 2.0.0
|
29 |
*
|
30 |
* @param string $product_group_id product group ID
|
31 |
+
* @param int $limit max number of results returned
|
32 |
*/
|
33 |
public function __construct( $product_group_id, $limit ) {
|
34 |
|
35 |
parent::__construct( "/{$product_group_id}/products", 'GET' );
|
36 |
|
37 |
+
$this->set_params(
|
38 |
+
array(
|
39 |
+
'fields' => 'id,retailer_id',
|
40 |
+
'limit' => $limit,
|
41 |
+
)
|
42 |
+
);
|
43 |
}
|
44 |
|
45 |
|
includes/API/Catalog/Product_Group/Products/Read/Response.php
CHANGED
@@ -34,7 +34,7 @@ class Response extends API\Response {
|
|
34 |
*/
|
35 |
public function get_ids() {
|
36 |
|
37 |
-
$product_item_ids =
|
38 |
|
39 |
foreach ( $this->get_data() as $entry ) {
|
40 |
$product_item_ids[ $entry->retailer_id ] = $entry->id;
|
34 |
*/
|
35 |
public function get_ids() {
|
36 |
|
37 |
+
$product_item_ids = array();
|
38 |
|
39 |
foreach ( $this->get_data() as $entry ) {
|
40 |
$product_item_ids[ $entry->retailer_id ] = $entry->id;
|
includes/API/Catalog/Product_Item/Find/Request.php
CHANGED
@@ -58,7 +58,7 @@ class Request extends API\Request {
|
|
58 |
*/
|
59 |
public function get_params() {
|
60 |
|
61 |
-
return
|
62 |
}
|
63 |
|
64 |
|
58 |
*/
|
59 |
public function get_params() {
|
60 |
|
61 |
+
return array( 'fields' => 'id,product_group{id}' );
|
62 |
}
|
63 |
|
64 |
|
includes/API/Catalog/Request.php
CHANGED
@@ -19,7 +19,7 @@ use SkyVerge\WooCommerce\Facebook\API;
|
|
19 |
*
|
20 |
* @since 2.0.0
|
21 |
*/
|
22 |
-
class Request extends API\Request
|
23 |
|
24 |
|
25 |
/**
|
@@ -57,7 +57,7 @@ class Request extends API\Request {
|
|
57 |
*/
|
58 |
public function get_params() {
|
59 |
|
60 |
-
return
|
61 |
}
|
62 |
|
63 |
|
19 |
*
|
20 |
* @since 2.0.0
|
21 |
*/
|
22 |
+
class Request extends API\Request {
|
23 |
|
24 |
|
25 |
/**
|
57 |
*/
|
58 |
public function get_params() {
|
59 |
|
60 |
+
return array( 'fields' => 'name' );
|
61 |
}
|
62 |
|
63 |
|
includes/API/Catalog/Send_Item_Updates/Request.php
CHANGED
@@ -19,11 +19,11 @@ use SkyVerge\WooCommerce\Facebook\API;
|
|
19 |
*
|
20 |
* @since 2.0.0
|
21 |
*/
|
22 |
-
class Request extends API\Request
|
23 |
|
24 |
|
25 |
/** @var array an array of item update requests */
|
26 |
-
protected $requests =
|
27 |
|
28 |
/** @var bool determines whether updates for products that are not currently in the catalog should create new items */
|
29 |
protected $allow_upsert = true;
|
@@ -115,13 +115,13 @@ class Request extends API\Request {
|
|
115 |
* @since 2.0.0
|
116 |
*/
|
117 |
public function get_data() {
|
118 |
-
|
119 |
|
120 |
-
return
|
121 |
'allow_upsert' => $this->get_allow_upsert(),
|
122 |
'requests' => $this->get_requests(),
|
123 |
'item_type' => 'PRODUCT_ITEM',
|
124 |
-
|
125 |
}
|
126 |
|
127 |
|
19 |
*
|
20 |
* @since 2.0.0
|
21 |
*/
|
22 |
+
class Request extends API\Request {
|
23 |
|
24 |
|
25 |
/** @var array an array of item update requests */
|
26 |
+
protected $requests = array();
|
27 |
|
28 |
/** @var bool determines whether updates for products that are not currently in the catalog should create new items */
|
29 |
protected $allow_upsert = true;
|
115 |
* @since 2.0.0
|
116 |
*/
|
117 |
public function get_data() {
|
118 |
+
// TODO: Make it so the item type is based on the actual item type
|
119 |
|
120 |
+
return array(
|
121 |
'allow_upsert' => $this->get_allow_upsert(),
|
122 |
'requests' => $this->get_requests(),
|
123 |
'item_type' => 'PRODUCT_ITEM',
|
124 |
+
);
|
125 |
}
|
126 |
|
127 |
|
includes/API/FBE/Configuration/Messenger.php
CHANGED
@@ -27,7 +27,7 @@ class Messenger {
|
|
27 |
private $default_locale;
|
28 |
|
29 |
/** @var string[] approved domains */
|
30 |
-
private $domains =
|
31 |
|
32 |
|
33 |
/**
|
@@ -35,13 +35,16 @@ class Messenger {
|
|
35 |
*
|
36 |
* @param array $data configuration data
|
37 |
*/
|
38 |
-
public function __construct( array $data =
|
39 |
|
40 |
-
$data = wp_parse_args(
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
|
|
|
|
|
|
45 |
|
46 |
$this->set_enabled( $data['enabled'] );
|
47 |
$this->set_default_locale( $data['default_locale'] );
|
@@ -87,7 +90,7 @@ class Messenger {
|
|
87 |
if ( is_array( $this->domains ) ) {
|
88 |
$domains = array_map( 'trailingslashit', $this->domains );
|
89 |
} else {
|
90 |
-
$domains =
|
91 |
}
|
92 |
|
93 |
return $domains;
|
@@ -129,7 +132,7 @@ class Messenger {
|
|
129 |
*/
|
130 |
public function add_domain( $domain ) {
|
131 |
|
132 |
-
$domains = is_array( $this->domains ) ? $this->domains :
|
133 |
|
134 |
$domains[] = $domain;
|
135 |
|
27 |
private $default_locale;
|
28 |
|
29 |
/** @var string[] approved domains */
|
30 |
+
private $domains = array();
|
31 |
|
32 |
|
33 |
/**
|
35 |
*
|
36 |
* @param array $data configuration data
|
37 |
*/
|
38 |
+
public function __construct( array $data = array() ) {
|
39 |
|
40 |
+
$data = wp_parse_args(
|
41 |
+
$data,
|
42 |
+
array(
|
43 |
+
'enabled' => false,
|
44 |
+
'default_locale' => '',
|
45 |
+
'domains' => array(),
|
46 |
+
)
|
47 |
+
);
|
48 |
|
49 |
$this->set_enabled( $data['enabled'] );
|
50 |
$this->set_default_locale( $data['default_locale'] );
|
90 |
if ( is_array( $this->domains ) ) {
|
91 |
$domains = array_map( 'trailingslashit', $this->domains );
|
92 |
} else {
|
93 |
+
$domains = array();
|
94 |
}
|
95 |
|
96 |
return $domains;
|
132 |
*/
|
133 |
public function add_domain( $domain ) {
|
134 |
|
135 |
+
$domains = is_array( $this->domains ) ? $this->domains : array();
|
136 |
|
137 |
$domains[] = $domain;
|
138 |
|
includes/API/FBE/Configuration/Read/Response.php
CHANGED
@@ -19,7 +19,7 @@ use SkyVerge\WooCommerce\Facebook\API;
|
|
19 |
*
|
20 |
* @since 2.0.0
|
21 |
*/
|
22 |
-
class Response extends API\Response
|
23 |
|
24 |
|
25 |
/**
|
19 |
*
|
20 |
* @since 2.0.0
|
21 |
*/
|
22 |
+
class Response extends API\Response {
|
23 |
|
24 |
|
25 |
/**
|
includes/API/FBE/Configuration/Request.php
CHANGED
@@ -19,7 +19,7 @@ use SkyVerge\WooCommerce\Facebook\API;
|
|
19 |
*
|
20 |
* @since 2.0.0
|
21 |
*/
|
22 |
-
class Request extends API\Request
|
23 |
|
24 |
|
25 |
/**
|
@@ -34,9 +34,9 @@ class Request extends API\Request {
|
|
34 |
|
35 |
parent::__construct( '/fbe_business', $method );
|
36 |
|
37 |
-
$this->params =
|
38 |
'fbe_external_business_id' => $external_business_id,
|
39 |
-
|
40 |
}
|
41 |
|
42 |
|
19 |
*
|
20 |
* @since 2.0.0
|
21 |
*/
|
22 |
+
class Request extends API\Request {
|
23 |
|
24 |
|
25 |
/**
|
34 |
|
35 |
parent::__construct( '/fbe_business', $method );
|
36 |
|
37 |
+
$this->params = array(
|
38 |
'fbe_external_business_id' => $external_business_id,
|
39 |
+
);
|
40 |
}
|
41 |
|
42 |
|
includes/API/FBE/Configuration/Update/Request.php
CHANGED
@@ -19,7 +19,7 @@ use SkyVerge\WooCommerce\Facebook\API\FBE\Configuration;
|
|
19 |
*
|
20 |
* @since 2.0.0
|
21 |
*/
|
22 |
-
class Request extends Configuration\Request
|
23 |
|
24 |
|
25 |
/**
|
@@ -49,10 +49,10 @@ class Request extends Configuration\Request {
|
|
49 |
*/
|
50 |
public function set_messenger_configuration( Configuration\Messenger $configuration ) {
|
51 |
|
52 |
-
$this->data['messenger_chat'] =
|
53 |
'enabled' => $configuration->is_enabled(),
|
54 |
'domains' => $configuration->get_domains(),
|
55 |
-
|
56 |
}
|
57 |
|
58 |
|
19 |
*
|
20 |
* @since 2.0.0
|
21 |
*/
|
22 |
+
class Request extends Configuration\Request {
|
23 |
|
24 |
|
25 |
/**
|
49 |
*/
|
50 |
public function set_messenger_configuration( Configuration\Messenger $configuration ) {
|
51 |
|
52 |
+
$this->data['messenger_chat'] = array(
|
53 |
'enabled' => $configuration->is_enabled(),
|
54 |
'domains' => $configuration->get_domains(),
|
55 |
+
);
|
56 |
}
|
57 |
|
58 |
|
includes/API/FBE/Installation/Read/Request.php
CHANGED
@@ -19,7 +19,7 @@ use SkyVerge\WooCommerce\Facebook\API\FBE\Installation;
|
|
19 |
*
|
20 |
* @since 2.0.0
|
21 |
*/
|
22 |
-
class Request extends Installation\Request
|
23 |
|
24 |
|
25 |
/**
|
@@ -33,9 +33,9 @@ class Request extends Installation\Request {
|
|
33 |
|
34 |
parent::__construct( 'fbe_installs', 'GET' );
|
35 |
|
36 |
-
$this->params =
|
37 |
'fbe_external_business_id' => $external_business_id,
|
38 |
-
|
39 |
}
|
40 |
|
41 |
|
19 |
*
|
20 |
* @since 2.0.0
|
21 |
*/
|
22 |
+
class Request extends Installation\Request {
|
23 |
|
24 |
|
25 |
/**
|
33 |
|
34 |
parent::__construct( 'fbe_installs', 'GET' );
|
35 |
|
36 |
+
$this->params = array(
|
37 |
'fbe_external_business_id' => $external_business_id,
|
38 |
+
);
|
39 |
}
|
40 |
|
41 |
|
includes/API/FBE/Installation/Read/Response.php
CHANGED
@@ -19,7 +19,7 @@ use SkyVerge\WooCommerce\Facebook\API;
|
|
19 |
*
|
20 |
* @since 2.0.0
|
21 |
*/
|
22 |
-
class Response extends API\Response
|
23 |
|
24 |
|
25 |
/**
|
@@ -130,7 +130,7 @@ class Response extends API\Response {
|
|
130 |
*/
|
131 |
public function get_profiles() {
|
132 |
|
133 |
-
return ! empty( $this->get_data()->profiles ) ? $this->get_data()->profiles :
|
134 |
}
|
135 |
|
136 |
|
@@ -143,7 +143,7 @@ class Response extends API\Response {
|
|
143 |
*/
|
144 |
public function get_data() {
|
145 |
|
146 |
-
$data = ! empty( $this->response_data->data ) && is_array( $this->response_data->data ) ? $this->response_data->data :
|
147 |
|
148 |
return is_object( $data[0] ) ? $data[0] : new \stdClass();
|
149 |
}
|
19 |
*
|
20 |
* @since 2.0.0
|
21 |
*/
|
22 |
+
class Response extends API\Response {
|
23 |
|
24 |
|
25 |
/**
|
130 |
*/
|
131 |
public function get_profiles() {
|
132 |
|
133 |
+
return ! empty( $this->get_data()->profiles ) ? $this->get_data()->profiles : array();
|
134 |
}
|
135 |
|
136 |
|
143 |
*/
|
144 |
public function get_data() {
|
145 |
|
146 |
+
$data = ! empty( $this->response_data->data ) && is_array( $this->response_data->data ) ? $this->response_data->data : array();
|
147 |
|
148 |
return is_object( $data[0] ) ? $data[0] : new \stdClass();
|
149 |
}
|
includes/API/FBE/Installation/Request.php
CHANGED
@@ -19,7 +19,7 @@ use SkyVerge\WooCommerce\Facebook\API;
|
|
19 |
*
|
20 |
* @since 2.0.0
|
21 |
*/
|
22 |
-
class Request extends API\Request
|
23 |
|
24 |
|
25 |
/**
|
19 |
*
|
20 |
* @since 2.0.0
|
21 |
*/
|
22 |
+
class Request extends API\Request {
|
23 |
|
24 |
|
25 |
/**
|
includes/API/Orders/Acknowledge/Request.php
CHANGED
@@ -19,7 +19,7 @@ use SkyVerge\WooCommerce\Facebook\API;
|
|
19 |
*
|
20 |
* @since 2.1.0
|
21 |
*/
|
22 |
-
class Request extends API\Orders\Abstract_Request
|
23 |
|
24 |
|
25 |
use API\Traits\Idempotent_Request;
|
@@ -37,10 +37,12 @@ class Request extends API\Orders\Abstract_Request {
|
|
37 |
|
38 |
parent::__construct( "/{$remote_id}/acknowledge_order", 'POST' );
|
39 |
|
40 |
-
$this->set_data(
|
41 |
-
|
42 |
-
|
43 |
-
|
|
|
|
|
44 |
}
|
45 |
|
46 |
|
19 |
*
|
20 |
* @since 2.1.0
|
21 |
*/
|
22 |
+
class Request extends API\Orders\Abstract_Request {
|
23 |
|
24 |
|
25 |
use API\Traits\Idempotent_Request;
|
37 |
|
38 |
parent::__construct( "/{$remote_id}/acknowledge_order", 'POST' );
|
39 |
|
40 |
+
$this->set_data(
|
41 |
+
array(
|
42 |
+
'merchant_order_reference' => $merchant_order_reference,
|
43 |
+
'idempotency_key' => $this->get_idempotency_key(),
|
44 |
+
)
|
45 |
+
);
|
46 |
}
|
47 |
|
48 |
|
includes/API/Orders/Cancel/Request.php
CHANGED
@@ -19,7 +19,7 @@ use SkyVerge\WooCommerce\Facebook\API;
|
|
19 |
*
|
20 |
* @since 2.1.0
|
21 |
*/
|
22 |
-
class Request extends API\Orders\Abstract_Request
|
23 |
|
24 |
|
25 |
use API\Traits\Idempotent_Request;
|
@@ -32,19 +32,21 @@ class Request extends API\Orders\Abstract_Request {
|
|
32 |
*
|
33 |
* @param string $remote_id remote order ID
|
34 |
* @param string $reason cancellation reason code
|
35 |
-
* @param bool
|
36 |
*/
|
37 |
public function __construct( $remote_id, $reason, $restock_items = true ) {
|
38 |
|
39 |
parent::__construct( "/{$remote_id}/cancellations", 'POST' );
|
40 |
|
41 |
-
$this->set_data(
|
42 |
-
|
43 |
-
'
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
|
|
|
|
48 |
}
|
49 |
|
50 |
|
19 |
*
|
20 |
* @since 2.1.0
|
21 |
*/
|
22 |
+
class Request extends API\Orders\Abstract_Request {
|
23 |
|
24 |
|
25 |
use API\Traits\Idempotent_Request;
|
32 |
*
|
33 |
* @param string $remote_id remote order ID
|
34 |
* @param string $reason cancellation reason code
|
35 |
+
* @param bool $restock_items whether or not the items were restocked
|
36 |
*/
|
37 |
public function __construct( $remote_id, $reason, $restock_items = true ) {
|
38 |
|
39 |
parent::__construct( "/{$remote_id}/cancellations", 'POST' );
|
40 |
|
41 |
+
$this->set_data(
|
42 |
+
array(
|
43 |
+
'cancel_reason' => array(
|
44 |
+
'reason_code' => $reason,
|
45 |
+
),
|
46 |
+
'restock_items' => $restock_items,
|
47 |
+
'idempotency_key' => $this->get_idempotency_key(),
|
48 |
+
)
|
49 |
+
);
|
50 |
}
|
51 |
|
52 |
|
includes/API/Orders/Fulfillment/Request.php
CHANGED
@@ -19,7 +19,7 @@ use SkyVerge\WooCommerce\Facebook\API;
|
|
19 |
*
|
20 |
* @since 2.1.0
|
21 |
*/
|
22 |
-
class Request extends API\Orders\Abstract_Request
|
23 |
|
24 |
|
25 |
use API\Traits\Idempotent_Request;
|
@@ -31,7 +31,7 @@ class Request extends API\Orders\Abstract_Request {
|
|
31 |
* @since 2.1.0
|
32 |
*
|
33 |
* @param string $remote_id remote order ID
|
34 |
-
* @param array
|
35 |
*/
|
36 |
public function __construct( $remote_id, $fulfillment_data ) {
|
37 |
|
19 |
*
|
20 |
* @since 2.1.0
|
21 |
*/
|
22 |
+
class Request extends API\Orders\Abstract_Request {
|
23 |
|
24 |
|
25 |
use API\Traits\Idempotent_Request;
|
31 |
* @since 2.1.0
|
32 |
*
|
33 |
* @param string $remote_id remote order ID
|
34 |
+
* @param array $fulfillment_data fulfillment data
|
35 |
*/
|
36 |
public function __construct( $remote_id, $fulfillment_data ) {
|
37 |
|
includes/API/Orders/Order.php
CHANGED
@@ -87,7 +87,7 @@ class Order {
|
|
87 |
*/
|
88 |
public function get_items() {
|
89 |
|
90 |
-
return ! empty( $this->data['items']['data'] ) ? $this->data['items']['data'] :
|
91 |
}
|
92 |
|
93 |
|
@@ -115,7 +115,7 @@ class Order {
|
|
115 |
*/
|
116 |
public function get_selected_shipping_option() {
|
117 |
|
118 |
-
return isset( $this->data['selected_shipping_option'] ) ? $this->data['selected_shipping_option'] :
|
119 |
}
|
120 |
|
121 |
|
@@ -130,7 +130,7 @@ class Order {
|
|
130 |
*/
|
131 |
public function get_shipping_address() {
|
132 |
|
133 |
-
return isset( $this->data['shipping_address'] ) ? $this->data['shipping_address'] :
|
134 |
}
|
135 |
|
136 |
|
@@ -145,7 +145,7 @@ class Order {
|
|
145 |
*/
|
146 |
public function get_estimated_payment_details() {
|
147 |
|
148 |
-
return isset( $this->data['estimated_payment_details'] ) ? $this->data['estimated_payment_details'] :
|
149 |
}
|
150 |
|
151 |
|
@@ -160,7 +160,7 @@ class Order {
|
|
160 |
*/
|
161 |
public function get_buyer_details() {
|
162 |
|
163 |
-
return isset( $this->data['buyer_details'] ) ? $this->data['buyer_details'] :
|
164 |
}
|
165 |
|
166 |
|
87 |
*/
|
88 |
public function get_items() {
|
89 |
|
90 |
+
return ! empty( $this->data['items']['data'] ) ? $this->data['items']['data'] : array();
|
91 |
}
|
92 |
|
93 |
|
115 |
*/
|
116 |
public function get_selected_shipping_option() {
|
117 |
|
118 |
+
return isset( $this->data['selected_shipping_option'] ) ? $this->data['selected_shipping_option'] : array();
|
119 |
}
|
120 |
|
121 |
|
130 |
*/
|
131 |
public function get_shipping_address() {
|
132 |
|
133 |
+
return isset( $this->data['shipping_address'] ) ? $this->data['shipping_address'] : array();
|
134 |
}
|
135 |
|
136 |
|
145 |
*/
|
146 |
public function get_estimated_payment_details() {
|
147 |
|
148 |
+
return isset( $this->data['estimated_payment_details'] ) ? $this->data['estimated_payment_details'] : array();
|
149 |
}
|
150 |
|
151 |
|
160 |
*/
|
161 |
public function get_buyer_details() {
|
162 |
|
163 |
+
return isset( $this->data['buyer_details'] ) ? $this->data['buyer_details'] : array();
|
164 |
}
|
165 |
|
166 |
|
includes/API/Orders/Read/Request.php
CHANGED
@@ -19,7 +19,7 @@ use SkyVerge\WooCommerce\Facebook\API;
|
|
19 |
*
|
20 |
* @since 2.1.0
|
21 |
*/
|
22 |
-
class Request extends API\Orders\Abstract_Request
|
23 |
|
24 |
|
25 |
/**
|
@@ -28,36 +28,39 @@ class Request extends API\Orders\Abstract_Request {
|
|
28 |
* @since 2.1.0
|
29 |
*
|
30 |
* @param string $remote_id remote order ID
|
31 |
-
* @param array
|
32 |
*/
|
33 |
-
public function __construct( $remote_id, $fields =
|
34 |
|
35 |
parent::__construct( "/{$remote_id}", 'GET' );
|
36 |
|
37 |
if ( empty( $fields ) ) {
|
38 |
|
39 |
// request all top-level fields
|
40 |
-
$fields = implode(
|
41 |
-
'
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
|
|
|
|
|
|
54 |
|
55 |
} elseif ( is_array( $fields ) ) {
|
56 |
|
57 |
$fields = implode( ',', $fields );
|
58 |
}
|
59 |
|
60 |
-
$this->set_params(
|
61 |
}
|
62 |
|
63 |
|
19 |
*
|
20 |
* @since 2.1.0
|
21 |
*/
|
22 |
+
class Request extends API\Orders\Abstract_Request {
|
23 |
|
24 |
|
25 |
/**
|
28 |
* @since 2.1.0
|
29 |
*
|
30 |
* @param string $remote_id remote order ID
|
31 |
+
* @param array $fields fields to be returned
|
32 |
*/
|
33 |
+
public function __construct( $remote_id, $fields = array() ) {
|
34 |
|
35 |
parent::__construct( "/{$remote_id}", 'GET' );
|
36 |
|
37 |
if ( empty( $fields ) ) {
|
38 |
|
39 |
// request all top-level fields
|
40 |
+
$fields = implode(
|
41 |
+
',',
|
42 |
+
array(
|
43 |
+
'id',
|
44 |
+
'order_status',
|
45 |
+
'created',
|
46 |
+
'last_updated',
|
47 |
+
'items{id,retailer_id,product_id,quantity,price_per_unit,tax_details}',
|
48 |
+
'ship_by_date',
|
49 |
+
'merchant_order_id',
|
50 |
+
'channel',
|
51 |
+
'selected_shipping_option',
|
52 |
+
'shipping_address',
|
53 |
+
'estimated_payment_details',
|
54 |
+
'buyer_details',
|
55 |
+
)
|
56 |
+
);
|
57 |
|
58 |
} elseif ( is_array( $fields ) ) {
|
59 |
|
60 |
$fields = implode( ',', $fields );
|
61 |
}
|
62 |
|
63 |
+
$this->set_params( array( 'fields' => $fields ) );
|
64 |
}
|
65 |
|
66 |
|
includes/API/Orders/Refund/Request.php
CHANGED
@@ -19,7 +19,7 @@ use SkyVerge\WooCommerce\Facebook\API;
|
|
19 |
*
|
20 |
* @since 2.1.0
|
21 |
*/
|
22 |
-
class Request extends API\Orders\Abstract_Request
|
23 |
|
24 |
|
25 |
use API\Traits\Idempotent_Request;
|
@@ -31,7 +31,7 @@ class Request extends API\Orders\Abstract_Request {
|
|
31 |
* @since 2.1.0
|
32 |
*
|
33 |
* @param string $remote_id remote order ID
|
34 |
-
* @param array
|
35 |
*/
|
36 |
public function __construct( $remote_id, $refund_data ) {
|
37 |
|
19 |
*
|
20 |
* @since 2.1.0
|
21 |
*/
|
22 |
+
class Request extends API\Orders\Abstract_Request {
|
23 |
|
24 |
|
25 |
use API\Traits\Idempotent_Request;
|
31 |
* @since 2.1.0
|
32 |
*
|
33 |
* @param string $remote_id remote order ID
|
34 |
+
* @param array $refund_data refund data
|
35 |
*/
|
36 |
public function __construct( $remote_id, $refund_data ) {
|
37 |
|
includes/API/Orders/Request.php
CHANGED
@@ -17,7 +17,7 @@ defined( 'ABSPATH' ) or exit;
|
|
17 |
*
|
18 |
* @since 2.1.0
|
19 |
*/
|
20 |
-
class Request extends Abstract_Request
|
21 |
|
22 |
|
23 |
/**
|
@@ -43,13 +43,13 @@ class Request extends Abstract_Request {
|
|
43 |
* @since 2.1.0
|
44 |
*
|
45 |
* @param string $page_id page ID
|
46 |
-
* @param array
|
47 |
*/
|
48 |
-
public function __construct( $page_id, $args =
|
49 |
|
50 |
parent::__construct( "/{$page_id}/commerce_orders", 'GET' );
|
51 |
|
52 |
-
$params =
|
53 |
|
54 |
if ( isset( $args['updated_before'] ) ) {
|
55 |
|
@@ -78,20 +78,23 @@ class Request extends Abstract_Request {
|
|
78 |
} else {
|
79 |
|
80 |
// request all top-level fields
|
81 |
-
$params['fields'] = implode(
|
82 |
-
'
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
|
|
|
|
|
|
95 |
}
|
96 |
|
97 |
$this->set_params( $params );
|
17 |
*
|
18 |
* @since 2.1.0
|
19 |
*/
|
20 |
+
class Request extends Abstract_Request {
|
21 |
|
22 |
|
23 |
/**
|
43 |
* @since 2.1.0
|
44 |
*
|
45 |
* @param string $page_id page ID
|
46 |
+
* @param array $args optional additional arguments
|
47 |
*/
|
48 |
+
public function __construct( $page_id, $args = array() ) {
|
49 |
|
50 |
parent::__construct( "/{$page_id}/commerce_orders", 'GET' );
|
51 |
|
52 |
+
$params = array();
|
53 |
|
54 |
if ( isset( $args['updated_before'] ) ) {
|
55 |
|
78 |
} else {
|
79 |
|
80 |
// request all top-level fields
|
81 |
+
$params['fields'] = implode(
|
82 |
+
',',
|
83 |
+
array(
|
84 |
+
'id',
|
85 |
+
'order_status',
|
86 |
+
'created',
|
87 |
+
'last_updated',
|
88 |
+
'items{id,retailer_id,product_id,quantity,price_per_unit,tax_details}',
|
89 |
+
'ship_by_date',
|
90 |
+
'merchant_order_id',
|
91 |
+
'channel',
|
92 |
+
'selected_shipping_option',
|
93 |
+
'shipping_address',
|
94 |
+
'estimated_payment_details',
|
95 |
+
'buyer_details',
|
96 |
+
)
|
97 |
+
);
|
98 |
}
|
99 |
|
100 |
$this->set_params( $params );
|
includes/API/Orders/Response.php
CHANGED
@@ -34,7 +34,7 @@ class Response extends API\Response {
|
|
34 |
*/
|
35 |
public function get_orders() {
|
36 |
|
37 |
-
$orders =
|
38 |
|
39 |
foreach ( $this->get_data() as $order_data ) {
|
40 |
$orders[] = new Order( json_decode( json_encode( $order_data ), true ) );
|
34 |
*/
|
35 |
public function get_orders() {
|
36 |
|
37 |
+
$orders = array();
|
38 |
|
39 |
foreach ( $this->get_data() as $order_data ) {
|
40 |
$orders[] = new Order( json_decode( json_encode( $order_data ), true ) );
|
includes/API/Pages/Read/Request.php
CHANGED
@@ -19,7 +19,7 @@ use SkyVerge\WooCommerce\Facebook\API;
|
|
19 |
*
|
20 |
* @since 2.0.0
|
21 |
*/
|
22 |
-
class Request extends API\Request
|
23 |
|
24 |
|
25 |
/**
|
@@ -44,7 +44,7 @@ class Request extends API\Request {
|
|
44 |
*/
|
45 |
public function get_params() {
|
46 |
|
47 |
-
return
|
48 |
}
|
49 |
|
50 |
|
19 |
*
|
20 |
* @since 2.0.0
|
21 |
*/
|
22 |
+
class Request extends API\Request {
|
23 |
|
24 |
|
25 |
/**
|
44 |
*/
|
45 |
public function get_params() {
|
46 |
|
47 |
+
return array( 'fields' => 'name,link' );
|
48 |
}
|
49 |
|
50 |
|
includes/API/Pages/Read/Response.php
CHANGED
@@ -19,7 +19,7 @@ use SkyVerge\WooCommerce\Facebook\API;
|
|
19 |
*
|
20 |
* @since 2.0.0
|
21 |
*/
|
22 |
-
class Response extends API\Response
|
23 |
|
24 |
|
25 |
/**
|
19 |
*
|
20 |
* @since 2.0.0
|
21 |
*/
|
22 |
+
class Response extends API\Response {
|
23 |
|
24 |
|
25 |
/**
|
includes/API/Pixel/Events/Request.php
CHANGED
@@ -30,7 +30,7 @@ class Request extends API\Request {
|
|
30 |
/**
|
31 |
* Request constructor.
|
32 |
*
|
33 |
-
* @param string
|
34 |
* @param Event[] $events events to send
|
35 |
*/
|
36 |
public function __construct( $pixel_id, array $events ) {
|
@@ -50,10 +50,10 @@ class Request extends API\Request {
|
|
50 |
*/
|
51 |
public function get_data() {
|
52 |
|
53 |
-
$data =
|
54 |
-
'data' =>
|
55 |
'partner_agent' => Event::get_platform_identifier(),
|
56 |
-
|
57 |
|
58 |
foreach ( $this->events as $event ) {
|
59 |
|
@@ -88,7 +88,7 @@ class Request extends API\Request {
|
|
88 |
* @param array $data request data
|
89 |
* @param Request $request request object
|
90 |
*/
|
91 |
-
return apply_filters( 'wc_facebook_api_pixel_event_request_data', $data, $this);
|
92 |
}
|
93 |
|
94 |
|
30 |
/**
|
31 |
* Request constructor.
|
32 |
*
|
33 |
+
* @param string $pixel_id
|
34 |
* @param Event[] $events events to send
|
35 |
*/
|
36 |
public function __construct( $pixel_id, array $events ) {
|
50 |
*/
|
51 |
public function get_data() {
|
52 |
|
53 |
+
$data = array(
|
54 |
+
'data' => array(),
|
55 |
'partner_agent' => Event::get_platform_identifier(),
|
56 |
+
);
|
57 |
|
58 |
foreach ( $this->events as $event ) {
|
59 |
|
88 |
* @param array $data request data
|
89 |
* @param Request $request request object
|
90 |
*/
|
91 |
+
return apply_filters( 'wc_facebook_api_pixel_event_request_data', $data, $this );
|
92 |
}
|
93 |
|
94 |
|
includes/API/Request.php
CHANGED
@@ -32,7 +32,7 @@ class Request extends Framework\SV_WC_API_JSON_Request {
|
|
32 |
protected $retry_count = 0;
|
33 |
|
34 |
/** @var int[] the response codes that should trigger a retry */
|
35 |
-
protected $retry_codes =
|
36 |
|
37 |
|
38 |
/**
|
32 |
protected $retry_count = 0;
|
33 |
|
34 |
/** @var int[] the response codes that should trigger a retry */
|
35 |
+
protected $retry_codes = array();
|
36 |
|
37 |
|
38 |
/**
|
includes/API/Traits/Paginated_Response.php
CHANGED
@@ -65,7 +65,7 @@ trait Paginated_Response {
|
|
65 |
*/
|
66 |
public function get_data() {
|
67 |
|
68 |
-
return ! empty( $this->response_data->data ) ? $this->response_data->data :
|
69 |
}
|
70 |
|
71 |
|
65 |
*/
|
66 |
public function get_data() {
|
67 |
|
68 |
+
return ! empty( $this->response_data->data ) ? $this->response_data->data : array();
|
69 |
}
|
70 |
|
71 |
|
includes/API/Traits/Rate_Limited_API.php
CHANGED
@@ -30,7 +30,7 @@ trait Rate_Limited_API {
|
|
30 |
* @since 2.0.0
|
31 |
*
|
32 |
* @param string $rate_limit_id request ID for rate limiting
|
33 |
-
* @param int
|
34 |
*/
|
35 |
public function set_rate_limit_delay( $rate_limit_id, $delay ) {
|
36 |
|
@@ -68,7 +68,7 @@ trait Rate_Limited_API {
|
|
68 |
* @since 2.0.0
|
69 |
*
|
70 |
* @param Rate_Limited_Response $response API response object
|
71 |
-
* @param array
|
72 |
* @return int delay in seconds
|
73 |
*/
|
74 |
protected function calculate_rate_limit_delay( $response, $headers ) {
|
30 |
* @since 2.0.0
|
31 |
*
|
32 |
* @param string $rate_limit_id request ID for rate limiting
|
33 |
+
* @param int $delay delay in seconds
|
34 |
*/
|
35 |
public function set_rate_limit_delay( $rate_limit_id, $delay ) {
|
36 |
|
68 |
* @since 2.0.0
|
69 |
*
|
70 |
* @param Rate_Limited_Response $response API response object
|
71 |
+
* @param array $headers API response headers
|
72 |
* @return int delay in seconds
|
73 |
*/
|
74 |
protected function calculate_rate_limit_delay( $response, $headers ) {
|
includes/API/Traits/Rate_Limited_Response.php
CHANGED
@@ -33,7 +33,7 @@ trait Rate_Limited_Response {
|
|
33 |
*/
|
34 |
private function get_usage_data( $headers ) {
|
35 |
|
36 |
-
$usage_data =
|
37 |
|
38 |
if ( ! empty( $headers['X-Business-Use-Case-Usage'] ) ) {
|
39 |
|
33 |
*/
|
34 |
private function get_usage_data( $headers ) {
|
35 |
|
36 |
+
$usage_data = array();
|
37 |
|
38 |
if ( ! empty( $headers['X-Business-Use-Case-Usage'] ) ) {
|
39 |
|
includes/API/User/Permissions/Delete/Request.php
CHANGED
@@ -19,7 +19,7 @@ use SkyVerge\WooCommerce\Facebook\API;
|
|
19 |
*
|
20 |
* @since 2.0.0
|
21 |
*/
|
22 |
-
class Request extends API\Request
|
23 |
|
24 |
|
25 |
/**
|
19 |
*
|
20 |
* @since 2.0.0
|
21 |
*/
|
22 |
+
class Request extends API\Request {
|
23 |
|
24 |
|
25 |
/**
|
includes/API/User/Request.php
CHANGED
@@ -19,7 +19,7 @@ use SkyVerge\WooCommerce\Facebook\API;
|
|
19 |
*
|
20 |
* @since 2.0.0
|
21 |
*/
|
22 |
-
class Request extends API\Request
|
23 |
|
24 |
|
25 |
/**
|
19 |
*
|
20 |
* @since 2.0.0
|
21 |
*/
|
22 |
+
class Request extends API\Request {
|
23 |
|
24 |
|
25 |
/**
|
includes/Admin.php
CHANGED
@@ -43,7 +43,7 @@ class Admin {
|
|
43 |
public function __construct() {
|
44 |
|
45 |
// enqueue admin scripts
|
46 |
-
add_action( 'admin_enqueue_scripts',
|
47 |
|
48 |
$plugin = facebook_for_woocommerce();
|
49 |
|
@@ -57,7 +57,7 @@ class Admin {
|
|
57 |
require_once __DIR__ . '/Admin/Product_Sets.php';
|
58 |
|
59 |
$this->product_categories = new Admin\Product_Categories();
|
60 |
-
$this->product_sets
|
61 |
|
62 |
// add a modal in admin product pages
|
63 |
add_action( 'admin_footer', array( $this, 'render_modal_template' ) );
|
@@ -141,46 +141,77 @@ class Admin {
|
|
141 |
if ( in_array( $current_screen->id, $modal_screens, true ) || facebook_for_woocommerce()->is_plugin_settings() ) {
|
142 |
|
143 |
// enqueue modal functions
|
144 |
-
wp_enqueue_script(
|
|
|
|
|
|
|
|
|
|
|
145 |
}
|
146 |
|
147 |
if ( 'edit-fb_product_set' === $current_screen->id ) {
|
148 |
|
149 |
// enqueue WooCommerce Admin Styles because of Select2
|
150 |
-
wp_enqueue_style(
|
151 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
152 |
|
153 |
-
wp_enqueue_script(
|
|
|
|
|
|
|
|
|
|
|
|
|
154 |
}
|
155 |
|
156 |
if ( 'product' === $current_screen->id || 'edit-product' === $current_screen->id ) {
|
157 |
|
158 |
-
wp_enqueue_style(
|
|
|
|
|
|
|
|
|
|
|
159 |
|
160 |
-
wp_enqueue_script(
|
|
|
|
|
|
|
|
|
|
|
161 |
|
162 |
wp_localize_script(
|
163 |
'facebook-for-woocommerce-products-admin',
|
164 |
'facebook_for_woocommerce_products_admin',
|
165 |
-
|
166 |
-
'ajax_url'
|
167 |
-
'enhanced_attribute_optional_selector'
|
168 |
-
'enhanced_attribute_page_type_edit_category'
|
169 |
-
'enhanced_attribute_page_type_add_category'
|
170 |
-
'enhanced_attribute_page_type_edit_product'
|
171 |
-
'is_sync_enabled_for_product'
|
172 |
-
'set_product_visibility_nonce'
|
173 |
-
'set_product_sync_prompt_nonce'
|
174 |
-
'set_product_sync_bulk_action_prompt_nonce'
|
175 |
-
'product_not_ready_modal_message'
|
176 |
-
'product_not_ready_modal_buttons'
|
177 |
'product_removed_from_sync_confirm_modal_message' => $this->get_product_removed_from_sync_confirm_modal_message(),
|
178 |
'product_removed_from_sync_confirm_modal_buttons' => $this->get_product_removed_from_sync_confirm_modal_buttons(),
|
179 |
-
'product_removed_from_sync_field_id'
|
180 |
-
'i18n'
|
181 |
'missing_google_product_category_message' => __( 'Please enter a Google product category and at least one sub-category to sell this product on Instagram.', 'facebook-for-woocommerce' ),
|
182 |
-
|
183 |
-
|
184 |
);
|
185 |
|
186 |
}//end if
|
@@ -192,8 +223,12 @@ class Admin {
|
|
192 |
}
|
193 |
}//end if
|
194 |
|
195 |
-
|
196 |
-
|
|
|
|
|
|
|
|
|
197 |
|
198 |
wp_localize_script(
|
199 |
'wc-facebook-google-product-category-fields',
|
@@ -245,18 +280,30 @@ class Admin {
|
|
245 |
|
246 |
<ul class="ul-disc">
|
247 |
<li><?php esc_html_e( 'Has a price defined', 'facebook-for-woocommerce' ); ?></li>
|
248 |
-
<li
|
|
|
|
|
|
|
249 |
/* translators: Placeholders: %1$s - <strong> opening HTML tag, %2$s - </strong> closing HTML tag */
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
255 |
/* translators: Placeholders: %1$s - <strong> opening HTML tag, %2$s - </strong> closing HTML tag */
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
-
|
|
|
|
|
|
|
260 |
</ul>
|
261 |
<?php
|
262 |
|
@@ -300,12 +347,16 @@ class Admin {
|
|
300 |
ob_start();
|
301 |
|
302 |
?>
|
303 |
-
<p
|
|
|
|
|
304 |
/* translators: Placeholders: %1$s - opening <a> link tag, %2$s - closing </a> link tag */
|
305 |
-
|
306 |
-
|
307 |
-
|
308 |
-
|
|
|
|
|
309 |
<?php
|
310 |
|
311 |
return ob_get_clean();
|
@@ -400,7 +451,6 @@ class Admin {
|
|
400 |
} else {
|
401 |
esc_html_e( 'Sync and hide', 'facebook-for-woocommerce' );
|
402 |
}
|
403 |
-
|
404 |
} else {
|
405 |
|
406 |
esc_html_e( 'Do not sync', 'facebook-for-woocommerce' );
|
@@ -1278,10 +1328,12 @@ class Admin {
|
|
1278 |
)
|
1279 |
);
|
1280 |
|
1281 |
-
woocommerce_wp_hidden_input(
|
1282 |
-
|
1283 |
-
|
1284 |
-
|
|
|
|
|
1285 |
|
1286 |
?>
|
1287 |
</div>
|
43 |
public function __construct() {
|
44 |
|
45 |
// enqueue admin scripts
|
46 |
+
add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
|
47 |
|
48 |
$plugin = facebook_for_woocommerce();
|
49 |
|
57 |
require_once __DIR__ . '/Admin/Product_Sets.php';
|
58 |
|
59 |
$this->product_categories = new Admin\Product_Categories();
|
60 |
+
$this->product_sets = new Admin\Product_Sets();
|
61 |
|
62 |
// add a modal in admin product pages
|
63 |
add_action( 'admin_footer', array( $this, 'render_modal_template' ) );
|
141 |
if ( in_array( $current_screen->id, $modal_screens, true ) || facebook_for_woocommerce()->is_plugin_settings() ) {
|
142 |
|
143 |
// enqueue modal functions
|
144 |
+
wp_enqueue_script(
|
145 |
+
'facebook-for-woocommerce-modal',
|
146 |
+
facebook_for_woocommerce()->get_asset_build_dir_url() . '/admin/modal.js',
|
147 |
+
array( 'jquery', 'wc-backbone-modal', 'jquery-blockui' ),
|
148 |
+
\WC_Facebookcommerce::PLUGIN_VERSION
|
149 |
+
);
|
150 |
}
|
151 |
|
152 |
if ( 'edit-fb_product_set' === $current_screen->id ) {
|
153 |
|
154 |
// enqueue WooCommerce Admin Styles because of Select2
|
155 |
+
wp_enqueue_style(
|
156 |
+
'woocommerce_admin_styles',
|
157 |
+
WC()->plugin_url() . '/assets/css/admin.css',
|
158 |
+
array(),
|
159 |
+
\WC_Facebookcommerce::PLUGIN_VERSION
|
160 |
+
);
|
161 |
+
wp_enqueue_style(
|
162 |
+
'facebook-for-woocommerce-product-sets-admin',
|
163 |
+
facebook_for_woocommerce()->get_plugin_url() . '/assets/css/admin/facebook-for-woocommerce-product-sets-admin.css',
|
164 |
+
array(),
|
165 |
+
\WC_Facebookcommerce::PLUGIN_VERSION
|
166 |
+
);
|
167 |
|
168 |
+
wp_enqueue_script(
|
169 |
+
'facebook-for-woocommerce-product-sets',
|
170 |
+
facebook_for_woocommerce()->get_asset_build_dir_url() . '/admin/product-sets-admin.js',
|
171 |
+
array( 'jquery', 'select2' ),
|
172 |
+
\WC_Facebookcommerce::PLUGIN_VERSION,
|
173 |
+
true
|
174 |
+
);
|
175 |
}
|
176 |
|
177 |
if ( 'product' === $current_screen->id || 'edit-product' === $current_screen->id ) {
|
178 |
|
179 |
+
wp_enqueue_style(
|
180 |
+
'facebook-for-woocommerce-products-admin',
|
181 |
+
facebook_for_woocommerce()->get_plugin_url() . '/assets/css/admin/facebook-for-woocommerce-products-admin.css',
|
182 |
+
array(),
|
183 |
+
\WC_Facebookcommerce::PLUGIN_VERSION
|
184 |
+
);
|
185 |
|
186 |
+
wp_enqueue_script(
|
187 |
+
'facebook-for-woocommerce-products-admin',
|
188 |
+
facebook_for_woocommerce()->get_asset_build_dir_url() . '/admin/products-admin.js',
|
189 |
+
array( 'jquery', 'wc-backbone-modal', 'jquery-blockui', 'facebook-for-woocommerce-modal' ),
|
190 |
+
\WC_Facebookcommerce::PLUGIN_VERSION
|
191 |
+
);
|
192 |
|
193 |
wp_localize_script(
|
194 |
'facebook-for-woocommerce-products-admin',
|
195 |
'facebook_for_woocommerce_products_admin',
|
196 |
+
array(
|
197 |
+
'ajax_url' => admin_url( 'admin-ajax.php' ),
|
198 |
+
'enhanced_attribute_optional_selector' => \SkyVerge\WooCommerce\Facebook\Admin\Enhanced_Catalog_Attribute_Fields::FIELD_ENHANCED_CATALOG_ATTRIBUTE_PREFIX . \SkyVerge\WooCommerce\Facebook\Admin\Enhanced_Catalog_Attribute_Fields::OPTIONAL_SELECTOR_KEY,
|
199 |
+
'enhanced_attribute_page_type_edit_category' => \SkyVerge\WooCommerce\Facebook\Admin\Enhanced_Catalog_Attribute_Fields::PAGE_TYPE_EDIT_CATEGORY,
|
200 |
+
'enhanced_attribute_page_type_add_category' => \SkyVerge\WooCommerce\Facebook\Admin\Enhanced_Catalog_Attribute_Fields::PAGE_TYPE_ADD_CATEGORY,
|
201 |
+
'enhanced_attribute_page_type_edit_product' => \SkyVerge\WooCommerce\Facebook\Admin\Enhanced_Catalog_Attribute_Fields::PAGE_TYPE_EDIT_PRODUCT,
|
202 |
+
'is_sync_enabled_for_product' => $this->is_sync_enabled_for_current_product(),
|
203 |
+
'set_product_visibility_nonce' => wp_create_nonce( 'set-products-visibility' ),
|
204 |
+
'set_product_sync_prompt_nonce' => wp_create_nonce( 'set-product-sync-prompt' ),
|
205 |
+
'set_product_sync_bulk_action_prompt_nonce' => wp_create_nonce( 'set-product-sync-bulk-action-prompt' ),
|
206 |
+
'product_not_ready_modal_message' => $this->get_product_not_ready_modal_message(),
|
207 |
+
'product_not_ready_modal_buttons' => $this->get_product_not_ready_modal_buttons(),
|
208 |
'product_removed_from_sync_confirm_modal_message' => $this->get_product_removed_from_sync_confirm_modal_message(),
|
209 |
'product_removed_from_sync_confirm_modal_buttons' => $this->get_product_removed_from_sync_confirm_modal_buttons(),
|
210 |
+
'product_removed_from_sync_field_id' => '#' . \WC_Facebook_Product::FB_REMOVE_FROM_SYNC,
|
211 |
+
'i18n' => array(
|
212 |
'missing_google_product_category_message' => __( 'Please enter a Google product category and at least one sub-category to sell this product on Instagram.', 'facebook-for-woocommerce' ),
|
213 |
+
),
|
214 |
+
)
|
215 |
);
|
216 |
|
217 |
}//end if
|
223 |
}
|
224 |
}//end if
|
225 |
|
226 |
+
wp_enqueue_script(
|
227 |
+
'wc-facebook-google-product-category-fields',
|
228 |
+
facebook_for_woocommerce()->get_asset_build_dir_url() . '/admin/google-product-category-fields.js',
|
229 |
+
array( 'jquery' ),
|
230 |
+
\WC_Facebookcommerce::PLUGIN_VERSION
|
231 |
+
);
|
232 |
|
233 |
wp_localize_script(
|
234 |
'wc-facebook-google-product-category-fields',
|
280 |
|
281 |
<ul class="ul-disc">
|
282 |
<li><?php esc_html_e( 'Has a price defined', 'facebook-for-woocommerce' ); ?></li>
|
283 |
+
<li>
|
284 |
+
<?php
|
285 |
+
echo esc_html(
|
286 |
+
sprintf(
|
287 |
/* translators: Placeholders: %1$s - <strong> opening HTML tag, %2$s - </strong> closing HTML tag */
|
288 |
+
__( 'Has %1$sManage Stock%2$s enabled on the %1$sInventory%2$s tab', 'facebook-for-woocommerce' ),
|
289 |
+
'<strong>',
|
290 |
+
'</strong>'
|
291 |
+
)
|
292 |
+
);
|
293 |
+
?>
|
294 |
+
</li>
|
295 |
+
<li>
|
296 |
+
<?php
|
297 |
+
echo esc_html(
|
298 |
+
sprintf(
|
299 |
/* translators: Placeholders: %1$s - <strong> opening HTML tag, %2$s - </strong> closing HTML tag */
|
300 |
+
__( 'Has the %1$sFacebook Sync%2$s setting set to "Sync and show" or "Sync and hide"', 'facebook-for-woocommerce' ),
|
301 |
+
'<strong>',
|
302 |
+
'</strong>'
|
303 |
+
)
|
304 |
+
);
|
305 |
+
?>
|
306 |
+
</li>
|
307 |
</ul>
|
308 |
<?php
|
309 |
|
347 |
ob_start();
|
348 |
|
349 |
?>
|
350 |
+
<p>
|
351 |
+
<?php
|
352 |
+
printf(
|
353 |
/* translators: Placeholders: %1$s - opening <a> link tag, %2$s - closing </a> link tag */
|
354 |
+
__( 'You\'re removing a product from the Facebook sync that is currently listed in your %1$sFacebook catalog%2$s. Would you like to delete the product from the Facebook catalog as well?', 'facebook-for-woocommerce' ),
|
355 |
+
'<a href="https://www.facebook.com/products" target="_blank">',
|
356 |
+
'</a>'
|
357 |
+
);
|
358 |
+
?>
|
359 |
+
</p>
|
360 |
<?php
|
361 |
|
362 |
return ob_get_clean();
|
451 |
} else {
|
452 |
esc_html_e( 'Sync and hide', 'facebook-for-woocommerce' );
|
453 |
}
|
|
|
454 |
} else {
|
455 |
|
456 |
esc_html_e( 'Do not sync', 'facebook-for-woocommerce' );
|
1328 |
)
|
1329 |
);
|
1330 |
|
1331 |
+
woocommerce_wp_hidden_input(
|
1332 |
+
array(
|
1333 |
+
'id' => \WC_Facebook_Product::FB_REMOVE_FROM_SYNC,
|
1334 |
+
'value' => '',
|
1335 |
+
)
|
1336 |
+
);
|
1337 |
|
1338 |
?>
|
1339 |
</div>
|
includes/Admin/Abstract_Settings_Screen.php
CHANGED
@@ -118,6 +118,7 @@ abstract class Abstract_Settings_Screen {
|
|
118 |
* Gets the settings.
|
119 |
*
|
120 |
* Should return a multi-dimensional array of settings in the format expected by \WC_Admin_Settings
|
|
|
121 |
* @return array
|
122 |
*/
|
123 |
abstract public function get_settings();
|
118 |
* Gets the settings.
|
119 |
*
|
120 |
* Should return a multi-dimensional array of settings in the format expected by \WC_Admin_Settings
|
121 |
+
*
|
122 |
* @return array
|
123 |
*/
|
124 |
abstract public function get_settings();
|
includes/Admin/Enhanced_Catalog_Attribute_Fields.php
CHANGED
@@ -43,7 +43,7 @@ class Enhanced_Catalog_Attribute_Fields {
|
|
43 |
}
|
44 |
|
45 |
private function extract_attribute( &$attributes, $key ) {
|
46 |
-
$index = array_search($key, array_column( $attributes, 'key' ));
|
47 |
$extracted = false === $index ? array() : array_splice( $attributes, $index, 1 );
|
48 |
return empty( $extracted ) ? null : array_shift( $extracted );
|
49 |
}
|
43 |
}
|
44 |
|
45 |
private function extract_attribute( &$attributes, $key ) {
|
46 |
+
$index = array_search( $key, array_column( $attributes, 'key' ) );
|
47 |
$extracted = false === $index ? array() : array_splice( $attributes, $index, 1 );
|
48 |
return empty( $extracted ) ? null : array_shift( $extracted );
|
49 |
}
|
includes/Admin/Product_Categories.php
CHANGED
@@ -59,7 +59,7 @@ class Product_Categories {
|
|
59 |
|
60 |
wp_enqueue_script(
|
61 |
'wc-facebook-product-categories',
|
62 |
-
facebook_for_woocommerce()->
|
63 |
array(
|
64 |
'jquery',
|
65 |
'wc-backbone-modal',
|
@@ -269,7 +269,7 @@ class Product_Categories {
|
|
269 |
* @since 2.1.0
|
270 |
*
|
271 |
* @param \WP_Term $term current taxonomy term object.
|
272 |
-
* @param string
|
273 |
*/
|
274 |
public function render_edit_enhanced_catalog_attributes_field( \WP_Term $term, $category_id = null ) {
|
275 |
if ( empty( $category_id ) ) {
|
59 |
|
60 |
wp_enqueue_script(
|
61 |
'wc-facebook-product-categories',
|
62 |
+
facebook_for_woocommerce()->get_asset_build_dir_url() . '/admin/product-categories.js',
|
63 |
array(
|
64 |
'jquery',
|
65 |
'wc-backbone-modal',
|
269 |
* @since 2.1.0
|
270 |
*
|
271 |
* @param \WP_Term $term current taxonomy term object.
|
272 |
+
* @param string $category_id passed in category id
|
273 |
*/
|
274 |
public function render_edit_enhanced_catalog_attributes_field( \WP_Term $term, $category_id = null ) {
|
275 |
if ( empty( $category_id ) ) {
|
includes/Admin/Settings.php
CHANGED
@@ -76,7 +76,7 @@ class Settings {
|
|
76 |
if ( Framework\SV_WC_Plugin_Compatibility::is_enhanced_admin_available() ) {
|
77 |
|
78 |
$is_marketing_enabled = is_callable( '\Automattic\WooCommerce\Admin\Loader::is_feature_enabled' )
|
79 |
-
|
80 |
|
81 |
if ( $is_marketing_enabled ) {
|
82 |
|
@@ -88,8 +88,9 @@ class Settings {
|
|
88 |
$root_menu_item,
|
89 |
__( 'Facebook for WooCommerce', 'facebook-for-woocommerce' ),
|
90 |
__( 'Facebook', 'facebook-for-woocommerce' ),
|
91 |
-
'manage_woocommerce',
|
92 |
-
|
|
|
93 |
5
|
94 |
);
|
95 |
|
@@ -109,33 +110,35 @@ class Settings {
|
|
109 |
|
110 |
if ( is_callable( 'wc_admin_connect_page' ) ) {
|
111 |
|
112 |
-
$crumbs =
|
113 |
__( 'Facebook for WooCommerce', 'facebook-for-woocommerce' ),
|
114 |
-
|
115 |
|
116 |
if ( ! empty( $_GET['tab'] ) ) {
|
117 |
switch ( $_GET['tab'] ) {
|
118 |
-
case Settings_Screens\Connection::ID
|
119 |
$crumbs[] = __( 'Connection', 'facebook-for-woocommerce' );
|
120 |
-
|
121 |
-
case Settings_Screens\Messenger::ID
|
122 |
$crumbs[] = __( 'Messenger', 'facebook-for-woocommerce' );
|
123 |
-
|
124 |
-
case Settings_Screens\Product_Sync::ID
|
125 |
$crumbs[] = __( 'Product sync', 'facebook-for-woocommerce' );
|
126 |
-
|
127 |
-
case Settings_Screens\Advertise::ID
|
128 |
$crumbs[] = __( 'Advertise', 'facebook-for-woocommerce' );
|
129 |
-
|
130 |
}
|
131 |
}
|
132 |
|
133 |
-
wc_admin_connect_page(
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
|
|
|
|
139 |
}
|
140 |
}
|
141 |
|
@@ -160,7 +163,7 @@ class Settings {
|
|
160 |
|
161 |
<div class="wrap woocommerce">
|
162 |
|
163 |
-
<?php if ( ! $this->use_woo_nav ): ?>
|
164 |
<nav class="nav-tab-wrapper woo-nav-tab-wrapper">
|
165 |
|
166 |
<?php foreach ( $tabs as $id => $label ) : ?>
|
@@ -325,14 +328,14 @@ class Settings {
|
|
325 |
);
|
326 |
|
327 |
$order = 1;
|
328 |
-
foreach( $this->get_screens() as $screen_id => $screen ) {
|
329 |
$url = $screen instanceof Settings_Screens\Product_Sets
|
330 |
? 'edit-tags.php?taxonomy=fb_product_set&post_type=product'
|
331 |
: 'wc-facebook&tab=' . $screen->get_id();
|
332 |
|
333 |
WooAdminMenu::add_plugin_item(
|
334 |
array(
|
335 |
-
'id' => 'facebook-for-woocommerce-'. $screen->get_id(),
|
336 |
'parent' => 'facebook-for-woocommerce',
|
337 |
'title' => $screen->get_label(),
|
338 |
'url' => $url,
|
76 |
if ( Framework\SV_WC_Plugin_Compatibility::is_enhanced_admin_available() ) {
|
77 |
|
78 |
$is_marketing_enabled = is_callable( '\Automattic\WooCommerce\Admin\Loader::is_feature_enabled' )
|
79 |
+
&& \Automattic\WooCommerce\Admin\Loader::is_feature_enabled( 'marketing' );
|
80 |
|
81 |
if ( $is_marketing_enabled ) {
|
82 |
|
88 |
$root_menu_item,
|
89 |
__( 'Facebook for WooCommerce', 'facebook-for-woocommerce' ),
|
90 |
__( 'Facebook', 'facebook-for-woocommerce' ),
|
91 |
+
'manage_woocommerce',
|
92 |
+
self::PAGE_ID,
|
93 |
+
array( $this, 'render' ),
|
94 |
5
|
95 |
);
|
96 |
|
110 |
|
111 |
if ( is_callable( 'wc_admin_connect_page' ) ) {
|
112 |
|
113 |
+
$crumbs = array(
|
114 |
__( 'Facebook for WooCommerce', 'facebook-for-woocommerce' ),
|
115 |
+
);
|
116 |
|
117 |
if ( ! empty( $_GET['tab'] ) ) {
|
118 |
switch ( $_GET['tab'] ) {
|
119 |
+
case Settings_Screens\Connection::ID:
|
120 |
$crumbs[] = __( 'Connection', 'facebook-for-woocommerce' );
|
121 |
+
break;
|
122 |
+
case Settings_Screens\Messenger::ID:
|
123 |
$crumbs[] = __( 'Messenger', 'facebook-for-woocommerce' );
|
124 |
+
break;
|
125 |
+
case Settings_Screens\Product_Sync::ID:
|
126 |
$crumbs[] = __( 'Product sync', 'facebook-for-woocommerce' );
|
127 |
+
break;
|
128 |
+
case Settings_Screens\Advertise::ID:
|
129 |
$crumbs[] = __( 'Advertise', 'facebook-for-woocommerce' );
|
130 |
+
break;
|
131 |
}
|
132 |
}
|
133 |
|
134 |
+
wc_admin_connect_page(
|
135 |
+
array(
|
136 |
+
'id' => self::PAGE_ID,
|
137 |
+
'screen_id' => $screen_id,
|
138 |
+
'path' => add_query_arg( 'page', self::PAGE_ID, 'admin.php' ),
|
139 |
+
'title' => $crumbs,
|
140 |
+
)
|
141 |
+
);
|
142 |
}
|
143 |
}
|
144 |
|
163 |
|
164 |
<div class="wrap woocommerce">
|
165 |
|
166 |
+
<?php if ( ! $this->use_woo_nav ) : ?>
|
167 |
<nav class="nav-tab-wrapper woo-nav-tab-wrapper">
|
168 |
|
169 |
<?php foreach ( $tabs as $id => $label ) : ?>
|
328 |
);
|
329 |
|
330 |
$order = 1;
|
331 |
+
foreach ( $this->get_screens() as $screen_id => $screen ) {
|
332 |
$url = $screen instanceof Settings_Screens\Product_Sets
|
333 |
? 'edit-tags.php?taxonomy=fb_product_set&post_type=product'
|
334 |
: 'wc-facebook&tab=' . $screen->get_id();
|
335 |
|
336 |
WooAdminMenu::add_plugin_item(
|
337 |
array(
|
338 |
+
'id' => 'facebook-for-woocommerce-' . $screen->get_id(),
|
339 |
'parent' => 'facebook-for-woocommerce',
|
340 |
'title' => $screen->get_label(),
|
341 |
'url' => $url,
|
includes/Admin/Settings_Screens/Advertise.php
CHANGED
@@ -48,9 +48,9 @@ class Advertise extends Admin\Abstract_Settings_Screen {
|
|
48 |
*/
|
49 |
private function add_hooks() {
|
50 |
|
51 |
-
add_action( 'admin_head',
|
52 |
|
53 |
-
add_action( 'admin_enqueue_scripts',
|
54 |
}
|
55 |
|
56 |
|
@@ -67,7 +67,7 @@ class Advertise extends Admin\Abstract_Settings_Screen {
|
|
67 |
return;
|
68 |
}
|
69 |
|
70 |
-
wp_enqueue_style( 'wc-facebook-admin-advertise-settings', facebook_for_woocommerce()->get_plugin_url() . '/assets/css/admin/facebook-for-woocommerce-advertise.css',
|
71 |
}
|
72 |
|
73 |
|
@@ -113,23 +113,23 @@ class Advertise extends Admin\Abstract_Settings_Screen {
|
|
113 |
$connection_handler = facebook_for_woocommerce()->get_connection_handler();
|
114 |
|
115 |
if ( ! $connection_handler || ! $connection_handler->is_connected() ) {
|
116 |
-
return
|
117 |
}
|
118 |
|
119 |
-
return
|
120 |
-
'business_config' =>
|
121 |
-
'business' =>
|
122 |
'name' => $connection_handler->get_business_name(),
|
123 |
-
|
124 |
-
|
125 |
-
'setup' =>
|
126 |
'external_business_id' => $connection_handler->get_external_business_id(),
|
127 |
'timezone' => $this->parse_timezone( wc_timezone_string(), wc_timezone_offset() ),
|
128 |
'currency' => get_woocommerce_currency(),
|
129 |
'business_vertical' => 'ECOMMERCE',
|
130 |
-
|
131 |
'repeat' => false,
|
132 |
-
|
133 |
}
|
134 |
|
135 |
|
@@ -200,7 +200,7 @@ class Advertise extends Admin\Abstract_Settings_Screen {
|
|
200 |
printf(
|
201 |
/* translators: Placeholders: %1$s - opening <a> HTML link tag, %2$s - closing </a> HTML link tag */
|
202 |
esc_html__( 'Please %1$sconnect your store%2$s to Facebook to create ads.', 'facebook-for-woocommerce' ),
|
203 |
-
'<a href="' . esc_url( add_query_arg(
|
204 |
'</a>'
|
205 |
);
|
206 |
|
@@ -238,7 +238,7 @@ class Advertise extends Admin\Abstract_Settings_Screen {
|
|
238 |
*/
|
239 |
public function get_settings() {
|
240 |
|
241 |
-
return
|
242 |
}
|
243 |
|
244 |
|
48 |
*/
|
49 |
private function add_hooks() {
|
50 |
|
51 |
+
add_action( 'admin_head', array( $this, 'output_scripts' ) );
|
52 |
|
53 |
+
add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_assets' ) );
|
54 |
}
|
55 |
|
56 |
|
67 |
return;
|
68 |
}
|
69 |
|
70 |
+
wp_enqueue_style( 'wc-facebook-admin-advertise-settings', facebook_for_woocommerce()->get_plugin_url() . '/assets/css/admin/facebook-for-woocommerce-advertise.css', array(), \WC_Facebookcommerce::VERSION );
|
71 |
}
|
72 |
|
73 |
|
113 |
$connection_handler = facebook_for_woocommerce()->get_connection_handler();
|
114 |
|
115 |
if ( ! $connection_handler || ! $connection_handler->is_connected() ) {
|
116 |
+
return array();
|
117 |
}
|
118 |
|
119 |
+
return array(
|
120 |
+
'business_config' => array(
|
121 |
+
'business' => array(
|
122 |
'name' => $connection_handler->get_business_name(),
|
123 |
+
),
|
124 |
+
),
|
125 |
+
'setup' => array(
|
126 |
'external_business_id' => $connection_handler->get_external_business_id(),
|
127 |
'timezone' => $this->parse_timezone( wc_timezone_string(), wc_timezone_offset() ),
|
128 |
'currency' => get_woocommerce_currency(),
|
129 |
'business_vertical' => 'ECOMMERCE',
|
130 |
+
),
|
131 |
'repeat' => false,
|
132 |
+
);
|
133 |
}
|
134 |
|
135 |
|
200 |
printf(
|
201 |
/* translators: Placeholders: %1$s - opening <a> HTML link tag, %2$s - closing </a> HTML link tag */
|
202 |
esc_html__( 'Please %1$sconnect your store%2$s to Facebook to create ads.', 'facebook-for-woocommerce' ),
|
203 |
+
'<a href="' . esc_url( add_query_arg( array( 'tab' => Connection::ID ), facebook_for_woocommerce()->get_settings_url() ) ) . '">',
|
204 |
'</a>'
|
205 |
);
|
206 |
|
238 |
*/
|
239 |
public function get_settings() {
|
240 |
|
241 |
+
return array();
|
242 |
}
|
243 |
|
244 |
|
includes/Admin/Settings_Screens/Connection.php
CHANGED
@@ -34,9 +34,9 @@ class Connection extends Admin\Abstract_Settings_Screen {
|
|
34 |
$this->label = __( 'Connection', 'facebook-for-woocommerce' );
|
35 |
$this->title = __( 'Connection', 'facebook-for-woocommerce' );
|
36 |
|
37 |
-
add_action( 'admin_enqueue_scripts',
|
38 |
|
39 |
-
add_action( 'admin_notices',
|
40 |
}
|
41 |
|
42 |
|
@@ -55,14 +55,21 @@ class Connection extends Admin\Abstract_Settings_Screen {
|
|
55 |
$message = sprintf(
|
56 |
/* translators: Placeholders: %1$s - <strong> tag, %2$s - </strong> tag, %3$s - <a> tag, %4$s - </a> tag, %5$s - <a> tag, %6$s - </a> tag */
|
57 |
__( '%1$sHeads up!%2$s It looks like there was a problem with reconnecting your site to Facebook. Please %3$sclick here%4$s to try again, or %5$sget in touch with our support team%6$s for assistance.', 'facebook-for-woocommerce' ),
|
58 |
-
'<strong>',
|
59 |
-
'
|
60 |
-
'<a href="' . esc_url( facebook_for_woocommerce()->
|
|
|
|
|
|
|
61 |
);
|
62 |
|
63 |
-
facebook_for_woocommerce()->get_admin_notice_handler()->add_admin_notice(
|
64 |
-
|
65 |
-
|
|
|
|
|
|
|
|
|
66 |
|
67 |
delete_transient( 'wc_facebook_connection_failed' );
|
68 |
}
|
@@ -82,7 +89,7 @@ class Connection extends Admin\Abstract_Settings_Screen {
|
|
82 |
return;
|
83 |
}
|
84 |
|
85 |
-
wp_enqueue_style( 'wc-facebook-admin-connection-settings', facebook_for_woocommerce()->get_plugin_url() . '/assets/css/admin/facebook-for-woocommerce-connection.css',
|
86 |
}
|
87 |
|
88 |
|
@@ -118,37 +125,37 @@ class Connection extends Admin\Abstract_Settings_Screen {
|
|
118 |
* TODO: add pixel & ad account API retrieval when we gain the ads_management permission
|
119 |
* TODO: add the page name and link when we gain the manage_pages permission
|
120 |
*/
|
121 |
-
$static_items =
|
122 |
-
'page'
|
123 |
'label' => __( 'Page', 'facebook-for-woocommerce' ),
|
124 |
'value' => facebook_for_woocommerce()->get_integration()->get_facebook_page_id(),
|
125 |
-
|
126 |
-
'pixel'
|
127 |
'label' => __( 'Pixel', 'facebook-for-woocommerce' ),
|
128 |
'value' => facebook_for_woocommerce()->get_integration()->get_facebook_pixel_id(),
|
129 |
-
|
130 |
-
'catalog'
|
131 |
'label' => __( 'Catalog', 'facebook-for-woocommerce' ),
|
132 |
'value' => facebook_for_woocommerce()->get_integration()->get_product_catalog_id(),
|
133 |
'url' => 'https://facebook.com/products',
|
134 |
-
|
135 |
-
'business-manager'
|
136 |
'label' => __( 'Business Manager account', 'facebook-for-woocommerce' ),
|
137 |
'value' => facebook_for_woocommerce()->get_connection_handler()->get_business_manager_id(),
|
138 |
-
|
139 |
-
'ad-account'
|
140 |
'label' => __( 'Ad Manager account', 'facebook-for-woocommerce' ),
|
141 |
'value' => facebook_for_woocommerce()->get_connection_handler()->get_ad_account_id(),
|
142 |
-
|
143 |
-
'instagram-business-id'
|
144 |
'label' => __( 'Instagram Business ID', 'facebook-for-woocommerce' ),
|
145 |
'value' => facebook_for_woocommerce()->get_connection_handler()->get_instagram_business_id(),
|
146 |
-
|
147 |
-
'commerce-merchant-settings-id' =>
|
148 |
'label' => __( 'Commerce Merchant Settings ID', 'facebook-for-woocommerce' ),
|
149 |
'value' => facebook_for_woocommerce()->get_connection_handler()->get_commerce_merchant_settings_id(),
|
150 |
-
|
151 |
-
|
152 |
|
153 |
// if the catalog ID is set, update the URL and try to get its name for display
|
154 |
if ( $catalog_id = $static_items['catalog']['value'] ) {
|
@@ -162,8 +169,8 @@ class Connection extends Admin\Abstract_Settings_Screen {
|
|
162 |
if ( $name = $response->get_name() ) {
|
163 |
$static_items['catalog']['value'] = $name;
|
164 |
}
|
165 |
-
|
166 |
-
}
|
167 |
}
|
168 |
|
169 |
?>
|
@@ -171,13 +178,17 @@ class Connection extends Admin\Abstract_Settings_Screen {
|
|
171 |
<table class="form-table">
|
172 |
<tbody>
|
173 |
|
174 |
-
<?php
|
|
|
175 |
|
176 |
-
$item = wp_parse_args(
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
|
|
|
|
|
|
181 |
|
182 |
?>
|
183 |
|
@@ -212,7 +223,7 @@ class Connection extends Admin\Abstract_Settings_Screen {
|
|
212 |
|
213 |
<?php else : ?>
|
214 |
|
215 |
-
<?php echo '-' ?>
|
216 |
|
217 |
<?php endif; ?>
|
218 |
|
@@ -246,11 +257,11 @@ class Connection extends Admin\Abstract_Settings_Screen {
|
|
246 |
}
|
247 |
|
248 |
$subtitle = __( 'Use this WooCommerce and Facebook integration to:', 'facebook-for-woocommerce' );
|
249 |
-
$benefits =
|
250 |
-
__( 'Create an ad in a few steps', 'facebook-for-woocommerce'),
|
251 |
-
__( 'Use built-in best practices for online sales', 'facebook-for-woocommerce'),
|
252 |
-
__( 'Get reporting on sales and revenue', 'facebook-for-woocommerce'),
|
253 |
-
|
254 |
|
255 |
?>
|
256 |
|
@@ -304,25 +315,25 @@ class Connection extends Admin\Abstract_Settings_Screen {
|
|
304 |
*/
|
305 |
public function get_settings() {
|
306 |
|
307 |
-
return
|
308 |
|
309 |
-
|
310 |
'title' => __( 'Debug', 'facebook-for-woocommerce' ),
|
311 |
'type' => 'title',
|
312 |
-
|
313 |
|
314 |
-
|
315 |
'id' => \WC_Facebookcommerce_Integration::SETTING_ENABLE_DEBUG_MODE,
|
316 |
'title' => __( 'Enable debug mode', 'facebook-for-woocommerce' ),
|
317 |
'type' => 'checkbox',
|
318 |
'desc' => __( 'Log plugin events for debugging', 'facebook-for-woocommerce' ),
|
319 |
'desc_tip' => __( 'Only enable this if you are experiencing problems with the plugin.', 'facebook-for-woocommerce' ),
|
320 |
'default' => 'no',
|
321 |
-
|
322 |
|
323 |
-
|
324 |
|
325 |
-
|
326 |
}
|
327 |
|
328 |
|
34 |
$this->label = __( 'Connection', 'facebook-for-woocommerce' );
|
35 |
$this->title = __( 'Connection', 'facebook-for-woocommerce' );
|
36 |
|
37 |
+
add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_assets' ) );
|
38 |
|
39 |
+
add_action( 'admin_notices', array( $this, 'add_notices' ) );
|
40 |
}
|
41 |
|
42 |
|
55 |
$message = sprintf(
|
56 |
/* translators: Placeholders: %1$s - <strong> tag, %2$s - </strong> tag, %3$s - <a> tag, %4$s - </a> tag, %5$s - <a> tag, %6$s - </a> tag */
|
57 |
__( '%1$sHeads up!%2$s It looks like there was a problem with reconnecting your site to Facebook. Please %3$sclick here%4$s to try again, or %5$sget in touch with our support team%6$s for assistance.', 'facebook-for-woocommerce' ),
|
58 |
+
'<strong>',
|
59 |
+
'</strong>',
|
60 |
+
'<a href="' . esc_url( facebook_for_woocommerce()->get_connection_handler()->get_connect_url() ) . '">',
|
61 |
+
'</a>',
|
62 |
+
'<a href="' . esc_url( facebook_for_woocommerce()->get_support_url() ) . '" target="_blank">',
|
63 |
+
'</a>'
|
64 |
);
|
65 |
|
66 |
+
facebook_for_woocommerce()->get_admin_notice_handler()->add_admin_notice(
|
67 |
+
$message,
|
68 |
+
'wc_facebook_connection_failed',
|
69 |
+
array(
|
70 |
+
'notice_class' => 'error',
|
71 |
+
)
|
72 |
+
);
|
73 |
|
74 |
delete_transient( 'wc_facebook_connection_failed' );
|
75 |
}
|
89 |
return;
|
90 |
}
|
91 |
|
92 |
+
wp_enqueue_style( 'wc-facebook-admin-connection-settings', facebook_for_woocommerce()->get_plugin_url() . '/assets/css/admin/facebook-for-woocommerce-connection.css', array(), \WC_Facebookcommerce::VERSION );
|
93 |
}
|
94 |
|
95 |
|
125 |
* TODO: add pixel & ad account API retrieval when we gain the ads_management permission
|
126 |
* TODO: add the page name and link when we gain the manage_pages permission
|
127 |
*/
|
128 |
+
$static_items = array(
|
129 |
+
'page' => array(
|
130 |
'label' => __( 'Page', 'facebook-for-woocommerce' ),
|
131 |
'value' => facebook_for_woocommerce()->get_integration()->get_facebook_page_id(),
|
132 |
+
),
|
133 |
+
'pixel' => array(
|
134 |
'label' => __( 'Pixel', 'facebook-for-woocommerce' ),
|
135 |
'value' => facebook_for_woocommerce()->get_integration()->get_facebook_pixel_id(),
|
136 |
+
),
|
137 |
+
'catalog' => array(
|
138 |
'label' => __( 'Catalog', 'facebook-for-woocommerce' ),
|
139 |
'value' => facebook_for_woocommerce()->get_integration()->get_product_catalog_id(),
|
140 |
'url' => 'https://facebook.com/products',
|
141 |
+
),
|
142 |
+
'business-manager' => array(
|
143 |
'label' => __( 'Business Manager account', 'facebook-for-woocommerce' ),
|
144 |
'value' => facebook_for_woocommerce()->get_connection_handler()->get_business_manager_id(),
|
145 |
+
),
|
146 |
+
'ad-account' => array(
|
147 |
'label' => __( 'Ad Manager account', 'facebook-for-woocommerce' ),
|
148 |
'value' => facebook_for_woocommerce()->get_connection_handler()->get_ad_account_id(),
|
149 |
+
),
|
150 |
+
'instagram-business-id' => array(
|
151 |
'label' => __( 'Instagram Business ID', 'facebook-for-woocommerce' ),
|
152 |
'value' => facebook_for_woocommerce()->get_connection_handler()->get_instagram_business_id(),
|
153 |
+
),
|
154 |
+
'commerce-merchant-settings-id' => array(
|
155 |
'label' => __( 'Commerce Merchant Settings ID', 'facebook-for-woocommerce' ),
|
156 |
'value' => facebook_for_woocommerce()->get_connection_handler()->get_commerce_merchant_settings_id(),
|
157 |
+
),
|
158 |
+
);
|
159 |
|
160 |
// if the catalog ID is set, update the URL and try to get its name for display
|
161 |
if ( $catalog_id = $static_items['catalog']['value'] ) {
|
169 |
if ( $name = $response->get_name() ) {
|
170 |
$static_items['catalog']['value'] = $name;
|
171 |
}
|
172 |
+
} catch ( Framework\SV_WC_API_Exception $exception ) {
|
173 |
+
}
|
174 |
}
|
175 |
|
176 |
?>
|
178 |
<table class="form-table">
|
179 |
<tbody>
|
180 |
|
181 |
+
<?php
|
182 |
+
foreach ( $static_items as $id => $item ) :
|
183 |
|
184 |
+
$item = wp_parse_args(
|
185 |
+
$item,
|
186 |
+
array(
|
187 |
+
'label' => '',
|
188 |
+
'value' => '',
|
189 |
+
'url' => '',
|
190 |
+
)
|
191 |
+
);
|
192 |
|
193 |
?>
|
194 |
|
223 |
|
224 |
<?php else : ?>
|
225 |
|
226 |
+
<?php echo '-'; ?>
|
227 |
|
228 |
<?php endif; ?>
|
229 |
|
257 |
}
|
258 |
|
259 |
$subtitle = __( 'Use this WooCommerce and Facebook integration to:', 'facebook-for-woocommerce' );
|
260 |
+
$benefits = array(
|
261 |
+
__( 'Create an ad in a few steps', 'facebook-for-woocommerce' ),
|
262 |
+
__( 'Use built-in best practices for online sales', 'facebook-for-woocommerce' ),
|
263 |
+
__( 'Get reporting on sales and revenue', 'facebook-for-woocommerce' ),
|
264 |
+
);
|
265 |
|
266 |
?>
|
267 |
|
315 |
*/
|
316 |
public function get_settings() {
|
317 |
|
318 |
+
return array(
|
319 |
|
320 |
+
array(
|
321 |
'title' => __( 'Debug', 'facebook-for-woocommerce' ),
|
322 |
'type' => 'title',
|
323 |
+
),
|
324 |
|
325 |
+
array(
|
326 |
'id' => \WC_Facebookcommerce_Integration::SETTING_ENABLE_DEBUG_MODE,
|
327 |
'title' => __( 'Enable debug mode', 'facebook-for-woocommerce' ),
|
328 |
'type' => 'checkbox',
|
329 |
'desc' => __( 'Log plugin events for debugging', 'facebook-for-woocommerce' ),
|
330 |
'desc_tip' => __( 'Only enable this if you are experiencing problems with the plugin.', 'facebook-for-woocommerce' ),
|
331 |
'default' => 'no',
|
332 |
+
),
|
333 |
|
334 |
+
array( 'type' => 'sectionend' ),
|
335 |
|
336 |
+
);
|
337 |
}
|
338 |
|
339 |
|
includes/Admin/Settings_Screens/Messenger.php
CHANGED
@@ -40,10 +40,10 @@ class Messenger extends Admin\Abstract_Settings_Screen {
|
|
40 |
$this->label = __( 'Messenger', 'facebook-for-woocommerce' );
|
41 |
$this->title = __( 'Messenger', 'facebook-for-woocommerce' );
|
42 |
|
43 |
-
add_action( 'admin_enqueue_scripts',
|
44 |
|
45 |
-
add_action( 'woocommerce_admin_field_messenger_locale',
|
46 |
-
add_action( 'woocommerce_admin_field_messenger_greeting',
|
47 |
}
|
48 |
|
49 |
|
@@ -115,11 +115,14 @@ class Messenger extends Admin\Abstract_Settings_Screen {
|
|
115 |
</th>
|
116 |
<td class="forminp forminp-<?php echo esc_attr( sanitize_title( $field['type'] ) ); ?>">
|
117 |
<p>
|
118 |
-
<?php
|
|
|
119 |
/* translators: Placeholders: %1$s - <a> tag, %2$s - </a> tag */
|
120 |
esc_html__( '%1$sClick here%2$s to manage your Messenger greeting and colors.', 'facebook-for-woocommerce' ),
|
121 |
-
'<a href="' . esc_url( facebook_for_woocommerce()->get_connection_handler()->get_manage_url() ) . '" target="_blank">',
|
122 |
-
|
|
|
|
|
123 |
</p>
|
124 |
</td>
|
125 |
</tr>
|
@@ -138,38 +141,38 @@ class Messenger extends Admin\Abstract_Settings_Screen {
|
|
138 |
|
139 |
$is_enabled = $this->remote_configuration && $this->remote_configuration->is_enabled();
|
140 |
|
141 |
-
$settings =
|
142 |
|
143 |
-
|
144 |
'title' => __( 'Messenger', 'facebook-for-woocommerce' ),
|
145 |
'type' => 'title',
|
146 |
-
|
147 |
|
148 |
-
|
149 |
'id' => \WC_Facebookcommerce_Integration::SETTING_ENABLE_MESSENGER,
|
150 |
'title' => __( 'Enable Messenger', 'facebook-for-woocommerce' ),
|
151 |
'type' => 'checkbox',
|
152 |
'desc' => __( 'Enable and customize Facebook Messenger on your store', 'facebook-for-woocommerce' ),
|
153 |
'default' => 'no',
|
154 |
'value' => $is_enabled ? 'yes' : 'no',
|
155 |
-
|
156 |
-
|
157 |
|
158 |
// only add the static configuration display if messenger is enabled
|
159 |
if ( $is_enabled ) {
|
160 |
|
161 |
-
$settings[] =
|
162 |
'title' => __( 'Language', 'facebook-for-woocommerce' ),
|
163 |
'type' => 'messenger_locale',
|
164 |
-
|
165 |
|
166 |
-
$settings[] =
|
167 |
'title' => __( 'Greeting & Colors', 'facebook-for-woocommerce' ),
|
168 |
'type' => 'messenger_greeting',
|
169 |
-
|
170 |
}
|
171 |
|
172 |
-
$settings[] =
|
173 |
|
174 |
return $settings;
|
175 |
}
|
@@ -187,7 +190,8 @@ class Messenger extends Admin\Abstract_Settings_Screen {
|
|
187 |
return sprintf(
|
188 |
/* translators: Placeholders: %1$s - <a> tag, %2$s - </a> tag */
|
189 |
__( 'Please %1$sconnect to Facebook%2$s to enable and manage Facebook Messenger.', 'facebook-for-woocommerce' ),
|
190 |
-
'<a href="' . esc_url( facebook_for_woocommerce()->get_connection_handler()->get_connect_url() ) . '">',
|
|
|
191 |
);
|
192 |
}
|
193 |
|
@@ -235,11 +239,14 @@ class Messenger extends Admin\Abstract_Settings_Screen {
|
|
235 |
?>
|
236 |
<div class="notice notice-error">
|
237 |
<p>
|
238 |
-
<?php
|
|
|
239 |
/* translators: Placeholders: %1$s - <a> tag, %2$s - </a> tag */
|
240 |
esc_html__( 'There was an error communicating with the Facebook Business Extension. %1$sClick here%2$s to manage your Messenger settings.', 'facebook-for-woocommerce' ),
|
241 |
-
'<a href="' . esc_url( $plugin->get_connection_handler()->get_manage_url() ) . '" target="_blank">',
|
242 |
-
|
|
|
|
|
243 |
</p>
|
244 |
</div>
|
245 |
<?php
|
40 |
$this->label = __( 'Messenger', 'facebook-for-woocommerce' );
|
41 |
$this->title = __( 'Messenger', 'facebook-for-woocommerce' );
|
42 |
|
43 |
+
add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_assets' ) );
|
44 |
|
45 |
+
add_action( 'woocommerce_admin_field_messenger_locale', array( $this, 'render_locale_field' ) );
|
46 |
+
add_action( 'woocommerce_admin_field_messenger_greeting', array( $this, 'render_greeting_field' ) );
|
47 |
}
|
48 |
|
49 |
|
115 |
</th>
|
116 |
<td class="forminp forminp-<?php echo esc_attr( sanitize_title( $field['type'] ) ); ?>">
|
117 |
<p>
|
118 |
+
<?php
|
119 |
+
printf(
|
120 |
/* translators: Placeholders: %1$s - <a> tag, %2$s - </a> tag */
|
121 |
esc_html__( '%1$sClick here%2$s to manage your Messenger greeting and colors.', 'facebook-for-woocommerce' ),
|
122 |
+
'<a href="' . esc_url( facebook_for_woocommerce()->get_connection_handler()->get_manage_url() ) . '" target="_blank">',
|
123 |
+
'</a>'
|
124 |
+
);
|
125 |
+
?>
|
126 |
</p>
|
127 |
</td>
|
128 |
</tr>
|
141 |
|
142 |
$is_enabled = $this->remote_configuration && $this->remote_configuration->is_enabled();
|
143 |
|
144 |
+
$settings = array(
|
145 |
|
146 |
+
array(
|
147 |
'title' => __( 'Messenger', 'facebook-for-woocommerce' ),
|
148 |
'type' => 'title',
|
149 |
+
),
|
150 |
|
151 |
+
array(
|
152 |
'id' => \WC_Facebookcommerce_Integration::SETTING_ENABLE_MESSENGER,
|
153 |
'title' => __( 'Enable Messenger', 'facebook-for-woocommerce' ),
|
154 |
'type' => 'checkbox',
|
155 |
'desc' => __( 'Enable and customize Facebook Messenger on your store', 'facebook-for-woocommerce' ),
|
156 |
'default' => 'no',
|
157 |
'value' => $is_enabled ? 'yes' : 'no',
|
158 |
+
),
|
159 |
+
);
|
160 |
|
161 |
// only add the static configuration display if messenger is enabled
|
162 |
if ( $is_enabled ) {
|
163 |
|
164 |
+
$settings[] = array(
|
165 |
'title' => __( 'Language', 'facebook-for-woocommerce' ),
|
166 |
'type' => 'messenger_locale',
|
167 |
+
);
|
168 |
|
169 |
+
$settings[] = array(
|
170 |
'title' => __( 'Greeting & Colors', 'facebook-for-woocommerce' ),
|
171 |
'type' => 'messenger_greeting',
|
172 |
+
);
|
173 |
}
|
174 |
|
175 |
+
$settings[] = array( 'type' => 'sectionend' );
|
176 |
|
177 |
return $settings;
|
178 |
}
|
190 |
return sprintf(
|
191 |
/* translators: Placeholders: %1$s - <a> tag, %2$s - </a> tag */
|
192 |
__( 'Please %1$sconnect to Facebook%2$s to enable and manage Facebook Messenger.', 'facebook-for-woocommerce' ),
|
193 |
+
'<a href="' . esc_url( facebook_for_woocommerce()->get_connection_handler()->get_connect_url() ) . '">',
|
194 |
+
'</a>'
|
195 |
);
|
196 |
}
|
197 |
|
239 |
?>
|
240 |
<div class="notice notice-error">
|
241 |
<p>
|
242 |
+
<?php
|
243 |
+
printf(
|
244 |
/* translators: Placeholders: %1$s - <a> tag, %2$s - </a> tag */
|
245 |
esc_html__( 'There was an error communicating with the Facebook Business Extension. %1$sClick here%2$s to manage your Messenger settings.', 'facebook-for-woocommerce' ),
|
246 |
+
'<a href="' . esc_url( $plugin->get_connection_handler()->get_manage_url() ) . '" target="_blank">',
|
247 |
+
'</a>'
|
248 |
+
);
|
249 |
+
?>
|
250 |
</p>
|
251 |
</div>
|
252 |
<?php
|
includes/Admin/Settings_Screens/Product_Sync.php
CHANGED
@@ -42,11 +42,11 @@ class Product_Sync extends Admin\Abstract_Settings_Screen {
|
|
42 |
$this->label = __( 'Product sync', 'facebook-for-woocommerce' );
|
43 |
$this->title = __( 'Product sync', 'facebook-for-woocommerce' );
|
44 |
|
45 |
-
add_action( 'admin_enqueue_scripts',
|
46 |
|
47 |
-
add_action( 'woocommerce_admin_field_product_sync_title',
|
48 |
|
49 |
-
add_action( 'woocommerce_admin_field_product_sync_google_product_categories',
|
50 |
}
|
51 |
|
52 |
|
@@ -63,35 +63,49 @@ class Product_Sync extends Admin\Abstract_Settings_Screen {
|
|
63 |
return;
|
64 |
}
|
65 |
|
66 |
-
wp_enqueue_script( 'wc-backbone-modal', null,
|
67 |
-
wp_enqueue_script(
|
68 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
69 |
|
70 |
/* translators: Placeholders: {count} number of remaining items */
|
71 |
$sync_remaining_items_string = _n_noop( '{count} item remaining.', '{count} items remaining.', 'facebook-for-woocommerce' );
|
72 |
|
73 |
-
wp_localize_script(
|
74 |
-
'
|
75 |
-
'
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
'
|
84 |
-
'
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
|
|
|
|
|
|
|
|
95 |
}
|
96 |
|
97 |
/**
|
@@ -119,7 +133,8 @@ class Product_Sync extends Admin\Abstract_Settings_Screen {
|
|
119 |
return sprintf(
|
120 |
/* translators: Placeholders: %1$s - <strong> tag, %2$s - </strong> tag */
|
121 |
esc_html__( 'Products and categories that inherit this global setting (they do not have a specific Google product category set) will use the new default immediately. %1$sIf you have cleared the Google Product Category%2$s, items inheriting the default will not be available for Instagram checkout. Are you sure you want to proceed?', 'facebook-for-woocommerce' ),
|
122 |
-
'<strong>',
|
|
|
123 |
);
|
124 |
}
|
125 |
|
@@ -216,16 +231,20 @@ class Product_Sync extends Admin\Abstract_Settings_Screen {
|
|
216 |
private function disable_sync_for_excluded_products( $product_cat_ids, $product_tag_ids ) {
|
217 |
|
218 |
// disable sync for all products belonging to excluded categories
|
219 |
-
Products::disable_sync_for_products_with_terms(
|
220 |
-
|
221 |
-
|
222 |
-
|
|
|
|
|
223 |
|
224 |
// disable sync for all products belonging to excluded tags
|
225 |
-
Products::disable_sync_for_products_with_terms(
|
226 |
-
|
227 |
-
|
228 |
-
|
|
|
|
|
229 |
}
|
230 |
|
231 |
|
@@ -238,87 +257,91 @@ class Product_Sync extends Admin\Abstract_Settings_Screen {
|
|
238 |
*/
|
239 |
public function get_settings() {
|
240 |
|
241 |
-
$term_query = new \WP_Term_Query(
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
|
|
|
|
246 |
|
247 |
$product_categories = $term_query->get_terms();
|
248 |
|
249 |
-
$term_query = new \WP_Term_Query(
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
|
|
|
|
255 |
|
256 |
$product_tags = $term_query->get_terms();
|
257 |
|
258 |
-
return
|
259 |
|
260 |
-
|
261 |
'type' => 'product_sync_title',
|
262 |
'title' => __( 'Product sync', 'facebook-for-woocommerce' ),
|
263 |
-
|
264 |
|
265 |
-
|
266 |
'id' => \WC_Facebookcommerce_Integration::SETTING_ENABLE_PRODUCT_SYNC,
|
267 |
'title' => __( 'Enable product sync', 'facebook-for-woocommerce' ),
|
268 |
'type' => 'checkbox',
|
269 |
'label' => ' ',
|
270 |
'default' => 'yes',
|
271 |
-
|
272 |
|
273 |
-
|
274 |
'id' => \WC_Facebookcommerce_Integration::SETTING_EXCLUDED_PRODUCT_CATEGORY_IDS,
|
275 |
'title' => __( 'Exclude categories from sync', 'facebook-for-woocommerce' ),
|
276 |
'type' => 'multiselect',
|
277 |
'class' => 'wc-enhanced-select product-sync-field',
|
278 |
'css' => 'min-width: 300px;',
|
279 |
'desc_tip' => __( 'Products in one or more of these categories will not sync to Facebook.', 'facebook-for-woocommerce' ),
|
280 |
-
'default' =>
|
281 |
-
'options' => is_array( $product_categories ) ? $product_categories :
|
282 |
-
'custom_attributes' =>
|
283 |
'data-placeholder' => __( 'Search for a product category…', 'facebook-for-woocommerce' ),
|
284 |
-
|
285 |
-
|
286 |
|
287 |
-
|
288 |
'id' => \WC_Facebookcommerce_Integration::SETTING_EXCLUDED_PRODUCT_TAG_IDS,
|
289 |
'title' => __( 'Exclude tags from sync', 'facebook-for-woocommerce' ),
|
290 |
'type' => 'multiselect',
|
291 |
'class' => 'wc-enhanced-select product-sync-field',
|
292 |
'css' => 'min-width: 300px;',
|
293 |
'desc_tip' => __( 'Products with one or more of these tags will not sync to Facebook.', 'facebook-for-woocommerce' ),
|
294 |
-
'default' =>
|
295 |
-
'options' => is_array( $product_tags ) ? $product_tags :
|
296 |
-
'custom_attributes' =>
|
297 |
'data-placeholder' => __( 'Search for a product tag…', 'facebook-for-woocommerce' ),
|
298 |
-
|
299 |
-
|
300 |
|
301 |
-
|
302 |
'id' => \WC_Facebookcommerce_Integration::SETTING_PRODUCT_DESCRIPTION_MODE,
|
303 |
'title' => __( 'Product description sync', 'facebook-for-woocommerce' ),
|
304 |
'type' => 'select',
|
305 |
'class' => 'product-sync-field',
|
306 |
'desc_tip' => __( 'Choose which product description to display in the Facebook catalog.', 'facebook-for-woocommerce' ),
|
307 |
'default' => \WC_Facebookcommerce_Integration::PRODUCT_DESCRIPTION_MODE_STANDARD,
|
308 |
-
'options' =>
|
309 |
\WC_Facebookcommerce_Integration::PRODUCT_DESCRIPTION_MODE_STANDARD => __( 'Standard description', 'facebook-for-woocommerce' ),
|
310 |
\WC_Facebookcommerce_Integration::PRODUCT_DESCRIPTION_MODE_SHORT => __( 'Short description', 'facebook-for-woocommerce' ),
|
311 |
-
|
312 |
-
|
313 |
-
|
314 |
'id' => \SkyVerge\WooCommerce\Facebook\Commerce::OPTION_GOOGLE_PRODUCT_CATEGORY_ID,
|
315 |
'type' => 'product_sync_google_product_categories',
|
316 |
'title' => __( 'Default Google product category', 'facebook-for-woocommerce' ),
|
317 |
'desc_tip' => __( 'Choose a default Google product category for your products. Defaults can also be set for product categories. Products need at least two category levels defined for tax to be correctly applied.', 'facebook-for-woocommerce' ),
|
318 |
-
|
319 |
-
|
320 |
|
321 |
-
|
322 |
}
|
323 |
|
324 |
/**
|
@@ -361,7 +384,8 @@ class Product_Sync extends Admin\Abstract_Settings_Screen {
|
|
361 |
return sprintf(
|
362 |
/* translators: Placeholders: %1$s - <a> tag, %2$s - </a> tag */
|
363 |
__( 'Please %1$sconnect to Facebook%2$s to enable and manage product sync.', 'facebook-for-woocommerce' ),
|
364 |
-
'<a href="' . esc_url( facebook_for_woocommerce()->get_connection_handler()->get_connect_url() ) . '">',
|
|
|
365 |
);
|
366 |
}
|
367 |
|
42 |
$this->label = __( 'Product sync', 'facebook-for-woocommerce' );
|
43 |
$this->title = __( 'Product sync', 'facebook-for-woocommerce' );
|
44 |
|
45 |
+
add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_assets' ) );
|
46 |
|
47 |
+
add_action( 'woocommerce_admin_field_product_sync_title', array( $this, 'render_title' ) );
|
48 |
|
49 |
+
add_action( 'woocommerce_admin_field_product_sync_google_product_categories', array( $this, 'render_google_product_category_field' ) );
|
50 |
}
|
51 |
|
52 |
|
63 |
return;
|
64 |
}
|
65 |
|
66 |
+
wp_enqueue_script( 'wc-backbone-modal', null, array( 'backbone' ) );
|
67 |
+
wp_enqueue_script(
|
68 |
+
'facebook-for-woocommerce-modal',
|
69 |
+
facebook_for_woocommerce()->get_asset_build_dir_url() . '/admin/modal.js',
|
70 |
+
array( 'jquery', 'wc-backbone-modal', 'jquery-blockui' ),
|
71 |
+
\WC_Facebookcommerce::PLUGIN_VERSION
|
72 |
+
);
|
73 |
+
wp_enqueue_script(
|
74 |
+
'facebook-for-woocommerce-settings-sync',
|
75 |
+
facebook_for_woocommerce()->get_asset_build_dir_url() . '/admin/settings-sync.js',
|
76 |
+
array( 'jquery', 'wc-backbone-modal', 'jquery-blockui', 'jquery-tiptip', 'facebook-for-woocommerce-modal', 'wc-enhanced-select' ),
|
77 |
+
\WC_Facebookcommerce::PLUGIN_VERSION
|
78 |
+
);
|
79 |
|
80 |
/* translators: Placeholders: {count} number of remaining items */
|
81 |
$sync_remaining_items_string = _n_noop( '{count} item remaining.', '{count} items remaining.', 'facebook-for-woocommerce' );
|
82 |
|
83 |
+
wp_localize_script(
|
84 |
+
'facebook-for-woocommerce-settings-sync',
|
85 |
+
'facebook_for_woocommerce_settings_sync',
|
86 |
+
array(
|
87 |
+
'ajax_url' => admin_url( 'admin-ajax.php' ),
|
88 |
+
'set_excluded_terms_prompt_nonce' => wp_create_nonce( 'set-excluded-terms-prompt' ),
|
89 |
+
'sync_products_nonce' => wp_create_nonce( self::ACTION_SYNC_PRODUCTS ),
|
90 |
+
'sync_status_nonce' => wp_create_nonce( self::ACTION_GET_SYNC_STATUS ),
|
91 |
+
'sync_in_progress' => Sync::is_sync_in_progress(),
|
92 |
+
'excluded_category_ids' => facebook_for_woocommerce()->get_integration()->get_excluded_product_category_ids(),
|
93 |
+
'excluded_tag_ids' => facebook_for_woocommerce()->get_integration()->get_excluded_product_tag_ids(),
|
94 |
+
'i18n' => array(
|
95 |
+
/* translators: Placeholders %s - html code for a spinner icon */
|
96 |
+
'confirm_resync' => esc_html__( 'Your products will now be resynced to Facebook, this may take some time.', 'facebook-for-woocommerce' ),
|
97 |
+
'confirm_sync' => esc_html__( "Facebook for WooCommerce automatically syncs your products on create/update. Are you sure you want to force product resync?\n\nThis will query all published products and may take some time. You only need to do this if your products are out of sync or some of your products did not sync.", 'facebook-for-woocommerce' ),
|
98 |
+
'sync_in_progress' => sprintf( esc_html__( 'Your products are syncing - you may safely leave this page %s', 'facebook-for-woocommerce' ), '<span class="spinner is-active"></span>' ),
|
99 |
+
'sync_remaining_items_singular' => sprintf( esc_html( translate_nooped_plural( $sync_remaining_items_string, 1 ) ), '<strong>', '</strong>', '<span class="spinner is-active"></span>' ),
|
100 |
+
'sync_remaining_items_plural' => sprintf( esc_html( translate_nooped_plural( $sync_remaining_items_string, 2 ) ), '<strong>', '</strong>', '<span class="spinner is-active"></span>' ),
|
101 |
+
'general_error' => esc_html__( 'There was an error trying to sync the products to Facebook.', 'facebook-for-woocommerce' ),
|
102 |
+
'feed_upload_error' => esc_html__( 'Something went wrong while uploading the product information, please try again.', 'facebook-for-woocommerce' ),
|
103 |
+
),
|
104 |
+
'default_google_product_category_modal_message' => $this->get_default_google_product_category_modal_message(),
|
105 |
+
'default_google_product_category_modal_message_empty' => $this->get_default_google_product_category_modal_message_empty(),
|
106 |
+
'default_google_product_category_modal_buttons' => $this->get_default_google_product_category_modal_buttons(),
|
107 |
+
)
|
108 |
+
);
|
109 |
}
|
110 |
|
111 |
/**
|
133 |
return sprintf(
|
134 |
/* translators: Placeholders: %1$s - <strong> tag, %2$s - </strong> tag */
|
135 |
esc_html__( 'Products and categories that inherit this global setting (they do not have a specific Google product category set) will use the new default immediately. %1$sIf you have cleared the Google Product Category%2$s, items inheriting the default will not be available for Instagram checkout. Are you sure you want to proceed?', 'facebook-for-woocommerce' ),
|
136 |
+
'<strong>',
|
137 |
+
'</strong>'
|
138 |
);
|
139 |
}
|
140 |
|
231 |
private function disable_sync_for_excluded_products( $product_cat_ids, $product_tag_ids ) {
|
232 |
|
233 |
// disable sync for all products belonging to excluded categories
|
234 |
+
Products::disable_sync_for_products_with_terms(
|
235 |
+
array(
|
236 |
+
'taxonomy' => 'product_cat',
|
237 |
+
'include' => $product_cat_ids,
|
238 |
+
)
|
239 |
+
);
|
240 |
|
241 |
// disable sync for all products belonging to excluded tags
|
242 |
+
Products::disable_sync_for_products_with_terms(
|
243 |
+
array(
|
244 |
+
'taxonomy' => 'product_tag',
|
245 |
+
'include' => $product_tag_ids,
|
246 |
+
)
|
247 |
+
);
|
248 |
}
|
249 |
|
250 |
|
257 |
*/
|
258 |
public function get_settings() {
|
259 |
|
260 |
+
$term_query = new \WP_Term_Query(
|
261 |
+
array(
|
262 |
+
'taxonomy' => 'product_cat',
|
263 |
+
'hide_empty' => false,
|
264 |
+
'fields' => 'id=>name',
|
265 |
+
)
|
266 |
+
);
|
267 |
|
268 |
$product_categories = $term_query->get_terms();
|
269 |
|
270 |
+
$term_query = new \WP_Term_Query(
|
271 |
+
array(
|
272 |
+
'taxonomy' => 'product_tag',
|
273 |
+
'hide_empty' => false,
|
274 |
+
'hierarchical' => false,
|
275 |
+
'fields' => 'id=>name',
|
276 |
+
)
|
277 |
+
);
|
278 |
|
279 |
$product_tags = $term_query->get_terms();
|
280 |
|
281 |
+
return array(
|
282 |
|
283 |
+
array(
|
284 |
'type' => 'product_sync_title',
|
285 |
'title' => __( 'Product sync', 'facebook-for-woocommerce' ),
|
286 |
+
),
|
287 |
|
288 |
+
array(
|
289 |
'id' => \WC_Facebookcommerce_Integration::SETTING_ENABLE_PRODUCT_SYNC,
|
290 |
'title' => __( 'Enable product sync', 'facebook-for-woocommerce' ),
|
291 |
'type' => 'checkbox',
|
292 |
'label' => ' ',
|
293 |
'default' => 'yes',
|
294 |
+
),
|
295 |
|
296 |
+
array(
|
297 |
'id' => \WC_Facebookcommerce_Integration::SETTING_EXCLUDED_PRODUCT_CATEGORY_IDS,
|
298 |
'title' => __( 'Exclude categories from sync', 'facebook-for-woocommerce' ),
|
299 |
'type' => 'multiselect',
|
300 |
'class' => 'wc-enhanced-select product-sync-field',
|
301 |
'css' => 'min-width: 300px;',
|
302 |
'desc_tip' => __( 'Products in one or more of these categories will not sync to Facebook.', 'facebook-for-woocommerce' ),
|
303 |
+
'default' => array(),
|
304 |
+
'options' => is_array( $product_categories ) ? $product_categories : array(),
|
305 |
+
'custom_attributes' => array(
|
306 |
'data-placeholder' => __( 'Search for a product category…', 'facebook-for-woocommerce' ),
|
307 |
+
),
|
308 |
+
),
|
309 |
|
310 |
+
array(
|
311 |
'id' => \WC_Facebookcommerce_Integration::SETTING_EXCLUDED_PRODUCT_TAG_IDS,
|
312 |
'title' => __( 'Exclude tags from sync', 'facebook-for-woocommerce' ),
|
313 |
'type' => 'multiselect',
|
314 |
'class' => 'wc-enhanced-select product-sync-field',
|
315 |
'css' => 'min-width: 300px;',
|
316 |
'desc_tip' => __( 'Products with one or more of these tags will not sync to Facebook.', 'facebook-for-woocommerce' ),
|
317 |
+
'default' => array(),
|
318 |
+
'options' => is_array( $product_tags ) ? $product_tags : array(),
|
319 |
+
'custom_attributes' => array(
|
320 |
'data-placeholder' => __( 'Search for a product tag…', 'facebook-for-woocommerce' ),
|
321 |
+
),
|
322 |
+
),
|
323 |
|
324 |
+
array(
|
325 |
'id' => \WC_Facebookcommerce_Integration::SETTING_PRODUCT_DESCRIPTION_MODE,
|
326 |
'title' => __( 'Product description sync', 'facebook-for-woocommerce' ),
|
327 |
'type' => 'select',
|
328 |
'class' => 'product-sync-field',
|
329 |
'desc_tip' => __( 'Choose which product description to display in the Facebook catalog.', 'facebook-for-woocommerce' ),
|
330 |
'default' => \WC_Facebookcommerce_Integration::PRODUCT_DESCRIPTION_MODE_STANDARD,
|
331 |
+
'options' => array(
|
332 |
\WC_Facebookcommerce_Integration::PRODUCT_DESCRIPTION_MODE_STANDARD => __( 'Standard description', 'facebook-for-woocommerce' ),
|
333 |
\WC_Facebookcommerce_Integration::PRODUCT_DESCRIPTION_MODE_SHORT => __( 'Short description', 'facebook-for-woocommerce' ),
|
334 |
+
),
|
335 |
+
),
|
336 |
+
array(
|
337 |
'id' => \SkyVerge\WooCommerce\Facebook\Commerce::OPTION_GOOGLE_PRODUCT_CATEGORY_ID,
|
338 |
'type' => 'product_sync_google_product_categories',
|
339 |
'title' => __( 'Default Google product category', 'facebook-for-woocommerce' ),
|
340 |
'desc_tip' => __( 'Choose a default Google product category for your products. Defaults can also be set for product categories. Products need at least two category levels defined for tax to be correctly applied.', 'facebook-for-woocommerce' ),
|
341 |
+
),
|
342 |
+
array( 'type' => 'sectionend' ),
|
343 |
|
344 |
+
);
|
345 |
}
|
346 |
|
347 |
/**
|
384 |
return sprintf(
|
385 |
/* translators: Placeholders: %1$s - <a> tag, %2$s - </a> tag */
|
386 |
__( 'Please %1$sconnect to Facebook%2$s to enable and manage product sync.', 'facebook-for-woocommerce' ),
|
387 |
+
'<a href="' . esc_url( facebook_for_woocommerce()->get_connection_handler()->get_connect_url() ) . '">',
|
388 |
+
'</a>'
|
389 |
);
|
390 |
}
|
391 |
|
includes/Commerce/Orders.php
CHANGED
@@ -106,7 +106,7 @@ class Orders {
|
|
106 |
*/
|
107 |
public static function is_commerce_order( \WC_Order $order ) {
|
108 |
|
109 |
-
return in_array( $order->get_created_via(),
|
110 |
}
|
111 |
|
112 |
|
@@ -120,12 +120,14 @@ class Orders {
|
|
120 |
*/
|
121 |
public function find_local_order( $remote_id ) {
|
122 |
|
123 |
-
$orders = wc_get_orders(
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
|
|
|
|
129 |
|
130 |
return ! empty( $orders ) ? current( $orders ) : null;
|
131 |
}
|
@@ -158,7 +160,7 @@ class Orders {
|
|
158 |
*
|
159 |
* @since 2.1.0
|
160 |
*
|
161 |
-
* @param Order
|
162 |
* @param \WC_Order $local_order local order object
|
163 |
* @return \WC_Order
|
164 |
* @throws SV_WC_Plugin_Exception|\WC_Data_Exception
|
@@ -212,10 +214,12 @@ class Orders {
|
|
212 |
$matching_wc_order_item->set_subtotal( $item['quantity'] * $item['price_per_unit']['amount'] );
|
213 |
$matching_wc_order_item->set_total( $item['quantity'] * $item['price_per_unit']['amount'] );
|
214 |
// we use the estimated_tax because the captured_tax represents the tax after the order/item has been shipped and we don't fulfill order at the line-item level
|
215 |
-
$matching_wc_order_item->set_taxes(
|
216 |
-
|
217 |
-
|
218 |
-
|
|
|
|
|
219 |
$matching_wc_order_item->save();
|
220 |
|
221 |
if ( ! empty( $item['tax_details']['estimated_tax']['amount'] ) ) {
|
@@ -250,9 +254,11 @@ class Orders {
|
|
250 |
}
|
251 |
|
252 |
$matching_shipping_order_item->set_total( $selected_shipping_option['price']['amount'] );
|
253 |
-
$matching_shipping_order_item->set_taxes(
|
254 |
-
|
255 |
-
|
|
|
|
|
256 |
$matching_shipping_order_item->save();
|
257 |
|
258 |
// add tax item
|
@@ -399,7 +405,6 @@ class Orders {
|
|
399 |
} else {
|
400 |
$local_order = $this->update_local_order( $remote_order, $local_order );
|
401 |
}
|
402 |
-
|
403 |
} catch ( \Exception $exception ) {
|
404 |
|
405 |
if ( ! empty( $local_order ) ) {
|
@@ -422,10 +427,13 @@ class Orders {
|
|
422 |
$local_order->set_status( 'processing' );
|
423 |
|
424 |
/* translators: Placeholders: %1$s - order remote id, %2$s - order created by */
|
425 |
-
$local_order->add_order_note(
|
426 |
-
|
427 |
-
|
428 |
-
|
|
|
|
|
|
|
429 |
|
430 |
} catch ( SV_WC_API_Exception $exception ) {
|
431 |
|
@@ -521,11 +529,11 @@ class Orders {
|
|
521 |
* @since 2.1.0
|
522 |
*/
|
523 |
public function schedule_local_orders_update() {
|
524 |
-
if ( facebook_for_woocommerce()->get_commerce_handler()->is_connected() && false === as_next_scheduled_action( self::ACTION_FETCH_ORDERS,
|
525 |
|
526 |
$interval = $this->get_order_update_interval();
|
527 |
|
528 |
-
as_schedule_recurring_action( time() + $interval, $interval, self::ACTION_FETCH_ORDERS,
|
529 |
}
|
530 |
}
|
531 |
|
@@ -538,15 +546,15 @@ class Orders {
|
|
538 |
public function add_hooks() {
|
539 |
|
540 |
// schedule a recurring ACTION_FETCH_ORDERS action, if not already scheduled
|
541 |
-
add_action( 'init',
|
542 |
|
543 |
-
add_action( self::ACTION_FETCH_ORDERS,
|
544 |
|
545 |
// prevent sending emails for Commerce orders
|
546 |
-
add_action( 'woocommerce_email_enabled_customer_completed_order',
|
547 |
-
add_action( 'woocommerce_email_enabled_customer_processing_order',
|
548 |
-
add_action( 'woocommerce_email_enabled_customer_refunded_order',
|
549 |
-
add_action( 'woocommerce_email_enabled_customer_partially_refunded_order',
|
550 |
}
|
551 |
|
552 |
|
@@ -562,8 +570,8 @@ class Orders {
|
|
562 |
* @since 2.1.0
|
563 |
*
|
564 |
* @param \WC_Order $order order object
|
565 |
-
* @param string
|
566 |
-
* @param string
|
567 |
* @throws SV_WC_Plugin_Exception
|
568 |
*/
|
569 |
public function fulfill_order( \WC_Order $order, $tracking_number, $carrier ) {
|
@@ -583,17 +591,17 @@ class Orders {
|
|
583 |
throw new SV_WC_Plugin_Exception( sprintf( __( '%s is not a valid shipping carrier code.', 'facebook-for-woocommerce' ), $carrier ) );
|
584 |
}
|
585 |
|
586 |
-
$items =
|
587 |
|
588 |
/** @var \WC_Order_Item_Product $item */
|
589 |
foreach ( $order->get_items() as $item ) {
|
590 |
|
591 |
if ( $product = $item->get_product() ) {
|
592 |
|
593 |
-
$items[] =
|
594 |
'retailer_id' => \WC_Facebookcommerce_Utils::get_fb_retailer_id( $product ),
|
595 |
'quantity' => $item->get_quantity(),
|
596 |
-
|
597 |
}
|
598 |
}
|
599 |
|
@@ -601,32 +609,36 @@ class Orders {
|
|
601 |
throw new SV_WC_Plugin_Exception( __( 'No valid Facebook products were found.', 'facebook-for-woocommerce' ) );
|
602 |
}
|
603 |
|
604 |
-
$fulfillment_data =
|
605 |
'items' => $items,
|
606 |
-
'tracking_info' =>
|
607 |
'carrier' => $carrier,
|
608 |
'tracking_number' => $tracking_number,
|
609 |
-
|
610 |
-
|
611 |
|
612 |
$plugin = facebook_for_woocommerce();
|
613 |
|
614 |
$plugin->get_api( $plugin->get_connection_handler()->get_page_access_token() )->fulfill_order( $remote_id, $fulfillment_data );
|
615 |
|
616 |
-
$order->add_order_note(
|
|
|
617 |
/* translators: Placeholder: %s - sales channel name, like Facebook or Instagram */
|
618 |
-
|
619 |
-
|
620 |
-
|
|
|
621 |
|
622 |
} catch ( SV_WC_Plugin_Exception $exception ) {
|
623 |
|
624 |
-
$order->add_order_note(
|
|
|
625 |
/* translators: Placeholders: %1$s - sales channel name, like Facebook or Instagram, %2$s - error message */
|
626 |
-
|
627 |
-
|
628 |
-
|
629 |
-
|
|
|
630 |
|
631 |
throw $exception;
|
632 |
}
|
@@ -639,7 +651,7 @@ class Orders {
|
|
639 |
* @since 2.1.0
|
640 |
*
|
641 |
* @param \WC_Order_Refund $refund order refund object
|
642 |
-
* @param string
|
643 |
* @throws SV_WC_Plugin_Exception
|
644 |
*/
|
645 |
public function add_order_refund( \WC_Order_Refund $refund, $reason_code ) {
|
@@ -648,14 +660,14 @@ class Orders {
|
|
648 |
|
649 |
$api = $plugin->get_api( $plugin->get_connection_handler()->get_page_access_token() );
|
650 |
|
651 |
-
$valid_reason_codes =
|
652 |
self::REFUND_REASON_BUYERS_REMORSE,
|
653 |
self::REFUND_REASON_DAMAGED_GOODS,
|
654 |
self::REFUND_REASON_NOT_AS_DESCRIBED,
|
655 |
self::REFUND_REASON_QUALITY_ISSUE,
|
656 |
self::REFUND_REASON_OTHER,
|
657 |
self::REFUND_REASON_WRONG_ITEM,
|
658 |
-
|
659 |
|
660 |
if ( ! in_array( $reason_code, $valid_reason_codes, true ) ) {
|
661 |
$reason_code = self::REFUND_REASON_OTHER;
|
@@ -675,9 +687,9 @@ class Orders {
|
|
675 |
throw new SV_WC_Plugin_Exception( __( 'Remote ID for parent order not found.', 'facebook-for-woocommerce' ) );
|
676 |
}
|
677 |
|
678 |
-
$refund_data =
|
679 |
'reason_code' => $reason_code,
|
680 |
-
|
681 |
|
682 |
if ( ! empty( $reason_text = $refund->get_reason() ) ) {
|
683 |
$refund_data['reason_text'] = $reason_text;
|
@@ -690,32 +702,36 @@ class Orders {
|
|
690 |
|
691 |
if ( ! empty( $refund->get_shipping_total() ) ) {
|
692 |
|
693 |
-
$refund_data['shipping'] =
|
694 |
-
'shipping_refund' =>
|
695 |
'amount' => abs( $refund->get_shipping_total() ),
|
696 |
'currency' => $refund->get_currency(),
|
697 |
-
|
698 |
-
|
699 |
}
|
700 |
|
701 |
$api->add_order_refund( $remote_id, $refund_data );
|
702 |
|
703 |
-
$parent_order->add_order_note(
|
|
|
704 |
/* translators: Placeholder: %s - sales channel name, like Facebook or Instagram */
|
705 |
-
|
706 |
-
|
707 |
-
|
|
|
708 |
|
709 |
} catch ( SV_WC_Plugin_Exception $exception ) {
|
710 |
|
711 |
if ( ! empty( $parent_order ) && $parent_order instanceof \WC_Order ) {
|
712 |
|
713 |
-
$parent_order->add_order_note(
|
|
|
714 |
/* translators: Placeholders: %1$s - sales channel name, like Facebook or Instagram, %2$s - error message */
|
715 |
-
|
716 |
-
|
717 |
-
|
718 |
-
|
|
|
719 |
|
720 |
} else {
|
721 |
|
@@ -739,16 +755,16 @@ class Orders {
|
|
739 |
*/
|
740 |
private function get_refund_items( \WC_Order_Refund $refund ) {
|
741 |
|
742 |
-
$items =
|
743 |
|
744 |
/** @var \WC_Order_Item_Product $item */
|
745 |
foreach ( $refund->get_items() as $item ) {
|
746 |
|
747 |
if ( $product = $item->get_product() ) {
|
748 |
|
749 |
-
$refund_item =
|
750 |
'retailer_id' => \WC_Facebookcommerce_Utils::get_fb_retailer_id( $product ),
|
751 |
-
|
752 |
|
753 |
if ( ! empty( $item->get_quantity() ) ) {
|
754 |
|
@@ -756,10 +772,10 @@ class Orders {
|
|
756 |
|
757 |
} else {
|
758 |
|
759 |
-
$refund_item['item_refund_amount'] =
|
760 |
'amount' => abs( $item->get_total() ),
|
761 |
'currency' => $refund->get_currency(),
|
762 |
-
|
763 |
}
|
764 |
|
765 |
$items[] = $refund_item;
|
@@ -780,7 +796,7 @@ class Orders {
|
|
780 |
* @since 2.1.0
|
781 |
*
|
782 |
* @param \WC_Order $order order object
|
783 |
-
* @param string
|
784 |
* @throws SV_WC_Plugin_Exception
|
785 |
*/
|
786 |
public function cancel_order( \WC_Order $order, $reason_code ) {
|
@@ -792,7 +808,7 @@ class Orders {
|
|
792 |
$valid_reason_codes = array_keys( $this->get_cancellation_reasons() );
|
793 |
|
794 |
if ( ! in_array( $reason_code, $valid_reason_codes, true ) ) {
|
795 |
-
$reason_code =
|
796 |
}
|
797 |
|
798 |
try {
|
@@ -805,20 +821,24 @@ class Orders {
|
|
805 |
|
806 |
$api->cancel_order( $remote_id, $reason_code );
|
807 |
|
808 |
-
$order->add_order_note(
|
|
|
809 |
/* translators: Placeholder: %s - sales channel name, like Facebook or Instagram */
|
810 |
-
|
811 |
-
|
812 |
-
|
|
|
813 |
|
814 |
} catch ( SV_WC_Plugin_Exception $exception ) {
|
815 |
|
816 |
-
$order->add_order_note(
|
|
|
817 |
/* translators: Placeholders: %1$s - sales channel name, like Facebook or Instagram, %2$s - error message */
|
818 |
-
|
819 |
-
|
820 |
-
|
821 |
-
|
|
|
822 |
|
823 |
throw $exception;
|
824 |
}
|
@@ -834,14 +854,14 @@ class Orders {
|
|
834 |
*/
|
835 |
public function get_cancellation_reasons() {
|
836 |
|
837 |
-
return
|
838 |
|
839 |
self::CANCEL_REASON_CUSTOMER_REQUESTED => __( 'Customer requested cancellation', 'facebook-for-woocommerce' ),
|
840 |
self::CANCEL_REASON_OUT_OF_STOCK => __( 'Product(s) are out of stock', 'facebook-for-woocommerce' ),
|
841 |
self::CANCEL_REASON_INVALID_ADDRESS => __( 'Customer address is invalid', 'facebook-for-woocommerce' ),
|
842 |
self::CANCEL_REASON_SUSPICIOUS_ORDER => __( 'Suspicious order', 'facebook-for-woocommerce' ),
|
843 |
self::CANCEL_REASON_OTHER => __( 'Other', 'facebook-for-woocommerce' ),
|
844 |
-
|
845 |
}
|
846 |
|
847 |
|
@@ -852,7 +872,7 @@ class Orders {
|
|
852 |
*
|
853 |
* @since 2.1.0
|
854 |
*
|
855 |
-
* @param bool
|
856 |
* @param \WC_Order $order order object
|
857 |
* @return bool
|
858 |
*/
|
@@ -877,7 +897,6 @@ class Orders {
|
|
877 |
* @param bool $is_enabled whether the email is enabled
|
878 |
* @param \WC_Order $order order object
|
879 |
* @param Orders $this admin orders instance
|
880 |
-
*
|
881 |
*/
|
882 |
$is_enabled = (bool) apply_filters( 'wc_facebook_commerce_send_woocommerce_emails', $is_enabled, $order, $this );
|
883 |
}
|
106 |
*/
|
107 |
public static function is_commerce_order( \WC_Order $order ) {
|
108 |
|
109 |
+
return in_array( $order->get_created_via(), array( 'instagram', 'facebook' ), true );
|
110 |
}
|
111 |
|
112 |
|
120 |
*/
|
121 |
public function find_local_order( $remote_id ) {
|
122 |
|
123 |
+
$orders = wc_get_orders(
|
124 |
+
array(
|
125 |
+
'limit' => 1,
|
126 |
+
'status' => 'any',
|
127 |
+
'meta_key' => self::REMOTE_ID_META_KEY,
|
128 |
+
'meta_value' => $remote_id,
|
129 |
+
)
|
130 |
+
);
|
131 |
|
132 |
return ! empty( $orders ) ? current( $orders ) : null;
|
133 |
}
|
160 |
*
|
161 |
* @since 2.1.0
|
162 |
*
|
163 |
+
* @param Order $remote_order Orders API order object
|
164 |
* @param \WC_Order $local_order local order object
|
165 |
* @return \WC_Order
|
166 |
* @throws SV_WC_Plugin_Exception|\WC_Data_Exception
|
214 |
$matching_wc_order_item->set_subtotal( $item['quantity'] * $item['price_per_unit']['amount'] );
|
215 |
$matching_wc_order_item->set_total( $item['quantity'] * $item['price_per_unit']['amount'] );
|
216 |
// we use the estimated_tax because the captured_tax represents the tax after the order/item has been shipped and we don't fulfill order at the line-item level
|
217 |
+
$matching_wc_order_item->set_taxes(
|
218 |
+
array(
|
219 |
+
'subtotal' => array( $item['tax_details']['estimated_tax']['amount'] ),
|
220 |
+
'total' => array( $item['tax_details']['estimated_tax']['amount'] ),
|
221 |
+
)
|
222 |
+
);
|
223 |
$matching_wc_order_item->save();
|
224 |
|
225 |
if ( ! empty( $item['tax_details']['estimated_tax']['amount'] ) ) {
|
254 |
}
|
255 |
|
256 |
$matching_shipping_order_item->set_total( $selected_shipping_option['price']['amount'] );
|
257 |
+
$matching_shipping_order_item->set_taxes(
|
258 |
+
array(
|
259 |
+
'total' => array( $selected_shipping_option['calculated_tax']['amount'] ),
|
260 |
+
)
|
261 |
+
);
|
262 |
$matching_shipping_order_item->save();
|
263 |
|
264 |
// add tax item
|
405 |
} else {
|
406 |
$local_order = $this->update_local_order( $remote_order, $local_order );
|
407 |
}
|
|
|
408 |
} catch ( \Exception $exception ) {
|
409 |
|
410 |
if ( ! empty( $local_order ) ) {
|
427 |
$local_order->set_status( 'processing' );
|
428 |
|
429 |
/* translators: Placeholders: %1$s - order remote id, %2$s - order created by */
|
430 |
+
$local_order->add_order_note(
|
431 |
+
sprintf(
|
432 |
+
__( 'Order %1$s paid in %2$s', 'facebook-for-woocommerce' ),
|
433 |
+
$remote_order->get_id(),
|
434 |
+
ucfirst( $remote_order->get_channel() )
|
435 |
+
)
|
436 |
+
);
|
437 |
|
438 |
} catch ( SV_WC_API_Exception $exception ) {
|
439 |
|
529 |
* @since 2.1.0
|
530 |
*/
|
531 |
public function schedule_local_orders_update() {
|
532 |
+
if ( facebook_for_woocommerce()->get_commerce_handler()->is_connected() && false === as_next_scheduled_action( self::ACTION_FETCH_ORDERS, array(), \WC_Facebookcommerce::PLUGIN_ID ) ) {
|
533 |
|
534 |
$interval = $this->get_order_update_interval();
|
535 |
|
536 |
+
as_schedule_recurring_action( time() + $interval, $interval, self::ACTION_FETCH_ORDERS, array(), \WC_Facebookcommerce::PLUGIN_ID );
|
537 |
}
|
538 |
}
|
539 |
|
546 |
public function add_hooks() {
|
547 |
|
548 |
// schedule a recurring ACTION_FETCH_ORDERS action, if not already scheduled
|
549 |
+
add_action( 'init', array( $this, 'schedule_local_orders_update' ) );
|
550 |
|
551 |
+
add_action( self::ACTION_FETCH_ORDERS, array( $this, 'update_local_orders' ) );
|
552 |
|
553 |
// prevent sending emails for Commerce orders
|
554 |
+
add_action( 'woocommerce_email_enabled_customer_completed_order', array( $this, 'maybe_stop_order_email' ), 10, 2 );
|
555 |
+
add_action( 'woocommerce_email_enabled_customer_processing_order', array( $this, 'maybe_stop_order_email' ), 10, 2 );
|
556 |
+
add_action( 'woocommerce_email_enabled_customer_refunded_order', array( $this, 'maybe_stop_order_email' ), 10, 2 );
|
557 |
+
add_action( 'woocommerce_email_enabled_customer_partially_refunded_order', array( $this, 'maybe_stop_order_email' ), 10, 2 );
|
558 |
}
|
559 |
|
560 |
|
570 |
* @since 2.1.0
|
571 |
*
|
572 |
* @param \WC_Order $order order object
|
573 |
+
* @param string $tracking_number shipping tracking number
|
574 |
+
* @param string $carrier shipping carrier
|
575 |
* @throws SV_WC_Plugin_Exception
|
576 |
*/
|
577 |
public function fulfill_order( \WC_Order $order, $tracking_number, $carrier ) {
|
591 |
throw new SV_WC_Plugin_Exception( sprintf( __( '%s is not a valid shipping carrier code.', 'facebook-for-woocommerce' ), $carrier ) );
|
592 |
}
|
593 |
|
594 |
+
$items = array();
|
595 |
|
596 |
/** @var \WC_Order_Item_Product $item */
|
597 |
foreach ( $order->get_items() as $item ) {
|
598 |
|
599 |
if ( $product = $item->get_product() ) {
|
600 |
|
601 |
+
$items[] = array(
|
602 |
'retailer_id' => \WC_Facebookcommerce_Utils::get_fb_retailer_id( $product ),
|
603 |
'quantity' => $item->get_quantity(),
|
604 |
+
);
|
605 |
}
|
606 |
}
|
607 |
|
609 |
throw new SV_WC_Plugin_Exception( __( 'No valid Facebook products were found.', 'facebook-for-woocommerce' ) );
|
610 |
}
|
611 |
|
612 |
+
$fulfillment_data = array(
|
613 |
'items' => $items,
|
614 |
+
'tracking_info' => array(
|
615 |
'carrier' => $carrier,
|
616 |
'tracking_number' => $tracking_number,
|
617 |
+
),
|
618 |
+
);
|
619 |
|
620 |
$plugin = facebook_for_woocommerce();
|
621 |
|
622 |
$plugin->get_api( $plugin->get_connection_handler()->get_page_access_token() )->fulfill_order( $remote_id, $fulfillment_data );
|
623 |
|
624 |
+
$order->add_order_note(
|
625 |
+
sprintf(
|
626 |
/* translators: Placeholder: %s - sales channel name, like Facebook or Instagram */
|
627 |
+
__( '%s order fulfilled.', 'facebook-for-woocommerce' ),
|
628 |
+
ucfirst( $order->get_created_via() )
|
629 |
+
)
|
630 |
+
);
|
631 |
|
632 |
} catch ( SV_WC_Plugin_Exception $exception ) {
|
633 |
|
634 |
+
$order->add_order_note(
|
635 |
+
sprintf(
|
636 |
/* translators: Placeholders: %1$s - sales channel name, like Facebook or Instagram, %2$s - error message */
|
637 |
+
__( '%1$s order could not be fulfilled. %2$s', 'facebook-for-woocommerce' ),
|
638 |
+
ucfirst( $order->get_created_via() ),
|
639 |
+
$exception->getMessage()
|
640 |
+
)
|
641 |
+
);
|
642 |
|
643 |
throw $exception;
|
644 |
}
|
651 |
* @since 2.1.0
|
652 |
*
|
653 |
* @param \WC_Order_Refund $refund order refund object
|
654 |
+
* @param string $reason_code refund reason code
|
655 |
* @throws SV_WC_Plugin_Exception
|
656 |
*/
|
657 |
public function add_order_refund( \WC_Order_Refund $refund, $reason_code ) {
|
660 |
|
661 |
$api = $plugin->get_api( $plugin->get_connection_handler()->get_page_access_token() );
|
662 |
|
663 |
+
$valid_reason_codes = array(
|
664 |
self::REFUND_REASON_BUYERS_REMORSE,
|
665 |
self::REFUND_REASON_DAMAGED_GOODS,
|
666 |
self::REFUND_REASON_NOT_AS_DESCRIBED,
|
667 |
self::REFUND_REASON_QUALITY_ISSUE,
|
668 |
self::REFUND_REASON_OTHER,
|
669 |
self::REFUND_REASON_WRONG_ITEM,
|
670 |
+
);
|
671 |
|
672 |
if ( ! in_array( $reason_code, $valid_reason_codes, true ) ) {
|
673 |
$reason_code = self::REFUND_REASON_OTHER;
|
687 |
throw new SV_WC_Plugin_Exception( __( 'Remote ID for parent order not found.', 'facebook-for-woocommerce' ) );
|
688 |
}
|
689 |
|
690 |
+
$refund_data = array(
|
691 |
'reason_code' => $reason_code,
|
692 |
+
);
|
693 |
|
694 |
if ( ! empty( $reason_text = $refund->get_reason() ) ) {
|
695 |
$refund_data['reason_text'] = $reason_text;
|
702 |
|
703 |
if ( ! empty( $refund->get_shipping_total() ) ) {
|
704 |
|
705 |
+
$refund_data['shipping'] = array(
|
706 |
+
'shipping_refund' => array(
|
707 |
'amount' => abs( $refund->get_shipping_total() ),
|
708 |
'currency' => $refund->get_currency(),
|
709 |
+
),
|
710 |
+
);
|
711 |
}
|
712 |
|
713 |
$api->add_order_refund( $remote_id, $refund_data );
|
714 |
|
715 |
+
$parent_order->add_order_note(
|
716 |
+
sprintf(
|
717 |
/* translators: Placeholder: %s - sales channel name, like Facebook or Instagram */
|
718 |
+
__( 'Order refunded on %s.', 'facebook-for-woocommerce' ),
|
719 |
+
ucfirst( $parent_order->get_created_via() )
|
720 |
+
)
|
721 |
+
);
|
722 |
|
723 |
} catch ( SV_WC_Plugin_Exception $exception ) {
|
724 |
|
725 |
if ( ! empty( $parent_order ) && $parent_order instanceof \WC_Order ) {
|
726 |
|
727 |
+
$parent_order->add_order_note(
|
728 |
+
sprintf(
|
729 |
/* translators: Placeholders: %1$s - sales channel name, like Facebook or Instagram, %2$s - error message */
|
730 |
+
__( 'Could not refund %1$s order: %2$s', 'facebook-for-woocommerce' ),
|
731 |
+
ucfirst( $parent_order->get_created_via() ),
|
732 |
+
$exception->getMessage()
|
733 |
+
)
|
734 |
+
);
|
735 |
|
736 |
} else {
|
737 |
|
755 |
*/
|
756 |
private function get_refund_items( \WC_Order_Refund $refund ) {
|
757 |
|
758 |
+
$items = array();
|
759 |
|
760 |
/** @var \WC_Order_Item_Product $item */
|
761 |
foreach ( $refund->get_items() as $item ) {
|
762 |
|
763 |
if ( $product = $item->get_product() ) {
|
764 |
|
765 |
+
$refund_item = array(
|
766 |
'retailer_id' => \WC_Facebookcommerce_Utils::get_fb_retailer_id( $product ),
|
767 |
+
);
|
768 |
|
769 |
if ( ! empty( $item->get_quantity() ) ) {
|
770 |
|
772 |
|
773 |
} else {
|
774 |
|
775 |
+
$refund_item['item_refund_amount'] = array(
|
776 |
'amount' => abs( $item->get_total() ),
|
777 |
'currency' => $refund->get_currency(),
|
778 |
+
);
|
779 |
}
|
780 |
|
781 |
$items[] = $refund_item;
|
796 |
* @since 2.1.0
|
797 |
*
|
798 |
* @param \WC_Order $order order object
|
799 |
+
* @param string $reason_code cancellation reason code
|
800 |
* @throws SV_WC_Plugin_Exception
|
801 |
*/
|
802 |
public function cancel_order( \WC_Order $order, $reason_code ) {
|
808 |
$valid_reason_codes = array_keys( $this->get_cancellation_reasons() );
|
809 |
|
810 |
if ( ! in_array( $reason_code, $valid_reason_codes, true ) ) {
|
811 |
+
$reason_code = self::CANCEL_REASON_OTHER;
|
812 |
}
|
813 |
|
814 |
try {
|
821 |
|
822 |
$api->cancel_order( $remote_id, $reason_code );
|
823 |
|
824 |
+
$order->add_order_note(
|
825 |
+
sprintf(
|
826 |
/* translators: Placeholder: %s - sales channel name, like Facebook or Instagram */
|
827 |
+
__( '%s order cancelled.', 'facebook-for-woocommerce' ),
|
828 |
+
ucfirst( $order->get_created_via() )
|
829 |
+
)
|
830 |
+
);
|
831 |
|
832 |
} catch ( SV_WC_Plugin_Exception $exception ) {
|
833 |
|
834 |
+
$order->add_order_note(
|
835 |
+
sprintf(
|
836 |
/* translators: Placeholders: %1$s - sales channel name, like Facebook or Instagram, %2$s - error message */
|
837 |
+
__( '%1$s order could not be cancelled. %2$s', 'facebook-for-woocommerce' ),
|
838 |
+
ucfirst( $order->get_created_via() ),
|
839 |
+
$exception->getMessage()
|
840 |
+
)
|
841 |
+
);
|
842 |
|
843 |
throw $exception;
|
844 |
}
|
854 |
*/
|
855 |
public function get_cancellation_reasons() {
|
856 |
|
857 |
+
return array(
|
858 |
|
859 |
self::CANCEL_REASON_CUSTOMER_REQUESTED => __( 'Customer requested cancellation', 'facebook-for-woocommerce' ),
|
860 |
self::CANCEL_REASON_OUT_OF_STOCK => __( 'Product(s) are out of stock', 'facebook-for-woocommerce' ),
|
861 |
self::CANCEL_REASON_INVALID_ADDRESS => __( 'Customer address is invalid', 'facebook-for-woocommerce' ),
|
862 |
self::CANCEL_REASON_SUSPICIOUS_ORDER => __( 'Suspicious order', 'facebook-for-woocommerce' ),
|
863 |
self::CANCEL_REASON_OTHER => __( 'Other', 'facebook-for-woocommerce' ),
|
864 |
+
);
|
865 |
}
|
866 |
|
867 |
|
872 |
*
|
873 |
* @since 2.1.0
|
874 |
*
|
875 |
+
* @param bool $is_enabled whether the email is enabled in the first place
|
876 |
* @param \WC_Order $order order object
|
877 |
* @return bool
|
878 |
*/
|
897 |
* @param bool $is_enabled whether the email is enabled
|
898 |
* @param \WC_Order $order order object
|
899 |
* @param Orders $this admin orders instance
|
|
|
900 |
*/
|
901 |
$is_enabled = (bool) apply_filters( 'wc_facebook_commerce_send_woocommerce_emails', $is_enabled, $order, $this );
|
902 |
}
|
includes/Events/AAMSettings.php
CHANGED
@@ -14,7 +14,6 @@ defined( 'ABSPATH' ) or exit;
|
|
14 |
|
15 |
/**
|
16 |
* Base Automatic advanced matching settings object
|
17 |
-
*
|
18 |
*/
|
19 |
class AAMSettings {
|
20 |
|
@@ -39,9 +38,9 @@ class AAMSettings {
|
|
39 |
* @param array $data
|
40 |
*/
|
41 |
public function __construct( $data = array() ) {
|
42 |
-
$this->enable_automatic_matching
|
43 |
-
$this->enabled_automatic_matching_fields =
|
44 |
-
$this->pixel_id
|
45 |
}
|
46 |
|
47 |
|
@@ -53,9 +52,9 @@ class AAMSettings {
|
|
53 |
* @param string $pixel_id pixel ID
|
54 |
* @return string
|
55 |
*/
|
56 |
-
public static function get_url( $pixel_id ){
|
57 |
|
58 |
-
return self::CONNECT_FACEBOOK_DOMAIN.self::SIGNALS_JSON_CONFIG_PATH.'/'
|
59 |
}
|
60 |
|
61 |
/**
|
@@ -66,17 +65,16 @@ class AAMSettings {
|
|
66 |
*
|
67 |
* @param string $pixel_id
|
68 |
*/
|
69 |
-
public static function build_from_pixel_id( $pixel_id ){
|
70 |
-
$url
|
71 |
-
$response = wp_remote_get($url);
|
72 |
if ( is_wp_error( $response ) ) {
|
73 |
return null;
|
74 |
-
}
|
75 |
-
else{
|
76 |
$response_body = json_decode( wp_remote_retrieve_body( $response ), true );
|
77 |
-
if (!array_key_exists('errorMessage', $response_body)){
|
78 |
$response_body['matchingConfig']['pixelId'] = $pixel_id;
|
79 |
-
return new AAMSettings($response_body['matchingConfig']);
|
80 |
}
|
81 |
}
|
82 |
return null;
|
@@ -89,7 +87,7 @@ class AAMSettings {
|
|
89 |
*
|
90 |
* @return bool
|
91 |
*/
|
92 |
-
public function get_enable_automatic_matching(){
|
93 |
return $this->enable_automatic_matching;
|
94 |
}
|
95 |
|
@@ -100,7 +98,7 @@ class AAMSettings {
|
|
100 |
*
|
101 |
* @return string[]
|
102 |
*/
|
103 |
-
public function get_enabled_automatic_matching_fields(){
|
104 |
return $this->enabled_automatic_matching_fields;
|
105 |
}
|
106 |
|
@@ -111,7 +109,7 @@ class AAMSettings {
|
|
111 |
*
|
112 |
* @return string
|
113 |
*/
|
114 |
-
public function get_pixel_id(){
|
115 |
return $this->pixel_id;
|
116 |
}
|
117 |
|
@@ -122,7 +120,7 @@ class AAMSettings {
|
|
122 |
*
|
123 |
* @return AAMSettings
|
124 |
*/
|
125 |
-
public function set_enable_automatic_matching($enable_automatic_matching){
|
126 |
$this->enable_automatic_matching = $enable_automatic_matching;
|
127 |
return $this;
|
128 |
}
|
@@ -134,7 +132,7 @@ class AAMSettings {
|
|
134 |
*
|
135 |
* @return AAMSettings
|
136 |
*/
|
137 |
-
public function set_enabled_automatic_matching_fields($enabled_automatic_matching_fields){
|
138 |
$this->enabled_automatic_matching_fields = $enabled_automatic_matching_fields;
|
139 |
return $this;
|
140 |
}
|
@@ -146,7 +144,7 @@ class AAMSettings {
|
|
146 |
*
|
147 |
* @return AAMSettings
|
148 |
*/
|
149 |
-
public function set_pixel_id($pixel_id){
|
150 |
$this->pixel_id = $pixel_id;
|
151 |
return $this;
|
152 |
}
|
@@ -158,12 +156,12 @@ class AAMSettings {
|
|
158 |
*
|
159 |
* @return string
|
160 |
*/
|
161 |
-
public function __toString(){
|
162 |
return json_encode(
|
163 |
array(
|
164 |
-
'enableAutomaticMatching'
|
165 |
'enabledAutomaticMatchingFields' => $this->enabled_automatic_matching_fields,
|
166 |
-
'pixelId'
|
167 |
)
|
168 |
);
|
169 |
}
|
14 |
|
15 |
/**
|
16 |
* Base Automatic advanced matching settings object
|
|
|
17 |
*/
|
18 |
class AAMSettings {
|
19 |
|
38 |
* @param array $data
|
39 |
*/
|
40 |
public function __construct( $data = array() ) {
|
41 |
+
$this->enable_automatic_matching = isset( $data['enableAutomaticMatching'] ) ? $data['enableAutomaticMatching'] : null;
|
42 |
+
$this->enabled_automatic_matching_fields = isset( $data['enabledAutomaticMatchingFields'] ) ? $data['enabledAutomaticMatchingFields'] : null;
|
43 |
+
$this->pixel_id = isset( $data['pixelId'] ) ? $data['pixelId'] : null;
|
44 |
}
|
45 |
|
46 |
|
52 |
* @param string $pixel_id pixel ID
|
53 |
* @return string
|
54 |
*/
|
55 |
+
public static function get_url( $pixel_id ) {
|
56 |
|
57 |
+
return self::CONNECT_FACEBOOK_DOMAIN . self::SIGNALS_JSON_CONFIG_PATH . '/' . $pixel_id;
|
58 |
}
|
59 |
|
60 |
/**
|
65 |
*
|
66 |
* @param string $pixel_id
|
67 |
*/
|
68 |
+
public static function build_from_pixel_id( $pixel_id ) {
|
69 |
+
$url = self::get_url( $pixel_id );
|
70 |
+
$response = wp_remote_get( $url );
|
71 |
if ( is_wp_error( $response ) ) {
|
72 |
return null;
|
73 |
+
} else {
|
|
|
74 |
$response_body = json_decode( wp_remote_retrieve_body( $response ), true );
|
75 |
+
if ( ! array_key_exists( 'errorMessage', $response_body ) ) {
|
76 |
$response_body['matchingConfig']['pixelId'] = $pixel_id;
|
77 |
+
return new AAMSettings( $response_body['matchingConfig'] );
|
78 |
}
|
79 |
}
|
80 |
return null;
|
87 |
*
|
88 |
* @return bool
|
89 |
*/
|
90 |
+
public function get_enable_automatic_matching() {
|
91 |
return $this->enable_automatic_matching;
|
92 |
}
|
93 |
|
98 |
*
|
99 |
* @return string[]
|
100 |
*/
|
101 |
+
public function get_enabled_automatic_matching_fields() {
|
102 |
return $this->enabled_automatic_matching_fields;
|
103 |
}
|
104 |
|
109 |
*
|
110 |
* @return string
|
111 |
*/
|
112 |
+
public function get_pixel_id() {
|
113 |
return $this->pixel_id;
|
114 |
}
|
115 |
|
120 |
*
|
121 |
* @return AAMSettings
|
122 |
*/
|
123 |
+
public function set_enable_automatic_matching( $enable_automatic_matching ) {
|
124 |
$this->enable_automatic_matching = $enable_automatic_matching;
|
125 |
return $this;
|
126 |
}
|
132 |
*
|
133 |
* @return AAMSettings
|
134 |
*/
|
135 |
+
public function set_enabled_automatic_matching_fields( $enabled_automatic_matching_fields ) {
|
136 |
$this->enabled_automatic_matching_fields = $enabled_automatic_matching_fields;
|
137 |
return $this;
|
138 |
}
|
144 |
*
|
145 |
* @return AAMSettings
|
146 |
*/
|
147 |
+
public function set_pixel_id( $pixel_id ) {
|
148 |
$this->pixel_id = $pixel_id;
|
149 |
return $this;
|
150 |
}
|
156 |
*
|
157 |
* @return string
|
158 |
*/
|
159 |
+
public function __toString() {
|
160 |
return json_encode(
|
161 |
array(
|
162 |
+
'enableAutomaticMatching' => $this->enable_automatic_matching,
|
163 |
'enabledAutomaticMatchingFields' => $this->enabled_automatic_matching_fields,
|
164 |
+
'pixelId' => $this->pixel_id,
|
165 |
)
|
166 |
);
|
167 |
}
|
includes/Events/Event.php
CHANGED
@@ -25,7 +25,7 @@ class Event {
|
|
25 |
*
|
26 |
* @see https://developers.facebook.com/docs/marketing-api/server-side-api/payload-helper
|
27 |
*/
|
28 |
-
protected $data =
|
29 |
|
30 |
|
31 |
/**
|
@@ -39,11 +39,11 @@ class Event {
|
|
39 |
*/
|
40 |
public static function get_version_info() {
|
41 |
|
42 |
-
return
|
43 |
'source' => 'woocommerce',
|
44 |
'version' => WC()->version,
|
45 |
'pluginVersion' => facebook_for_woocommerce()->get_version(),
|
46 |
-
|
47 |
}
|
48 |
|
49 |
|
@@ -69,7 +69,7 @@ class Event {
|
|
69 |
*
|
70 |
* @param array $data event data
|
71 |
*/
|
72 |
-
public function __construct( $data =
|
73 |
|
74 |
$this->prepare_data( $data );
|
75 |
}
|
@@ -87,14 +87,17 @@ class Event {
|
|
87 |
*/
|
88 |
protected function prepare_data( $data ) {
|
89 |
|
90 |
-
$this->data = wp_parse_args(
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
|
|
|
|
|
|
98 |
|
99 |
$this->prepare_user_data( $this->data['user_data'] );
|
100 |
}
|
@@ -110,20 +113,23 @@ class Event {
|
|
110 |
* @param array $data user data
|
111 |
*/
|
112 |
protected function prepare_user_data( $data ) {
|
113 |
-
$this->data['user_data'] = wp_parse_args(
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
|
|
|
|
|
|
119 |
|
120 |
// Country key is not the same in pixel and CAPI events, see:
|
121 |
// https://developers.facebook.com/docs/facebook-pixel/advanced/advanced-matching
|
122 |
// https://developers.facebook.com/docs/marketing-api/conversions-api/parameters
|
123 |
-
if(array_key_exists('cn', $this->data['user_data'])){
|
124 |
-
$country
|
125 |
$this->data['user_data']['country'] = $country;
|
126 |
-
unset($this->data['user_data']['cn']);
|
127 |
}
|
128 |
|
129 |
$this->data['user_data'] = Normalizer::normalize_array( $this->data['user_data'], false );
|
@@ -142,11 +148,11 @@ class Event {
|
|
142 |
*
|
143 |
* @return array
|
144 |
*/
|
145 |
-
protected function hash_pii_data( $user_data ){
|
146 |
-
$keys_to_hash =
|
147 |
-
foreach( $keys_to_hash as $key ){
|
148 |
-
if(array_key_exists($key, $user_data)){
|
149 |
-
$user_data[$key] = hash('sha256', $user_data[$key], false);
|
150 |
}
|
151 |
}
|
152 |
return $user_data;
|
@@ -174,25 +180,24 @@ class Event {
|
|
174 |
} catch ( \Exception $e ) {
|
175 |
|
176 |
// fall back to mt_rand if random_bytes is unavailable
|
177 |
-
return sprintf(
|
178 |
-
|
179 |
// 32 bits for "time_low"
|
180 |
-
mt_rand( 0, 0xffff ),
|
181 |
-
|
182 |
// 16 bits for "time_mid"
|
183 |
mt_rand( 0, 0xffff ),
|
184 |
-
|
185 |
// 16 bits for "time_hi_and_version",
|
186 |
// four most significant bits holds version number 4
|
187 |
mt_rand( 0, 0x0fff ) | 0x4000,
|
188 |
-
|
189 |
// 16 bits, 8 bits for "clk_seq_hi_res",
|
190 |
// 8 bits for "clk_seq_low",
|
191 |
// two most significant bits holds zero and one for variant DCE1.1
|
192 |
mt_rand( 0, 0x3fff ) | 0x8000,
|
193 |
-
|
194 |
// 48 bits for "node"
|
195 |
-
mt_rand( 0, 0xffff ),
|
|
|
|
|
196 |
);
|
197 |
}
|
198 |
}
|
@@ -345,7 +350,7 @@ class Event {
|
|
345 |
*/
|
346 |
public function get_user_data() {
|
347 |
|
348 |
-
return ! empty( $this->data['user_data'] ) ? $this->data['user_data'] :
|
349 |
}
|
350 |
|
351 |
|
@@ -358,7 +363,7 @@ class Event {
|
|
358 |
*/
|
359 |
public function get_custom_data() {
|
360 |
|
361 |
-
return ! empty( $this->data['custom_data'] ) ? $this->data['custom_data'] :
|
362 |
}
|
363 |
|
364 |
}
|
25 |
*
|
26 |
* @see https://developers.facebook.com/docs/marketing-api/server-side-api/payload-helper
|
27 |
*/
|
28 |
+
protected $data = array();
|
29 |
|
30 |
|
31 |
/**
|
39 |
*/
|
40 |
public static function get_version_info() {
|
41 |
|
42 |
+
return array(
|
43 |
'source' => 'woocommerce',
|
44 |
'version' => WC()->version,
|
45 |
'pluginVersion' => facebook_for_woocommerce()->get_version(),
|
46 |
+
);
|
47 |
}
|
48 |
|
49 |
|
69 |
*
|
70 |
* @param array $data event data
|
71 |
*/
|
72 |
+
public function __construct( $data = array() ) {
|
73 |
|
74 |
$this->prepare_data( $data );
|
75 |
}
|
87 |
*/
|
88 |
protected function prepare_data( $data ) {
|
89 |
|
90 |
+
$this->data = wp_parse_args(
|
91 |
+
$data,
|
92 |
+
array(
|
93 |
+
'action_source' => 'website',
|
94 |
+
'event_time' => time(),
|
95 |
+
'event_id' => $this->generate_event_id(),
|
96 |
+
'event_source_url' => $this->get_current_url(),
|
97 |
+
'custom_data' => array(),
|
98 |
+
'user_data' => array(),
|
99 |
+
)
|
100 |
+
);
|
101 |
|
102 |
$this->prepare_user_data( $this->data['user_data'] );
|
103 |
}
|
113 |
* @param array $data user data
|
114 |
*/
|
115 |
protected function prepare_user_data( $data ) {
|
116 |
+
$this->data['user_data'] = wp_parse_args(
|
117 |
+
$data,
|
118 |
+
array(
|
119 |
+
'client_ip_address' => $this->get_client_ip(),
|
120 |
+
'client_user_agent' => $this->get_client_user_agent(),
|
121 |
+
'click_id' => $this->get_click_id(),
|
122 |
+
'browser_id' => $this->get_browser_id(),
|
123 |
+
)
|
124 |
+
);
|
125 |
|
126 |
// Country key is not the same in pixel and CAPI events, see:
|
127 |
// https://developers.facebook.com/docs/facebook-pixel/advanced/advanced-matching
|
128 |
// https://developers.facebook.com/docs/marketing-api/conversions-api/parameters
|
129 |
+
if ( array_key_exists( 'cn', $this->data['user_data'] ) ) {
|
130 |
+
$country = $this->data['user_data']['cn'];
|
131 |
$this->data['user_data']['country'] = $country;
|
132 |
+
unset( $this->data['user_data']['cn'] );
|
133 |
}
|
134 |
|
135 |
$this->data['user_data'] = Normalizer::normalize_array( $this->data['user_data'], false );
|
148 |
*
|
149 |
* @return array
|
150 |
*/
|
151 |
+
protected function hash_pii_data( $user_data ) {
|
152 |
+
$keys_to_hash = array( 'em', 'fn', 'ln', 'ph', 'ct', 'st', 'zp', 'country', 'external_id' );
|
153 |
+
foreach ( $keys_to_hash as $key ) {
|
154 |
+
if ( array_key_exists( $key, $user_data ) ) {
|
155 |
+
$user_data[ $key ] = hash( 'sha256', $user_data[ $key ], false );
|
156 |
}
|
157 |
}
|
158 |
return $user_data;
|
180 |
} catch ( \Exception $e ) {
|
181 |
|
182 |
// fall back to mt_rand if random_bytes is unavailable
|
183 |
+
return sprintf(
|
184 |
+
'%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
|
185 |
// 32 bits for "time_low"
|
186 |
+
mt_rand( 0, 0xffff ),
|
187 |
+
mt_rand( 0, 0xffff ),
|
188 |
// 16 bits for "time_mid"
|
189 |
mt_rand( 0, 0xffff ),
|
|
|
190 |
// 16 bits for "time_hi_and_version",
|
191 |
// four most significant bits holds version number 4
|
192 |
mt_rand( 0, 0x0fff ) | 0x4000,
|
|
|
193 |
// 16 bits, 8 bits for "clk_seq_hi_res",
|
194 |
// 8 bits for "clk_seq_low",
|
195 |
// two most significant bits holds zero and one for variant DCE1.1
|
196 |
mt_rand( 0, 0x3fff ) | 0x8000,
|
|
|
197 |
// 48 bits for "node"
|
198 |
+
mt_rand( 0, 0xffff ),
|
199 |
+
mt_rand( 0, 0xffff ),
|
200 |
+
mt_rand( 0, 0xffff )
|
201 |
);
|
202 |
}
|
203 |
}
|
350 |
*/
|
351 |
public function get_user_data() {
|
352 |
|
353 |
+
return ! empty( $this->data['user_data'] ) ? $this->data['user_data'] : array();
|
354 |
}
|
355 |
|
356 |
|
363 |
*/
|
364 |
public function get_custom_data() {
|
365 |
|
366 |
+
return ! empty( $this->data['custom_data'] ) ? $this->data['custom_data'] : array();
|
367 |
}
|
368 |
|
369 |
}
|
includes/Events/Normalizer.php
CHANGED
@@ -16,7 +16,6 @@ defined( 'ABSPATH' ) or exit;
|
|
16 |
|
17 |
/**
|
18 |
* Normalizer class.
|
19 |
-
*
|
20 |
*/
|
21 |
class Normalizer {
|
22 |
|
@@ -30,42 +29,42 @@ class Normalizer {
|
|
30 |
* @return string
|
31 |
* @throws InvalidArgumentException
|
32 |
*/
|
33 |
-
public static function normalize($field, $data) {
|
34 |
-
if ($data == null || strlen($data) == 0) {
|
35 |
return null;
|
36 |
}
|
37 |
|
38 |
-
$data
|
39 |
$normalized_data = $data;
|
40 |
|
41 |
-
switch ($field) {
|
42 |
case 'em':
|
43 |
-
|
44 |
-
|
45 |
|
46 |
case 'ph':
|
47 |
-
|
48 |
-
|
49 |
|
50 |
case 'zp':
|
51 |
-
|
52 |
-
|
53 |
|
54 |
case 'ct':
|
55 |
-
|
56 |
-
|
57 |
|
58 |
case 'st':
|
59 |
-
|
60 |
-
|
61 |
|
62 |
case 'country':
|
63 |
-
|
64 |
-
|
65 |
|
66 |
case 'cn':
|
67 |
-
|
68 |
-
|
69 |
|
70 |
default:
|
71 |
}
|
@@ -81,23 +80,21 @@ class Normalizer {
|
|
81 |
* @param string[] array with user data to be normalized
|
82 |
* @return string[]
|
83 |
*/
|
84 |
-
public static function normalize_array($data, $is_pixel_data){
|
85 |
// Country is encoded as cn in Pixel events and country in CAPI events
|
86 |
-
$keys_to_normalize =
|
87 |
-
if($is_pixel_data){
|
88 |
$keys_to_normalize[] = 'cn';
|
89 |
-
}
|
90 |
-
else{
|
91 |
$keys_to_normalize[] = 'country';
|
92 |
}
|
93 |
-
foreach($keys_to_normalize as $key){
|
94 |
-
if(array_key_exists($key, $data)){
|
95 |
-
//If the data is invalid, it is erased from the array
|
96 |
-
try{
|
97 |
-
$data[$key] = self::normalize($key, $data[$key]);
|
98 |
-
}
|
99 |
-
|
100 |
-
unset($data[$key]);
|
101 |
}
|
102 |
}
|
103 |
}
|
@@ -113,12 +110,12 @@ class Normalizer {
|
|
113 |
* @return string
|
114 |
* @throws InvalidArgumentException
|
115 |
*/
|
116 |
-
private static function normalizeEmail($email) {
|
117 |
// Validates email against RFC 822
|
118 |
-
$result = filter_var($email, FILTER_SANITIZE_EMAIL);
|
119 |
|
120 |
-
if (!filter_var($result, FILTER_VALIDATE_EMAIL)) {
|
121 |
-
throw new InvalidArgumentException('Invalid email format for the passed email: ' . $email . 'Please check the passed email format.');
|
122 |
}
|
123 |
|
124 |
return $result;
|
@@ -132,8 +129,8 @@ class Normalizer {
|
|
132 |
* @param string $city city name to be normalized.
|
133 |
* @return string
|
134 |
*/
|
135 |
-
private static function normalizeCity($city) {
|
136 |
-
return trim(preg_replace('/[0-9.\s\-()]/', '', $city));
|
137 |
}
|
138 |
|
139 |
/**
|
@@ -144,8 +141,8 @@ class Normalizer {
|
|
144 |
* @param string $state state name to be normalized.
|
145 |
* @return string
|
146 |
*/
|
147 |
-
private static function normalizeState($state) {
|
148 |
-
return preg_replace('/[^a-z]/', '', $state);
|
149 |
}
|
150 |
|
151 |
/**
|
@@ -157,11 +154,11 @@ class Normalizer {
|
|
157 |
* @return string
|
158 |
* @throws InvalidArgumentException
|
159 |
*/
|
160 |
-
private static function normalizeCountry($country) {
|
161 |
-
$result = preg_replace('/[^a-z]/i', '', $country);
|
162 |
|
163 |
-
if (strlen($result) != 2) {
|
164 |
-
throw new InvalidArgumentException('Invalid country format passed(' . $country . '). Country Code should be a two-letter ISO Country Code');
|
165 |
}
|
166 |
|
167 |
return $result;
|
@@ -175,12 +172,12 @@ class Normalizer {
|
|
175 |
* @param string $zip postal code to be normalized.
|
176 |
* @return string
|
177 |
*/
|
178 |
-
private static function normalizeZipCode($zip) {
|
179 |
// Removing the spaces from the zip code. Eg:
|
180 |
-
$zip = preg_replace('/[ ]/', '', $zip);
|
181 |
|
182 |
// If the code has more than one part, retain the first part.
|
183 |
-
$zip = explode('-', $zip)[0];
|
184 |
return $zip;
|
185 |
}
|
186 |
|
@@ -192,11 +189,11 @@ class Normalizer {
|
|
192 |
* @param string $phone phone number to be normalized.
|
193 |
* @return string
|
194 |
*/
|
195 |
-
private static function normalizePhone($phone) {
|
196 |
-
$result = trim(preg_replace('/[a-z()-]/', '', $phone));
|
197 |
|
198 |
-
if (
|
199 |
-
$result = preg_replace('/[\-\s+]/', '', $result);
|
200 |
}
|
201 |
|
202 |
return $result;
|
@@ -210,20 +207,20 @@ class Normalizer {
|
|
210 |
* @param string $phone_number Phone number to be normalized.
|
211 |
* @return bool
|
212 |
*/
|
213 |
-
private static function isInternationalNumber($phone_number) {
|
214 |
// Remove spaces and hyphens
|
215 |
-
$phone_number = preg_replace('/[\-\s]/', '', $phone_number);
|
216 |
|
217 |
// Strip + and up to 2 leading 0s
|
218 |
-
$phone_number = preg_replace('/^\+?0{0,2}/', '', $phone_number);
|
219 |
|
220 |
-
if (substr($phone_number, 0, 1) === '0') {
|
221 |
return false;
|
222 |
}
|
223 |
|
224 |
// International Phone number with country calling code.
|
225 |
$international_number_regex = '/^\d{1,4}\(?\d{2,3}\)?\d{4,}$/';
|
226 |
|
227 |
-
return preg_match($international_number_regex, $phone_number);
|
228 |
}
|
229 |
}
|
16 |
|
17 |
/**
|
18 |
* Normalizer class.
|
|
|
19 |
*/
|
20 |
class Normalizer {
|
21 |
|
29 |
* @return string
|
30 |
* @throws InvalidArgumentException
|
31 |
*/
|
32 |
+
public static function normalize( $field, $data ) {
|
33 |
+
if ( $data == null || strlen( $data ) == 0 ) {
|
34 |
return null;
|
35 |
}
|
36 |
|
37 |
+
$data = trim( strtolower( $data ) );
|
38 |
$normalized_data = $data;
|
39 |
|
40 |
+
switch ( $field ) {
|
41 |
case 'em':
|
42 |
+
$normalized_data = self::normalizeEmail( $data );
|
43 |
+
break;
|
44 |
|
45 |
case 'ph':
|
46 |
+
$normalized_data = self::normalizePhone( $data );
|
47 |
+
break;
|
48 |
|
49 |
case 'zp':
|
50 |
+
$normalized_data = self::normalizeZipCode( $data );
|
51 |
+
break;
|
52 |
|
53 |
case 'ct':
|
54 |
+
$normalized_data = self::normalizeCity( $data );
|
55 |
+
break;
|
56 |
|
57 |
case 'st':
|
58 |
+
$normalized_data = self::normalizeState( $data );
|
59 |
+
break;
|
60 |
|
61 |
case 'country':
|
62 |
+
$normalized_data = self::normalizeCountry( $data );
|
63 |
+
break;
|
64 |
|
65 |
case 'cn':
|
66 |
+
$normalized_data = self::normalizeCountry( $data );
|
67 |
+
break;
|
68 |
|
69 |
default:
|
70 |
}
|
80 |
* @param string[] array with user data to be normalized
|
81 |
* @return string[]
|
82 |
*/
|
83 |
+
public static function normalize_array( $data, $is_pixel_data ) {
|
84 |
// Country is encoded as cn in Pixel events and country in CAPI events
|
85 |
+
$keys_to_normalize = array( 'fn', 'ln', 'em', 'ph', 'zp', 'ct', 'st' );
|
86 |
+
if ( $is_pixel_data ) {
|
87 |
$keys_to_normalize[] = 'cn';
|
88 |
+
} else {
|
|
|
89 |
$keys_to_normalize[] = 'country';
|
90 |
}
|
91 |
+
foreach ( $keys_to_normalize as $key ) {
|
92 |
+
if ( array_key_exists( $key, $data ) ) {
|
93 |
+
// If the data is invalid, it is erased from the array
|
94 |
+
try {
|
95 |
+
$data[ $key ] = self::normalize( $key, $data[ $key ] );
|
96 |
+
} catch ( InvalidArgumentException $e ) {
|
97 |
+
unset( $data[ $key ] );
|
|
|
98 |
}
|
99 |
}
|
100 |
}
|
110 |
* @return string
|
111 |
* @throws InvalidArgumentException
|
112 |
*/
|
113 |
+
private static function normalizeEmail( $email ) {
|
114 |
// Validates email against RFC 822
|
115 |
+
$result = filter_var( $email, FILTER_SANITIZE_EMAIL );
|
116 |
|
117 |
+
if ( ! filter_var( $result, FILTER_VALIDATE_EMAIL ) ) {
|
118 |
+
throw new InvalidArgumentException( 'Invalid email format for the passed email: ' . $email . 'Please check the passed email format.' );
|
119 |
}
|
120 |
|
121 |
return $result;
|
129 |
* @param string $city city name to be normalized.
|
130 |
* @return string
|
131 |
*/
|
132 |
+
private static function normalizeCity( $city ) {
|
133 |
+
return trim( preg_replace( '/[0-9.\s\-()]/', '', $city ) );
|
134 |
}
|
135 |
|
136 |
/**
|
141 |
* @param string $state state name to be normalized.
|
142 |
* @return string
|
143 |
*/
|
144 |
+
private static function normalizeState( $state ) {
|
145 |
+
return preg_replace( '/[^a-z]/', '', $state );
|
146 |
}
|
147 |
|
148 |
/**
|
154 |
* @return string
|
155 |
* @throws InvalidArgumentException
|
156 |
*/
|
157 |
+
private static function normalizeCountry( $country ) {
|
158 |
+
$result = preg_replace( '/[^a-z]/i', '', $country );
|
159 |
|
160 |
+
if ( strlen( $result ) != 2 ) {
|
161 |
+
throw new InvalidArgumentException( 'Invalid country format passed(' . $country . '). Country Code should be a two-letter ISO Country Code' );
|
162 |
}
|
163 |
|
164 |
return $result;
|
172 |
* @param string $zip postal code to be normalized.
|
173 |
* @return string
|
174 |
*/
|
175 |
+
private static function normalizeZipCode( $zip ) {
|
176 |
// Removing the spaces from the zip code. Eg:
|
177 |
+
$zip = preg_replace( '/[ ]/', '', $zip );
|
178 |
|
179 |
// If the code has more than one part, retain the first part.
|
180 |
+
$zip = explode( '-', $zip )[0];
|
181 |
return $zip;
|
182 |
}
|
183 |
|
189 |
* @param string $phone phone number to be normalized.
|
190 |
* @return string
|
191 |
*/
|
192 |
+
private static function normalizePhone( $phone ) {
|
193 |
+
$result = trim( preg_replace( '/[a-z()-]/', '', $phone ) );
|
194 |
|
195 |
+
if ( self::isInternationalNumber( $result ) ) {
|
196 |
+
$result = preg_replace( '/[\-\s+]/', '', $result );
|
197 |
}
|
198 |
|
199 |
return $result;
|
207 |
* @param string $phone_number Phone number to be normalized.
|
208 |
* @return bool
|
209 |
*/
|
210 |
+
private static function isInternationalNumber( $phone_number ) {
|
211 |
// Remove spaces and hyphens
|
212 |
+
$phone_number = preg_replace( '/[\-\s]/', '', $phone_number );
|
213 |
|
214 |
// Strip + and up to 2 leading 0s
|
215 |
+
$phone_number = preg_replace( '/^\+?0{0,2}/', '', $phone_number );
|
216 |
|
217 |
+
if ( substr( $phone_number, 0, 1 ) === '0' ) {
|
218 |
return false;
|
219 |
}
|
220 |
|
221 |
// International Phone number with country calling code.
|
222 |
$international_number_regex = '/^\d{1,4}\(?\d{2,3}\)?\d{4,}$/';
|
223 |
|
224 |
+
return preg_match( $international_number_regex, $phone_number );
|
225 |
}
|
226 |
}
|
includes/Exceptions/ConnectWCAPIException.php
ADDED
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace SkyVerge\WooCommerce\Facebook\API\Exceptions;
|
4 |
+
|
5 |
+
defined( 'ABSPATH' ) or exit;
|
6 |
+
|
7 |
+
/**
|
8 |
+
* Class Connect_WC_API_Exception.
|
9 |
+
* Exception is trown when Connection with FB fails. @see \SkyVerge\WooCommerce\Facebook\Handlers\Connection
|
10 |
+
*
|
11 |
+
* @package SkyVerge\WooCommerce\Facebook\API\Exceptions
|
12 |
+
*/
|
13 |
+
class Connect_WC_API_Exception extends \Exception {
|
14 |
+
}
|
includes/Handlers/Connection.php
CHANGED
@@ -12,6 +12,7 @@ namespace SkyVerge\WooCommerce\Facebook\Handlers;
|
|
12 |
|
13 |
use SkyVerge\WooCommerce\PluginFramework\v5_10_0\SV_WC_API_Exception;
|
14 |
use SkyVerge\WooCommerce\PluginFramework\v5_10_0\SV_WC_Helper;
|
|
|
15 |
|
16 |
defined( 'ABSPATH' ) or exit;
|
17 |
|
@@ -92,6 +93,8 @@ class Connection {
|
|
92 |
/** @var \WC_Facebookcommerce */
|
93 |
private $plugin;
|
94 |
|
|
|
|
|
95 |
|
96 |
/**
|
97 |
* Constructs a new Connection.
|
@@ -102,15 +105,15 @@ class Connection {
|
|
102 |
|
103 |
$this->plugin = $plugin;
|
104 |
|
105 |
-
add_action( 'init',
|
106 |
|
107 |
-
add_action( 'admin_init',
|
108 |
|
109 |
-
add_action( 'woocommerce_api_' . self::ACTION_CONNECT,
|
110 |
|
111 |
-
add_action( 'admin_action_' . self::ACTION_DISCONNECT,
|
112 |
|
113 |
-
add_action( 'woocommerce_api_' . self::ACTION_FBE_REDIRECT,
|
114 |
|
115 |
add_action( 'fbe_webhook', array( $this, 'fbe_install_webhook' ) );
|
116 |
|
@@ -159,7 +162,6 @@ class Connection {
|
|
159 |
$this->get_plugin()->get_api()->update_messenger_configuration( $this->get_external_business_id(), $messenger_configuration );
|
160 |
}
|
161 |
}
|
162 |
-
|
163 |
} catch ( SV_WC_API_Exception $exception ) {
|
164 |
|
165 |
if ( $this->get_plugin()->get_integration()->is_debug_mode_enabled() ) {
|
@@ -272,20 +274,24 @@ class Connection {
|
|
272 |
throw new SV_WC_API_Exception( 'Invalid nonce' );
|
273 |
}
|
274 |
|
275 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
276 |
|
277 |
if ( ! $merchant_access_token ) {
|
278 |
throw new SV_WC_API_Exception( 'Access token is missing' );
|
279 |
}
|
280 |
|
281 |
-
$system_user_access_token = ! empty( $_GET['system_user_access_token'] ) ? sanitize_text_field( $_GET['system_user_access_token'] ) : '';
|
282 |
-
|
283 |
if ( ! $system_user_access_token ) {
|
284 |
throw new SV_WC_API_Exception( 'System User access token is missing' );
|
285 |
}
|
286 |
|
287 |
-
$system_user_id = ! empty( $_GET['system_user_id'] ) ? sanitize_text_field( $_GET['system_user_id'] ) : '';
|
288 |
-
|
289 |
if ( ! $system_user_id ) {
|
290 |
throw new SV_WC_API_Exception( 'System User ID is missing' );
|
291 |
}
|
@@ -313,6 +319,11 @@ class Connection {
|
|
313 |
|
314 |
facebook_for_woocommerce()->log( sprintf( 'Connection failed: %s', $exception->getMessage() ) );
|
315 |
|
|
|
|
|
|
|
|
|
|
|
316 |
set_transient( 'wc_facebook_connection_failed', time(), 30 );
|
317 |
}
|
318 |
|
@@ -405,11 +416,13 @@ class Connection {
|
|
405 |
|
406 |
facebook_for_woocommerce()->log( print_r( $body, true ) );
|
407 |
|
408 |
-
throw new SV_WC_API_Exception(
|
|
|
409 |
/* translators: Placeholders: %s - API error message */
|
410 |
-
|
411 |
-
|
412 |
-
|
|
|
413 |
}
|
414 |
|
415 |
$page_access_tokens = wp_list_pluck( $body['data'], 'access_token', 'id' );
|
@@ -417,11 +430,13 @@ class Connection {
|
|
417 |
// bail if the user isn't authorized to manage the page
|
418 |
if ( empty( $page_access_tokens[ $page_id ] ) ) {
|
419 |
|
420 |
-
throw new SV_WC_API_Exception(
|
|
|
421 |
/* translators: Placeholders: %s - Facebook page ID */
|
422 |
-
|
423 |
-
|
424 |
-
|
|
|
425 |
}
|
426 |
|
427 |
return $page_access_tokens[ $page_id ];
|
@@ -534,19 +549,25 @@ class Connection {
|
|
534 |
public function get_commerce_connect_url() {
|
535 |
|
536 |
// build the site URL to which the user will ultimately return
|
537 |
-
$site_url = add_query_arg(
|
538 |
-
|
539 |
-
|
540 |
-
|
|
|
|
|
|
|
541 |
|
542 |
// build the proxy app URL where the user will land after onboarding, to be redirected to the site URL
|
543 |
$redirect_url = add_query_arg( 'site_url', urlencode( $site_url ), 'https://connect.woocommerce.com/auth/facebookcommerce/' );
|
544 |
|
545 |
// build the final connect URL, direct to Facebook
|
546 |
-
$connect_url = add_query_arg(
|
547 |
-
|
548 |
-
|
549 |
-
|
|
|
|
|
|
|
550 |
|
551 |
/**
|
552 |
* Filters the URL used to connect to Facebook Commerce.
|
@@ -599,14 +620,14 @@ class Connection {
|
|
599 |
*/
|
600 |
public function get_scopes() {
|
601 |
|
602 |
-
$scopes =
|
603 |
'manage_business_extension',
|
604 |
'catalog_management',
|
605 |
'ads_management',
|
606 |
'ads_read',
|
607 |
'pages_read_engagement', // this scope is needed to enable order management if using the Commerce feature
|
608 |
'instagram_basic',
|
609 |
-
|
610 |
|
611 |
/**
|
612 |
* Filters the scopes that will be requested during the connection flow.
|
@@ -648,7 +669,7 @@ class Connection {
|
|
648 |
$external_id = sanitize_key( (string) apply_filters( 'wc_facebook_connection_business_id', get_bloginfo( 'name' ) ) );
|
649 |
|
650 |
if ( empty( $external_id ) ) {
|
651 |
-
$external_id = sanitize_key( str_replace(
|
652 |
}
|
653 |
|
654 |
$external_id = uniqid( sprintf( '%s-', $external_id ), false );
|
@@ -829,12 +850,15 @@ class Connection {
|
|
829 |
*/
|
830 |
public function get_redirect_url() {
|
831 |
|
832 |
-
$redirect_url = add_query_arg(
|
833 |
-
|
834 |
-
|
835 |
-
|
836 |
-
|
837 |
-
|
|
|
|
|
|
|
838 |
|
839 |
/**
|
840 |
* Filters the redirect URL where the user will return to after OAuth.
|
@@ -871,15 +895,18 @@ class Connection {
|
|
871 |
*
|
872 |
* @param array $parameters connection parameters
|
873 |
*/
|
874 |
-
return apply_filters(
|
875 |
-
'
|
876 |
-
|
877 |
-
|
878 |
-
|
879 |
-
|
880 |
-
|
881 |
-
|
882 |
-
|
|
|
|
|
|
|
883 |
}
|
884 |
|
885 |
|
@@ -894,22 +921,22 @@ class Connection {
|
|
894 |
*/
|
895 |
private function get_connect_parameters_extras() {
|
896 |
|
897 |
-
$parameters =
|
898 |
-
'setup'
|
899 |
'external_business_id' => $this->get_external_business_id(),
|
900 |
'timezone' => $this->get_timezone_string(),
|
901 |
'currency' => get_woocommerce_currency(),
|
902 |
'business_vertical' => 'ECOMMERCE',
|
903 |
'domain' => home_url(),
|
904 |
'channel' => 'COMMERCE_OFFSITE',
|
905 |
-
|
906 |
-
'business_config' =>
|
907 |
-
'business' =>
|
908 |
'name' => $this->get_business_name(),
|
909 |
-
|
910 |
-
|
911 |
-
'repeat'
|
912 |
-
|
913 |
|
914 |
if ( $external_merchant_settings_id = facebook_for_woocommerce()->get_integration()->get_external_merchant_settings_id() ) {
|
915 |
$parameters['setup']['merchant_settings_id'] = $external_merchant_settings_id;
|
@@ -918,12 +945,12 @@ class Connection {
|
|
918 |
// if messenger was previously enabled
|
919 |
if ( facebook_for_woocommerce()->get_integration()->is_messenger_enabled() ) {
|
920 |
|
921 |
-
$parameters['business_config']['messenger_chat'] =
|
922 |
'enabled' => true,
|
923 |
-
'domains' =>
|
924 |
home_url( '/' ),
|
925 |
-
|
926 |
-
|
927 |
}
|
928 |
|
929 |
return $parameters;
|
@@ -1368,11 +1395,11 @@ class Connection {
|
|
1368 |
|
1369 |
if ( empty( $_REQUEST['success'] ) ) { //phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
1370 |
|
1371 |
-
$url_params =
|
1372 |
'store_url' => '',
|
1373 |
'redirect_uri' => rawurlencode( $redirect_uri ),
|
1374 |
-
'errors' =>
|
1375 |
-
|
1376 |
|
1377 |
$redirect_url = add_query_arg(
|
1378 |
$url_params,
|
12 |
|
13 |
use SkyVerge\WooCommerce\PluginFramework\v5_10_0\SV_WC_API_Exception;
|
14 |
use SkyVerge\WooCommerce\PluginFramework\v5_10_0\SV_WC_Helper;
|
15 |
+
use SkyVerge\WooCommerce\Facebook\API\Exceptions\Connect_WC_API_Exception;
|
16 |
|
17 |
defined( 'ABSPATH' ) or exit;
|
18 |
|
93 |
/** @var \WC_Facebookcommerce */
|
94 |
private $plugin;
|
95 |
|
96 |
+
/** @var array */
|
97 |
+
protected $proxy_error_messages;
|
98 |
|
99 |
/**
|
100 |
* Constructs a new Connection.
|
105 |
|
106 |
$this->plugin = $plugin;
|
107 |
|
108 |
+
add_action( 'init', array( $this, 'refresh_business_configuration' ) );
|
109 |
|
110 |
+
add_action( 'admin_init', array( $this, 'refresh_installation_data' ) );
|
111 |
|
112 |
+
add_action( 'woocommerce_api_' . self::ACTION_CONNECT, array( $this, 'handle_connect' ) );
|
113 |
|
114 |
+
add_action( 'admin_action_' . self::ACTION_DISCONNECT, array( $this, 'handle_disconnect' ) );
|
115 |
|
116 |
+
add_action( 'woocommerce_api_' . self::ACTION_FBE_REDIRECT, array( $this, 'handle_fbe_redirect' ) );
|
117 |
|
118 |
add_action( 'fbe_webhook', array( $this, 'fbe_install_webhook' ) );
|
119 |
|
162 |
$this->get_plugin()->get_api()->update_messenger_configuration( $this->get_external_business_id(), $messenger_configuration );
|
163 |
}
|
164 |
}
|
|
|
165 |
} catch ( SV_WC_API_Exception $exception ) {
|
166 |
|
167 |
if ( $this->get_plugin()->get_integration()->is_debug_mode_enabled() ) {
|
274 |
throw new SV_WC_API_Exception( 'Invalid nonce' );
|
275 |
}
|
276 |
|
277 |
+
$is_error = ! empty( $_GET['err'] ) ? true : false;
|
278 |
+
$error_code = ! empty( $_GET['err_code'] ) ? sanitize_text_field( $_GET['err_code'] ) : '';
|
279 |
+
$merchant_access_token = ! empty( $_GET['merchant_access_token'] ) ? sanitize_text_field( $_GET['merchant_access_token'] ) : '';
|
280 |
+
$system_user_access_token = ! empty( $_GET['system_user_access_token'] ) ? sanitize_text_field( $_GET['system_user_access_token'] ) : '';
|
281 |
+
$system_user_id = ! empty( $_GET['system_user_id'] ) ? sanitize_text_field( $_GET['system_user_id'] ) : '';
|
282 |
+
|
283 |
+
if ( $is_error && $error_code ) {
|
284 |
+
throw new Connect_WC_API_Exception( $error_code );
|
285 |
+
}
|
286 |
|
287 |
if ( ! $merchant_access_token ) {
|
288 |
throw new SV_WC_API_Exception( 'Access token is missing' );
|
289 |
}
|
290 |
|
|
|
|
|
291 |
if ( ! $system_user_access_token ) {
|
292 |
throw new SV_WC_API_Exception( 'System User access token is missing' );
|
293 |
}
|
294 |
|
|
|
|
|
295 |
if ( ! $system_user_id ) {
|
296 |
throw new SV_WC_API_Exception( 'System User ID is missing' );
|
297 |
}
|
319 |
|
320 |
facebook_for_woocommerce()->log( sprintf( 'Connection failed: %s', $exception->getMessage() ) );
|
321 |
|
322 |
+
set_transient( 'wc_facebook_connection_failed', time(), 30 );
|
323 |
+
} catch ( Connect_WC_API_Exception $exception ) {
|
324 |
+
|
325 |
+
facebook_for_woocommerce()->log( sprintf( 'Failed to connect to Facebook. Facebook API returned error code: %s', $exception->getMessage() ), 'facebook_for_woocommerce_connect' );
|
326 |
+
|
327 |
set_transient( 'wc_facebook_connection_failed', time(), 30 );
|
328 |
}
|
329 |
|
416 |
|
417 |
facebook_for_woocommerce()->log( print_r( $body, true ) );
|
418 |
|
419 |
+
throw new SV_WC_API_Exception(
|
420 |
+
sprintf(
|
421 |
/* translators: Placeholders: %s - API error message */
|
422 |
+
__( 'Could not retrieve page access data. %s', 'facebook for woocommerce' ),
|
423 |
+
wp_remote_retrieve_response_message( $response )
|
424 |
+
)
|
425 |
+
);
|
426 |
}
|
427 |
|
428 |
$page_access_tokens = wp_list_pluck( $body['data'], 'access_token', 'id' );
|
430 |
// bail if the user isn't authorized to manage the page
|
431 |
if ( empty( $page_access_tokens[ $page_id ] ) ) {
|
432 |
|
433 |
+
throw new SV_WC_API_Exception(
|
434 |
+
sprintf(
|
435 |
/* translators: Placeholders: %s - Facebook page ID */
|
436 |
+
__( 'Page %s not authorized.', 'facebook-for-woocommerce' ),
|
437 |
+
$page_id
|
438 |
+
)
|
439 |
+
);
|
440 |
}
|
441 |
|
442 |
return $page_access_tokens[ $page_id ];
|
549 |
public function get_commerce_connect_url() {
|
550 |
|
551 |
// build the site URL to which the user will ultimately return
|
552 |
+
$site_url = add_query_arg(
|
553 |
+
array(
|
554 |
+
'wc-api' => self::ACTION_CONNECT_COMMERCE,
|
555 |
+
'nonce' => wp_create_nonce( self::ACTION_CONNECT_COMMERCE ),
|
556 |
+
),
|
557 |
+
home_url( '/' )
|
558 |
+
);
|
559 |
|
560 |
// build the proxy app URL where the user will land after onboarding, to be redirected to the site URL
|
561 |
$redirect_url = add_query_arg( 'site_url', urlencode( $site_url ), 'https://connect.woocommerce.com/auth/facebookcommerce/' );
|
562 |
|
563 |
// build the final connect URL, direct to Facebook
|
564 |
+
$connect_url = add_query_arg(
|
565 |
+
array(
|
566 |
+
'app_id' => $this->get_client_id(), // this endpoint calls the client ID "app ID"
|
567 |
+
'redirect_url' => urlencode( $redirect_url ),
|
568 |
+
),
|
569 |
+
'https://www.facebook.com/commerce_manager/onboarding/'
|
570 |
+
);
|
571 |
|
572 |
/**
|
573 |
* Filters the URL used to connect to Facebook Commerce.
|
620 |
*/
|
621 |
public function get_scopes() {
|
622 |
|
623 |
+
$scopes = array(
|
624 |
'manage_business_extension',
|
625 |
'catalog_management',
|
626 |
'ads_management',
|
627 |
'ads_read',
|
628 |
'pages_read_engagement', // this scope is needed to enable order management if using the Commerce feature
|
629 |
'instagram_basic',
|
630 |
+
);
|
631 |
|
632 |
/**
|
633 |
* Filters the scopes that will be requested during the connection flow.
|
669 |
$external_id = sanitize_key( (string) apply_filters( 'wc_facebook_connection_business_id', get_bloginfo( 'name' ) ) );
|
670 |
|
671 |
if ( empty( $external_id ) ) {
|
672 |
+
$external_id = sanitize_key( str_replace( array( 'http', 'https', 'www' ), '', get_bloginfo( 'url' ) ) );
|
673 |
}
|
674 |
|
675 |
$external_id = uniqid( sprintf( '%s-', $external_id ), false );
|
850 |
*/
|
851 |
public function get_redirect_url() {
|
852 |
|
853 |
+
$redirect_url = add_query_arg(
|
854 |
+
array(
|
855 |
+
'wc-api' => self::ACTION_CONNECT,
|
856 |
+
'external_business_id' => $this->get_external_business_id(),
|
857 |
+
'nonce' => wp_create_nonce( self::ACTION_CONNECT ),
|
858 |
+
'type' => self::AUTH_TYPE_STANDARD,
|
859 |
+
),
|
860 |
+
home_url( '/' )
|
861 |
+
);
|
862 |
|
863 |
/**
|
864 |
* Filters the redirect URL where the user will return to after OAuth.
|
895 |
*
|
896 |
* @param array $parameters connection parameters
|
897 |
*/
|
898 |
+
return apply_filters(
|
899 |
+
'wc_facebook_connection_parameters',
|
900 |
+
array(
|
901 |
+
'client_id' => $this->get_client_id(),
|
902 |
+
'redirect_uri' => $this->get_proxy_url(),
|
903 |
+
'state' => $state,
|
904 |
+
'display' => 'page',
|
905 |
+
'response_type' => 'code',
|
906 |
+
'scope' => implode( ',', $this->get_scopes() ),
|
907 |
+
'extras' => json_encode( $this->get_connect_parameters_extras() ),
|
908 |
+
)
|
909 |
+
);
|
910 |
}
|
911 |
|
912 |
|
921 |
*/
|
922 |
private function get_connect_parameters_extras() {
|
923 |
|
924 |
+
$parameters = array(
|
925 |
+
'setup' => array(
|
926 |
'external_business_id' => $this->get_external_business_id(),
|
927 |
'timezone' => $this->get_timezone_string(),
|
928 |
'currency' => get_woocommerce_currency(),
|
929 |
'business_vertical' => 'ECOMMERCE',
|
930 |
'domain' => home_url(),
|
931 |
'channel' => 'COMMERCE_OFFSITE',
|
932 |
+
),
|
933 |
+
'business_config' => array(
|
934 |
+
'business' => array(
|
935 |
'name' => $this->get_business_name(),
|
936 |
+
),
|
937 |
+
),
|
938 |
+
'repeat' => false,
|
939 |
+
);
|
940 |
|
941 |
if ( $external_merchant_settings_id = facebook_for_woocommerce()->get_integration()->get_external_merchant_settings_id() ) {
|
942 |
$parameters['setup']['merchant_settings_id'] = $external_merchant_settings_id;
|
945 |
// if messenger was previously enabled
|
946 |
if ( facebook_for_woocommerce()->get_integration()->is_messenger_enabled() ) {
|
947 |
|
948 |
+
$parameters['business_config']['messenger_chat'] = array(
|
949 |
'enabled' => true,
|
950 |
+
'domains' => array(
|
951 |
home_url( '/' ),
|
952 |
+
),
|
953 |
+
);
|
954 |
}
|
955 |
|
956 |
return $parameters;
|
1395 |
|
1396 |
if ( empty( $_REQUEST['success'] ) ) { //phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
1397 |
|
1398 |
+
$url_params = array(
|
1399 |
'store_url' => '',
|
1400 |
'redirect_uri' => rawurlencode( $redirect_uri ),
|
1401 |
+
'errors' => array( 'You need to grant access to WooCommerce.' ),
|
1402 |
+
);
|
1403 |
|
1404 |
$redirect_url = add_query_arg(
|
1405 |
$url_params,
|
includes/Integrations/Bookings.php
CHANGED
@@ -27,7 +27,7 @@ class Bookings {
|
|
27 |
*/
|
28 |
public function __construct() {
|
29 |
|
30 |
-
add_action( 'init',
|
31 |
}
|
32 |
|
33 |
|
@@ -38,8 +38,8 @@ class Bookings {
|
|
38 |
*/
|
39 |
public function add_hooks() {
|
40 |
|
41 |
-
if ( facebook_for_woocommerce()->is_plugin_active( 'woocommerce-bookings.php') ) {
|
42 |
-
add_filter( 'wc_facebook_product_price',
|
43 |
}
|
44 |
}
|
45 |
|
@@ -51,8 +51,8 @@ class Bookings {
|
|
51 |
*
|
52 |
* @since 2.0.0-dev.3
|
53 |
*
|
54 |
-
* @param int
|
55 |
-
* @param float
|
56 |
* @param \WC_Product $product product object
|
57 |
* @return int
|
58 |
*/
|
@@ -61,9 +61,9 @@ class Bookings {
|
|
61 |
if ( ! $facebook_price && $product instanceof \WC_Product && $this->is_bookable_product( $product ) ) {
|
62 |
|
63 |
$product = new \WC_Product_Booking( $product );
|
64 |
-
$display_cost = is_callable(
|
65 |
|
66 |
-
$price = (int) round( wc_get_price_to_display( $product,
|
67 |
}
|
68 |
|
69 |
return $price;
|
27 |
*/
|
28 |
public function __construct() {
|
29 |
|
30 |
+
add_action( 'init', array( $this, 'add_hooks' ) );
|
31 |
}
|
32 |
|
33 |
|
38 |
*/
|
39 |
public function add_hooks() {
|
40 |
|
41 |
+
if ( facebook_for_woocommerce()->is_plugin_active( 'woocommerce-bookings.php' ) ) {
|
42 |
+
add_filter( 'wc_facebook_product_price', array( $this, 'get_product_price' ), 10, 3 );
|
43 |
}
|
44 |
}
|
45 |
|
51 |
*
|
52 |
* @since 2.0.0-dev.3
|
53 |
*
|
54 |
+
* @param int $price product price in cents
|
55 |
+
* @param float $facebook_price user defined facebook price
|
56 |
* @param \WC_Product $product product object
|
57 |
* @return int
|
58 |
*/
|
61 |
if ( ! $facebook_price && $product instanceof \WC_Product && $this->is_bookable_product( $product ) ) {
|
62 |
|
63 |
$product = new \WC_Product_Booking( $product );
|
64 |
+
$display_cost = is_callable( array( $product, 'get_display_cost' ) ) ? $product->get_display_cost() : 0;
|
65 |
|
66 |
+
$price = (int) round( wc_get_price_to_display( $product, array( 'price' => $display_cost ) ) * 100 );
|
67 |
}
|
68 |
|
69 |
return $price;
|
includes/Integrations/Integrations.php
CHANGED
@@ -51,10 +51,10 @@ class Integrations {
|
|
51 |
*/
|
52 |
private function load_integrations() {
|
53 |
|
54 |
-
$registered_integrations =
|
55 |
'WC_Facebook_WPML_Injector' => '/includes/fbwpml.php',
|
56 |
Bookings::class => '/includes/Integrations/Bookings.php',
|
57 |
-
|
58 |
|
59 |
foreach ( $registered_integrations as $class_name => $path ) {
|
60 |
|
51 |
*/
|
52 |
private function load_integrations() {
|
53 |
|
54 |
+
$registered_integrations = array(
|
55 |
'WC_Facebook_WPML_Injector' => '/includes/fbwpml.php',
|
56 |
Bookings::class => '/includes/Integrations/Bookings.php',
|
57 |
+
);
|
58 |
|
59 |
foreach ( $registered_integrations as $class_name => $path ) {
|
60 |
|
includes/Jobs/AbstractChainedJob.php
ADDED
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace SkyVerge\WooCommerce\Facebook\Jobs;
|
4 |
+
|
5 |
+
use Automattic\WooCommerce\ActionSchedulerJobFramework\AbstractChainedJob as FrameworkAbstractChainedJob;
|
6 |
+
use Exception;
|
7 |
+
|
8 |
+
defined( 'ABSPATH' ) || exit;
|
9 |
+
|
10 |
+
/**
|
11 |
+
* Class AbstractChainedJob
|
12 |
+
*
|
13 |
+
* @since 2.5.0
|
14 |
+
*/
|
15 |
+
abstract class AbstractChainedJob extends FrameworkAbstractChainedJob {
|
16 |
+
|
17 |
+
/**
|
18 |
+
* Handle processing a chain batch.
|
19 |
+
*
|
20 |
+
* @hooked {plugin_name}/jobs/{job_name}/chain_batch
|
21 |
+
*
|
22 |
+
* @param int $batch_number The batch number for the new batch.
|
23 |
+
* @param array $args The args for the job.
|
24 |
+
*
|
25 |
+
* @throws Exception On error. The failure will be logged by Action Scheduler and the job chain will stop.
|
26 |
+
*/
|
27 |
+
public function handle_batch_action( int $batch_number, array $args ) {
|
28 |
+
// Use the profile logger to log the usage of each job batch
|
29 |
+
$logger = facebook_for_woocommerce()->get_profiling_logger();
|
30 |
+
$process_name = $this->get_name() . '_job';
|
31 |
+
|
32 |
+
$logger->start( $process_name );
|
33 |
+
|
34 |
+
parent::handle_batch_action( $batch_number, $args );
|
35 |
+
|
36 |
+
$logger->stop( $process_name );
|
37 |
+
}
|
38 |
+
|
39 |
+
}
|
includes/Jobs/GenerateProductFeed.php
ADDED
@@ -0,0 +1,145 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace SkyVerge\WooCommerce\Facebook\Jobs;
|
4 |
+
|
5 |
+
use Automattic\WooCommerce\ActionSchedulerJobFramework\Utilities\BatchQueryOffset;
|
6 |
+
use Exception;
|
7 |
+
use WC_Facebookcommerce;
|
8 |
+
use WC_Product;
|
9 |
+
|
10 |
+
defined( 'ABSPATH' ) || exit;
|
11 |
+
|
12 |
+
/**
|
13 |
+
* Class GenerateProductFeed
|
14 |
+
*
|
15 |
+
* @since 2.5.0
|
16 |
+
*/
|
17 |
+
class GenerateProductFeed extends AbstractChainedJob {
|
18 |
+
|
19 |
+
use BatchQueryOffset, LoggingTrait;
|
20 |
+
|
21 |
+
/**
|
22 |
+
* Called before starting the job.
|
23 |
+
*/
|
24 |
+
protected function handle_start() {
|
25 |
+
// Optionally override this method in child class.
|
26 |
+
}
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Called after the finishing the job.
|
30 |
+
*/
|
31 |
+
protected function handle_end() {
|
32 |
+
// Optionally override this method in child class.
|
33 |
+
}
|
34 |
+
|
35 |
+
/**
|
36 |
+
* Get a set of items for the batch.
|
37 |
+
*
|
38 |
+
* NOTE: when using an OFFSET based query to retrieve items it's recommended to order by the item ID while
|
39 |
+
* ASCENDING. This is so that any newly added items will not disrupt the query offset.
|
40 |
+
*
|
41 |
+
* @param int $batch_number The batch number increments for each new batch in the job cycle.
|
42 |
+
* @param array $args The args for the job.
|
43 |
+
*
|
44 |
+
* @throws Exception On error. The failure will be logged by Action Scheduler and the job chain will stop.
|
45 |
+
*/
|
46 |
+
protected function get_items_for_batch( int $batch_number, array $args ): array {
|
47 |
+
global $wpdb;
|
48 |
+
|
49 |
+
$product_ids = $wpdb->get_col(
|
50 |
+
$wpdb->prepare(
|
51 |
+
"SELECT post.ID
|
52 |
+
FROM wp_posts as post
|
53 |
+
LEFT JOIN wp_posts as parent ON post.post_parent = parent.ID
|
54 |
+
WHERE
|
55 |
+
( post.post_type = 'product_variation' AND parent.post_status = 'publish' )
|
56 |
+
OR
|
57 |
+
( post.post_type = 'product' AND post.post_status = 'publish' )
|
58 |
+
ORDER BY post.ID ASC
|
59 |
+
LIMIT %d OFFSET %d",
|
60 |
+
$this->get_batch_size(),
|
61 |
+
$this->get_query_offset( $batch_number )
|
62 |
+
)
|
63 |
+
);
|
64 |
+
|
65 |
+
return array_map( 'intval', $product_ids );
|
66 |
+
}
|
67 |
+
|
68 |
+
/**
|
69 |
+
* Filter-like function that runs before items in a batch are processed.
|
70 |
+
*
|
71 |
+
* For example, this could be useful for pre-fetching full objects.
|
72 |
+
*
|
73 |
+
* @param array $items
|
74 |
+
*
|
75 |
+
* @return array
|
76 |
+
*/
|
77 |
+
protected function filter_items_before_processing( array $items ): array {
|
78 |
+
// Pre-fetch full product objects.
|
79 |
+
// Variable products will be filtered out here since we don't need them for the feed. It's important to not
|
80 |
+
// filter out variable products in ::get_items_for_batch() because if a batch only contains variable products
|
81 |
+
// the job will end prematurely thinking it has nothing more to process.
|
82 |
+
return wc_get_products(
|
83 |
+
[
|
84 |
+
'type' => [ 'simple', 'variation' ],
|
85 |
+
'include' => $items,
|
86 |
+
'orderby' => 'none',
|
87 |
+
]
|
88 |
+
);
|
89 |
+
}
|
90 |
+
|
91 |
+
/**
|
92 |
+
* Process a single item.
|
93 |
+
*
|
94 |
+
* @param WC_Product $product A single item from the get_items_for_batch() method.
|
95 |
+
* @param array $args The args for the job.
|
96 |
+
*
|
97 |
+
* @throws Exception On error. The failure will be logged by Action Scheduler and the job chain will stop.
|
98 |
+
*/
|
99 |
+
protected function process_item( $product, array $args ) {
|
100 |
+
try {
|
101 |
+
if ( ! $product ) {
|
102 |
+
throw new Exception( 'Product not found.' );
|
103 |
+
}
|
104 |
+
|
105 |
+
$this->log( $product->get_id() );
|
106 |
+
|
107 |
+
} catch ( Exception $e ) {
|
108 |
+
$this->log(
|
109 |
+
sprintf(
|
110 |
+
'Error processing item #%d - %s',
|
111 |
+
$product instanceof WC_Product ? $product->get_id() : 0,
|
112 |
+
$e->getMessage()
|
113 |
+
)
|
114 |
+
);
|
115 |
+
}
|
116 |
+
}
|
117 |
+
|
118 |
+
/**
|
119 |
+
* Get the name/slug of the job.
|
120 |
+
*
|
121 |
+
* @return string
|
122 |
+
*/
|
123 |
+
public function get_name(): string {
|
124 |
+
return 'generate_feed';
|
125 |
+
}
|
126 |
+
|
127 |
+
/**
|
128 |
+
* Get the name/slug of the plugin that owns the job.
|
129 |
+
*
|
130 |
+
* @return string
|
131 |
+
*/
|
132 |
+
public function get_plugin_name(): string {
|
133 |
+
return WC_Facebookcommerce::PLUGIN_ID;
|
134 |
+
}
|
135 |
+
|
136 |
+
/**
|
137 |
+
* Get the job's batch size.
|
138 |
+
*
|
139 |
+
* @return int
|
140 |
+
*/
|
141 |
+
protected function get_batch_size(): int {
|
142 |
+
return 15;
|
143 |
+
}
|
144 |
+
|
145 |
+
}
|
includes/Jobs/JobRegistry.php
ADDED
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace SkyVerge\WooCommerce\Facebook\Jobs;
|
4 |
+
|
5 |
+
use Automattic\WooCommerce\ActionSchedulerJobFramework\Proxies\ActionScheduler;
|
6 |
+
|
7 |
+
defined( 'ABSPATH' ) || exit;
|
8 |
+
|
9 |
+
/**
|
10 |
+
* Class JobRegistry
|
11 |
+
*
|
12 |
+
* @since 2.5.0
|
13 |
+
*/
|
14 |
+
class JobRegistry {
|
15 |
+
|
16 |
+
/**
|
17 |
+
* @var GenerateProductFeed
|
18 |
+
*/
|
19 |
+
public $generate_product_feed_job;
|
20 |
+
|
21 |
+
/**
|
22 |
+
* Instantiate and init all jobs for the plugin.
|
23 |
+
*/
|
24 |
+
public function init() {
|
25 |
+
$action_scheduler_proxy = new ActionScheduler();
|
26 |
+
|
27 |
+
$this->generate_product_feed_job = new GenerateProductFeed( $action_scheduler_proxy );
|
28 |
+
$this->generate_product_feed_job->init();
|
29 |
+
}
|
30 |
+
|
31 |
+
}
|
includes/Jobs/LoggingTrait.php
ADDED
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace SkyVerge\WooCommerce\Facebook\Jobs;
|
4 |
+
|
5 |
+
use WC_Facebookcommerce;
|
6 |
+
|
7 |
+
defined( 'ABSPATH' ) || exit;
|
8 |
+
|
9 |
+
/**
|
10 |
+
* Trait LoggingTrait
|
11 |
+
*
|
12 |
+
* Logging helper trait for jobs.
|
13 |
+
*
|
14 |
+
* @since 2.5.0
|
15 |
+
*/
|
16 |
+
trait LoggingTrait {
|
17 |
+
|
18 |
+
/**
|
19 |
+
* Get the name/slug of the job.
|
20 |
+
*
|
21 |
+
* @return string
|
22 |
+
*/
|
23 |
+
abstract public function get_name(): string;
|
24 |
+
|
25 |
+
/**
|
26 |
+
* Write a log entry using the plugin's logger.
|
27 |
+
*
|
28 |
+
* @param string $message
|
29 |
+
*/
|
30 |
+
protected function log( string $message ) {
|
31 |
+
facebook_for_woocommerce()->log(
|
32 |
+
$message,
|
33 |
+
sprintf( '%s_%s', WC_Facebookcommerce::PLUGIN_ID, $this->get_name() )
|
34 |
+
);
|
35 |
+
}
|
36 |
+
|
37 |
+
|
38 |
+
}
|
includes/Lifecycle.php
CHANGED
@@ -35,7 +35,7 @@ class Lifecycle extends Framework\Plugin\Lifecycle {
|
|
35 |
|
36 |
parent::__construct( $plugin );
|
37 |
|
38 |
-
$this->upgrade_versions =
|
39 |
'1.10.0',
|
40 |
'1.10.1',
|
41 |
'1.11.0',
|
@@ -43,7 +43,8 @@ class Lifecycle extends Framework\Plugin\Lifecycle {
|
|
43 |
'2.0.3',
|
44 |
'2.0.4',
|
45 |
'2.4.0',
|
46 |
-
|
|
|
47 |
}
|
48 |
|
49 |
|
@@ -86,7 +87,7 @@ class Lifecycle extends Framework\Plugin\Lifecycle {
|
|
86 |
*/
|
87 |
private function migrate_1_9_settings() {
|
88 |
|
89 |
-
$values = get_option( 'woocommerce_facebookcommerce_settings',
|
90 |
|
91 |
// preserve legacy values
|
92 |
if ( false === get_option( 'woocommerce_facebookcommerce_legacy_settings' ) ) {
|
@@ -94,14 +95,14 @@ class Lifecycle extends Framework\Plugin\Lifecycle {
|
|
94 |
}
|
95 |
|
96 |
// migrate options from woocommerce_facebookcommerce_settings
|
97 |
-
$options =
|
98 |
'fb_api_key' => \WC_Facebookcommerce_Integration::OPTION_PAGE_ACCESS_TOKEN,
|
99 |
'fb_product_catalog_id' => \WC_Facebookcommerce_Integration::OPTION_PRODUCT_CATALOG_ID,
|
100 |
'fb_external_merchant_settings_id' => \WC_Facebookcommerce_Integration::OPTION_EXTERNAL_MERCHANT_SETTINGS_ID,
|
101 |
'fb_feed_id' => \WC_Facebookcommerce_Integration::OPTION_FEED_ID,
|
102 |
'facebook_jssdk_version' => \WC_Facebookcommerce_Integration::OPTION_JS_SDK_VERSION,
|
103 |
'pixel_install_time' => \WC_Facebookcommerce_Integration::OPTION_PIXEL_INSTALL_TIME,
|
104 |
-
|
105 |
|
106 |
foreach ( $options as $old_index => $new_option_name ) {
|
107 |
|
@@ -125,10 +126,10 @@ class Lifecycle extends Framework\Plugin\Lifecycle {
|
|
125 |
}
|
126 |
}
|
127 |
|
128 |
-
$new_settings = get_option( 'woocommerce_' . \WC_Facebookcommerce::INTEGRATION_ID . '_settings',
|
129 |
|
130 |
// migrate settings from woocommerce_facebookcommerce_settings
|
131 |
-
$settings =
|
132 |
'fb_page_id' => \WC_Facebookcommerce_Integration::SETTING_FACEBOOK_PAGE_ID,
|
133 |
'fb_pixel_id' => \WC_Facebookcommerce_Integration::SETTING_FACEBOOK_PIXEL_ID,
|
134 |
'fb_pixel_use_pii' => \WC_Facebookcommerce_Integration::SETTING_ENABLE_ADVANCED_MATCHING,
|
@@ -136,7 +137,7 @@ class Lifecycle extends Framework\Plugin\Lifecycle {
|
|
136 |
'msger_chat_customization_locale' => \WC_Facebookcommerce_Integration::SETTING_MESSENGER_LOCALE,
|
137 |
'msger_chat_customization_greeting_text_code' => \WC_Facebookcommerce_Integration::SETTING_MESSENGER_GREETING,
|
138 |
'msger_chat_customization_theme_color_code' => \WC_Facebookcommerce_Integration::SETTING_MESSENGER_COLOR_HEX,
|
139 |
-
|
140 |
|
141 |
foreach ( $settings as $old_index => $new_index ) {
|
142 |
|
@@ -174,7 +175,7 @@ class Lifecycle extends Framework\Plugin\Lifecycle {
|
|
174 |
}
|
175 |
|
176 |
// maybe remove old settings entries
|
177 |
-
$old_indexes = array_merge( array_keys( $options ), array_keys( $settings ),
|
178 |
|
179 |
foreach ( $old_indexes as $old_index ) {
|
180 |
unset( $new_settings[ $old_index ] );
|
@@ -212,7 +213,7 @@ class Lifecycle extends Framework\Plugin\Lifecycle {
|
|
212 |
*/
|
213 |
protected function upgrade_to_1_11_0() {
|
214 |
|
215 |
-
$settings = get_option( 'woocommerce_' . \WC_Facebookcommerce::INTEGRATION_ID . '_settings',
|
216 |
|
217 |
// moves the upload ID to a standalone option
|
218 |
if ( ! empty( $settings['fb_upload_id'] ) ) {
|
@@ -232,7 +233,7 @@ class Lifecycle extends Framework\Plugin\Lifecycle {
|
|
232 |
if ( $handler = $this->get_plugin()->get_background_handle_virtual_products_variations_instance() ) {
|
233 |
|
234 |
// create_job() expects an non-empty array of attributes
|
235 |
-
$handler->create_job(
|
236 |
$handler->dispatch();
|
237 |
}
|
238 |
|
@@ -242,7 +243,7 @@ class Lifecycle extends Framework\Plugin\Lifecycle {
|
|
242 |
|
243 |
if ( is_array( $settings ) ) {
|
244 |
|
245 |
-
$settings_map =
|
246 |
'facebook_pixel_id' => \WC_Facebookcommerce_Integration::SETTING_FACEBOOK_PIXEL_ID,
|
247 |
'facebook_page_id' => \WC_Facebookcommerce_Integration::SETTING_FACEBOOK_PAGE_ID,
|
248 |
'enable_product_sync' => \WC_Facebookcommerce_Integration::SETTING_ENABLE_PRODUCT_SYNC,
|
@@ -254,7 +255,7 @@ class Lifecycle extends Framework\Plugin\Lifecycle {
|
|
254 |
'messenger_greeting' => \WC_Facebookcommerce_Integration::SETTING_MESSENGER_GREETING,
|
255 |
'messenger_color_hex' => \WC_Facebookcommerce_Integration::SETTING_MESSENGER_COLOR_HEX,
|
256 |
'enable_debug_mode' => \WC_Facebookcommerce_Integration::SETTING_ENABLE_DEBUG_MODE,
|
257 |
-
|
258 |
|
259 |
foreach ( $settings_map as $old_name => $new_name ) {
|
260 |
|
@@ -289,7 +290,7 @@ class Lifecycle extends Framework\Plugin\Lifecycle {
|
|
289 |
if ( $handler = $this->get_plugin()->get_background_remove_duplicate_visibility_meta_instance() ) {
|
290 |
|
291 |
// create_job() expects an non-empty array of attributes
|
292 |
-
$handler->create_job(
|
293 |
$handler->dispatch();
|
294 |
}
|
295 |
}
|
@@ -347,4 +348,18 @@ class Lifecycle extends Framework\Plugin\Lifecycle {
|
|
347 |
delete_transient( 'wc_facebook_google_product_categories' );
|
348 |
}
|
349 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
350 |
}
|
35 |
|
36 |
parent::__construct( $plugin );
|
37 |
|
38 |
+
$this->upgrade_versions = array(
|
39 |
'1.10.0',
|
40 |
'1.10.1',
|
41 |
'1.11.0',
|
43 |
'2.0.3',
|
44 |
'2.0.4',
|
45 |
'2.4.0',
|
46 |
+
'2.5.0',
|
47 |
+
);
|
48 |
}
|
49 |
|
50 |
|
87 |
*/
|
88 |
private function migrate_1_9_settings() {
|
89 |
|
90 |
+
$values = get_option( 'woocommerce_facebookcommerce_settings', array() );
|
91 |
|
92 |
// preserve legacy values
|
93 |
if ( false === get_option( 'woocommerce_facebookcommerce_legacy_settings' ) ) {
|
95 |
}
|
96 |
|
97 |
// migrate options from woocommerce_facebookcommerce_settings
|
98 |
+
$options = array(
|
99 |
'fb_api_key' => \WC_Facebookcommerce_Integration::OPTION_PAGE_ACCESS_TOKEN,
|
100 |
'fb_product_catalog_id' => \WC_Facebookcommerce_Integration::OPTION_PRODUCT_CATALOG_ID,
|
101 |
'fb_external_merchant_settings_id' => \WC_Facebookcommerce_Integration::OPTION_EXTERNAL_MERCHANT_SETTINGS_ID,
|
102 |
'fb_feed_id' => \WC_Facebookcommerce_Integration::OPTION_FEED_ID,
|
103 |
'facebook_jssdk_version' => \WC_Facebookcommerce_Integration::OPTION_JS_SDK_VERSION,
|
104 |
'pixel_install_time' => \WC_Facebookcommerce_Integration::OPTION_PIXEL_INSTALL_TIME,
|
105 |
+
);
|
106 |
|
107 |
foreach ( $options as $old_index => $new_option_name ) {
|
108 |
|
126 |
}
|
127 |
}
|
128 |
|
129 |
+
$new_settings = get_option( 'woocommerce_' . \WC_Facebookcommerce::INTEGRATION_ID . '_settings', array() );
|
130 |
|
131 |
// migrate settings from woocommerce_facebookcommerce_settings
|
132 |
+
$settings = array(
|
133 |
'fb_page_id' => \WC_Facebookcommerce_Integration::SETTING_FACEBOOK_PAGE_ID,
|
134 |
'fb_pixel_id' => \WC_Facebookcommerce_Integration::SETTING_FACEBOOK_PIXEL_ID,
|
135 |
'fb_pixel_use_pii' => \WC_Facebookcommerce_Integration::SETTING_ENABLE_ADVANCED_MATCHING,
|
137 |
'msger_chat_customization_locale' => \WC_Facebookcommerce_Integration::SETTING_MESSENGER_LOCALE,
|
138 |
'msger_chat_customization_greeting_text_code' => \WC_Facebookcommerce_Integration::SETTING_MESSENGER_GREETING,
|
139 |
'msger_chat_customization_theme_color_code' => \WC_Facebookcommerce_Integration::SETTING_MESSENGER_COLOR_HEX,
|
140 |
+
);
|
141 |
|
142 |
foreach ( $settings as $old_index => $new_index ) {
|
143 |
|
175 |
}
|
176 |
|
177 |
// maybe remove old settings entries
|
178 |
+
$old_indexes = array_merge( array_keys( $options ), array_keys( $settings ), array( 'fb_settings_heading', 'fb_upload_id', 'upload_end_time' ) );
|
179 |
|
180 |
foreach ( $old_indexes as $old_index ) {
|
181 |
unset( $new_settings[ $old_index ] );
|
213 |
*/
|
214 |
protected function upgrade_to_1_11_0() {
|
215 |
|
216 |
+
$settings = get_option( 'woocommerce_' . \WC_Facebookcommerce::INTEGRATION_ID . '_settings', array() );
|
217 |
|
218 |
// moves the upload ID to a standalone option
|
219 |
if ( ! empty( $settings['fb_upload_id'] ) ) {
|
233 |
if ( $handler = $this->get_plugin()->get_background_handle_virtual_products_variations_instance() ) {
|
234 |
|
235 |
// create_job() expects an non-empty array of attributes
|
236 |
+
$handler->create_job( array( 'created_at' => current_time( 'mysql' ) ) );
|
237 |
$handler->dispatch();
|
238 |
}
|
239 |
|
243 |
|
244 |
if ( is_array( $settings ) ) {
|
245 |
|
246 |
+
$settings_map = array(
|
247 |
'facebook_pixel_id' => \WC_Facebookcommerce_Integration::SETTING_FACEBOOK_PIXEL_ID,
|
248 |
'facebook_page_id' => \WC_Facebookcommerce_Integration::SETTING_FACEBOOK_PAGE_ID,
|
249 |
'enable_product_sync' => \WC_Facebookcommerce_Integration::SETTING_ENABLE_PRODUCT_SYNC,
|
255 |
'messenger_greeting' => \WC_Facebookcommerce_Integration::SETTING_MESSENGER_GREETING,
|
256 |
'messenger_color_hex' => \WC_Facebookcommerce_Integration::SETTING_MESSENGER_COLOR_HEX,
|
257 |
'enable_debug_mode' => \WC_Facebookcommerce_Integration::SETTING_ENABLE_DEBUG_MODE,
|
258 |
+
);
|
259 |
|
260 |
foreach ( $settings_map as $old_name => $new_name ) {
|
261 |
|
290 |
if ( $handler = $this->get_plugin()->get_background_remove_duplicate_visibility_meta_instance() ) {
|
291 |
|
292 |
// create_job() expects an non-empty array of attributes
|
293 |
+
$handler->create_job( array( 'created_at' => current_time( 'mysql' ) ) );
|
294 |
$handler->dispatch();
|
295 |
}
|
296 |
}
|
348 |
delete_transient( 'wc_facebook_google_product_categories' );
|
349 |
}
|
350 |
|
351 |
+
/**
|
352 |
+
* Upgrades to version 2.5.0
|
353 |
+
*
|
354 |
+
* @since 2.5.0
|
355 |
+
*/
|
356 |
+
protected function upgrade_to_2_5_0() {
|
357 |
+
/**
|
358 |
+
* Since 2.5.0 the feed generation interval is increased to 24h.
|
359 |
+
* Update procedure just needs to remove all current actions.
|
360 |
+
* The Feed class will reschedule new generation with proper cadence.
|
361 |
+
*/
|
362 |
+
as_unschedule_all_actions( \SkyVerge\WooCommerce\Facebook\Products\Feed::GENERATE_FEED_ACTION );
|
363 |
+
}
|
364 |
+
|
365 |
}
|
includes/Locale.php
CHANGED
@@ -25,7 +25,7 @@ class Locale {
|
|
25 |
|
26 |
|
27 |
/** @var string[] an array of supported locale identifiers */
|
28 |
-
private static $supported_locales =
|
29 |
'af_ZA',
|
30 |
'ar_AR',
|
31 |
'as_IN',
|
@@ -128,7 +128,7 @@ class Locale {
|
|
128 |
'zh_CN',
|
129 |
'zh_HK',
|
130 |
'zh_TW',
|
131 |
-
|
132 |
|
133 |
|
134 |
/**
|
@@ -143,7 +143,7 @@ class Locale {
|
|
143 |
*/
|
144 |
public static function get_supported_locales() {
|
145 |
|
146 |
-
$locales =
|
147 |
|
148 |
if ( class_exists( 'Locale' ) ) {
|
149 |
|
@@ -154,10 +154,9 @@ class Locale {
|
|
154 |
$locales[ $locale ] = ucfirst( $name );
|
155 |
}
|
156 |
}
|
157 |
-
|
158 |
} else {
|
159 |
|
160 |
-
include_once
|
161 |
|
162 |
$translations = wp_get_available_translations();
|
163 |
|
25 |
|
26 |
|
27 |
/** @var string[] an array of supported locale identifiers */
|
28 |
+
private static $supported_locales = array(
|
29 |
'af_ZA',
|
30 |
'ar_AR',
|
31 |
'as_IN',
|
128 |
'zh_CN',
|
129 |
'zh_HK',
|
130 |
'zh_TW',
|
131 |
+
);
|
132 |
|
133 |
|
134 |
/**
|
143 |
*/
|
144 |
public static function get_supported_locales() {
|
145 |
|
146 |
+
$locales = array();
|
147 |
|
148 |
if ( class_exists( 'Locale' ) ) {
|
149 |
|
154 |
$locales[ $locale ] = ucfirst( $name );
|
155 |
}
|
156 |
}
|
|
|
157 |
} else {
|
158 |
|
159 |
+
include_once ABSPATH . '/wp-admin/includes/translation-install.php';
|
160 |
|
161 |
$translations = wp_get_available_translations();
|
162 |
|
includes/ProductSets/Sync.php
CHANGED
@@ -385,8 +385,8 @@ class Sync {
|
|
385 |
}
|
386 |
|
387 |
$data = array(
|
388 |
-
'name'
|
389 |
-
'filter'
|
390 |
'metadata' => wp_json_encode( array( 'description' => $term->description ) ),
|
391 |
);
|
392 |
|
385 |
}
|
386 |
|
387 |
$data = array(
|
388 |
+
'name' => $term->name,
|
389 |
+
'filter' => wp_json_encode( array( 'or' => $products ) ),
|
390 |
'metadata' => wp_json_encode( array( 'description' => $term->description ) ),
|
391 |
);
|
392 |
|
includes/Product_Categories.php
CHANGED
@@ -41,7 +41,7 @@ class Product_Categories {
|
|
41 |
*
|
42 |
* @since 2.2.0
|
43 |
*
|
44 |
-
* @param int
|
45 |
* @param string $category_id Google product category ID
|
46 |
*/
|
47 |
public static function update_google_product_category_id( $id, $category_id ) {
|
41 |
*
|
42 |
* @since 2.2.0
|
43 |
*
|
44 |
+
* @param int $id category ID
|
45 |
* @param string $category_id Google product category ID
|
46 |
*/
|
47 |
public static function update_google_product_category_id( $id, $category_id ) {
|
includes/Products.php
CHANGED
@@ -431,11 +431,11 @@ class Products {
|
|
431 |
$price = get_option( 'woocommerce_tax_display_shop' ) === 'incl' ? $product->get_composite_price_including_tax() : $product->get_composite_price();
|
432 |
|
433 |
} elseif ( class_exists( 'WC_Product_Bundle' )
|
434 |
-
|
435 |
-
|
436 |
|
437 |
// if product is a product bundle with individually priced items, we rely on their pricing
|
438 |
-
$price = wc_get_price_to_display( $product,
|
439 |
|
440 |
} else {
|
441 |
|
@@ -1132,8 +1132,8 @@ class Products {
|
|
1132 |
// Check normal product attributes
|
1133 |
foreach ( $product->get_attributes() as $slug => $attribute ) {
|
1134 |
if ( $product->is_type( 'variation' ) ) {
|
1135 |
-
$attr_name
|
1136 |
-
$attr_val
|
1137 |
} else {
|
1138 |
$attr_name = $attribute->get_name();
|
1139 |
$attr_val = $product->get_attribute( $slug );
|
@@ -1202,12 +1202,12 @@ class Products {
|
|
1202 |
function( $attrs, $attr_key ) use ( $prefix ) {
|
1203 |
return array_merge(
|
1204 |
$attrs,
|
1205 |
-
|
1206 |
str_replace( $prefix, '', $attr_key ) => wc_clean( Framework\SV_WC_Helper::get_posted_value( $attr_key ) ),
|
1207 |
-
|
1208 |
);
|
1209 |
},
|
1210 |
-
|
1211 |
);
|
1212 |
}
|
1213 |
|
431 |
$price = get_option( 'woocommerce_tax_display_shop' ) === 'incl' ? $product->get_composite_price_including_tax() : $product->get_composite_price();
|
432 |
|
433 |
} elseif ( class_exists( 'WC_Product_Bundle' )
|
434 |
+
&& empty( $product->get_regular_price() )
|
435 |
+
&& 'bundle' === $product->get_type() ) {
|
436 |
|
437 |
// if product is a product bundle with individually priced items, we rely on their pricing
|
438 |
+
$price = wc_get_price_to_display( $product, array( 'price' => $product->get_bundle_price() ) );
|
439 |
|
440 |
} else {
|
441 |
|
1132 |
// Check normal product attributes
|
1133 |
foreach ( $product->get_attributes() as $slug => $attribute ) {
|
1134 |
if ( $product->is_type( 'variation' ) ) {
|
1135 |
+
$attr_name = $slug;
|
1136 |
+
$attr_val = \WC_Facebookcommerce_Utils::get_variant_option_name( $product_id, 'attribute_' . $slug, $attribute );
|
1137 |
} else {
|
1138 |
$attr_name = $attribute->get_name();
|
1139 |
$attr_val = $product->get_attribute( $slug );
|
1202 |
function( $attrs, $attr_key ) use ( $prefix ) {
|
1203 |
return array_merge(
|
1204 |
$attrs,
|
1205 |
+
array(
|
1206 |
str_replace( $prefix, '', $attr_key ) => wc_clean( Framework\SV_WC_Helper::get_posted_value( $attr_key ) ),
|
1207 |
+
)
|
1208 |
);
|
1209 |
},
|
1210 |
+
array()
|
1211 |
);
|
1212 |
}
|
1213 |
|
includes/Products/FBCategories.php
CHANGED
@@ -232,7 +232,7 @@ class FBCategories {
|
|
232 |
if ( $contents ) {
|
233 |
$data = json_decode( $contents, true );
|
234 |
} else {
|
235 |
-
$data =
|
236 |
facebook_for_woocommerce()->log( 'Error reading category attributes JSON data.' );
|
237 |
}
|
238 |
}
|
@@ -253,7 +253,7 @@ class FBCategories {
|
|
253 |
if ( $contents ) {
|
254 |
$data = json_decode( $contents, true );
|
255 |
} else {
|
256 |
-
$data =
|
257 |
facebook_for_woocommerce()->log( 'Error reading category attributes fields JSON data.' );
|
258 |
}
|
259 |
}
|
232 |
if ( $contents ) {
|
233 |
$data = json_decode( $contents, true );
|
234 |
} else {
|
235 |
+
$data = array();
|
236 |
facebook_for_woocommerce()->log( 'Error reading category attributes JSON data.' );
|
237 |
}
|
238 |
}
|
253 |
if ( $contents ) {
|
254 |
$data = json_decode( $contents, true );
|
255 |
} else {
|
256 |
+
$data = array();
|
257 |
facebook_for_woocommerce()->log( 'Error reading category attributes fields JSON data.' );
|
258 |
}
|
259 |
}
|
includes/Products/Feed.php
CHANGED
@@ -54,13 +54,13 @@ class Feed {
|
|
54 |
private function add_hooks() {
|
55 |
|
56 |
// schedule the recurring feed generation
|
57 |
-
add_action( '
|
58 |
|
59 |
// regenerate the product feed
|
60 |
-
add_action( self::GENERATE_FEED_ACTION,
|
61 |
|
62 |
// handle the feed data request
|
63 |
-
add_action( 'woocommerce_api_' . self::REQUEST_FEED_ACTION,
|
64 |
}
|
65 |
|
66 |
|
@@ -86,7 +86,7 @@ class Feed {
|
|
86 |
try {
|
87 |
|
88 |
// bail early if the feed secret is not included or is not valid
|
89 |
-
if (
|
90 |
throw new Framework\SV_WC_Plugin_Exception( 'Invalid feed secret provided.', 401 );
|
91 |
}
|
92 |
|
@@ -102,7 +102,7 @@ class Feed {
|
|
102 |
header( 'Expires: 0' );
|
103 |
header( 'Cache-Control: must-revalidate, post-check=0, pre-check=0' );
|
104 |
header( 'Pragma: public' );
|
105 |
-
header( 'Content-Length:'. filesize( $file_path ) );
|
106 |
|
107 |
$file = @fopen( $file_path, 'rb' );
|
108 |
|
@@ -123,7 +123,6 @@ class Feed {
|
|
123 |
|
124 |
echo $contents;
|
125 |
}
|
126 |
-
|
127 |
} catch ( \Exception $exception ) {
|
128 |
|
129 |
\WC_Facebookcommerce_Utils::log( 'Could not serve product feed. ' . $exception->getMessage() . ' (' . $exception->getCode() . ')' );
|
@@ -158,11 +157,14 @@ class Feed {
|
|
158 |
* @since 1.11.0
|
159 |
*/
|
160 |
public function schedule_feed_generation() {
|
161 |
-
|
162 |
-
$
|
163 |
-
|
164 |
-
//
|
165 |
-
|
|
|
|
|
|
|
166 |
as_unschedule_all_actions( self::GENERATE_FEED_ACTION );
|
167 |
return;
|
168 |
}
|
@@ -171,13 +173,14 @@ class Feed {
|
|
171 |
* Filters the frequency with which the product feed data is generated.
|
172 |
*
|
173 |
* @since 1.11.0
|
|
|
174 |
*
|
175 |
* @param int $interval the frequency with which the product feed data is generated, in seconds. Defaults to every 15 minutes.
|
176 |
*/
|
177 |
-
$interval = apply_filters( 'wc_facebook_feed_generation_interval',
|
178 |
|
179 |
if ( ! as_next_scheduled_action( self::GENERATE_FEED_ACTION ) ) {
|
180 |
-
as_schedule_recurring_action( time(), max( 2, $interval ), self::GENERATE_FEED_ACTION,
|
181 |
}
|
182 |
}
|
183 |
|
@@ -215,10 +218,10 @@ class Feed {
|
|
215 |
*/
|
216 |
public static function get_feed_data_url() {
|
217 |
|
218 |
-
$query_args =
|
219 |
'wc-api' => self::REQUEST_FEED_ACTION,
|
220 |
'secret' => self::get_feed_secret(),
|
221 |
-
|
222 |
|
223 |
return add_query_arg( $query_args, home_url( '/' ) );
|
224 |
}
|
@@ -237,7 +240,7 @@ class Feed {
|
|
237 |
|
238 |
$secret = get_option( self::OPTION_FEED_URL_SECRET, '' );
|
239 |
|
240 |
-
if
|
241 |
|
242 |
$secret = wp_hash( 'products-feed-' . time() );
|
243 |
|
54 |
private function add_hooks() {
|
55 |
|
56 |
// schedule the recurring feed generation
|
57 |
+
add_action( 'admin_init', array( $this, 'schedule_feed_generation' ) );
|
58 |
|
59 |
// regenerate the product feed
|
60 |
+
add_action( self::GENERATE_FEED_ACTION, array( $this, 'regenerate_feed' ) );
|
61 |
|
62 |
// handle the feed data request
|
63 |
+
add_action( 'woocommerce_api_' . self::REQUEST_FEED_ACTION, array( $this, 'handle_feed_data_request' ) );
|
64 |
}
|
65 |
|
66 |
|
86 |
try {
|
87 |
|
88 |
// bail early if the feed secret is not included or is not valid
|
89 |
+
if ( self::get_feed_secret() !== Framework\SV_WC_Helper::get_requested_value( 'secret' ) ) {
|
90 |
throw new Framework\SV_WC_Plugin_Exception( 'Invalid feed secret provided.', 401 );
|
91 |
}
|
92 |
|
102 |
header( 'Expires: 0' );
|
103 |
header( 'Cache-Control: must-revalidate, post-check=0, pre-check=0' );
|
104 |
header( 'Pragma: public' );
|
105 |
+
header( 'Content-Length:' . filesize( $file_path ) );
|
106 |
|
107 |
$file = @fopen( $file_path, 'rb' );
|
108 |
|
123 |
|
124 |
echo $contents;
|
125 |
}
|
|
|
126 |
} catch ( \Exception $exception ) {
|
127 |
|
128 |
\WC_Facebookcommerce_Utils::log( 'Could not serve product feed. ' . $exception->getMessage() . ' (' . $exception->getCode() . ')' );
|
157 |
* @since 1.11.0
|
158 |
*/
|
159 |
public function schedule_feed_generation() {
|
160 |
+
$integration = facebook_for_woocommerce()->get_integration();
|
161 |
+
$configured_ok = $integration && $integration->is_configured();
|
162 |
+
|
163 |
+
// Only schedule feed job if store has not opted out of product sync.
|
164 |
+
$store_allows_sync = $configured_ok && $integration->is_product_sync_enabled();
|
165 |
+
// Only schedule if has not opted out of feed generation (e.g. large stores).
|
166 |
+
$store_allows_feed = $configured_ok && $integration->is_legacy_feed_file_generation_enabled();
|
167 |
+
if ( ! $store_allows_sync || ! $store_allows_feed ) {
|
168 |
as_unschedule_all_actions( self::GENERATE_FEED_ACTION );
|
169 |
return;
|
170 |
}
|
173 |
* Filters the frequency with which the product feed data is generated.
|
174 |
*
|
175 |
* @since 1.11.0
|
176 |
+
* @since 2.5.0 Feed generation interval increased to 24h.
|
177 |
*
|
178 |
* @param int $interval the frequency with which the product feed data is generated, in seconds. Defaults to every 15 minutes.
|
179 |
*/
|
180 |
+
$interval = apply_filters( 'wc_facebook_feed_generation_interval', DAY_IN_SECONDS );
|
181 |
|
182 |
if ( ! as_next_scheduled_action( self::GENERATE_FEED_ACTION ) ) {
|
183 |
+
as_schedule_recurring_action( time(), max( 2, $interval ), self::GENERATE_FEED_ACTION, array(), facebook_for_woocommerce()->get_id_dasherized() );
|
184 |
}
|
185 |
}
|
186 |
|
218 |
*/
|
219 |
public static function get_feed_data_url() {
|
220 |
|
221 |
+
$query_args = array(
|
222 |
'wc-api' => self::REQUEST_FEED_ACTION,
|
223 |
'secret' => self::get_feed_secret(),
|
224 |
+
);
|
225 |
|
226 |
return add_query_arg( $query_args, home_url( '/' ) );
|
227 |
}
|
240 |
|
241 |
$secret = get_option( self::OPTION_FEED_URL_SECRET, '' );
|
242 |
|
243 |
+
if ( ! $secret ) {
|
244 |
|
245 |
$secret = wp_hash( 'products-feed-' . time() );
|
246 |
|
includes/Products/Stock.php
CHANGED
@@ -40,8 +40,8 @@ class Stock {
|
|
40 |
*/
|
41 |
private function add_hooks() {
|
42 |
|
43 |
-
add_action( 'woocommerce_variation_set_stock',
|
44 |
-
add_action( 'woocommerce_product_set_stock',
|
45 |
}
|
46 |
|
47 |
|
@@ -81,12 +81,15 @@ class Stock {
|
|
81 |
|
82 |
if ( $product->is_type( 'variable' ) ) {
|
83 |
|
84 |
-
return array_filter(
|
85 |
-
|
86 |
-
|
|
|
|
|
|
|
87 |
}
|
88 |
|
89 |
-
return
|
90 |
}
|
91 |
|
92 |
|
@@ -103,11 +106,11 @@ class Stock {
|
|
103 |
|
104 |
if ( Products::product_should_be_deleted( $product ) ) {
|
105 |
|
106 |
-
facebook_for_woocommerce()->get_products_sync_handler()->delete_products(
|
107 |
return;
|
108 |
}
|
109 |
|
110 |
-
facebook_for_woocommerce()->get_products_sync_handler()->create_or_update_products(
|
111 |
}
|
112 |
|
113 |
|
40 |
*/
|
41 |
private function add_hooks() {
|
42 |
|
43 |
+
add_action( 'woocommerce_variation_set_stock', array( $this, 'set_product_stock' ) );
|
44 |
+
add_action( 'woocommerce_product_set_stock', array( $this, 'set_product_stock' ) );
|
45 |
}
|
46 |
|
47 |
|
81 |
|
82 |
if ( $product->is_type( 'variable' ) ) {
|
83 |
|
84 |
+
return array_filter(
|
85 |
+
array_map( 'wc_get_product', $product->get_children() ),
|
86 |
+
function ( $item ) {
|
87 |
+
return $item instanceof \WC_Product;
|
88 |
+
}
|
89 |
+
);
|
90 |
}
|
91 |
|
92 |
+
return array( $product );
|
93 |
}
|
94 |
|
95 |
|
106 |
|
107 |
if ( Products::product_should_be_deleted( $product ) ) {
|
108 |
|
109 |
+
facebook_for_woocommerce()->get_products_sync_handler()->delete_products( array( \WC_Facebookcommerce_Utils::get_fb_retailer_id( $product ) ) );
|
110 |
return;
|
111 |
}
|
112 |
|
113 |
+
facebook_for_woocommerce()->get_products_sync_handler()->create_or_update_products( array( $product->get_id() ) );
|
114 |
}
|
115 |
|
116 |
|
includes/Products/Sync.php
CHANGED
@@ -32,7 +32,7 @@ class Sync {
|
|
32 |
const ACTION_DELETE = 'DELETE';
|
33 |
|
34 |
/** @var array the array of requests to schedule for sync */
|
35 |
-
protected $requests =
|
36 |
|
37 |
|
38 |
/**
|
@@ -53,11 +53,11 @@ class Sync {
|
|
53 |
*/
|
54 |
public function add_hooks() {
|
55 |
|
56 |
-
add_action( 'shutdown',
|
57 |
|
58 |
// stock update actions
|
59 |
-
add_action( 'woocommerce_product_set_stock',
|
60 |
-
add_action( 'woocommerce_variation_set_stock',
|
61 |
}
|
62 |
|
63 |
|
@@ -134,7 +134,7 @@ class Sync {
|
|
134 |
}
|
135 |
|
136 |
// add the product to the list of products to be updated
|
137 |
-
$this->create_or_update_products(
|
138 |
}
|
139 |
|
140 |
|
@@ -150,7 +150,7 @@ class Sync {
|
|
150 |
if ( ! empty( $this->requests ) ) {
|
151 |
|
152 |
$job_handler = facebook_for_woocommerce()->get_products_sync_background_handler();
|
153 |
-
$job = $job_handler->create_job(
|
154 |
|
155 |
$job_handler->dispatch();
|
156 |
|
@@ -182,9 +182,11 @@ class Sync {
|
|
182 |
*/
|
183 |
public static function is_sync_in_progress() {
|
184 |
|
185 |
-
$jobs = facebook_for_woocommerce()->get_products_sync_background_handler()->get_jobs(
|
186 |
-
|
187 |
-
|
|
|
|
|
188 |
|
189 |
return ! empty( $jobs );
|
190 |
}
|
32 |
const ACTION_DELETE = 'DELETE';
|
33 |
|
34 |
/** @var array the array of requests to schedule for sync */
|
35 |
+
protected $requests = array();
|
36 |
|
37 |
|
38 |
/**
|
53 |
*/
|
54 |
public function add_hooks() {
|
55 |
|
56 |
+
add_action( 'shutdown', array( $this, 'schedule_sync' ) );
|
57 |
|
58 |
// stock update actions
|
59 |
+
add_action( 'woocommerce_product_set_stock', array( $this, 'handle_stock_update' ) );
|
60 |
+
add_action( 'woocommerce_variation_set_stock', array( $this, 'handle_stock_update' ) );
|
61 |
}
|
62 |
|
63 |
|
134 |
}
|
135 |
|
136 |
// add the product to the list of products to be updated
|
137 |
+
$this->create_or_update_products( array( $product->get_id() ) );
|
138 |
}
|
139 |
|
140 |
|
150 |
if ( ! empty( $this->requests ) ) {
|
151 |
|
152 |
$job_handler = facebook_for_woocommerce()->get_products_sync_background_handler();
|
153 |
+
$job = $job_handler->create_job( array( 'requests' => $this->requests ) );
|
154 |
|
155 |
$job_handler->dispatch();
|
156 |
|
182 |
*/
|
183 |
public static function is_sync_in_progress() {
|
184 |
|
185 |
+
$jobs = facebook_for_woocommerce()->get_products_sync_background_handler()->get_jobs(
|
186 |
+
array(
|
187 |
+
'status' => 'processing',
|
188 |
+
)
|
189 |
+
);
|
190 |
|
191 |
return ! empty( $jobs );
|
192 |
}
|
includes/Products/Sync/Background.php
CHANGED
@@ -40,7 +40,7 @@ class Background extends Framework\SV_WP_Background_Job_Handler {
|
|
40 |
* @since 2.0.0
|
41 |
*
|
42 |
* @param \stdClass|object $job
|
43 |
-
* @param int|null
|
44 |
* @throws \Exception when job data is incorrect
|
45 |
* @return \stdClass $job
|
46 |
*/
|
@@ -109,23 +109,22 @@ class Background extends Framework\SV_WP_Background_Job_Handler {
|
|
109 |
* @since 2.0.0
|
110 |
*
|
111 |
* @param \stdClass|object $job
|
112 |
-
* @param array
|
113 |
-
* @param int|null
|
114 |
*/
|
115 |
public function process_items( $job, $data, $items_per_batch = null ) {
|
116 |
|
117 |
$processed = 0;
|
118 |
-
$requests =
|
119 |
|
120 |
foreach ( $data as $item_id => $method ) {
|
121 |
|
122 |
try {
|
123 |
|
124 |
-
if ( $request = $this->process_item(
|
125 |
$requests[] = $request;
|
126 |
}
|
127 |
-
|
128 |
-
} catch ( Framework\SV_WC_Plugin_Exception $e ) {
|
129 |
|
130 |
facebook_for_woocommerce()->log( "Background sync error: {$e->getMessage()}" );
|
131 |
}
|
@@ -155,7 +154,7 @@ class Background extends Framework\SV_WP_Background_Job_Handler {
|
|
155 |
|
156 |
} catch ( Framework\SV_WC_API_Exception $e ) {
|
157 |
|
158 |
-
$message = sprintf( __( 'There was an error trying sync products using the Catalog Batch API for job %s: %s' ), $job->id, $e->getMessage() );
|
159 |
|
160 |
facebook_for_woocommerce()->log( $message );
|
161 |
}
|
@@ -168,7 +167,7 @@ class Background extends Framework\SV_WP_Background_Job_Handler {
|
|
168 |
*
|
169 |
* @since 2.0.0
|
170 |
*
|
171 |
-
* @param mixed
|
172 |
* @param object|\stdClass $job
|
173 |
* @return array|null
|
174 |
* @throws Framework\SV_WC_Plugin_Exception
|
@@ -177,7 +176,7 @@ class Background extends Framework\SV_WP_Background_Job_Handler {
|
|
177 |
|
178 |
list( $item_id, $method ) = $item;
|
179 |
|
180 |
-
if ( ! in_array( $method,
|
181 |
throw new Framework\SV_WC_Plugin_Exception( "Invalid sync request method: {$method}." );
|
182 |
}
|
183 |
|
@@ -222,16 +221,16 @@ class Background extends Framework\SV_WP_Background_Job_Handler {
|
|
222 |
// extract the retailer_id
|
223 |
$retailer_id = $product_data['retailer_id'];
|
224 |
|
225 |
-
//NB: Changing this to get items_batch to work
|
226 |
// retailer_id cannot be included in the data object
|
227 |
unset( $product_data['retailer_id'] );
|
228 |
$product_data['id'] = $retailer_id;
|
229 |
|
230 |
-
$request =
|
231 |
// 'retailer_id' => $retailer_id,
|
232 |
-
'method'
|
233 |
-
'data'
|
234 |
-
|
235 |
|
236 |
/**
|
237 |
* Filters the data that will be included in a UPDATE sync request.
|
@@ -283,24 +282,44 @@ class Background extends Framework\SV_WP_Background_Job_Handler {
|
|
283 |
*
|
284 |
* @since 2.0.0
|
285 |
*
|
286 |
-
* @param array $data product data
|
287 |
* @return array
|
288 |
*/
|
289 |
private function normalize_product_data( $data ) {
|
290 |
|
291 |
-
//
|
292 |
$data['condition'] = 'new';
|
293 |
|
294 |
-
//
|
295 |
if ( isset( $data['custom_data'] ) && is_array( $data['custom_data'] ) ) {
|
296 |
|
297 |
-
$attributes =
|
298 |
-
|
299 |
-
foreach ($data['custom_data'] as $key => $val) {
|
300 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
301 |
}
|
302 |
|
303 |
-
$data['additional_variant_attribute'] = implode(',', $attributes);
|
304 |
unset( $data['custom_data'] );
|
305 |
}
|
306 |
|
@@ -337,10 +356,10 @@ class Background extends Framework\SV_WP_Background_Job_Handler {
|
|
337 |
*/
|
338 |
private function process_item_delete( $retailer_id ) {
|
339 |
|
340 |
-
$request =
|
341 |
'data' => array( 'id' => $retailer_id ),
|
342 |
'method' => Sync::ACTION_DELETE,
|
343 |
-
|
344 |
|
345 |
/**
|
346 |
* Filters the data that will be included in a DELETE sync request.
|
40 |
* @since 2.0.0
|
41 |
*
|
42 |
* @param \stdClass|object $job
|
43 |
+
* @param int|null $items_per_batch number of items to process in a single request (defaults to null for unlimited)
|
44 |
* @throws \Exception when job data is incorrect
|
45 |
* @return \stdClass $job
|
46 |
*/
|
109 |
* @since 2.0.0
|
110 |
*
|
111 |
* @param \stdClass|object $job
|
112 |
+
* @param array $data
|
113 |
+
* @param int|null $items_per_batch number of items to process in a single request (defaults to null for unlimited)
|
114 |
*/
|
115 |
public function process_items( $job, $data, $items_per_batch = null ) {
|
116 |
|
117 |
$processed = 0;
|
118 |
+
$requests = array();
|
119 |
|
120 |
foreach ( $data as $item_id => $method ) {
|
121 |
|
122 |
try {
|
123 |
|
124 |
+
if ( $request = $this->process_item( array( $item_id, $method ), $job ) ) {
|
125 |
$requests[] = $request;
|
126 |
}
|
127 |
+
} catch ( Framework\SV_WC_Plugin_Exception $e ) {
|
|
|
128 |
|
129 |
facebook_for_woocommerce()->log( "Background sync error: {$e->getMessage()}" );
|
130 |
}
|
154 |
|
155 |
} catch ( Framework\SV_WC_API_Exception $e ) {
|
156 |
|
157 |
+
$message = sprintf( __( 'There was an error trying sync products using the Catalog Batch API for job %1$s: %2$s' ), $job->id, $e->getMessage() );
|
158 |
|
159 |
facebook_for_woocommerce()->log( $message );
|
160 |
}
|
167 |
*
|
168 |
* @since 2.0.0
|
169 |
*
|
170 |
+
* @param mixed $item
|
171 |
* @param object|\stdClass $job
|
172 |
* @return array|null
|
173 |
* @throws Framework\SV_WC_Plugin_Exception
|
176 |
|
177 |
list( $item_id, $method ) = $item;
|
178 |
|
179 |
+
if ( ! in_array( $method, array( Sync::ACTION_UPDATE, Sync::ACTION_DELETE ), true ) ) {
|
180 |
throw new Framework\SV_WC_Plugin_Exception( "Invalid sync request method: {$method}." );
|
181 |
}
|
182 |
|
221 |
// extract the retailer_id
|
222 |
$retailer_id = $product_data['retailer_id'];
|
223 |
|
224 |
+
// NB: Changing this to get items_batch to work
|
225 |
// retailer_id cannot be included in the data object
|
226 |
unset( $product_data['retailer_id'] );
|
227 |
$product_data['id'] = $retailer_id;
|
228 |
|
229 |
+
$request = array(
|
230 |
// 'retailer_id' => $retailer_id,
|
231 |
+
'method' => Sync::ACTION_UPDATE,
|
232 |
+
'data' => $product_data,
|
233 |
+
);
|
234 |
|
235 |
/**
|
236 |
* Filters the data that will be included in a UPDATE sync request.
|
282 |
*
|
283 |
* @since 2.0.0
|
284 |
*
|
285 |
+
* @param array $data product data.
|
286 |
* @return array
|
287 |
*/
|
288 |
private function normalize_product_data( $data ) {
|
289 |
|
290 |
+
// Allowed values are 'refurbished', 'used', and 'new', but the plugin has always used the latter.
|
291 |
$data['condition'] = 'new';
|
292 |
|
293 |
+
// Attributes other than size, color, pattern, or gender need to be included in the additional_variant_attributes field.
|
294 |
if ( isset( $data['custom_data'] ) && is_array( $data['custom_data'] ) ) {
|
295 |
|
296 |
+
$attributes = array();
|
297 |
+
|
298 |
+
foreach ( $data['custom_data'] as $key => $val ) {
|
299 |
+
/**
|
300 |
+
* Filter: facebook_for_woocommerce_variant_attribute_comma_replacement
|
301 |
+
*
|
302 |
+
* The Facebook API expects a comma-separated list of attributes in `additional_variant_attribute` field.
|
303 |
+
* https://developers.facebook.com/docs/marketing-api/catalog/reference/
|
304 |
+
* This means that WooCommerce product attributes included in this field should avoid the comma (`,`) character.
|
305 |
+
* Facebook for WooCommerce replaces any `,` with a space by default.
|
306 |
+
* This filter allows a site to provide a different replacement string.
|
307 |
+
*
|
308 |
+
* @since 2.5.0
|
309 |
+
*
|
310 |
+
* @param string $replacement The default replacement string (`,`).
|
311 |
+
* @param string $value Attribute value.
|
312 |
+
* @return string Return the desired replacement string.
|
313 |
+
*/
|
314 |
+
$attribute_value = str_replace(
|
315 |
+
',',
|
316 |
+
apply_filters( 'facebook_for_woocommerce_variant_attribute_comma_replacement', ' ', $val ),
|
317 |
+
$val
|
318 |
+
);
|
319 |
+
$attributes[] = $key . ':' . $attribute_value;
|
320 |
}
|
321 |
|
322 |
+
$data['additional_variant_attribute'] = implode( ',', $attributes );
|
323 |
unset( $data['custom_data'] );
|
324 |
}
|
325 |
|
356 |
*/
|
357 |
private function process_item_delete( $retailer_id ) {
|
358 |
|
359 |
+
$request = array(
|
360 |
'data' => array( 'id' => $retailer_id ),
|
361 |
'method' => Sync::ACTION_DELETE,
|
362 |
+
);
|
363 |
|
364 |
/**
|
365 |
* Filters the data that will be included in a DELETE sync request.
|
includes/Utilities/Background_Handle_Virtual_Products_Variations.php
CHANGED
@@ -46,7 +46,7 @@ class Background_Handle_Virtual_Products_Variations extends Framework\SV_WP_Back
|
|
46 |
* @since 2.0.0
|
47 |
*
|
48 |
* @param object $job
|
49 |
-
* @param int
|
50 |
* @return object
|
51 |
*/
|
52 |
public function process_job( $job, $items_per_batch = null ) {
|
@@ -140,7 +140,7 @@ class Background_Handle_Virtual_Products_Variations extends Framework\SV_WP_Back
|
|
140 |
return 0;
|
141 |
}
|
142 |
|
143 |
-
$insert = $update =
|
144 |
|
145 |
foreach ( $results as $result ) {
|
146 |
|
@@ -202,7 +202,7 @@ class Background_Handle_Virtual_Products_Variations extends Framework\SV_WP_Back
|
|
202 |
return 0;
|
203 |
}
|
204 |
|
205 |
-
$values =
|
206 |
|
207 |
foreach ( $post_ids as $post_id ) {
|
208 |
$values[] = "('{$post_id}', 'fb_visibility', 'no')";
|
46 |
* @since 2.0.0
|
47 |
*
|
48 |
* @param object $job
|
49 |
+
* @param int $items_per_batch number of items to process in a single request. Defaults to unlimited.
|
50 |
* @return object
|
51 |
*/
|
52 |
public function process_job( $job, $items_per_batch = null ) {
|
140 |
return 0;
|
141 |
}
|
142 |
|
143 |
+
$insert = $update = array();
|
144 |
|
145 |
foreach ( $results as $result ) {
|
146 |
|
202 |
return 0;
|
203 |
}
|
204 |
|
205 |
+
$values = array();
|
206 |
|
207 |
foreach ( $post_ids as $post_id ) {
|
208 |
$values[] = "('{$post_id}', 'fb_visibility', 'no')";
|
includes/Utilities/Background_Remove_Duplicate_Visibility_Meta.php
CHANGED
@@ -48,7 +48,7 @@ class Background_Remove_Duplicate_Visibility_Meta extends Framework\SV_WP_Backgr
|
|
48 |
* @since 2.0.3
|
49 |
*
|
50 |
* @param object $job
|
51 |
-
* @param int
|
52 |
* @return object
|
53 |
*/
|
54 |
public function process_job( $job, $items_per_batch = null ) {
|
@@ -56,7 +56,7 @@ class Background_Remove_Duplicate_Visibility_Meta extends Framework\SV_WP_Backgr
|
|
56 |
// don't do anything until the job used to hide virtual variations is done
|
57 |
$handler = facebook_for_woocommerce()->get_background_handle_virtual_products_variations_instance();
|
58 |
|
59 |
-
if ( $handler && $handler->get_jobs(
|
60 |
return $job;
|
61 |
}
|
62 |
|
@@ -142,10 +142,12 @@ class Background_Remove_Duplicate_Visibility_Meta extends Framework\SV_WP_Backgr
|
|
142 |
|
143 |
if ( false === $wpdb->query( $wpdb->prepare( $sql, $result->post_id, $result->last_meta_id ) ) ) {
|
144 |
|
145 |
-
facebook_for_woocommerce()->log(
|
146 |
-
|
147 |
-
|
148 |
-
|
|
|
|
|
149 |
|
150 |
continue;
|
151 |
}
|
48 |
* @since 2.0.3
|
49 |
*
|
50 |
* @param object $job
|
51 |
+
* @param int $items_per_batch number of items to process in a single request. Defaults to unlimited.
|
52 |
* @return object
|
53 |
*/
|
54 |
public function process_job( $job, $items_per_batch = null ) {
|
56 |
// don't do anything until the job used to hide virtual variations is done
|
57 |
$handler = facebook_for_woocommerce()->get_background_handle_virtual_products_variations_instance();
|
58 |
|
59 |
+
if ( $handler && $handler->get_jobs( array( 'status' => array( 'processing', 'queued' ) ) ) ) {
|
60 |
return $job;
|
61 |
}
|
62 |
|
142 |
|
143 |
if ( false === $wpdb->query( $wpdb->prepare( $sql, $result->post_id, $result->last_meta_id ) ) ) {
|
144 |
|
145 |
+
facebook_for_woocommerce()->log(
|
146 |
+
sprintf(
|
147 |
+
'There was an error trying to set products and variations meta data. %s',
|
148 |
+
$wpdb->last_error
|
149 |
+
)
|
150 |
+
);
|
151 |
|
152 |
continue;
|
153 |
}
|
includes/Utilities/Shipment.php
CHANGED
@@ -37,521 +37,521 @@ class Shipment {
|
|
37 |
/**
|
38 |
* @see https://developers.facebook.com/docs/commerce-platform/order-management/carrier-codes
|
39 |
*/
|
40 |
-
$this->valid_carriers =
|
41 |
-
'AUSTRALIA_POST'
|
42 |
-
'CANADA_POST'
|
43 |
-
'DHL'
|
44 |
-
'DHL_ECOMMERCE_US'
|
45 |
-
'EAGLE'
|
46 |
-
'FEDEX'
|
47 |
-
'FEDEX_UK'
|
48 |
-
'NEW_ZEALAND_POST'
|
49 |
-
'ONTRAC'
|
50 |
-
'POST_DANMARK'
|
51 |
-
'PUROLATOR'
|
52 |
-
'ROYAL_MAIL'
|
53 |
-
'SPEE_DEE'
|
54 |
-
'TNT'
|
55 |
-
'TNT_POST'
|
56 |
-
'UPS'
|
57 |
-
'USPS'
|
58 |
-
'OTHER'
|
59 |
-
'ABF_FREIGHT'
|
60 |
-
'ABX_EXPRESS'
|
61 |
-
'AB_CUSTOM_GROUP'
|
62 |
-
'ACOMMERCE'
|
63 |
-
'ACS_COURIER'
|
64 |
-
'ACS_WORLDWIDE_EXPRESS'
|
65 |
-
'ADICIONAL_LOGISTICS'
|
66 |
-
'ADSONE'
|
67 |
-
'AIR21'
|
68 |
-
'AIRPAK_EXPRESS'
|
69 |
-
'AIRSPEED_INTERNATIONAL_CORPORATION'
|
70 |
-
'ALFATREX'
|
71 |
-
'ALLIED_EXPRESS'
|
72 |
-
'ALLJOY_SUPPLY_CHAIN_CO_LTD'
|
73 |
-
'ALPHAFAST'
|
74 |
-
'AMAZON_FBA_USA'
|
75 |
-
'AMAZON_LOGISTICS'
|
76 |
-
'AN_POST'
|
77 |
-
'APC_OVERNIGHT'
|
78 |
-
'APC_OVERNIGHT_REFERENCE'
|
79 |
-
'APC_POSTAL_LOGISTICS'
|
80 |
-
'APRISA_EXPRESS'
|
81 |
-
'ARAMEX'
|
82 |
-
'ARROW_XL'
|
83 |
-
'ASENDIA_GERMANY'
|
84 |
-
'ASENDIA_HK'
|
85 |
-
'ASENDIA_HK_PREMIUM_SERVICE_LATAM'
|
86 |
-
'ASENDIA_UK'
|
87 |
-
'ASENDIA_USA'
|
88 |
-
'ASM'
|
89 |
-
'AUPOST_CHINA'
|
90 |
-
'AUSTRALIA_POST_SFTP'
|
91 |
-
'AUSTRIAN_POST_EXPRESS'
|
92 |
-
'AUSTRIAN_POST_REGISTERED'
|
93 |
-
'AXL_EXPRESS_LOGISTICS'
|
94 |
-
'A_DUIE_PYLE'
|
95 |
-
'A_J_EXPRESS'
|
96 |
-
'B2C_EUROPE'
|
97 |
-
'BELPOST'
|
98 |
-
'BERT_TRANSPORT'
|
99 |
-
'BEST_EXPRESS'
|
100 |
-
'BEST_WAY_PARCEL'
|
101 |
-
'BIRDSYSTEM'
|
102 |
-
'BJS_DISTRIBUTION_STORAGE_COURIERS'
|
103 |
-
'BJS_DISTRIBUTION_STORAGE_COURIERS_FTP'
|
104 |
-
'BLUECARE_EXPRESS_LTD'
|
105 |
-
'BLUEDART'
|
106 |
-
'BLUE_STAR'
|
107 |
-
'BNEED'
|
108 |
-
'BONDS_COURIERS'
|
109 |
-
'BOXC'
|
110 |
-
'BPOST'
|
111 |
-
'BPOST_INTERNATIONAL'
|
112 |
-
'BRAZIL_CORREIOS'
|
113 |
-
'BRT_BARTOLINI'
|
114 |
-
'BRT_BARTOLINI_PARCEL_ID'
|
115 |
-
'BULGARIAN_POSTS'
|
116 |
-
'BUYLOGIC'
|
117 |
-
'CAMBODIA_POST'
|
118 |
-
'CANPAR_COURIER'
|
119 |
-
'CAPITAL_TRANSPORT'
|
120 |
-
'CARRIER_007EX'
|
121 |
-
'CARRIER_17_POST_SERVICE'
|
122 |
-
'CARRIER_2GO'
|
123 |
-
'CARRIER_360_LION_EXPRESS'
|
124 |
-
'CARRIER_4PX'
|
125 |
-
'CARRIER_4_72_ENTREGANDO'
|
126 |
-
'CARRIER_ECHO'
|
127 |
-
'CBL_LOGISTICS'
|
128 |
-
'CELERITAS_TRANSPORTE_SL'
|
129 |
-
'CESKA_POSTA'
|
130 |
-
'CHINA_EMS_EPACKET'
|
131 |
-
'CHINA_POST'
|
132 |
-
'CHIT_CHATS'
|
133 |
-
'CHRONOPOST_FRANCE'
|
134 |
-
'CHRONOPOST_PORTUGAL'
|
135 |
-
'CH_ROBINSON_WORLDWIDE_INC'
|
136 |
-
'CITY_LINK_EXPRESS'
|
137 |
-
'CJ_CENTURY'
|
138 |
-
'CJ_CENTURY_INTERNATIONAL'
|
139 |
-
'CJ_GLS'
|
140 |
-
'CJ_KOREA_EXPRESS'
|
141 |
-
'CJ_LOGISTICS_INTERNATIONAL'
|
142 |
-
'CJ_TRANSNATIONAL_PHILIPPINES'
|
143 |
-
'CLEVY_LINKS'
|
144 |
-
'CLOUDWISH_ASIA'
|
145 |
-
'CNE_EXPRESS'
|
146 |
-
'COLISSIMO'
|
147 |
-
'COLIS_PRIVE'
|
148 |
-
'COLLECTCO'
|
149 |
-
'COLLECT_PLUS'
|
150 |
-
'CON_WAY_FREIGHT'
|
151 |
-
'COPA_AIRLINES_COURIER'
|
152 |
-
'CORREOS_CHILE'
|
153 |
-
'CORREOS_DE_COSTA_RICA'
|
154 |
-
'CORREOS_DE_ESPANA'
|
155 |
-
'CORREOS_DE_MEXICO'
|
156 |
-
'CORREOS_EXPRESS'
|
157 |
-
'CORREO_ARGENTINO'
|
158 |
-
'COSMETICS_NOW'
|
159 |
-
'COUREX'
|
160 |
-
'COURIERPOST'
|
161 |
-
'COURIERS_PLEASE'
|
162 |
-
'COURIER_IT'
|
163 |
-
'COURIER_PLUS'
|
164 |
-
'CPACKET'
|
165 |
-
'CUCKOO_EXPRESS'
|
166 |
-
'CYPRUS_POST'
|
167 |
-
'DACHSER'
|
168 |
-
'DAWN_WING'
|
169 |
-
'DAYLIGHT_TRANSPORT_LLC'
|
170 |
-
'DB_SCHENKER'
|
171 |
-
'DB_SCHENKER_SWEDEN'
|
172 |
-
'DD_EXPRESS_COURIER'
|
173 |
-
'DELCART'
|
174 |
-
'DELHIVERY'
|
175 |
-
'DELIVERYONTIME_LOGISTICS_PVT_LTD'
|
176 |
-
'DELTEC_COURIER'
|
177 |
-
'DEMANDSHIP'
|
178 |
-
'DETRACK'
|
179 |
-
'DEUTSCHE_POST_DHL'
|
180 |
-
'DEUTSCHE_POST_MAIL'
|
181 |
-
'DEX_I'
|
182 |
-
'DHL_2_MANN_HANDLING'
|
183 |
-
'DHL_ACTIVE_TRACING'
|
184 |
-
'DHL_BENELUX'
|
185 |
-
'DHL_ECOMMERCE_ASIA'
|
186 |
-
'DHL_EXPRESS_PIECE_ID'
|
187 |
-
'DHL_GLOBAL_FORWARDING'
|
188 |
-
'DHL_HONG_KONG'
|
189 |
-
'DHL_NETHERLANDS'
|
190 |
-
'DHL_PARCEL_NL'
|
191 |
-
'DHL_PARCEL_SPAIN'
|
192 |
-
'DHL_POLAND_DOMESTIC'
|
193 |
-
'DHL_SPAIN_DOMESTIC'
|
194 |
-
'DIMERCO_EXPRESS_GROUP'
|
195 |
-
'DIRECTLOG'
|
196 |
-
'DIRECT_FREIGHT_EXPRESS'
|
197 |
-
'DIRECT_LINK'
|
198 |
-
'DMM_NETWORK'
|
199 |
-
'DOORA_LOGISTICS'
|
200 |
-
'DOTZOT'
|
201 |
-
'DPD'
|
202 |
-
'DPD_FRANCE'
|
203 |
-
'DPD_GERMANY'
|
204 |
-
'DPD_HK'
|
205 |
-
'DPD_IRELAND'
|
206 |
-
'DPD_LOCAL'
|
207 |
-
'DPD_LOCAL_REFERENCE'
|
208 |
-
'DPD_POLAND'
|
209 |
-
'DPD_ROMANIA'
|
210 |
-
'DPD_RUSSIA'
|
211 |
-
'DPD_UK'
|
212 |
-
'DPEX'
|
213 |
-
'DPEX_CHINA'
|
214 |
-
'DPE_EXPRESS'
|
215 |
-
'DPE_SOUTH_AFRICA'
|
216 |
-
'DSV'
|
217 |
-
'DTDC_AUSTRALIA'
|
218 |
-
'DTDC_EXPRESS_GLOBAL_PTE_LTD'
|
219 |
-
'DTDC_INDIA'
|
220 |
-
'DX'
|
221 |
-
'DX_FREIGHT'
|
222 |
-
'DYNALOGIC_BENELUX_BV'
|
223 |
-
'DYNAMIC_LOGISTICS'
|
224 |
-
'EASY_MAIL'
|
225 |
-
'ECARGO'
|
226 |
-
'ECMS_INTERNATIONAL_LOGISTICS_CO_LTD'
|
227 |
-
'ECOM_EXPRESS'
|
228 |
-
'EC_FIRSTCLASS'
|
229 |
-
'EFS_E_COMMERCE_FULFILLMENT_SERVICE'
|
230 |
-
'EKART'
|
231 |
-
'ELTA_HELLENIC_POST'
|
232 |
-
'EMIRATES_POST'
|
233 |
-
'EMPS_EXPRESS'
|
234 |
-
'ENSENDA'
|
235 |
-
'ENVIALIA'
|
236 |
-
'EPARCEL_KOREA'
|
237 |
-
'EP_BOX'
|
238 |
-
'EQUICK_CHINA'
|
239 |
-
'ESTAFETA'
|
240 |
-
'ESTES'
|
241 |
-
'ETOTAL_SOLUTION_LIMITED'
|
242 |
-
'EURODIS'
|
243 |
-
'EXPEDITORS'
|
244 |
-
'EZSHIP'
|
245 |
-
'FASTRAK_SERVICES'
|
246 |
-
'FASTWAY_AUSTRALIA'
|
247 |
-
'FASTWAY_IRELAND'
|
248 |
-
'FASTWAY_NEW_ZEALAND'
|
249 |
-
'FASTWAY_SOUTH_AFRICA'
|
250 |
-
'FEDEX_CROSS_BORDER'
|
251 |
-
'FEDEX_FREIGHT'
|
252 |
-
'FEDEX_POLAND_DOMESTIC'
|
253 |
-
'FERCAM_LOGISTICS_TRANSPORT'
|
254 |
-
'FIRST_FLIGHT_COURIERS'
|
255 |
-
'FIRST_LOGISTICS'
|
256 |
-
'FLYT_EXPRESS'
|
257 |
-
'GATI_KWE'
|
258 |
-
'GDEX'
|
259 |
-
'GENIKI_TAXYDROMIKI'
|
260 |
-
'GEODIS_E_SPACE'
|
261 |
-
'GEODIS_DISTRIBUTION_EXPRESS'
|
262 |
-
'GIAO_HANG_NHANH'
|
263 |
-
'GLOBEGISTICS_INC'
|
264 |
-
'GLS'
|
265 |
-
'GLS_CZECH_REPUBLIC'
|
266 |
-
'GLS_ITALY'
|
267 |
-
'GLS_NETHERLANDS'
|
268 |
-
'GOFLY'
|
269 |
-
'GOJAVAS'
|
270 |
-
'GREYHOUND'
|
271 |
-
'GSI_EXPRESS'
|
272 |
-
'HERMESWORLD'
|
273 |
-
'HERMES_GERMANY'
|
274 |
-
'HERMES_ITALY'
|
275 |
-
'HOLISOL'
|
276 |
-
'HOMEDIRECT_LOGISTICS'
|
277 |
-
'HONG_KONG_POST'
|
278 |
-
'HRVATSKA_POSTA'
|
279 |
-
'HUA_HAN_LOGISTICS'
|
280 |
-
'HUNTER_EXPRESS'
|
281 |
-
'ICELAND_POST'
|
282 |
-
'IDEX'
|
283 |
-
'IMEX_GLOBAL_SOLUTIONS'
|
284 |
-
'IMX_MAIL'
|
285 |
-
'INDIA_POST_DOMESTIC'
|
286 |
-
'INDIA_POST_INTERNATIONAL'
|
287 |
-
'INPOST_PACZKOMATY'
|
288 |
-
'INSTANT_TIONG_NAM_EBIZ_EXPRESS_SDN_BHD'
|
289 |
-
'INTERNATIONAL_SEUR'
|
290 |
-
'INTERNET_EXPRESS'
|
291 |
-
'ISRAEL_POST'
|
292 |
-
'ISRAEL_POST_DOMESTIC'
|
293 |
-
'ITALY_SDA'
|
294 |
-
'I_PARCEL'
|
295 |
-
'J_T_EXPRESS'
|
296 |
-
'JAM_EXPRESS'
|
297 |
-
'JANCO_ECOMMERCE'
|
298 |
-
'JAPAN_POST'
|
299 |
-
'JAYON_EXPRESS_JEX'
|
300 |
-
'JCEX'
|
301 |
-
'JERSEY_POST'
|
302 |
-
'JET_SHIP_WORLDWIDE'
|
303 |
-
'JINSUNG_TRADING'
|
304 |
-
'JNE'
|
305 |
-
'JOCOM'
|
306 |
-
'JP_BH_POSTA'
|
307 |
-
'JX'
|
308 |
-
'J_NET'
|
309 |
-
'K1_EXPRESS'
|
310 |
-
'KANGAROO_WORLDWIDE_EXPRESS'
|
311 |
-
'KERRY_EXPRESS_HONG_KONG'
|
312 |
-
'KERRY_EXPRESS_THAILAND'
|
313 |
-
'KERRY_EXPRESS_VIETNAM_CO_LTD'
|
314 |
-
'KGM_HUB'
|
315 |
-
'KIALA'
|
316 |
-
'KOREA_POST'
|
317 |
-
'KOREA_POST_EMS'
|
318 |
-
'KRONOS_EXPRESS'
|
319 |
-
'KUEHNE_NAGEL'
|
320 |
-
'LANDMARK_GLOBAL'
|
321 |
-
'LAO_POST'
|
322 |
-
'LASERSHIP'
|
323 |
-
'LA_POSTE'
|
324 |
-
'LBC_EXPRESS'
|
325 |
-
'LHT_EXPRESS'
|
326 |
-
'LIETUVOS_PASTAS'
|
327 |
-
'LINE_CLEAR_EXPRESS_LOGISTICS_SDN_BHD'
|
328 |
'LINK_BRIDGE_BEIJING_INTERNATIONAL_LOGISTICS_COLTD' => 'Link Bridge(BeiJing)international logistics co.,ltd',
|
329 |
-
'LION_PARCEL'
|
330 |
-
'LOGISTIC_WORLDWIDE_EXPRESS'
|
331 |
-
'LOGWIN_LOGISTICS'
|
332 |
-
'LONE_STAR_OVERNIGHT'
|
333 |
-
'MAGYAR_POSTA'
|
334 |
-
'MAILAMERICAS'
|
335 |
-
'MAILPLUS'
|
336 |
-
'MAINFREIGHT'
|
337 |
-
'MALAYSIA_POST_EMS_POS_LAJU'
|
338 |
-
'MALAYSIA_POST_REGISTERED'
|
339 |
-
'MARA_XPRESS'
|
340 |
-
'MATDESPATCH'
|
341 |
-
'MATKAHUOLTO'
|
342 |
-
'MDS_COLLIVERY_PTY_LTD'
|
343 |
-
'MEGASAVE'
|
344 |
-
'MEXICO_AEROFLASH'
|
345 |
-
'MEXICO_REDPACK'
|
346 |
-
'MEXICO_SENDA_EXPRESS'
|
347 |
-
'MIKROPAKKET'
|
348 |
-
'MONDIAL_RELAY'
|
349 |
-
'MRW'
|
350 |
-
'MUDITA'
|
351 |
-
'MXE_EXPRESS'
|
352 |
-
'MYHERMES_UK'
|
353 |
-
'MYPOSTONLINE'
|
354 |
-
'M_XPRESS_SDN_BHD'
|
355 |
-
'NACEX_SPAIN'
|
356 |
-
'NANJING_WOYUAN'
|
357 |
-
'NATIONAL_SAMEDAY'
|
358 |
-
'NATIONWIDE_EXPRESS'
|
359 |
-
'NEWGISTICS'
|
360 |
-
'NEWGISTICS_API'
|
361 |
-
'NEXIVE_TNT_POST_ITALY'
|
362 |
-
'NHANS_SOLUTIONS'
|
363 |
-
'NIGHTLINE'
|
364 |
-
'NIM_EXPRESS'
|
365 |
-
'NINJA_VAN'
|
366 |
-
'NINJA_VAN_INDONESIA'
|
367 |
-
'NINJA_VAN_MALAYSIA'
|
368 |
-
'NINJA_VAN_PHILIPPINES'
|
369 |
-
'NINJA_VAN_THAILAND'
|
370 |
-
'NIPOST'
|
371 |
-
'NORSK_GLOBAL'
|
372 |
-
'NOVA_POSHTA'
|
373 |
-
'NOVA_POSHTA_INTERNATIONAL'
|
374 |
-
'OCA_ARGENTINA'
|
375 |
-
'OLD_DOMINION_FREIGHT_LINE'
|
376 |
-
'OMNIVA'
|
377 |
-
'OMNI_PARCEL'
|
378 |
-
'ONE_WORLD_EXPRESS'
|
379 |
-
'PACKLINK'
|
380 |
-
'PAL_EXPRESS_LIMITED'
|
381 |
-
'PANDU_LOGISTICS'
|
382 |
-
'PANTHER'
|
383 |
-
'PANTHER_ORDER_NUMBER'
|
384 |
-
'PANTHER_REFERENCE'
|
385 |
-
'PAQUETEXPRESS'
|
386 |
-
'PARCELLEDIN'
|
387 |
-
'PARCELPOINT_PTY_LTD'
|
388 |
-
'PARCEL_FORCE'
|
389 |
-
'PARCEL_POST_SINGAPORE'
|
390 |
-
'PAYPAL_PACKAGE'
|
391 |
-
'PFC_EXPRESS'
|
392 |
-
'PICKUPP'
|
393 |
-
'PICK_UPP_MYS_SGP'
|
394 |
-
'PILOT_FREIGHT_SERVICES'
|
395 |
-
'PITNEY_BOWES'
|
396 |
-
'PIXSELL_LOGISTICS'
|
397 |
-
'POCZTA_POLSKA'
|
398 |
-
'PORTUGAL_CTT'
|
399 |
-
'PORTUGAL_SEUR'
|
400 |
-
'POST56'
|
401 |
-
'POSTEN_NORGE_BRING'
|
402 |
-
'POSTE_ITALIANE'
|
403 |
-
'POSTE_ITALIANE_PACCOCELERE'
|
404 |
-
'POSTI'
|
405 |
-
'POSTNL_DOMESTIC'
|
406 |
-
'POSTNL_INTERNATIONAL'
|
407 |
-
'POSTNL_INTERNATIONAL_3S'
|
408 |
-
'POSTNORD_DENMARK'
|
409 |
-
'POSTNORD_LOGISTICS'
|
410 |
-
'POSTNORD_SWEDEN'
|
411 |
-
'POST_OF_SLOVENIA'
|
412 |
-
'POST_SERBIA'
|
413 |
-
'POS_INDONESIA_DOMESTIC'
|
414 |
-
'POS_INDONESIA_INTL'
|
415 |
-
'POSTA_ROMANA'
|
416 |
-
'PROFESSIONAL_COURIERS'
|
417 |
-
'PTT_POSTA'
|
418 |
-
'QUALITYPOST'
|
419 |
-
'QUANTIUM'
|
420 |
-
'QXPRESS'
|
421 |
-
'RABEN_GROUP'
|
422 |
-
'RAF_PHILIPPINES'
|
423 |
-
'RAIDEREX'
|
424 |
-
'RAM'
|
425 |
-
'REDUR_SPAIN'
|
426 |
-
'RED_CARPET_LOGISTICS'
|
427 |
-
'RINCOS'
|
428 |
-
'RL_CARRIERS'
|
429 |
-
'ROADBULL_LOGISTICS'
|
430 |
-
'ROCKET_PARCEL_INTERNATIONAL'
|
431 |
-
'RPD2MAN_DELIVERIES'
|
432 |
-
'RPX_INDONESIA'
|
433 |
-
'RPX_ONLINE'
|
434 |
-
'RRD_INTERNATIONAL_LOGISTICS_USA'
|
435 |
-
'RUSSIAN_POST'
|
436 |
-
'RUSTON'
|
437 |
-
'RZY_EXPRESS'
|
438 |
-
'SAFEXPRESS'
|
439 |
-
'SAGAWA'
|
440 |
-
'SAIA_LTL_FREIGHT'
|
441 |
-
'SAILPOST'
|
442 |
-
'SAP_EXPRESS'
|
443 |
-
'SAUDI_POST'
|
444 |
-
'SCUDEX_EXPRESS'
|
445 |
-
'SEINO'
|
446 |
-
'SEKO_LOGISTICS'
|
447 |
-
'SENDING_TRANSPORTE_URGENTE_Y_COMUNICACION_SAU'
|
448 |
-
'SENDIT'
|
449 |
-
'SENDLE'
|
450 |
-
'SFC_SERVICE'
|
451 |
-
'SF_EXPRESS'
|
452 |
-
'SF_INTERNATIONAL'
|
453 |
-
'SGT_CORRIERE_ESPRESSO'
|
454 |
-
'SHANGHAI_WISE_SUPPLY_CHAIN_MANAGEMENT_CO_LTD'
|
455 |
-
'SHENZHEN_JINGHUADA_LOGISTICS_CO_LTD'
|
456 |
-
'SHIPPIT'
|
457 |
-
'SHIPTOR'
|
458 |
-
'SHOPFANSRU_LLC'
|
459 |
-
'SHREE_MARUTI_COURIER_SERVICES_PVT_LTD'
|
460 |
-
'SHREE_TIRUPATI_COURIER_SERVICES_PVT_LTD'
|
461 |
-
'SHUNYOU_POST'
|
462 |
-
'SIMPLYPOST'
|
463 |
-
'SINGAPORE_POST'
|
464 |
-
'SINGAPORE_SPEEDPOST'
|
465 |
-
'SIODEMKA'
|
466 |
-
'SKYBOX'
|
467 |
-
'SKYNET_MALAYSIA'
|
468 |
-
'SKYNET_WORLDWIDE_EXPRESS'
|
469 |
-
'SKYNET_WORLDWIDE_EXPRESS_UAE'
|
470 |
-
'SKYNET_WORLDWIDE_EXPRESS_UK'
|
471 |
-
'SKYNET_WORLD_WIDE_EXPRESS_SOUTH_AFRICA'
|
472 |
-
'SKYPOSTAL'
|
473 |
-
'SMOOTH_COURIERS'
|
474 |
-
'SMSA_EXPRESS'
|
475 |
-
'SOUTH_AFRICAN_POST_OFFICE'
|
476 |
-
'SPANISH_SEUR'
|
477 |
-
'SPECIALISED_FREIGHT'
|
478 |
-
'SPEEDEX_COURIER'
|
479 |
-
'SPEED_COURIERS'
|
480 |
-
'SPOTON_LOGISTICS_PVT_LTD'
|
481 |
-
'SRE_KOREA'
|
482 |
-
'STARTRACK'
|
483 |
-
'STAR_TRACK_COURIER'
|
484 |
-
'STAR_TRACK_EXPRESS'
|
485 |
-
'STO_EXPRESS'
|
486 |
-
'SWISS_POST'
|
487 |
-
'TAIWAN_POST'
|
488 |
-
'TAQBIN_HONG_KONG'
|
489 |
-
'TAQBIN_MALAYSIA'
|
490 |
-
'TAQBIN_SINGAPORE'
|
491 |
-
'TCS'
|
492 |
-
'TELIWAY_SIC_EXPRESS'
|
493 |
-
'THAILAND_THAI_POST'
|
494 |
-
'THE_COURIER_GUY'
|
495 |
-
'TIKI'
|
496 |
-
'TIPSA'
|
497 |
-
'TNT_AUSTRALIA'
|
498 |
-
'TNT_CLICK_ITALY'
|
499 |
-
'TNT_FRANCE'
|
500 |
-
'TNT_ITALY'
|
501 |
-
'TNT_REFERENCE'
|
502 |
-
'TNT_UK_REFERENCE'
|
503 |
-
'TOLL_IPEC'
|
504 |
-
'TOLL_PRIORITY'
|
505 |
-
'TOLOS'
|
506 |
-
'TRAKPAK'
|
507 |
-
'TRANSMISSION'
|
508 |
-
'TRANS_KARGO_INTERNASIONAL'
|
509 |
-
'TUFFNELLS_PARCELS_EXPRESS'
|
510 |
-
'UBI_SMART_PARCEL'
|
511 |
-
'UKRPOSHTA'
|
512 |
-
'UK_MAIL'
|
513 |
-
'UNITED_DELIVERY_SERVICE_LTD'
|
514 |
-
'UPS_FREIGHT'
|
515 |
-
'UPS_MAIL_INNOVATIONS'
|
516 |
-
'VIETNAM_POST'
|
517 |
-
'VIETNAM_POST_EMS'
|
518 |
-
'VIETTELPOST'
|
519 |
-
'WAHANA'
|
520 |
-
'WANBEXPRESS'
|
521 |
-
'WEDO_LOGISTICS'
|
522 |
-
'WEPOST_LOGISTICS'
|
523 |
-
'WHISTL'
|
524 |
-
'WISELOADS'
|
525 |
-
'WISE_EXPRESS'
|
526 |
-
'WISHPOST'
|
527 |
-
'WNDIRECT'
|
528 |
-
'XDP_EXPRESS'
|
529 |
-
'XDP_EXPRESS_REFERENCE'
|
530 |
-
'XEND_EXPRESS'
|
531 |
-
'XL_EXPRESS'
|
532 |
-
'XPOSTPH'
|
533 |
-
'XPRESSBEES'
|
534 |
-
'XQ_EXPRESS'
|
535 |
-
'YAKIT'
|
536 |
-
'YAMATO_JAPAN'
|
537 |
-
'YANWEN'
|
538 |
-
'YODEL_DOMESTIC'
|
539 |
-
'YODEL_INTERNATIONAL'
|
540 |
-
'YRC'
|
541 |
-
'YTO_EXPRESS'
|
542 |
-
'YUNDA_EXPRESS'
|
543 |
-
'YUN_EXPRESS'
|
544 |
-
'ZEPTOEXPRESS'
|
545 |
-
'ZINC'
|
546 |
-
'ZJS_INTERNATIONAL'
|
547 |
-
'ZTO_EXPRESS'
|
548 |
-
'ZYLLEM'
|
549 |
-
|
550 |
|
551 |
/**
|
552 |
* @see https://docs.woocommerce.com/document/shipment-tracking/#section-5
|
553 |
*/
|
554 |
-
$this->shipment_tracking_carriers =
|
555 |
// Australia
|
556 |
'Australia Post' => 'AUSTRALIA_POST',
|
557 |
'Fastway Couriers' => 'FASTWAY_AUSTRALIA',
|
@@ -630,7 +630,7 @@ class Shipment {
|
|
630 |
'UPS' => 'UPS',
|
631 |
'USPS' => 'USPS',
|
632 |
'DHL US' => 'DHL_ECOMMERCE_US', // TODO: may be DHL
|
633 |
-
|
634 |
}
|
635 |
|
636 |
|
@@ -673,7 +673,7 @@ class Shipment {
|
|
673 |
|
674 |
if ( isset( $this->shipment_tracking_carriers[ $carrier ] ) ) {
|
675 |
$carrier_code = $this->shipment_tracking_carriers[ $carrier ];
|
676 |
-
|
677 |
$carrier_code = array_search( $carrier, $this->get_carrier_options(), true );
|
678 |
} elseif ( array_key_exists( $carrier, $this->get_carrier_options() ) ) {
|
679 |
$carrier_code = $carrier;
|
37 |
/**
|
38 |
* @see https://developers.facebook.com/docs/commerce-platform/order-management/carrier-codes
|
39 |
*/
|
40 |
+
$this->valid_carriers = array(
|
41 |
+
'AUSTRALIA_POST' => 'Australia Post',
|
42 |
+
'CANADA_POST' => 'Canada Post',
|
43 |
+
'DHL' => 'DHL',
|
44 |
+
'DHL_ECOMMERCE_US' => 'DHL eCommerce US',
|
45 |
+
'EAGLE' => 'Eagle',
|
46 |
+
'FEDEX' => 'FedEx',
|
47 |
+
'FEDEX_UK' => 'FedEx UK',
|
48 |
+
'NEW_ZEALAND_POST' => 'New Zealand Post',
|
49 |
+
'ONTRAC' => 'OnTrac',
|
50 |
+
'POST_DANMARK' => 'Post Danmark',
|
51 |
+
'PUROLATOR' => 'Purolator',
|
52 |
+
'ROYAL_MAIL' => 'Royal Mail',
|
53 |
+
'SPEE_DEE' => 'Spee-Dee',
|
54 |
+
'TNT' => 'TNT',
|
55 |
+
'TNT_POST' => 'TNT Post',
|
56 |
+
'UPS' => 'UPS',
|
57 |
+
'USPS' => 'USPS',
|
58 |
+
'OTHER' => 'Other tracking number',
|
59 |
+
'ABF_FREIGHT' => 'ABF Freight',
|
60 |
+
'ABX_EXPRESS' => 'ABX Express',
|
61 |
+
'AB_CUSTOM_GROUP' => 'AB Custom Group',
|
62 |
+
'ACOMMERCE' => 'aCommerce',
|
63 |
+
'ACS_COURIER' => 'ACS Courier',
|
64 |
+
'ACS_WORLDWIDE_EXPRESS' => 'ACS Worldwide Express',
|
65 |
+
'ADICIONAL_LOGISTICS' => 'Adicional Logistics',
|
66 |
+
'ADSONE' => 'ADSOne',
|
67 |
+
'AIR21' => 'AIR21',
|
68 |
+
'AIRPAK_EXPRESS' => 'Airpak Express',
|
69 |
+
'AIRSPEED_INTERNATIONAL_CORPORATION' => 'Airspeed International Corporation',
|
70 |
+
'ALFATREX' => 'AlfaTrex',
|
71 |
+
'ALLIED_EXPRESS' => 'Allied Express',
|
72 |
+
'ALLJOY_SUPPLY_CHAIN_CO_LTD' => 'ALLJOY SUPPLY CHAIN CO., LTD',
|
73 |
+
'ALPHAFAST' => 'alphaFAST',
|
74 |
+
'AMAZON_FBA_USA' => 'Amazon FBA USA',
|
75 |
+
'AMAZON_LOGISTICS' => 'Amazon Logistics',
|
76 |
+
'AN_POST' => 'An Post',
|
77 |
+
'APC_OVERNIGHT' => 'APC Overnight',
|
78 |
+
'APC_OVERNIGHT_REFERENCE' => 'APC Overnight Reference',
|
79 |
+
'APC_POSTAL_LOGISTICS' => 'APC Postal Logistics',
|
80 |
+
'APRISA_EXPRESS' => 'Aprisa Express',
|
81 |
+
'ARAMEX' => 'Aramex',
|
82 |
+
'ARROW_XL' => 'Arrow XL',
|
83 |
+
'ASENDIA_GERMANY' => 'Asendia Germany',
|
84 |
+
'ASENDIA_HK' => 'Asendia HK',
|
85 |
+
'ASENDIA_HK_PREMIUM_SERVICE_LATAM' => 'Asendia HK - Premium Service (LATAM)',
|
86 |
+
'ASENDIA_UK' => 'Asendia UK',
|
87 |
+
'ASENDIA_USA' => 'Asendia USA',
|
88 |
+
'ASM' => 'ASM',
|
89 |
+
'AUPOST_CHINA' => 'AuPost China',
|
90 |
+
'AUSTRALIA_POST_SFTP' => 'Australia Post Sftp',
|
91 |
+
'AUSTRIAN_POST_EXPRESS' => 'Austrian Post (Express)',
|
92 |
+
'AUSTRIAN_POST_REGISTERED' => 'Austrian Post (Registered)',
|
93 |
+
'AXL_EXPRESS_LOGISTICS' => 'AXL Express & Logistics',
|
94 |
+
'A_DUIE_PYLE' => 'A Duie Pyle',
|
95 |
+
'A_J_EXPRESS' => 'a j express',
|
96 |
+
'B2C_EUROPE' => 'B2C Europe',
|
97 |
+
'BELPOST' => 'Belpost',
|
98 |
+
'BERT_TRANSPORT' => 'Bert Transport',
|
99 |
+
'BEST_EXPRESS' => 'Best Express',
|
100 |
+
'BEST_WAY_PARCEL' => 'Best Way Parcel',
|
101 |
+
'BIRDSYSTEM' => 'BirdSystem',
|
102 |
+
'BJS_DISTRIBUTION_STORAGE_COURIERS' => 'BJS Distribution, Storage & Couriers',
|
103 |
+
'BJS_DISTRIBUTION_STORAGE_COURIERS_FTP' => 'BJS Distribution, Storage & Couriers - FTP',
|
104 |
+
'BLUECARE_EXPRESS_LTD' => 'Bluecare Express Ltd',
|
105 |
+
'BLUEDART' => 'Bluedart',
|
106 |
+
'BLUE_STAR' => 'Blue Star',
|
107 |
+
'BNEED' => 'Bneed',
|
108 |
+
'BONDS_COURIERS' => 'Bonds Couriers',
|
109 |
+
'BOXC' => 'BoxC',
|
110 |
+
'BPOST' => 'Bpost',
|
111 |
+
'BPOST_INTERNATIONAL' => 'Bpost international',
|
112 |
+
'BRAZIL_CORREIOS' => 'Brazil Correios',
|
113 |
+
'BRT_BARTOLINI' => 'BRT Bartolini',
|
114 |
+
'BRT_BARTOLINI_PARCEL_ID' => 'BRT Bartolini(Parcel ID)',
|
115 |
+
'BULGARIAN_POSTS' => 'Bulgarian Posts',
|
116 |
+
'BUYLOGIC' => 'Buylogic',
|
117 |
+
'CAMBODIA_POST' => 'Cambodia Post',
|
118 |
+
'CANPAR_COURIER' => 'Canpar Courier',
|
119 |
+
'CAPITAL_TRANSPORT' => 'Capital Transport',
|
120 |
+
'CARRIER_007EX' => '007EX',
|
121 |
+
'CARRIER_17_POST_SERVICE' => '17 Post Service',
|
122 |
+
'CARRIER_2GO' => '2GO',
|
123 |
+
'CARRIER_360_LION_EXPRESS' => '360 Lion Express',
|
124 |
+
'CARRIER_4PX' => '4PX',
|
125 |
+
'CARRIER_4_72_ENTREGANDO' => '4-72 Entregando',
|
126 |
+
'CARRIER_ECHO' => 'Echo',
|
127 |
+
'CBL_LOGISTICS' => 'CBL Logistics',
|
128 |
+
'CELERITAS_TRANSPORTE_SL' => 'Celeritas Transporte, S.L',
|
129 |
+
'CESKA_POSTA' => 'Česká Poš',
|
130 |
+
'CHINA_EMS_EPACKET' => 'China EMS (ePacket)',
|
131 |
+
'CHINA_POST' => 'China Post',
|
132 |
+
'CHIT_CHATS' => 'Chit Chats',
|
133 |
+
'CHRONOPOST_FRANCE' => 'Chronopost France',
|
134 |
+
'CHRONOPOST_PORTUGAL' => 'Chronopost Portugal',
|
135 |
+
'CH_ROBINSON_WORLDWIDE_INC' => 'C.H. Robinson Worldwide, Inc.',
|
136 |
+
'CITY_LINK_EXPRESS' => 'City-Link Express',
|
137 |
+
'CJ_CENTURY' => 'CJ Century',
|
138 |
+
'CJ_CENTURY_INTERNATIONAL' => 'CJ Century (International)',
|
139 |
+
'CJ_GLS' => 'CJ GLS',
|
140 |
+
'CJ_KOREA_EXPRESS' => 'CJ Korea Express',
|
141 |
+
'CJ_LOGISTICS_INTERNATIONAL' => 'CJ Logistics International',
|
142 |
+
'CJ_TRANSNATIONAL_PHILIPPINES' => 'CJ Transnational Philippines',
|
143 |
+
'CLEVY_LINKS' => 'Clevy Links',
|
144 |
+
'CLOUDWISH_ASIA' => 'Cloudwish Asia',
|
145 |
+
'CNE_EXPRESS' => 'CNE Express',
|
146 |
+
'COLISSIMO' => 'Colissimo',
|
147 |
+
'COLIS_PRIVE' => 'Colis Privé',
|
148 |
+
'COLLECTCO' => 'CollectCo',
|
149 |
+
'COLLECT_PLUS' => 'Collect+',
|
150 |
+
'CON_WAY_FREIGHT' => 'Con-way Freight',
|
151 |
+
'COPA_AIRLINES_COURIER' => 'Copa Airlines Courier',
|
152 |
+
'CORREOS_CHILE' => 'Correos Chile',
|
153 |
+
'CORREOS_DE_COSTA_RICA' => 'Correos de Costa Rica',
|
154 |
+
'CORREOS_DE_ESPANA' => 'Correos de España',
|
155 |
+
'CORREOS_DE_MEXICO' => 'Correos de Mexico',
|
156 |
+
'CORREOS_EXPRESS' => 'Correos Express',
|
157 |
+
'CORREO_ARGENTINO' => 'Correo Argentino',
|
158 |
+
'COSMETICS_NOW' => 'Cosmetics Now',
|
159 |
+
'COUREX' => 'Courex',
|
160 |
+
'COURIERPOST' => 'CourierPost',
|
161 |
+
'COURIERS_PLEASE' => 'Couriers Please',
|
162 |
+
'COURIER_IT' => 'Courier IT',
|
163 |
+
'COURIER_PLUS' => 'Courier Plus',
|
164 |
+
'CPACKET' => 'cPacket',
|
165 |
+
'CUCKOO_EXPRESS' => 'Cuckoo Express',
|
166 |
+
'CYPRUS_POST' => 'Cyprus Post',
|
167 |
+
'DACHSER' => 'DACHSER',
|
168 |
+
'DAWN_WING' => 'Dawn Wing',
|
169 |
+
'DAYLIGHT_TRANSPORT_LLC' => 'Daylight Transport, LLC',
|
170 |
+
'DB_SCHENKER' => 'DB Schenker',
|
171 |
+
'DB_SCHENKER_SWEDEN' => 'DB Schenker Sweden',
|
172 |
+
'DD_EXPRESS_COURIER' => 'DD Express Courier',
|
173 |
+
'DELCART' => 'Delcart',
|
174 |
+
'DELHIVERY' => 'Delhivery',
|
175 |
+
'DELIVERYONTIME_LOGISTICS_PVT_LTD' => 'DELIVERYONTIME LOGISTICS PVT LTD',
|
176 |
+
'DELTEC_COURIER' => 'Deltec Courier',
|
177 |
+
'DEMANDSHIP' => 'DemandShip',
|
178 |
+
'DETRACK' => 'Detrack',
|
179 |
+
'DEUTSCHE_POST_DHL' => 'Deutsche Post DHL',
|
180 |
+
'DEUTSCHE_POST_MAIL' => 'Deutsche Post Mail',
|
181 |
+
'DEX_I' => 'DEX-I',
|
182 |
+
'DHL_2_MANN_HANDLING' => 'DHL 2-Mann-Handling',
|
183 |
+
'DHL_ACTIVE_TRACING' => 'DHL Active Tracing',
|
184 |
+
'DHL_BENELUX' => 'DHL Benelux',
|
185 |
+
'DHL_ECOMMERCE_ASIA' => 'DHL eCommerce Asia',
|
186 |
+
'DHL_EXPRESS_PIECE_ID' => 'DHL Express (Piece ID)',
|
187 |
+
'DHL_GLOBAL_FORWARDING' => 'DHL Global Forwarding',
|
188 |
+
'DHL_HONG_KONG' => 'DHL Hong Kong',
|
189 |
+
'DHL_NETHERLANDS' => 'DHL Netherlands',
|
190 |
+
'DHL_PARCEL_NL' => 'DHL Parcel NL',
|
191 |
+
'DHL_PARCEL_SPAIN' => 'DHL Parcel Spain',
|
192 |
+
'DHL_POLAND_DOMESTIC' => 'DHL Poland Domestic',
|
193 |
+
'DHL_SPAIN_DOMESTIC' => 'DHL Spain Domestic',
|
194 |
+
'DIMERCO_EXPRESS_GROUP' => 'Dimerco Express Group',
|
195 |
+
'DIRECTLOG' => 'Directlog',
|
196 |
+
'DIRECT_FREIGHT_EXPRESS' => 'Direct Freight Express',
|
197 |
+
'DIRECT_LINK' => 'Direct Link',
|
198 |
+
'DMM_NETWORK' => 'DMM Network',
|
199 |
+
'DOORA_LOGISTICS' => 'Doora Logistics',
|
200 |
+
'DOTZOT' => 'Dotzot',
|
201 |
+
'DPD' => 'DPD',
|
202 |
+
'DPD_FRANCE' => 'DPD France',
|
203 |
+
'DPD_GERMANY' => 'DPD Germany',
|
204 |
+
'DPD_HK' => 'DPD HK',
|
205 |
+
'DPD_IRELAND' => 'DPD Ireland',
|
206 |
+
'DPD_LOCAL' => 'DPD Local',
|
207 |
+
'DPD_LOCAL_REFERENCE' => 'DPD Local reference',
|
208 |
+
'DPD_POLAND' => 'DPD Poland',
|
209 |
+
'DPD_ROMANIA' => 'DPD Romania',
|
210 |
+
'DPD_RUSSIA' => 'DPD Russia',
|
211 |
+
'DPD_UK' => 'DPD UK',
|
212 |
+
'DPEX' => 'DPEX',
|
213 |
+
'DPEX_CHINA' => 'DPEX China',
|
214 |
+
'DPE_EXPRESS' => 'DPE Express',
|
215 |
+
'DPE_SOUTH_AFRICA' => 'DPE South Africa',
|
216 |
+
'DSV' => 'DSV',
|
217 |
+
'DTDC_AUSTRALIA' => 'DTDC Australia',
|
218 |
+
'DTDC_EXPRESS_GLOBAL_PTE_LTD' => 'DTDC Express Global PTE LTD',
|
219 |
+
'DTDC_INDIA' => 'DTDC India',
|
220 |
+
'DX' => 'DX',
|
221 |
+
'DX_FREIGHT' => 'DX Freight',
|
222 |
+
'DYNALOGIC_BENELUX_BV' => 'Dynalogic Benelux BV',
|
223 |
+
'DYNAMIC_LOGISTICS' => 'Dynamic Logistics',
|
224 |
+
'EASY_MAIL' => 'Easy Mail',
|
225 |
+
'ECARGO' => 'Ecargo',
|
226 |
+
'ECMS_INTERNATIONAL_LOGISTICS_CO_LTD' => 'ECMS International Logistics Co., Ltd.',
|
227 |
+
'ECOM_EXPRESS' => 'Ecom Express',
|
228 |
+
'EC_FIRSTCLASS' => 'EC-Firstclass',
|
229 |
+
'EFS_E_COMMERCE_FULFILLMENT_SERVICE' => 'EFS (E-commerce Fulfillment Service)',
|
230 |
+
'EKART' => 'Ekart',
|
231 |
+
'ELTA_HELLENIC_POST' => 'ELTA Hellenic Post',
|
232 |
+
'EMIRATES_POST' => 'Emirates Post',
|
233 |
+
'EMPS_EXPRESS' => 'EMPS Express',
|
234 |
+
'ENSENDA' => 'Ensenda',
|
235 |
+
'ENVIALIA' => 'Envialia',
|
236 |
+
'EPARCEL_KOREA' => 'eParcel Korea',
|
237 |
+
'EP_BOX' => 'EP-Box',
|
238 |
+
'EQUICK_CHINA' => 'Equick China',
|
239 |
+
'ESTAFETA' => 'Estafeta',
|
240 |
+
'ESTES' => 'Estes',
|
241 |
+
'ETOTAL_SOLUTION_LIMITED' => 'eTotal Solution Limited',
|
242 |
+
'EURODIS' => 'Eurodis',
|
243 |
+
'EXPEDITORS' => 'Expeditors',
|
244 |
+
'EZSHIP' => 'EZship',
|
245 |
+
'FASTRAK_SERVICES' => 'Fastrak Services',
|
246 |
+
'FASTWAY_AUSTRALIA' => 'Fastway Australia',
|
247 |
+
'FASTWAY_IRELAND' => 'Fastway Ireland',
|
248 |
+
'FASTWAY_NEW_ZEALAND' => 'Fastway New Zealand',
|
249 |
+
'FASTWAY_SOUTH_AFRICA' => 'Fastway South Africa',
|
250 |
+
'FEDEX_CROSS_BORDER' => 'Fedex Cross Border',
|
251 |
+
'FEDEX_FREIGHT' => 'FedEx Freight',
|
252 |
+
'FEDEX_POLAND_DOMESTIC' => 'FedEx Poland Domestic',
|
253 |
+
'FERCAM_LOGISTICS_TRANSPORT' => 'FERCAM Logistics & Transport',
|
254 |
+
'FIRST_FLIGHT_COURIERS' => 'First Flight Couriers',
|
255 |
+
'FIRST_LOGISTICS' => 'First Logistics',
|
256 |
+
'FLYT_EXPRESS' => 'Flyt Express',
|
257 |
+
'GATI_KWE' => 'Gati-KWE',
|
258 |
+
'GDEX' => 'GDEX',
|
259 |
+
'GENIKI_TAXYDROMIKI' => 'Geniki Taxydromiki',
|
260 |
+
'GEODIS_E_SPACE' => 'Geodis E-space',
|
261 |
+
'GEODIS_DISTRIBUTION_EXPRESS' => 'GEODIS - Distribution & Express',
|
262 |
+
'GIAO_HANG_NHANH' => 'Giao hàng nhanh',
|
263 |
+
'GLOBEGISTICS_INC' => 'Globegistics Inc.',
|
264 |
+
'GLS' => 'GLS',
|
265 |
+
'GLS_CZECH_REPUBLIC' => 'GLS Czech Republic',
|
266 |
+
'GLS_ITALY' => 'GLS Italy',
|
267 |
+
'GLS_NETHERLANDS' => 'GLS Netherlands',
|
268 |
+
'GOFLY' => 'GoFly',
|
269 |
+
'GOJAVAS' => 'GoJavas',
|
270 |
+
'GREYHOUND' => 'Greyhound',
|
271 |
+
'GSI_EXPRESS' => 'GSI EXPRESS',
|
272 |
+
'HERMESWORLD' => 'Hermesworld',
|
273 |
+
'HERMES_GERMANY' => 'Hermes Germany',
|
274 |
+
'HERMES_ITALY' => 'Hermes Italy',
|
275 |
+
'HOLISOL' => 'Holisol',
|
276 |
+
'HOMEDIRECT_LOGISTICS' => 'Homedirect Logistics',
|
277 |
+
'HONG_KONG_POST' => 'Hong Kong Post',
|
278 |
+
'HRVATSKA_POSTA' => 'Hrvatska Pošta',
|
279 |
+
'HUA_HAN_LOGISTICS' => 'Hua Han Logistics',
|
280 |
+
'HUNTER_EXPRESS' => 'Hunter Express',
|
281 |
+
'ICELAND_POST' => 'Iceland Post',
|
282 |
+
'IDEX' => 'IDEX',
|
283 |
+
'IMEX_GLOBAL_SOLUTIONS' => 'IMEX Global Solutions',
|
284 |
+
'IMX_MAIL' => 'IMX Mail',
|
285 |
+
'INDIA_POST_DOMESTIC' => 'India Post Domestic',
|
286 |
+
'INDIA_POST_INTERNATIONAL' => 'India Post International',
|
287 |
+
'INPOST_PACZKOMATY' => 'InPost Paczkomaty',
|
288 |
+
'INSTANT_TIONG_NAM_EBIZ_EXPRESS_SDN_BHD' => 'INSTANT (Tiong Nam Ebiz Express Sdn Bhd)',
|
289 |
+
'INTERNATIONAL_SEUR' => 'International Seur',
|
290 |
+
'INTERNET_EXPRESS' => 'Internet Express',
|
291 |
+
'ISRAEL_POST' => 'Israel Post',
|
292 |
+
'ISRAEL_POST_DOMESTIC' => 'Israel Post Domestic',
|
293 |
+
'ITALY_SDA' => 'Italy SDA',
|
294 |
+
'I_PARCEL' => 'i-parcel',
|
295 |
+
'J_T_EXPRESS' => 'J&T EXPRESS',
|
296 |
+
'JAM_EXPRESS' => 'Jam Express',
|
297 |
+
'JANCO_ECOMMERCE' => 'Janco Ecommerce',
|
298 |
+
'JAPAN_POST' => 'Japan Post',
|
299 |
+
'JAYON_EXPRESS_JEX' => 'Jayon Express (JEX)',
|
300 |
+
'JCEX' => 'JCEX',
|
301 |
+
'JERSEY_POST' => 'Jersey Post',
|
302 |
+
'JET_SHIP_WORLDWIDE' => 'Jet-Ship Worldwide',
|
303 |
+
'JINSUNG_TRADING' => 'JINSUNG TRADING',
|
304 |
+
'JNE' => 'JNE',
|
305 |
+
'JOCOM' => 'Jocom',
|
306 |
+
'JP_BH_POSTA' => 'JP BH Pošta',
|
307 |
+
'JX' => 'JX',
|
308 |
+
'J_NET' => 'J-Net',
|
309 |
+
'K1_EXPRESS' => 'K1 Express',
|
310 |
+
'KANGAROO_WORLDWIDE_EXPRESS' => 'Kangaroo Worldwide Express',
|
311 |
+
'KERRY_EXPRESS_HONG_KONG' => 'Kerry Express Hong Kong',
|
312 |
+
'KERRY_EXPRESS_THAILAND' => 'Kerry Express Thailand',
|
313 |
+
'KERRY_EXPRESS_VIETNAM_CO_LTD' => 'Kerry Express (Vietnam) Co Ltd',
|
314 |
+
'KGM_HUB' => 'KGM Hub',
|
315 |
+
'KIALA' => 'Kiala',
|
316 |
+
'KOREA_POST' => 'Korea Post',
|
317 |
+
'KOREA_POST_EMS' => 'Korea Post EMS',
|
318 |
+
'KRONOS_EXPRESS' => 'Kronos Express',
|
319 |
+
'KUEHNE_NAGEL' => 'Kuehne + Nagel',
|
320 |
+
'LANDMARK_GLOBAL' => 'Landmark Global',
|
321 |
+
'LAO_POST' => 'Lao Post',
|
322 |
+
'LASERSHIP' => 'LaserShip',
|
323 |
+
'LA_POSTE' => 'La Poste',
|
324 |
+
'LBC_EXPRESS' => 'LBC Express',
|
325 |
+
'LHT_EXPRESS' => 'LHT Express',
|
326 |
+
'LIETUVOS_PASTAS' => 'Lietuvos Paštas',
|
327 |
+
'LINE_CLEAR_EXPRESS_LOGISTICS_SDN_BHD' => 'Line Clear Express & Logistics Sdn Bhd',
|
328 |
'LINK_BRIDGE_BEIJING_INTERNATIONAL_LOGISTICS_COLTD' => 'Link Bridge(BeiJing)international logistics co.,ltd',
|
329 |
+
'LION_PARCEL' => 'Lion Parcel',
|
330 |
+
'LOGISTIC_WORLDWIDE_EXPRESS' => 'Logistic Worldwide Express',
|
331 |
+
'LOGWIN_LOGISTICS' => 'Logwin Logistics',
|
332 |
+
'LONE_STAR_OVERNIGHT' => 'Lone Star Overnight',
|
333 |
+
'MAGYAR_POSTA' => 'Magyar Posta',
|
334 |
+
'MAILAMERICAS' => 'MailAmericas',
|
335 |
+
'MAILPLUS' => 'MailPlus',
|
336 |
+
'MAINFREIGHT' => 'Mainfreight',
|
337 |
+
'MALAYSIA_POST_EMS_POS_LAJU' => 'Malaysia Post EMS / Pos Laju',
|
338 |
+
'MALAYSIA_POST_REGISTERED' => 'Malaysia Post - Registered',
|
339 |
+
'MARA_XPRESS' => 'Mara Xpress',
|
340 |
+
'MATDESPATCH' => 'Matdespatch',
|
341 |
+
'MATKAHUOLTO' => 'Matkahuolto',
|
342 |
+
'MDS_COLLIVERY_PTY_LTD' => 'MDS Collivery Pty (Ltd)',
|
343 |
+
'MEGASAVE' => 'Megasave',
|
344 |
+
'MEXICO_AEROFLASH' => 'Mexico AeroFlash',
|
345 |
+
'MEXICO_REDPACK' => 'Mexico Redpack',
|
346 |
+
'MEXICO_SENDA_EXPRESS' => 'Mexico Senda Express',
|
347 |
+
'MIKROPAKKET' => 'Mikropakket',
|
348 |
+
'MONDIAL_RELAY' => 'Mondial Relay',
|
349 |
+
'MRW' => 'MRW',
|
350 |
+
'MUDITA' => 'MUDITA',
|
351 |
+
'MXE_EXPRESS' => 'MXE Express',
|
352 |
+
'MYHERMES_UK' => 'myHermes UK',
|
353 |
+
'MYPOSTONLINE' => 'Mypostonline',
|
354 |
+
'M_XPRESS_SDN_BHD' => 'M Xpress Sdn Bhd',
|
355 |
+
'NACEX_SPAIN' => 'NACEX Spain',
|
356 |
+
'NANJING_WOYUAN' => 'Nanjing Woyuan',
|
357 |
+
'NATIONAL_SAMEDAY' => 'National Sameday',
|
358 |
+
'NATIONWIDE_EXPRESS' => 'Nationwide Express',
|
359 |
+
'NEWGISTICS' => 'Newgistics',
|
360 |
+
'NEWGISTICS_API' => 'Newgistics API',
|
361 |
+
'NEXIVE_TNT_POST_ITALY' => 'Nexive (TNT Post Italy)',
|
362 |
+
'NHANS_SOLUTIONS' => 'Nhans Solutions',
|
363 |
+
'NIGHTLINE' => 'Nightline',
|
364 |
+
'NIM_EXPRESS' => 'Nim Express',
|
365 |
+
'NINJA_VAN' => 'Ninja Van',
|
366 |
+
'NINJA_VAN_INDONESIA' => 'Ninja Van Indonesia',
|
367 |
+
'NINJA_VAN_MALAYSIA' => 'Ninja Van Malaysia',
|
368 |
+
'NINJA_VAN_PHILIPPINES' => 'Ninja Van Philippines',
|
369 |
+
'NINJA_VAN_THAILAND' => 'Ninja Van Thailand',
|
370 |
+
'NIPOST' => 'NiPost',
|
371 |
+
'NORSK_GLOBAL' => 'Norsk Global',
|
372 |
+
'NOVA_POSHTA' => 'Nova Poshta',
|
373 |
+
'NOVA_POSHTA_INTERNATIONAL' => 'Nova Poshta (International)',
|
374 |
+
'OCA_ARGENTINA' => 'OCA Argentina',
|
375 |
+
'OLD_DOMINION_FREIGHT_LINE' => 'Old Dominion Freight Line',
|
376 |
+
'OMNIVA' => 'Omniva',
|
377 |
+
'OMNI_PARCEL' => 'Omni Parcel',
|
378 |
+
'ONE_WORLD_EXPRESS' => 'One World Express',
|
379 |
+
'PACKLINK' => 'Packlink',
|
380 |
+
'PAL_EXPRESS_LIMITED' => 'PAL Express Limited',
|
381 |
+
'PANDU_LOGISTICS' => 'Pandu Logistics',
|
382 |
+
'PANTHER' => 'Panther',
|
383 |
+
'PANTHER_ORDER_NUMBER' => 'Panther Order Number',
|
384 |
+
'PANTHER_REFERENCE' => 'Panther Reference',
|
385 |
+
'PAQUETEXPRESS' => 'Paquetexpress',
|
386 |
+
'PARCELLEDIN' => 'Parcelled.in',
|
387 |
+
'PARCELPOINT_PTY_LTD' => 'ParcelPoint Pty Ltd',
|
388 |
+
'PARCEL_FORCE' => 'Parcel Force',
|
389 |
+
'PARCEL_POST_SINGAPORE' => 'Parcel Post Singapore',
|
390 |
+
'PAYPAL_PACKAGE' => 'PayPal Package',
|
391 |
+
'PFC_EXPRESS' => 'PFC Express',
|
392 |
+
'PICKUPP' => 'Pickupp',
|
393 |
+
'PICK_UPP_MYS_SGP' => 'PICK UPP',
|
394 |
+
'PILOT_FREIGHT_SERVICES' => 'Pilot Freight Services',
|
395 |
+
'PITNEY_BOWES' => 'Pitney Bowes',
|
396 |
+
'PIXSELL_LOGISTICS' => 'PIXSELL LOGISTICS',
|
397 |
+
'POCZTA_POLSKA' => 'Poczta Polska',
|
398 |
+
'PORTUGAL_CTT' => 'Portugal CTT',
|
399 |
+
'PORTUGAL_SEUR' => 'Portugal Seur',
|
400 |
+
'POST56' => 'Post56',
|
401 |
+
'POSTEN_NORGE_BRING' => 'Posten Norge / Bring',
|
402 |
+
'POSTE_ITALIANE' => 'Poste Italiane',
|
403 |
+
'POSTE_ITALIANE_PACCOCELERE' => 'Poste Italiane Paccocelere',
|
404 |
+
'POSTI' => 'Posti',
|
405 |
+
'POSTNL_DOMESTIC' => 'PostNL Domestic',
|
406 |
+
'POSTNL_INTERNATIONAL' => 'PostNL International',
|
407 |
+
'POSTNL_INTERNATIONAL_3S' => 'PostNL International 3S',
|
408 |
+
'POSTNORD_DENMARK' => 'PostNord Denmark',
|
409 |
+
'POSTNORD_LOGISTICS' => 'PostNord Logistics',
|
410 |
+
'POSTNORD_SWEDEN' => 'PostNord Sweden',
|
411 |
+
'POST_OF_SLOVENIA' => 'Post of Slovenia',
|
412 |
+
'POST_SERBIA' => 'Post Serbia',
|
413 |
+
'POS_INDONESIA_DOMESTIC' => 'Pos Indonesia Domestic',
|
414 |
+
'POS_INDONESIA_INTL' => "Pos Indonesia Int'l",
|
415 |
+
'POSTA_ROMANA' => 'Poșta Română',
|
416 |
+
'PROFESSIONAL_COURIERS' => 'Professional Couriers',
|
417 |
+
'PTT_POSTA' => 'PTT Posta',
|
418 |
+
'QUALITYPOST' => 'QualityPost',
|
419 |
+
'QUANTIUM' => 'Quantium',
|
420 |
+
'QXPRESS' => 'Qxpress',
|
421 |
+
'RABEN_GROUP' => 'Raben Group',
|
422 |
+
'RAF_PHILIPPINES' => 'RAF Philippines',
|
423 |
+
'RAIDEREX' => 'RaidereX',
|
424 |
+
'RAM' => 'RAM',
|
425 |
+
'REDUR_SPAIN' => 'Redur Spain',
|
426 |
+
'RED_CARPET_LOGISTICS' => 'Red Carpet Logistics',
|
427 |
+
'RINCOS' => 'Rincos',
|
428 |
+
'RL_CARRIERS' => 'RL Carriers',
|
429 |
+
'ROADBULL_LOGISTICS' => 'Roadbull Logistics',
|
430 |
+
'ROCKET_PARCEL_INTERNATIONAL' => 'Rocket Parcel International',
|
431 |
+
'RPD2MAN_DELIVERIES' => 'RPD2man Deliveries',
|
432 |
+
'RPX_INDONESIA' => 'RPX Indonesia',
|
433 |
+
'RPX_ONLINE' => 'RPX Online',
|
434 |
+
'RRD_INTERNATIONAL_LOGISTICS_USA' => 'RRD International Logistics U.S.A',
|
435 |
+
'RUSSIAN_POST' => 'Russian Post',
|
436 |
+
'RUSTON' => 'Ruston',
|
437 |
+
'RZY_EXPRESS' => 'RZY Express',
|
438 |
+
'SAFEXPRESS' => 'Safexpress',
|
439 |
+
'SAGAWA' => 'Sagawa',
|
440 |
+
'SAIA_LTL_FREIGHT' => 'Saia LTL Freight',
|
441 |
+
'SAILPOST' => 'SAILPOST',
|
442 |
+
'SAP_EXPRESS' => 'SAP EXPRESS',
|
443 |
+
'SAUDI_POST' => 'Saudi Post',
|
444 |
+
'SCUDEX_EXPRESS' => 'Scudex Express',
|
445 |
+
'SEINO' => 'Seino',
|
446 |
+
'SEKO_LOGISTICS' => 'SEKO Logistics',
|
447 |
+
'SENDING_TRANSPORTE_URGENTE_Y_COMUNICACION_SAU' => 'Sending Transporte Urgente y Comunicacion, S.A.U',
|
448 |
+
'SENDIT' => 'Sendit',
|
449 |
+
'SENDLE' => 'Sendle',
|
450 |
+
'SFC_SERVICE' => 'SFC Service',
|
451 |
+
'SF_EXPRESS' => 'S.F. Express',
|
452 |
+
'SF_INTERNATIONAL' => 'S.F International',
|
453 |
+
'SGT_CORRIERE_ESPRESSO' => 'SGT Corriere Espresso',
|
454 |
+
'SHANGHAI_WISE_SUPPLY_CHAIN_MANAGEMENT_CO_LTD' => '上海万色供应链管理有限公司(原:上海万色速递有限公司) Shanghai Wise Supply Chain Management Co., Ltd',
|
455 |
+
'SHENZHEN_JINGHUADA_LOGISTICS_CO_LTD' => 'Shenzhen Jinghuada Logistics Co., Ltd',
|
456 |
+
'SHIPPIT' => 'Shippit',
|
457 |
+
'SHIPTOR' => 'Shiptor',
|
458 |
+
'SHOPFANSRU_LLC' => 'ShopfansRU LLC',
|
459 |
+
'SHREE_MARUTI_COURIER_SERVICES_PVT_LTD' => 'Shree Maruti Courier Services Pvt Ltd',
|
460 |
+
'SHREE_TIRUPATI_COURIER_SERVICES_PVT_LTD' => 'SHREE TIRUPATI COURIER SERVICES PVT. LTD.',
|
461 |
+
'SHUNYOU_POST' => 'Shunyou Post',
|
462 |
+
'SIMPLYPOST' => 'SimplyPost',
|
463 |
+
'SINGAPORE_POST' => 'Singapore Post',
|
464 |
+
'SINGAPORE_SPEEDPOST' => 'Singapore Speedpost',
|
465 |
+
'SIODEMKA' => 'Siodemka',
|
466 |
+
'SKYBOX' => 'SKYBOX',
|
467 |
+
'SKYNET_MALAYSIA' => 'SkyNet Malaysia',
|
468 |
+
'SKYNET_WORLDWIDE_EXPRESS' => 'SkyNet Worldwide Express',
|
469 |
+
'SKYNET_WORLDWIDE_EXPRESS_UAE' => 'SkyNet Worldwide Express UAE',
|
470 |
+
'SKYNET_WORLDWIDE_EXPRESS_UK' => 'Skynet Worldwide Express UK',
|
471 |
+
'SKYNET_WORLD_WIDE_EXPRESS_SOUTH_AFRICA' => 'Skynet World Wide Express South Africa',
|
472 |
+
'SKYPOSTAL' => 'SkyPostal',
|
473 |
+
'SMOOTH_COURIERS' => 'Smooth Couriers',
|
474 |
+
'SMSA_EXPRESS' => 'SMSA Express',
|
475 |
+
'SOUTH_AFRICAN_POST_OFFICE' => 'South African Post Office',
|
476 |
+
'SPANISH_SEUR' => 'Spanish Seur',
|
477 |
+
'SPECIALISED_FREIGHT' => 'Specialised Freight',
|
478 |
+
'SPEEDEX_COURIER' => 'Speedex Courier',
|
479 |
+
'SPEED_COURIERS' => 'Speed Couriers',
|
480 |
+
'SPOTON_LOGISTICS_PVT_LTD' => 'SPOTON Logistics Pvt Ltd',
|
481 |
+
'SRE_KOREA' => 'SRE Korea',
|
482 |
+
'STARTRACK' => 'StarTrack',
|
483 |
+
'STAR_TRACK_COURIER' => 'Star Track Courier',
|
484 |
+
'STAR_TRACK_EXPRESS' => 'Star Track Express',
|
485 |
+
'STO_EXPRESS' => 'STO Express',
|
486 |
+
'SWISS_POST' => 'Swiss Post',
|
487 |
+
'TAIWAN_POST' => 'Taiwan Post',
|
488 |
+
'TAQBIN_HONG_KONG' => 'TAQBIN Hong Kong',
|
489 |
+
'TAQBIN_MALAYSIA' => 'TAQBIN Malaysia',
|
490 |
+
'TAQBIN_SINGAPORE' => 'TAQBIN Singapore',
|
491 |
+
'TCS' => 'TCS',
|
492 |
+
'TELIWAY_SIC_EXPRESS' => 'Teliway SIC Express',
|
493 |
+
'THAILAND_THAI_POST' => 'Thailand Thai Post',
|
494 |
+
'THE_COURIER_GUY' => 'The Courier Guy',
|
495 |
+
'TIKI' => 'Tiki',
|
496 |
+
'TIPSA' => 'TIPSA',
|
497 |
+
'TNT_AUSTRALIA' => 'TNT Australia',
|
498 |
+
'TNT_CLICK_ITALY' => 'TNT-Click Italy',
|
499 |
+
'TNT_FRANCE' => 'TNT France',
|
500 |
+
'TNT_ITALY' => 'TNT Italy',
|
501 |
+
'TNT_REFERENCE' => 'TNT Reference',
|
502 |
+
'TNT_UK_REFERENCE' => 'TNT UK Reference',
|
503 |
+
'TOLL_IPEC' => 'Toll IPEC',
|
504 |
+
'TOLL_PRIORITY' => 'Toll Priority',
|
505 |
+
'TOLOS' => 'Tolos',
|
506 |
+
'TRAKPAK' => 'TrakPak',
|
507 |
+
'TRANSMISSION' => 'TransMission',
|
508 |
+
'TRANS_KARGO_INTERNASIONAL' => 'Trans Kargo Internasional',
|
509 |
+
'TUFFNELLS_PARCELS_EXPRESS' => 'Tuffnells Parcels Express',
|
510 |
+
'UBI_SMART_PARCEL' => 'UBI Smart Parcel',
|
511 |
+
'UKRPOSHTA' => 'UkrPoshta',
|
512 |
+
'UK_MAIL' => 'UK Mail',
|
513 |
+
'UNITED_DELIVERY_SERVICE_LTD' => 'United Delivery Service, Ltd',
|
514 |
+
'UPS_FREIGHT' => 'UPS Freight',
|
515 |
+
'UPS_MAIL_INNOVATIONS' => 'UPS Mail Innovations',
|
516 |
+
'VIETNAM_POST' => 'Vietnam Post',
|
517 |
+
'VIETNAM_POST_EMS' => 'Vietnam Post EMS',
|
518 |
+
'VIETTELPOST' => 'ViettelPost',
|
519 |
+
'WAHANA' => 'Wahana',
|
520 |
+
'WANBEXPRESS' => 'WanbExpress',
|
521 |
+
'WEDO_LOGISTICS' => 'WeDo Logistics',
|
522 |
+
'WEPOST_LOGISTICS' => 'WePost Logistics',
|
523 |
+
'WHISTL' => 'Whistl',
|
524 |
+
'WISELOADS' => 'Wiseloads',
|
525 |
+
'WISE_EXPRESS' => 'Wise Express',
|
526 |
+
'WISHPOST' => 'WishPost',
|
527 |
+
'WNDIRECT' => 'wnDirect',
|
528 |
+
'XDP_EXPRESS' => 'XDP Express',
|
529 |
+
'XDP_EXPRESS_REFERENCE' => 'XDP Express Reference',
|
530 |
+
'XEND_EXPRESS' => 'Xend Express',
|
531 |
+
'XL_EXPRESS' => 'XL Express',
|
532 |
+
'XPOSTPH' => 'Xpost.ph',
|
533 |
+
'XPRESSBEES' => 'XpressBees',
|
534 |
+
'XQ_EXPRESS' => 'XQ Express',
|
535 |
+
'YAKIT' => 'Yakit',
|
536 |
+
'YAMATO_JAPAN' => 'Yamato Japan',
|
537 |
+
'YANWEN' => 'Yanwen',
|
538 |
+
'YODEL_DOMESTIC' => 'Yodel Domestic',
|
539 |
+
'YODEL_INTERNATIONAL' => 'Yodel International',
|
540 |
+
'YRC' => 'YRC',
|
541 |
+
'YTO_EXPRESS' => 'YTO Express',
|
542 |
+
'YUNDA_EXPRESS' => 'Yunda Express',
|
543 |
+
'YUN_EXPRESS' => 'Yun Express',
|
544 |
+
'ZEPTOEXPRESS' => 'ZeptoExpress',
|
545 |
+
'ZINC' => 'Zinc',
|
546 |
+
'ZJS_INTERNATIONAL' => 'ZJS International',
|
547 |
+
'ZTO_EXPRESS' => 'ZTO Express',
|
548 |
+
'ZYLLEM' => 'Zyllem',
|
549 |
+
);
|
550 |
|
551 |
/**
|
552 |
* @see https://docs.woocommerce.com/document/shipment-tracking/#section-5
|
553 |
*/
|
554 |
+
$this->shipment_tracking_carriers = array(
|
555 |
// Australia
|
556 |
'Australia Post' => 'AUSTRALIA_POST',
|
557 |
'Fastway Couriers' => 'FASTWAY_AUSTRALIA',
|
630 |
'UPS' => 'UPS',
|
631 |
'USPS' => 'USPS',
|
632 |
'DHL US' => 'DHL_ECOMMERCE_US', // TODO: may be DHL
|
633 |
+
);
|
634 |
}
|
635 |
|
636 |
|
673 |
|
674 |
if ( isset( $this->shipment_tracking_carriers[ $carrier ] ) ) {
|
675 |
$carrier_code = $this->shipment_tracking_carriers[ $carrier ];
|
676 |
+
} elseif ( in_array( $carrier, $this->get_carrier_options(), true ) ) {
|
677 |
$carrier_code = array_search( $carrier, $this->get_carrier_options(), true );
|
678 |
} elseif ( array_key_exists( $carrier, $this->get_carrier_options() ) ) {
|
679 |
$carrier_code = $carrier;
|
includes/Utilities/Tracker.php
CHANGED
@@ -48,7 +48,7 @@ class Tracker {
|
|
48 |
// Is the site connected?
|
49 |
// @since 2.3.4
|
50 |
$connection_is_happy = false;
|
51 |
-
$connection_handler
|
52 |
if ( $connection_handler ) {
|
53 |
$connection_is_happy = $connection_handler->is_connected() && ! get_transient( 'wc_facebook_connection_invalid' );
|
54 |
}
|
48 |
// Is the site connected?
|
49 |
// @since 2.3.4
|
50 |
$connection_is_happy = false;
|
51 |
+
$connection_handler = facebook_for_woocommerce()->get_connection_handler();
|
52 |
if ( $connection_handler ) {
|
53 |
$connection_is_happy = $connection_handler->is_connected() && ! get_transient( 'wc_facebook_connection_invalid' );
|
54 |
}
|
includes/fbgraph.php
CHANGED
@@ -52,12 +52,12 @@ if ( ! class_exists( 'WC_Facebookcommerce_Graph_API' ) ) :
|
|
52 |
|
53 |
$api_key = $api_key ?: $this->api_key;
|
54 |
|
55 |
-
$request_args =
|
56 |
-
'headers' =>
|
57 |
'Authorization' => 'Bearer ' . $api_key,
|
58 |
-
|
59 |
'timeout' => self::CURL_TIMEOUT,
|
60 |
-
|
61 |
|
62 |
$response = wp_remote_get( $url, $request_args );
|
63 |
|
@@ -80,12 +80,12 @@ if ( ! class_exists( 'WC_Facebookcommerce_Graph_API' ) ) :
|
|
80 |
*/
|
81 |
public function perform_request( $url ) {
|
82 |
|
83 |
-
$request_args =
|
84 |
-
'headers' =>
|
85 |
'Authorization' => 'Bearer ' . $this->api_key,
|
86 |
-
|
87 |
'timeout' => self::CURL_TIMEOUT,
|
88 |
-
|
89 |
|
90 |
$response = wp_remote_get( $url, $request_args );
|
91 |
|
@@ -102,7 +102,7 @@ if ( ! class_exists( 'WC_Facebookcommerce_Graph_API' ) ) :
|
|
102 |
if ( isset( $response_body->error->code, $response_body->error->message ) ) {
|
103 |
throw new Framework\SV_WC_API_Exception( $response_body->error->message, $response_body->error->code );
|
104 |
} else {
|
105 |
-
throw new Framework\SV_WC_API_Exception( sprintf( __( 'HTTP %s: %s', 'facebook-for-woocommerce' ), wp_remote_retrieve_response_code( $response ), wp_remote_retrieve_response_message( $response ) ) );
|
106 |
}
|
107 |
}
|
108 |
|
@@ -121,13 +121,13 @@ if ( ! class_exists( 'WC_Facebookcommerce_Graph_API' ) ) :
|
|
121 |
public function _post_sync( $url, $data, $api_key = '' ) {
|
122 |
$api_key = $api_key ?: $this->api_key;
|
123 |
|
124 |
-
$request_args =
|
125 |
'body' => $data,
|
126 |
-
'headers' =>
|
127 |
'Authorization' => 'Bearer ' . $api_key,
|
128 |
-
|
129 |
'timeout' => self::CURL_TIMEOUT,
|
130 |
-
|
131 |
|
132 |
$response = wp_remote_post( $url, $request_args );
|
133 |
|
@@ -141,7 +141,7 @@ if ( ! class_exists( 'WC_Facebookcommerce_Graph_API' ) ) :
|
|
141 |
* Issues an asynchronous POST request to the Graph API.
|
142 |
*
|
143 |
* @param string $url request URL
|
144 |
-
* @param array
|
145 |
* @param string $api_key Graph API key
|
146 |
* @return array|\WP_Error
|
147 |
*/
|
@@ -153,16 +153,15 @@ if ( ! class_exists( 'WC_Facebookcommerce_Graph_API' ) ) :
|
|
153 |
|
154 |
$api_key = $api_key ?: $this->api_key;
|
155 |
|
156 |
-
$request_args =
|
157 |
'body' => $data,
|
158 |
-
'headers' =>
|
159 |
'Authorization' => 'Bearer ' . $api_key,
|
160 |
-
|
161 |
'timeout' => self::CURL_TIMEOUT,
|
162 |
-
|
163 |
-
|
164 |
|
165 |
-
$fbasync
|
166 |
$fbasync->query_url = $url;
|
167 |
$fbasync->query_args = array();
|
168 |
$fbasync->post_args = $request_args;
|
@@ -186,13 +185,13 @@ if ( ! class_exists( 'WC_Facebookcommerce_Graph_API' ) ) :
|
|
186 |
|
187 |
$api_key = $api_key ?: $this->api_key;
|
188 |
|
189 |
-
$request_args =
|
190 |
-
'headers' =>
|
191 |
'Authorization' => 'Bearer ' . $api_key,
|
192 |
-
|
193 |
'timeout' => self::CURL_TIMEOUT,
|
194 |
'method' => 'DELETE',
|
195 |
-
|
196 |
|
197 |
$response = wp_remote_request( $url, $request_args );
|
198 |
|
@@ -210,7 +209,7 @@ if ( ! class_exists( 'WC_Facebookcommerce_Graph_API' ) ) :
|
|
210 |
* @param $url
|
211 |
* @param $request_args
|
212 |
* @param array|\WP_Error $response WordPress response object
|
213 |
-
* @param string
|
214 |
*/
|
215 |
private function log_request( $url, $request_args, $response, $method = '' ) {
|
216 |
|
@@ -220,9 +219,12 @@ if ( ! class_exists( 'WC_Facebookcommerce_Graph_API' ) ) :
|
|
220 |
}
|
221 |
|
222 |
// add the URI to the data
|
223 |
-
$request_data = array_merge(
|
224 |
-
|
225 |
-
|
|
|
|
|
|
|
226 |
|
227 |
// the request args may not include the method, so allow it to be set
|
228 |
if ( $method ) {
|
@@ -242,7 +244,7 @@ if ( ! class_exists( 'WC_Facebookcommerce_Graph_API' ) ) :
|
|
242 |
|
243 |
$code = $response->get_error_code();
|
244 |
$message = $response->get_error_message();
|
245 |
-
$headers =
|
246 |
$body = '';
|
247 |
|
248 |
} else {
|
@@ -252,7 +254,7 @@ if ( ! class_exists( 'WC_Facebookcommerce_Graph_API' ) ) :
|
|
252 |
if ( is_object( $headers ) ) {
|
253 |
$headers = $headers->getAll();
|
254 |
} elseif ( ! is_array( $headers ) ) {
|
255 |
-
$headers =
|
256 |
}
|
257 |
|
258 |
$code = wp_remote_retrieve_response_code( $response );
|
@@ -260,12 +262,12 @@ if ( ! class_exists( 'WC_Facebookcommerce_Graph_API' ) ) :
|
|
260 |
$body = wp_remote_retrieve_body( $response );
|
261 |
}
|
262 |
|
263 |
-
$response_data =
|
264 |
'code' => $code,
|
265 |
'message' => $message,
|
266 |
'headers' => $headers,
|
267 |
'body' => $body,
|
268 |
-
|
269 |
|
270 |
facebook_for_woocommerce()->log_api_request( $request_data, $response_data );
|
271 |
}
|
@@ -298,7 +300,7 @@ if ( ! class_exists( 'WC_Facebookcommerce_Graph_API' ) ) :
|
|
298 |
* Endpoint: https://graph.facebook.com/vX.X/{page-id}/?fields=link
|
299 |
*
|
300 |
* @param string|int $page_id page identifier
|
301 |
-
* @param string
|
302 |
* @return string URL
|
303 |
*/
|
304 |
public function get_page_url( $page_id, $api_key = '' ) {
|
@@ -441,15 +443,15 @@ if ( ! class_exists( 'WC_Facebookcommerce_Graph_API' ) ) :
|
|
441 |
}
|
442 |
|
443 |
public function create_upload( $facebook_feed_id, $path_to_feed_file ) {
|
444 |
-
$url
|
445 |
$facebook_feed_id,
|
446 |
'/uploads?access_token=' . $this->api_key
|
447 |
);
|
448 |
|
449 |
-
$data =
|
450 |
'file' => new CurlFile( $path_to_feed_file, 'text/csv' ),
|
451 |
'update_only' => true,
|
452 |
-
|
453 |
|
454 |
$curl = curl_init();
|
455 |
curl_setopt_array(
|
52 |
|
53 |
$api_key = $api_key ?: $this->api_key;
|
54 |
|
55 |
+
$request_args = array(
|
56 |
+
'headers' => array(
|
57 |
'Authorization' => 'Bearer ' . $api_key,
|
58 |
+
),
|
59 |
'timeout' => self::CURL_TIMEOUT,
|
60 |
+
);
|
61 |
|
62 |
$response = wp_remote_get( $url, $request_args );
|
63 |
|
80 |
*/
|
81 |
public function perform_request( $url ) {
|
82 |
|
83 |
+
$request_args = array(
|
84 |
+
'headers' => array(
|
85 |
'Authorization' => 'Bearer ' . $this->api_key,
|
86 |
+
),
|
87 |
'timeout' => self::CURL_TIMEOUT,
|
88 |
+
);
|
89 |
|
90 |
$response = wp_remote_get( $url, $request_args );
|
91 |
|
102 |
if ( isset( $response_body->error->code, $response_body->error->message ) ) {
|
103 |
throw new Framework\SV_WC_API_Exception( $response_body->error->message, $response_body->error->code );
|
104 |
} else {
|
105 |
+
throw new Framework\SV_WC_API_Exception( sprintf( __( 'HTTP %1$s: %2$s', 'facebook-for-woocommerce' ), wp_remote_retrieve_response_code( $response ), wp_remote_retrieve_response_message( $response ) ) );
|
106 |
}
|
107 |
}
|
108 |
|
121 |
public function _post_sync( $url, $data, $api_key = '' ) {
|
122 |
$api_key = $api_key ?: $this->api_key;
|
123 |
|
124 |
+
$request_args = array(
|
125 |
'body' => $data,
|
126 |
+
'headers' => array(
|
127 |
'Authorization' => 'Bearer ' . $api_key,
|
128 |
+
),
|
129 |
'timeout' => self::CURL_TIMEOUT,
|
130 |
+
);
|
131 |
|
132 |
$response = wp_remote_post( $url, $request_args );
|
133 |
|
141 |
* Issues an asynchronous POST request to the Graph API.
|
142 |
*
|
143 |
* @param string $url request URL
|
144 |
+
* @param array $data request data
|
145 |
* @param string $api_key Graph API key
|
146 |
* @return array|\WP_Error
|
147 |
*/
|
153 |
|
154 |
$api_key = $api_key ?: $this->api_key;
|
155 |
|
156 |
+
$request_args = array(
|
157 |
'body' => $data,
|
158 |
+
'headers' => array(
|
159 |
'Authorization' => 'Bearer ' . $api_key,
|
160 |
+
),
|
161 |
'timeout' => self::CURL_TIMEOUT,
|
162 |
+
);
|
|
|
163 |
|
164 |
+
$fbasync = new WC_Facebookcommerce_Async_Request();
|
165 |
$fbasync->query_url = $url;
|
166 |
$fbasync->query_args = array();
|
167 |
$fbasync->post_args = $request_args;
|
185 |
|
186 |
$api_key = $api_key ?: $this->api_key;
|
187 |
|
188 |
+
$request_args = array(
|
189 |
+
'headers' => array(
|
190 |
'Authorization' => 'Bearer ' . $api_key,
|
191 |
+
),
|
192 |
'timeout' => self::CURL_TIMEOUT,
|
193 |
'method' => 'DELETE',
|
194 |
+
);
|
195 |
|
196 |
$response = wp_remote_request( $url, $request_args );
|
197 |
|
209 |
* @param $url
|
210 |
* @param $request_args
|
211 |
* @param array|\WP_Error $response WordPress response object
|
212 |
+
* @param string $method
|
213 |
*/
|
214 |
private function log_request( $url, $request_args, $response, $method = '' ) {
|
215 |
|
219 |
}
|
220 |
|
221 |
// add the URI to the data
|
222 |
+
$request_data = array_merge(
|
223 |
+
array(
|
224 |
+
'uri' => $url,
|
225 |
+
),
|
226 |
+
$request_args
|
227 |
+
);
|
228 |
|
229 |
// the request args may not include the method, so allow it to be set
|
230 |
if ( $method ) {
|
244 |
|
245 |
$code = $response->get_error_code();
|
246 |
$message = $response->get_error_message();
|
247 |
+
$headers = array();
|
248 |
$body = '';
|
249 |
|
250 |
} else {
|
254 |
if ( is_object( $headers ) ) {
|
255 |
$headers = $headers->getAll();
|
256 |
} elseif ( ! is_array( $headers ) ) {
|
257 |
+
$headers = array();
|
258 |
}
|
259 |
|
260 |
$code = wp_remote_retrieve_response_code( $response );
|
262 |
$body = wp_remote_retrieve_body( $response );
|
263 |
}
|
264 |
|
265 |
+
$response_data = array(
|
266 |
'code' => $code,
|
267 |
'message' => $message,
|
268 |
'headers' => $headers,
|
269 |
'body' => $body,
|
270 |
+
);
|
271 |
|
272 |
facebook_for_woocommerce()->log_api_request( $request_data, $response_data );
|
273 |
}
|
300 |
* Endpoint: https://graph.facebook.com/vX.X/{page-id}/?fields=link
|
301 |
*
|
302 |
* @param string|int $page_id page identifier
|
303 |
+
* @param string $api_key API key
|
304 |
* @return string URL
|
305 |
*/
|
306 |
public function get_page_url( $page_id, $api_key = '' ) {
|
443 |
}
|
444 |
|
445 |
public function create_upload( $facebook_feed_id, $path_to_feed_file ) {
|
446 |
+
$url = $this->build_url(
|
447 |
$facebook_feed_id,
|
448 |
'/uploads?access_token=' . $this->api_key
|
449 |
);
|
450 |
|
451 |
+
$data = array(
|
452 |
'file' => new CurlFile( $path_to_feed_file, 'text/csv' ),
|
453 |
'update_only' => true,
|
454 |
+
);
|
455 |
|
456 |
$curl = curl_init();
|
457 |
curl_setopt_array(
|
includes/fbproduct.php
CHANGED
@@ -430,7 +430,7 @@ if ( ! class_exists( 'WC_Facebook_Product' ) ) :
|
|
430 |
// Convert all slug_names in $option_values into the visible names that
|
431 |
// advertisers have set to be the display names for a given attribute value
|
432 |
$terms = get_the_terms( $this->id, $key );
|
433 |
-
return ! is_array( $terms ) ?
|
434 |
function ( $slug_name ) use ( $terms ) {
|
435 |
foreach ( $terms as $term ) {
|
436 |
if ( $term->slug === $slug_name ) {
|
@@ -695,20 +695,21 @@ if ( ! class_exists( 'WC_Facebook_Product' ) ) :
|
|
695 |
* Filters list of attributes to only those available for a given product
|
696 |
*
|
697 |
* @param \WC_Product $product WooCommerce Product
|
698 |
-
* @param array
|
699 |
* @return array
|
700 |
*/
|
701 |
public function get_matched_attributes_for_product( $product, $all_attributes ) {
|
702 |
$matched_attributes = array();
|
703 |
-
$sanitized_keys
|
704 |
function( $key ) {
|
705 |
return \WC_Facebookcommerce_Utils::sanitize_variant_name( $key, false );
|
706 |
},
|
707 |
array_keys( $product->get_attributes() )
|
708 |
);
|
709 |
|
710 |
-
$matched_attributes = array_filter(
|
711 |
-
|
|
|
712 |
return in_array( $attribute['key'], $sanitized_keys );
|
713 |
}
|
714 |
);
|
430 |
// Convert all slug_names in $option_values into the visible names that
|
431 |
// advertisers have set to be the display names for a given attribute value
|
432 |
$terms = get_the_terms( $this->id, $key );
|
433 |
+
return ! is_array( $terms ) ? array() : array_map(
|
434 |
function ( $slug_name ) use ( $terms ) {
|
435 |
foreach ( $terms as $term ) {
|
436 |
if ( $term->slug === $slug_name ) {
|
695 |
* Filters list of attributes to only those available for a given product
|
696 |
*
|
697 |
* @param \WC_Product $product WooCommerce Product
|
698 |
+
* @param array $all_attributes List of Enhanced Catalog attributes to match
|
699 |
* @return array
|
700 |
*/
|
701 |
public function get_matched_attributes_for_product( $product, $all_attributes ) {
|
702 |
$matched_attributes = array();
|
703 |
+
$sanitized_keys = array_map(
|
704 |
function( $key ) {
|
705 |
return \WC_Facebookcommerce_Utils::sanitize_variant_name( $key, false );
|
706 |
},
|
707 |
array_keys( $product->get_attributes() )
|
708 |
);
|
709 |
|
710 |
+
$matched_attributes = array_filter(
|
711 |
+
$all_attributes,
|
712 |
+
function( $attribute ) use ( $sanitized_keys ) {
|
713 |
return in_array( $attribute['key'], $sanitized_keys );
|
714 |
}
|
715 |
);
|
includes/fbproductfeed.php
CHANGED
@@ -46,9 +46,9 @@ if ( ! class_exists( 'WC_Facebook_Product_Feed' ) ) :
|
|
46 |
/**
|
47 |
* WC_Facebook_Product_Feed constructor.
|
48 |
*
|
49 |
-
* @param string|null
|
50 |
* @param \WC_Facebookcommerce_Graph_API|null $fbgraph Facebook Graph API instance
|
51 |
-
* @param string|null
|
52 |
*/
|
53 |
public function __construct( $facebook_catalog_id = null, $fbgraph = null, $feed_id = null ) {
|
54 |
|
@@ -66,7 +66,7 @@ if ( ! class_exists( 'WC_Facebook_Product_Feed' ) ) :
|
|
66 |
public function schedule_feed_generation() {
|
67 |
|
68 |
// don't schedule another if one's already scheduled or in progress
|
69 |
-
if ( false !== as_next_scheduled_action( 'wc_facebook_generate_product_catalog_feed',
|
70 |
return;
|
71 |
}
|
72 |
|
@@ -74,9 +74,9 @@ if ( ! class_exists( 'WC_Facebook_Product_Feed' ) ) :
|
|
74 |
|
75 |
// if async priority actions are supported (AS 3.0+)
|
76 |
if ( function_exists( 'as_enqueue_async_action' ) ) {
|
77 |
-
as_enqueue_async_action( 'wc_facebook_generate_product_catalog_feed',
|
78 |
} else {
|
79 |
-
as_schedule_single_action( time(), 'wc_facebook_generate_product_catalog_feed',
|
80 |
}
|
81 |
}
|
82 |
|
@@ -210,7 +210,7 @@ if ( ! class_exists( 'WC_Facebook_Product_Feed' ) ) :
|
|
210 |
$time_estimate = $buffer_time;
|
211 |
}
|
212 |
|
213 |
-
WC_Facebookcommerce_Utils::log( 'Feed Generation Time Estimate: '. $time_estimate );
|
214 |
|
215 |
return $time_estimate;
|
216 |
}
|
@@ -381,7 +381,6 @@ if ( ! class_exists( 'WC_Facebook_Product_Feed' ) ) :
|
|
381 |
if ( ! $this->generate_productfeed_file() ) {
|
382 |
throw new Framework\SV_WC_Plugin_Exception( 'Feed file not generated' );
|
383 |
}
|
384 |
-
|
385 |
} catch ( Framework\SV_WC_Plugin_Exception $exception ) {
|
386 |
|
387 |
$this->log_feed_progress(
|
@@ -481,18 +480,18 @@ if ( ! class_exists( 'WC_Facebook_Product_Feed' ) ) :
|
|
481 |
|
482 |
$catalog_feed_directory = trailingslashit( $this->get_file_directory() );
|
483 |
|
484 |
-
$files =
|
485 |
-
|
486 |
'base' => $catalog_feed_directory,
|
487 |
'file' => 'index.html',
|
488 |
'content' => '',
|
489 |
-
|
490 |
-
|
491 |
'base' => $catalog_feed_directory,
|
492 |
'file' => '.htaccess',
|
493 |
'content' => 'deny from all',
|
494 |
-
|
495 |
-
|
496 |
|
497 |
foreach ( $files as $file ) {
|
498 |
|
@@ -514,14 +513,13 @@ if ( ! class_exists( 'WC_Facebook_Product_Feed' ) ) :
|
|
514 |
* @since 1.11.0
|
515 |
*
|
516 |
* @param int[] $wp_ids product IDs
|
517 |
-
* @param bool
|
518 |
* @return bool
|
519 |
*/
|
520 |
public function write_product_feed_file( $wp_ids, $is_dry_run = false ) {
|
521 |
|
522 |
try {
|
523 |
|
524 |
-
|
525 |
if ( ! $is_dry_run ) {
|
526 |
|
527 |
$temp_file_path = $this->get_temp_file_path();
|
@@ -570,7 +568,6 @@ if ( ! class_exists( 'WC_Facebook_Product_Feed' ) ) :
|
|
570 |
|
571 |
wp_reset_postdata();
|
572 |
|
573 |
-
|
574 |
if ( ! empty( $temp_feed_file ) ) {
|
575 |
fclose( $temp_feed_file );
|
576 |
}
|
@@ -620,7 +617,7 @@ if ( ! class_exists( 'WC_Facebook_Product_Feed' ) ) :
|
|
620 |
* Assembles product payload in feed upload for initial sync.
|
621 |
*
|
622 |
* @param \WC_Facebook_Product $woo_product WooCommerce product object normalized by Facebook
|
623 |
-
* @param array
|
624 |
* @return string product feed line data
|
625 |
*/
|
626 |
private function prepare_product_for_feed( $woo_product, &$attribute_variants ) {
|
@@ -641,11 +638,11 @@ if ( ! class_exists( 'WC_Facebook_Product_Feed' ) ) :
|
|
641 |
$gallery_urls = array_filter( $parent_product->get_gallery_urls() );
|
642 |
$variation_id = $parent_product->find_matching_product_variation();
|
643 |
$variants_for_group = $parent_product->prepare_variants_for_group( true );
|
644 |
-
$parent_attribute_values =
|
645 |
'gallery_urls' => $gallery_urls,
|
646 |
'default_variant_id' => $variation_id,
|
647 |
'item_group_id' => \WC_Facebookcommerce_Utils::get_fb_retailer_id( $parent_product ),
|
648 |
-
|
649 |
|
650 |
foreach ( $variants_for_group as $variant ) {
|
651 |
if ( isset( $variant['product_field'], $variant['options'] ) ) {
|
@@ -661,8 +658,8 @@ if ( ! class_exists( 'WC_Facebook_Product_Feed' ) ) :
|
|
661 |
$parent_attribute_values = $attribute_variants[ $parent_id ];
|
662 |
}
|
663 |
|
664 |
-
$variants_for_item
|
665 |
-
$variant_feed_column
|
666 |
|
667 |
foreach ( $variants_for_item as $variant_array ) {
|
668 |
|
@@ -839,9 +836,9 @@ if ( ! class_exists( 'WC_Facebook_Product_Feed' ) ) :
|
|
839 |
*
|
840 |
* @since 2.1.0
|
841 |
*
|
842 |
-
* @param array
|
843 |
* @param string $index the data index
|
844 |
-
* @param mixed
|
845 |
* @return mixed|string the data value or an empty string
|
846 |
*/
|
847 |
private static function get_value_from_product_data( &$product_data, $index, $return_if_not_set = '' ) {
|
@@ -879,7 +876,7 @@ if ( ! class_exists( 'WC_Facebook_Product_Feed' ) ) :
|
|
879 |
|
880 |
$upload_status = 'complete';
|
881 |
|
882 |
-
}
|
883 |
|
884 |
$upload_status = 'in progress';
|
885 |
}
|
46 |
/**
|
47 |
* WC_Facebook_Product_Feed constructor.
|
48 |
*
|
49 |
+
* @param string|null $facebook_catalog_id Facebook catalog ID, if any
|
50 |
* @param \WC_Facebookcommerce_Graph_API|null $fbgraph Facebook Graph API instance
|
51 |
+
* @param string|null $feed_id Facebook feed ID, if any
|
52 |
*/
|
53 |
public function __construct( $facebook_catalog_id = null, $fbgraph = null, $feed_id = null ) {
|
54 |
|
66 |
public function schedule_feed_generation() {
|
67 |
|
68 |
// don't schedule another if one's already scheduled or in progress
|
69 |
+
if ( false !== as_next_scheduled_action( 'wc_facebook_generate_product_catalog_feed', array(), 'facebook-for-woocommerce' ) ) {
|
70 |
return;
|
71 |
}
|
72 |
|
74 |
|
75 |
// if async priority actions are supported (AS 3.0+)
|
76 |
if ( function_exists( 'as_enqueue_async_action' ) ) {
|
77 |
+
as_enqueue_async_action( 'wc_facebook_generate_product_catalog_feed', array(), 'facebook-for-woocommerce' );
|
78 |
} else {
|
79 |
+
as_schedule_single_action( time(), 'wc_facebook_generate_product_catalog_feed', array(), 'facebook-for-woocommerce' );
|
80 |
}
|
81 |
}
|
82 |
|
210 |
$time_estimate = $buffer_time;
|
211 |
}
|
212 |
|
213 |
+
WC_Facebookcommerce_Utils::log( 'Feed Generation Time Estimate: ' . $time_estimate );
|
214 |
|
215 |
return $time_estimate;
|
216 |
}
|
381 |
if ( ! $this->generate_productfeed_file() ) {
|
382 |
throw new Framework\SV_WC_Plugin_Exception( 'Feed file not generated' );
|
383 |
}
|
|
|
384 |
} catch ( Framework\SV_WC_Plugin_Exception $exception ) {
|
385 |
|
386 |
$this->log_feed_progress(
|
480 |
|
481 |
$catalog_feed_directory = trailingslashit( $this->get_file_directory() );
|
482 |
|
483 |
+
$files = array(
|
484 |
+
array(
|
485 |
'base' => $catalog_feed_directory,
|
486 |
'file' => 'index.html',
|
487 |
'content' => '',
|
488 |
+
),
|
489 |
+
array(
|
490 |
'base' => $catalog_feed_directory,
|
491 |
'file' => '.htaccess',
|
492 |
'content' => 'deny from all',
|
493 |
+
),
|
494 |
+
);
|
495 |
|
496 |
foreach ( $files as $file ) {
|
497 |
|
513 |
* @since 1.11.0
|
514 |
*
|
515 |
* @param int[] $wp_ids product IDs
|
516 |
+
* @param bool $is_dry_run whether this is a dry run or the file should be written
|
517 |
* @return bool
|
518 |
*/
|
519 |
public function write_product_feed_file( $wp_ids, $is_dry_run = false ) {
|
520 |
|
521 |
try {
|
522 |
|
|
|
523 |
if ( ! $is_dry_run ) {
|
524 |
|
525 |
$temp_file_path = $this->get_temp_file_path();
|
568 |
|
569 |
wp_reset_postdata();
|
570 |
|
|
|
571 |
if ( ! empty( $temp_feed_file ) ) {
|
572 |
fclose( $temp_feed_file );
|
573 |
}
|
617 |
* Assembles product payload in feed upload for initial sync.
|
618 |
*
|
619 |
* @param \WC_Facebook_Product $woo_product WooCommerce product object normalized by Facebook
|
620 |
+
* @param array $attribute_variants passed by reference
|
621 |
* @return string product feed line data
|
622 |
*/
|
623 |
private function prepare_product_for_feed( $woo_product, &$attribute_variants ) {
|
638 |
$gallery_urls = array_filter( $parent_product->get_gallery_urls() );
|
639 |
$variation_id = $parent_product->find_matching_product_variation();
|
640 |
$variants_for_group = $parent_product->prepare_variants_for_group( true );
|
641 |
+
$parent_attribute_values = array(
|
642 |
'gallery_urls' => $gallery_urls,
|
643 |
'default_variant_id' => $variation_id,
|
644 |
'item_group_id' => \WC_Facebookcommerce_Utils::get_fb_retailer_id( $parent_product ),
|
645 |
+
);
|
646 |
|
647 |
foreach ( $variants_for_group as $variant ) {
|
648 |
if ( isset( $variant['product_field'], $variant['options'] ) ) {
|
658 |
$parent_attribute_values = $attribute_variants[ $parent_id ];
|
659 |
}
|
660 |
|
661 |
+
$variants_for_item = $woo_product->prepare_variants_for_item( $product_data );
|
662 |
+
$variant_feed_column = array();
|
663 |
|
664 |
foreach ( $variants_for_item as $variant_array ) {
|
665 |
|
836 |
*
|
837 |
* @since 2.1.0
|
838 |
*
|
839 |
+
* @param array $product_data the product data retrieved from a Woo product passed by reference
|
840 |
* @param string $index the data index
|
841 |
+
* @param mixed $return_if_not_set the value to be returned if product data has no index (default to '')
|
842 |
* @return mixed|string the data value or an empty string
|
843 |
*/
|
844 |
private static function get_value_from_product_data( &$product_data, $index, $return_if_not_set = '' ) {
|
876 |
|
877 |
$upload_status = 'complete';
|
878 |
|
879 |
+
} elseif ( 200 === (int) wp_remote_retrieve_response_code( $result ) ) {
|
880 |
|
881 |
$upload_status = 'in progress';
|
882 |
}
|
includes/fbutils.php
CHANGED
@@ -211,40 +211,40 @@ if ( ! class_exists( 'WC_Facebookcommerce_Utils' ) ) :
|
|
211 |
*/
|
212 |
public static function get_user_info( $aam_settings ) {
|
213 |
$current_user = wp_get_current_user();
|
214 |
-
if ( 0 === $current_user->ID || $aam_settings == null ||
|
215 |
// User not logged in or pixel not configured with automatic advance matching
|
216 |
return array();
|
217 |
} else {
|
218 |
// Keys documented in
|
219 |
// https://developers.facebook.com/docs/facebook-pixel/advanced/advanced-matching
|
220 |
-
$user_data
|
221 |
-
'em'
|
222 |
-
'fn'
|
223 |
-
'ln'
|
224 |
-
'external_id' => strval($current_user->ID),
|
225 |
);
|
226 |
-
$user_id
|
227 |
-
$user_data['ct']
|
228 |
-
$user_data['zp']
|
229 |
-
$user_data['country'] = get_user_meta($user_id, 'billing_country', true);
|
230 |
-
$user_data['st']
|
231 |
-
$user_data['ph']
|
232 |
// Each field that is not present in AAM settings or is empty is deleted from user data
|
233 |
-
foreach ($user_data as $field => $value) {
|
234 |
-
if( $value === null || $value === ''
|
235 |
-
|| !in_array($field, $aam_settings->get_enabled_automatic_matching_fields())
|
236 |
-
){
|
237 |
-
unset($user_data[$field]);
|
238 |
}
|
239 |
}
|
240 |
// Country is a special case, it is returned as country in AAM settings
|
241 |
// But used as cn in pixel
|
242 |
-
if(array_key_exists('country', $user_data)){
|
243 |
-
$country
|
244 |
$user_data['cn'] = $country;
|
245 |
-
unset($user_data['country']);
|
246 |
}
|
247 |
-
$user_data = Normalizer::normalize_array($user_data, true);
|
248 |
return $user_data;
|
249 |
}
|
250 |
}
|
211 |
*/
|
212 |
public static function get_user_info( $aam_settings ) {
|
213 |
$current_user = wp_get_current_user();
|
214 |
+
if ( 0 === $current_user->ID || $aam_settings == null || ! $aam_settings->get_enable_automatic_matching() ) {
|
215 |
// User not logged in or pixel not configured with automatic advance matching
|
216 |
return array();
|
217 |
} else {
|
218 |
// Keys documented in
|
219 |
// https://developers.facebook.com/docs/facebook-pixel/advanced/advanced-matching
|
220 |
+
$user_data = array(
|
221 |
+
'em' => $current_user->user_email,
|
222 |
+
'fn' => $current_user->user_firstname,
|
223 |
+
'ln' => $current_user->user_lastname,
|
224 |
+
'external_id' => strval( $current_user->ID ),
|
225 |
);
|
226 |
+
$user_id = $current_user->ID;
|
227 |
+
$user_data['ct'] = get_user_meta( $user_id, 'billing_city', true );
|
228 |
+
$user_data['zp'] = get_user_meta( $user_id, 'billing_postcode', true );
|
229 |
+
$user_data['country'] = get_user_meta( $user_id, 'billing_country', true );
|
230 |
+
$user_data['st'] = get_user_meta( $user_id, 'billing_state', true );
|
231 |
+
$user_data['ph'] = get_user_meta( $user_id, 'billing_phone', true );
|
232 |
// Each field that is not present in AAM settings or is empty is deleted from user data
|
233 |
+
foreach ( $user_data as $field => $value ) {
|
234 |
+
if ( $value === null || $value === ''
|
235 |
+
|| ! in_array( $field, $aam_settings->get_enabled_automatic_matching_fields() )
|
236 |
+
) {
|
237 |
+
unset( $user_data[ $field ] );
|
238 |
}
|
239 |
}
|
240 |
// Country is a special case, it is returned as country in AAM settings
|
241 |
// But used as cn in pixel
|
242 |
+
if ( array_key_exists( 'country', $user_data ) ) {
|
243 |
+
$country = $user_data['country'];
|
244 |
$user_data['cn'] = $country;
|
245 |
+
unset( $user_data['country'] );
|
246 |
}
|
247 |
+
$user_data = Normalizer::normalize_array( $user_data, true );
|
248 |
return $user_data;
|
249 |
}
|
250 |
}
|
includes/fbwpml.php
CHANGED
@@ -35,8 +35,8 @@ if ( ! class_exists( 'WC_Facebook_WPML_Injector' ) ) :
|
|
35 |
self::$default_lang = apply_filters( 'wpml_default_language', null );
|
36 |
|
37 |
if ( is_admin() ) {
|
38 |
-
add_action( 'icl_menu_footer',
|
39 |
-
add_action( 'icl_ajx_custom_call',
|
40 |
}
|
41 |
}
|
42 |
|
35 |
self::$default_lang = apply_filters( 'wpml_default_language', null );
|
36 |
|
37 |
if ( is_admin() ) {
|
38 |
+
add_action( 'icl_menu_footer', array( $this, 'wpml_support' ) );
|
39 |
+
add_action( 'icl_ajx_custom_call', array( $this, 'wpml_ajax_support' ), 10, 2 );
|
40 |
}
|
41 |
}
|
42 |
|
includes/test/facebook-integration-test.php
CHANGED
@@ -39,7 +39,7 @@ if ( ! class_exists( 'WC_Facebook_Integration_Test' ) ) :
|
|
39 |
private static $instance;
|
40 |
|
41 |
/** @var WC_Facebookcommerce_Integration full integration object */
|
42 |
-
public static $commerce
|
43 |
/** @var WC_Facebookcommerce_Graph_API */
|
44 |
public static $fbgraph = null;
|
45 |
public static $test_mode = false;
|
39 |
private static $instance;
|
40 |
|
41 |
/** @var WC_Facebookcommerce_Integration full integration object */
|
42 |
+
public static $commerce = null;
|
43 |
/** @var WC_Facebookcommerce_Graph_API */
|
44 |
public static $fbgraph = null;
|
45 |
public static $test_mode = false;
|
readme.txt
CHANGED
@@ -3,7 +3,7 @@ Contributors: facebook, automattic, woothemes
|
|
3 |
Tags: facebook, shop, catalog, advertise, pixel, product
|
4 |
Requires at least: 4.4
|
5 |
Tested up to: 5.6
|
6 |
-
Stable tag: 2.
|
7 |
Requires PHP: 5.6 or greater
|
8 |
MySQL: 5.6 or greater
|
9 |
License: GPLv2 or later
|
@@ -39,7 +39,21 @@ When opening a bug on GitHub, please give us as many details as possible.
|
|
39 |
|
40 |
== Changelog ==
|
41 |
|
42 |
-
=
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
43 |
* Fix - PHP<7.1 incompatible code for Google Taxonomy Setting in products.
|
44 |
|
45 |
= 2021.04.23 - version 2.4.0 =
|
3 |
Tags: facebook, shop, catalog, advertise, pixel, product
|
4 |
Requires at least: 4.4
|
5 |
Tested up to: 5.6
|
6 |
+
Stable tag: 2.5.0
|
7 |
Requires PHP: 5.6 or greater
|
8 |
MySQL: 5.6 or greater
|
9 |
License: GPLv2 or later
|
39 |
|
40 |
== Changelog ==
|
41 |
|
42 |
+
= 2.5.0 - 2021-05-19 =
|
43 |
+
* New - Option to allow larger sites to opt-out of feed generation (product sync) job
|
44 |
+
* New - Log connection errors to allow easier troubleshooting
|
45 |
+
* Fix - Reduce default feed generation (product sync) interval to once per day to reduce overhead
|
46 |
+
* Fix - Trigger feed (product sync) job from to `admin_init` to reduce impact on front-end requests
|
47 |
+
* Fix - Ensure variable product attribute values containing comma (`,`) sync correctly
|
48 |
+
* Fix - Use existing / current tab for connection `Get Started` button
|
49 |
+
* Dev - Require PHP version 7.0 or newer
|
50 |
+
* Dev - Adopt Composer autoloader to avoid manually `require`ing PHP class files
|
51 |
+
* Dev - Adopt WooRelease release tool for deploying releases
|
52 |
+
* Dev - Use wp-scripts to build assets
|
53 |
+
* Dev - Add `phpcs` tooling to help standardise PHP code style
|
54 |
+
* Dev - Add JobRegistry engine for managing periodic background batch jobs
|
55 |
+
|
56 |
+
= 2021.04.29 - version 2.4.1 =
|
57 |
* Fix - PHP<7.1 incompatible code for Google Taxonomy Setting in products.
|
58 |
|
59 |
= 2021.04.23 - version 2.4.0 =
|
vendor/autoload.php
ADDED
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
// autoload.php @generated by Composer
|
4 |
+
|
5 |
+
require_once __DIR__ . '/composer/autoload_real.php';
|
6 |
+
|
7 |
+
return ComposerAutoloaderInite5a9cceb09137b76082a540c9a14d271::getLoader();
|
vendor/composer/ClassLoader.php
ADDED
@@ -0,0 +1,445 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
* This file is part of Composer.
|
5 |
+
*
|
6 |
+
* (c) Nils Adermann <naderman@naderman.de>
|
7 |
+
* Jordi Boggiano <j.boggiano@seld.be>
|
8 |
+
*
|
9 |
+
* For the full copyright and license information, please view the LICENSE
|
10 |
+
* file that was distributed with this source code.
|
11 |
+
*/
|
12 |
+
|
13 |
+
namespace Composer\Autoload;
|
14 |
+
|
15 |
+
/**
|
16 |
+
* ClassLoader implements a PSR-0, PSR-4 and classmap class loader.
|
17 |
+
*
|
18 |
+
* $loader = new \Composer\Autoload\ClassLoader();
|
19 |
+
*
|
20 |
+
* // register classes with namespaces
|
21 |
+
* $loader->add('Symfony\Component', __DIR__.'/component');
|
22 |
+
* $loader->add('Symfony', __DIR__.'/framework');
|
23 |
+
*
|
24 |
+
* // activate the autoloader
|
25 |
+
* $loader->register();
|
26 |
+
*
|
27 |
+
* // to enable searching the include path (eg. for PEAR packages)
|
28 |
+
* $loader->setUseIncludePath(true);
|
29 |
+
*
|
30 |
+
* In this example, if you try to use a class in the Symfony\Component
|
31 |
+
* namespace or one of its children (Symfony\Component\Console for instance),
|
32 |
+
* the autoloader will first look for the class under the component/
|
33 |
+
* directory, and it will then fallback to the framework/ directory if not
|
34 |
+
* found before giving up.
|
35 |
+
*
|
36 |
+
* This class is loosely based on the Symfony UniversalClassLoader.
|
37 |
+
*
|
38 |
+
* @author Fabien Potencier <fabien@symfony.com>
|
39 |
+
* @author Jordi Boggiano <j.boggiano@seld.be>
|
40 |
+
* @see https://www.php-fig.org/psr/psr-0/
|
41 |
+
* @see https://www.php-fig.org/psr/psr-4/
|
42 |
+
*/
|
43 |
+
class ClassLoader
|
44 |
+
{
|
45 |
+
// PSR-4
|
46 |
+
private $prefixLengthsPsr4 = array();
|
47 |
+
private $prefixDirsPsr4 = array();
|
48 |
+
private $fallbackDirsPsr4 = array();
|
49 |
+
|
50 |
+
// PSR-0
|
51 |
+
private $prefixesPsr0 = array();
|
52 |
+
private $fallbackDirsPsr0 = array();
|
53 |
+
|
54 |
+
private $useIncludePath = false;
|
55 |
+
private $classMap = array();
|
56 |
+
private $classMapAuthoritative = false;
|
57 |
+
private $missingClasses = array();
|
58 |
+
private $apcuPrefix;
|
59 |
+
|
60 |
+
public function getPrefixes()
|
61 |
+
{
|
62 |
+
if (!empty($this->prefixesPsr0)) {
|
63 |
+
return call_user_func_array('array_merge', array_values($this->prefixesPsr0));
|
64 |
+
}
|
65 |
+
|
66 |
+
return array();
|
67 |
+
}
|
68 |
+
|
69 |
+
public function getPrefixesPsr4()
|
70 |
+
{
|
71 |
+
return $this->prefixDirsPsr4;
|
72 |
+
}
|
73 |
+
|
74 |
+
public function getFallbackDirs()
|
75 |
+
{
|
76 |
+
return $this->fallbackDirsPsr0;
|
77 |
+
}
|
78 |
+
|
79 |
+
public function getFallbackDirsPsr4()
|
80 |
+
{
|
81 |
+
return $this->fallbackDirsPsr4;
|
82 |
+
}
|
83 |
+
|
84 |
+
public function getClassMap()
|
85 |
+
{
|
86 |
+
return $this->classMap;
|
87 |
+
}
|
88 |
+
|
89 |
+
/**
|
90 |
+
* @param array $classMap Class to filename map
|
91 |
+
*/
|
92 |
+
public function addClassMap(array $classMap)
|
93 |
+
{
|
94 |
+
if ($this->classMap) {
|
95 |
+
$this->classMap = array_merge($this->classMap, $classMap);
|
96 |
+
} else {
|
97 |
+
$this->classMap = $classMap;
|
98 |
+
}
|
99 |
+
}
|
100 |
+
|
101 |
+
/**
|
102 |
+
* Registers a set of PSR-0 directories for a given prefix, either
|
103 |
+
* appending or prepending to the ones previously set for this prefix.
|
104 |
+
*
|
105 |
+
* @param string $prefix The prefix
|
106 |
+
* @param array|string $paths The PSR-0 root directories
|
107 |
+
* @param bool $prepend Whether to prepend the directories
|
108 |
+
*/
|
109 |
+
public function add($prefix, $paths, $prepend = false)
|
110 |
+
{
|
111 |
+
if (!$prefix) {
|
112 |
+
if ($prepend) {
|
113 |
+
$this->fallbackDirsPsr0 = array_merge(
|
114 |
+
(array) $paths,
|
115 |
+
$this->fallbackDirsPsr0
|
116 |
+
);
|
117 |
+
} else {
|
118 |
+
$this->fallbackDirsPsr0 = array_merge(
|
119 |
+
$this->fallbackDirsPsr0,
|
120 |
+
(array) $paths
|
121 |
+
);
|
122 |
+
}
|
123 |
+
|
124 |
+
return;
|
125 |
+
}
|
126 |
+
|
127 |
+
$first = $prefix[0];
|
128 |
+
if (!isset($this->prefixesPsr0[$first][$prefix])) {
|
129 |
+
$this->prefixesPsr0[$first][$prefix] = (array) $paths;
|
130 |
+
|
131 |
+
return;
|
132 |
+
}
|
133 |
+
if ($prepend) {
|
134 |
+
$this->prefixesPsr0[$first][$prefix] = array_merge(
|
135 |
+
(array) $paths,
|
136 |
+
$this->prefixesPsr0[$first][$prefix]
|
137 |
+
);
|
138 |
+
} else {
|
139 |
+
$this->prefixesPsr0[$first][$prefix] = array_merge(
|
140 |
+
$this->prefixesPsr0[$first][$prefix],
|
141 |
+
(array) $paths
|
142 |
+
);
|
143 |
+
}
|
144 |
+
}
|
145 |
+
|
146 |
+
/**
|
147 |
+
* Registers a set of PSR-4 directories for a given namespace, either
|
148 |
+
* appending or prepending to the ones previously set for this namespace.
|
149 |
+
*
|
150 |
+
* @param string $prefix The prefix/namespace, with trailing '\\'
|
151 |
+
* @param array|string $paths The PSR-4 base directories
|
152 |
+
* @param bool $prepend Whether to prepend the directories
|
153 |
+
*
|
154 |
+
* @throws \InvalidArgumentException
|
155 |
+
*/
|
156 |
+
public function addPsr4($prefix, $paths, $prepend = false)
|
157 |
+
{
|
158 |
+
if (!$prefix) {
|
159 |
+
// Register directories for the root namespace.
|
160 |
+
if ($prepend) {
|
161 |
+
$this->fallbackDirsPsr4 = array_merge(
|
162 |
+
(array) $paths,
|
163 |
+
$this->fallbackDirsPsr4
|
164 |
+
);
|
165 |
+
} else {
|
166 |
+
$this->fallbackDirsPsr4 = array_merge(
|
167 |
+
$this->fallbackDirsPsr4,
|
168 |
+
(array) $paths
|
169 |
+
);
|
170 |
+
}
|
171 |
+
} elseif (!isset($this->prefixDirsPsr4[$prefix])) {
|
172 |
+
// Register directories for a new namespace.
|
173 |
+
$length = strlen($prefix);
|
174 |
+
if ('\\' !== $prefix[$length - 1]) {
|
175 |
+
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
|
176 |
+
}
|
177 |
+
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
|
178 |
+
$this->prefixDirsPsr4[$prefix] = (array) $paths;
|
179 |
+
} elseif ($prepend) {
|
180 |
+
// Prepend directories for an already registered namespace.
|
181 |
+
$this->prefixDirsPsr4[$prefix] = array_merge(
|
182 |
+
(array) $paths,
|
183 |
+
$this->prefixDirsPsr4[$prefix]
|
184 |
+
);
|
185 |
+
} else {
|
186 |
+
// Append directories for an already registered namespace.
|
187 |
+
$this->prefixDirsPsr4[$prefix] = array_merge(
|
188 |
+
$this->prefixDirsPsr4[$prefix],
|
189 |
+
(array) $paths
|
190 |
+
);
|
191 |
+
}
|
192 |
+
}
|
193 |
+
|
194 |
+
/**
|
195 |
+
* Registers a set of PSR-0 directories for a given prefix,
|
196 |
+
* replacing any others previously set for this prefix.
|
197 |
+
*
|
198 |
+
* @param string $prefix The prefix
|
199 |
+
* @param array|string $paths The PSR-0 base directories
|
200 |
+
*/
|
201 |
+
public function set($prefix, $paths)
|
202 |
+
{
|
203 |
+
if (!$prefix) {
|
204 |
+
$this->fallbackDirsPsr0 = (array) $paths;
|
205 |
+
} else {
|
206 |
+
$this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
|
207 |
+
}
|
208 |
+
}
|
209 |
+
|
210 |
+
/**
|
211 |
+
* Registers a set of PSR-4 directories for a given namespace,
|
212 |
+
* replacing any others previously set for this namespace.
|
213 |
+
*
|
214 |
+
* @param string $prefix The prefix/namespace, with trailing '\\'
|
215 |
+
* @param array|string $paths The PSR-4 base directories
|
216 |
+
*
|
217 |
+
* @throws \InvalidArgumentException
|
218 |
+
*/
|
219 |
+
public function setPsr4($prefix, $paths)
|
220 |
+
{
|
221 |
+
if (!$prefix) {
|
222 |
+
$this->fallbackDirsPsr4 = (array) $paths;
|
223 |
+
} else {
|
224 |
+
$length = strlen($prefix);
|
225 |
+
if ('\\' !== $prefix[$length - 1]) {
|
226 |
+
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
|
227 |
+
}
|
228 |
+
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
|
229 |
+
$this->prefixDirsPsr4[$prefix] = (array) $paths;
|
230 |
+
}
|
231 |
+
}
|
232 |
+
|
233 |
+
/**
|
234 |
+
* Turns on searching the include path for class files.
|
235 |
+
*
|
236 |
+
* @param bool $useIncludePath
|
237 |
+
*/
|
238 |
+
public function setUseIncludePath($useIncludePath)
|
239 |
+
{
|
240 |
+
$this->useIncludePath = $useIncludePath;
|
241 |
+
}
|
242 |
+
|
243 |
+
/**
|
244 |
+
* Can be used to check if the autoloader uses the include path to check
|
245 |
+
* for classes.
|
246 |
+
*
|
247 |
+
* @return bool
|
248 |
+
*/
|
249 |
+
public function getUseIncludePath()
|
250 |
+
{
|
251 |
+
return $this->useIncludePath;
|
252 |
+
}
|
253 |
+
|
254 |
+
/**
|
255 |
+
* Turns off searching the prefix and fallback directories for classes
|
256 |
+
* that have not been registered with the class map.
|
257 |
+
*
|
258 |
+
* @param bool $classMapAuthoritative
|
259 |
+
*/
|
260 |
+
public function setClassMapAuthoritative($classMapAuthoritative)
|
261 |
+
{
|
262 |
+
$this->classMapAuthoritative = $classMapAuthoritative;
|
263 |
+
}
|
264 |
+
|
265 |
+
/**
|
266 |
+
* Should class lookup fail if not found in the current class map?
|
267 |
+
*
|
268 |
+
* @return bool
|
269 |
+
*/
|
270 |
+
public function isClassMapAuthoritative()
|
271 |
+
{
|
272 |
+
return $this->classMapAuthoritative;
|
273 |
+
}
|
274 |
+
|
275 |
+
/**
|
276 |
+
* APCu prefix to use to cache found/not-found classes, if the extension is enabled.
|
277 |
+
*
|
278 |
+
* @param string|null $apcuPrefix
|
279 |
+
*/
|
280 |
+
public function setApcuPrefix($apcuPrefix)
|
281 |
+
{
|
282 |
+
$this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null;
|
283 |
+
}
|
284 |
+
|
285 |
+
/**
|
286 |
+
* The APCu prefix in use, or null if APCu caching is not enabled.
|
287 |
+
*
|
288 |
+
* @return string|null
|
289 |
+
*/
|
290 |
+
public function getApcuPrefix()
|
291 |
+
{
|
292 |
+
return $this->apcuPrefix;
|
293 |
+
}
|
294 |
+
|
295 |
+
/**
|
296 |
+
* Registers this instance as an autoloader.
|
297 |
+
*
|
298 |
+
* @param bool $prepend Whether to prepend the autoloader or not
|
299 |
+
*/
|
300 |
+
public function register($prepend = false)
|
301 |
+
{
|
302 |
+
spl_autoload_register(array($this, 'loadClass'), true, $prepend);
|
303 |
+
}
|
304 |
+
|
305 |
+
/**
|
306 |
+
* Unregisters this instance as an autoloader.
|
307 |
+
*/
|
308 |
+
public function unregister()
|
309 |
+
{
|
310 |
+
spl_autoload_unregister(array($this, 'loadClass'));
|
311 |
+
}
|
312 |
+
|
313 |
+
/**
|
314 |
+
* Loads the given class or interface.
|
315 |
+
*
|
316 |
+
* @param string $class The name of the class
|
317 |
+
* @return bool|null True if loaded, null otherwise
|
318 |
+
*/
|
319 |
+
public function loadClass($class)
|
320 |
+
{
|
321 |
+
if ($file = $this->findFile($class)) {
|
322 |
+
includeFile($file);
|
323 |
+
|
324 |
+
return true;
|
325 |
+
}
|
326 |
+
}
|
327 |
+
|
328 |
+
/**
|
329 |
+
* Finds the path to the file where the class is defined.
|
330 |
+
*
|
331 |
+
* @param string $class The name of the class
|
332 |
+
*
|
333 |
+
* @return string|false The path if found, false otherwise
|
334 |
+
*/
|
335 |
+
public function findFile($class)
|
336 |
+
{
|
337 |
+
// class map lookup
|
338 |
+
if (isset($this->classMap[$class])) {
|
339 |
+
return $this->classMap[$class];
|
340 |
+
}
|
341 |
+
if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
|
342 |
+
return false;
|
343 |
+
}
|
344 |
+
if (null !== $this->apcuPrefix) {
|
345 |
+
$file = apcu_fetch($this->apcuPrefix.$class, $hit);
|
346 |
+
if ($hit) {
|
347 |
+
return $file;
|
348 |
+
}
|
349 |
+
}
|
350 |
+
|
351 |
+
$file = $this->findFileWithExtension($class, '.php');
|
352 |
+
|
353 |
+
// Search for Hack files if we are running on HHVM
|
354 |
+
if (false === $file && defined('HHVM_VERSION')) {
|
355 |
+
$file = $this->findFileWithExtension($class, '.hh');
|
356 |
+
}
|
357 |
+
|
358 |
+
if (null !== $this->apcuPrefix) {
|
359 |
+
apcu_add($this->apcuPrefix.$class, $file);
|
360 |
+
}
|
361 |
+
|
362 |
+
if (false === $file) {
|
363 |
+
// Remember that this class does not exist.
|
364 |
+
$this->missingClasses[$class] = true;
|
365 |
+
}
|
366 |
+
|
367 |
+
return $file;
|
368 |
+
}
|
369 |
+
|
370 |
+
private function findFileWithExtension($class, $ext)
|
371 |
+
{
|
372 |
+
// PSR-4 lookup
|
373 |
+
$logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
|
374 |
+
|
375 |
+
$first = $class[0];
|
376 |
+
if (isset($this->prefixLengthsPsr4[$first])) {
|
377 |
+
$subPath = $class;
|
378 |
+
while (false !== $lastPos = strrpos($subPath, '\\')) {
|
379 |
+
$subPath = substr($subPath, 0, $lastPos);
|
380 |
+
$search = $subPath . '\\';
|
381 |
+
if (isset($this->prefixDirsPsr4[$search])) {
|
382 |
+
$pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
|
383 |
+
foreach ($this->prefixDirsPsr4[$search] as $dir) {
|
384 |
+
if (file_exists($file = $dir . $pathEnd)) {
|
385 |
+
return $file;
|
386 |
+
}
|
387 |
+
}
|
388 |
+
}
|
389 |
+
}
|
390 |
+
}
|
391 |
+
|
392 |
+
// PSR-4 fallback dirs
|
393 |
+
foreach ($this->fallbackDirsPsr4 as $dir) {
|
394 |
+
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
|
395 |
+
return $file;
|
396 |
+
}
|
397 |
+
}
|
398 |
+
|
399 |
+
// PSR-0 lookup
|
400 |
+
if (false !== $pos = strrpos($class, '\\')) {
|
401 |
+
// namespaced class name
|
402 |
+
$logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
|
403 |
+
. strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
|
404 |
+
} else {
|
405 |
+
// PEAR-like class name
|
406 |
+
$logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
|
407 |
+
}
|
408 |
+
|
409 |
+
if (isset($this->prefixesPsr0[$first])) {
|
410 |
+
foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
|
411 |
+
if (0 === strpos($class, $prefix)) {
|
412 |
+
foreach ($dirs as $dir) {
|
413 |
+
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
|
414 |
+
return $file;
|
415 |
+
}
|
416 |
+
}
|
417 |
+
}
|
418 |
+
}
|
419 |
+
}
|
420 |
+
|
421 |
+
// PSR-0 fallback dirs
|
422 |
+
foreach ($this->fallbackDirsPsr0 as $dir) {
|
423 |
+
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
|
424 |
+
return $file;
|
425 |
+
}
|
426 |
+
}
|
427 |
+
|
428 |
+
// PSR-0 include paths.
|
429 |
+
if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
|
430 |
+
return $file;
|
431 |
+
}
|
432 |
+
|
433 |
+
return false;
|
434 |
+
}
|
435 |
+
}
|
436 |
+
|
437 |
+
/**
|
438 |
+
* Scope isolated include.
|
439 |
+
*
|
440 |
+
* Prevents access to $this/self from included files.
|
441 |
+
*/
|
442 |
+
function includeFile($file)
|
443 |
+
{
|
444 |
+
include $file;
|
445 |
+
}
|
vendor/composer/InstalledVersions.php
ADDED
@@ -0,0 +1,250 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace Composer;
|
4 |
+
|
5 |
+
use Composer\Semver\VersionParser;
|
6 |
+
|
7 |
+
|
8 |
+
|
9 |
+
|
10 |
+
|
11 |
+
|
12 |
+
class InstalledVersions
|
13 |
+
{
|
14 |
+
private static $installed = array (
|
15 |
+
'root' =>
|
16 |
+
array (
|
17 |
+
'pretty_version' => '2.5.0',
|
18 |
+
'version' => '2.5.0.0',
|
19 |
+
'aliases' =>
|
20 |
+
array (
|
21 |
+
),
|
22 |
+
'reference' => 'c221784785ff1288e22452fea34cc2b1674e7ef8',
|
23 |
+
'name' => 'facebookincubator/facebook-for-woocommerce',
|
24 |
+
),
|
25 |
+
'versions' =>
|
26 |
+
array (
|
27 |
+
'composer/installers' =>
|
28 |
+
array (
|
29 |
+
'pretty_version' => 'v1.11.0',
|
30 |
+
'version' => '1.11.0.0',
|
31 |
+
'aliases' =>
|
32 |
+
array (
|
33 |
+
),
|
34 |
+
'reference' => 'ae03311f45dfe194412081526be2e003960df74b',
|
35 |
+
),
|
36 |
+
'facebookincubator/facebook-for-woocommerce' =>
|
37 |
+
array (
|
38 |
+
'pretty_version' => '2.5.0',
|
39 |
+
'version' => '2.5.0.0',
|
40 |
+
'aliases' =>
|
41 |
+
array (
|
42 |
+
),
|
43 |
+
'reference' => 'c221784785ff1288e22452fea34cc2b1674e7ef8',
|
44 |
+
),
|
45 |
+
'roundcube/plugin-installer' =>
|
46 |
+
array (
|
47 |
+
'replaced' =>
|
48 |
+
array (
|
49 |
+
0 => '*',
|
50 |
+
),
|
51 |
+
),
|
52 |
+
'shama/baton' =>
|
53 |
+
array (
|
54 |
+
'replaced' =>
|
55 |
+
array (
|
56 |
+
0 => '*',
|
57 |
+
),
|
58 |
+
),
|
59 |
+
'skyverge/wc-plugin-framework' =>
|
60 |
+
array (
|
61 |
+
'pretty_version' => '5.10.0',
|
62 |
+
'version' => '5.10.0.0',
|
63 |
+
'aliases' =>
|
64 |
+
array (
|
65 |
+
),
|
66 |
+
'reference' => 'e230d7c40286854e49c0cafeec3398cbf2427a64',
|
67 |
+
),
|
68 |
+
'woocommerce/action-scheduler-job-framework' =>
|
69 |
+
array (
|
70 |
+
'pretty_version' => '1.0.0',
|
71 |
+
'version' => '1.0.0.0',
|
72 |
+
'aliases' =>
|
73 |
+
array (
|
74 |
+
),
|
75 |
+
'reference' => '718594e15d7ba2d56f8a37743bda6d7a8296e1c8',
|
76 |
+
),
|
77 |
+
),
|
78 |
+
);
|
79 |
+
|
80 |
+
|
81 |
+
|
82 |
+
|
83 |
+
|
84 |
+
|
85 |
+
|
86 |
+
public static function getInstalledPackages()
|
87 |
+
{
|
88 |
+
return array_keys(self::$installed['versions']);
|
89 |
+
}
|
90 |
+
|
91 |
+
|
92 |
+
|
93 |
+
|
94 |
+
|
95 |
+
|
96 |
+
|
97 |
+
|
98 |
+
|
99 |
+
public static function isInstalled($packageName)
|
100 |
+
{
|
101 |
+
return isset(self::$installed['versions'][$packageName]);
|
102 |
+
}
|
103 |
+
|
104 |
+
|
105 |
+
|
106 |
+
|
107 |
+
|
108 |
+
|
109 |
+
|
110 |
+
|
111 |
+
|
112 |
+
|
113 |
+
|
114 |
+
|
115 |
+
|
116 |
+
|
117 |
+
public static function satisfies(VersionParser $parser, $packageName, $constraint)
|
118 |
+
{
|
119 |
+
$constraint = $parser->parseConstraints($constraint);
|
120 |
+
$provided = $parser->parseConstraints(self::getVersionRanges($packageName));
|
121 |
+
|
122 |
+
return $provided->matches($constraint);
|
123 |
+
}
|
124 |
+
|
125 |
+
|
126 |
+
|
127 |
+
|
128 |
+
|
129 |
+
|
130 |
+
|
131 |
+
|
132 |
+
|
133 |
+
|
134 |
+
public static function getVersionRanges($packageName)
|
135 |
+
{
|
136 |
+
if (!isset(self::$installed['versions'][$packageName])) {
|
137 |
+
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
138 |
+
}
|
139 |
+
|
140 |
+
$ranges = array();
|
141 |
+
if (isset(self::$installed['versions'][$packageName]['pretty_version'])) {
|
142 |
+
$ranges[] = self::$installed['versions'][$packageName]['pretty_version'];
|
143 |
+
}
|
144 |
+
if (array_key_exists('aliases', self::$installed['versions'][$packageName])) {
|
145 |
+
$ranges = array_merge($ranges, self::$installed['versions'][$packageName]['aliases']);
|
146 |
+
}
|
147 |
+
if (array_key_exists('replaced', self::$installed['versions'][$packageName])) {
|
148 |
+
$ranges = array_merge($ranges, self::$installed['versions'][$packageName]['replaced']);
|
149 |
+
}
|
150 |
+
if (array_key_exists('provided', self::$installed['versions'][$packageName])) {
|
151 |
+
$ranges = array_merge($ranges, self::$installed['versions'][$packageName]['provided']);
|
152 |
+
}
|
153 |
+
|
154 |
+
return implode(' || ', $ranges);
|
155 |
+
}
|
156 |
+
|
157 |
+
|
158 |
+
|
159 |
+
|
160 |
+
|
161 |
+
public static function getVersion($packageName)
|
162 |
+
{
|
163 |
+
if (!isset(self::$installed['versions'][$packageName])) {
|
164 |
+
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
165 |
+
}
|
166 |
+
|
167 |
+
if (!isset(self::$installed['versions'][$packageName]['version'])) {
|
168 |
+
return null;
|
169 |
+
}
|
170 |
+
|
171 |
+
return self::$installed['versions'][$packageName]['version'];
|
172 |
+
}
|
173 |
+
|
174 |
+
|
175 |
+
|
176 |
+
|
177 |
+
|
178 |
+
public static function getPrettyVersion($packageName)
|
179 |
+
{
|
180 |
+
if (!isset(self::$installed['versions'][$packageName])) {
|
181 |
+
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
182 |
+
}
|
183 |
+
|
184 |
+
if (!isset(self::$installed['versions'][$packageName]['pretty_version'])) {
|
185 |
+
return null;
|
186 |
+
}
|
187 |
+
|
188 |
+
return self::$installed['versions'][$packageName]['pretty_version'];
|
189 |
+
}
|
190 |
+
|
191 |
+
|
192 |
+
|
193 |
+
|
194 |
+
|
195 |
+
public static function getReference($packageName)
|
196 |
+
{
|
197 |
+
if (!isset(self::$installed['versions'][$packageName])) {
|
198 |
+
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
199 |
+
}
|
200 |
+
|
201 |
+
if (!isset(self::$installed['versions'][$packageName]['reference'])) {
|
202 |
+
return null;
|
203 |
+
}
|
204 |
+
|
205 |
+
return self::$installed['versions'][$packageName]['reference'];
|
206 |
+
}
|
207 |
+
|
208 |
+
|
209 |
+
|
210 |
+
|
211 |
+
|
212 |
+
public static function getRootPackage()
|
213 |
+
{
|
214 |
+
return self::$installed['root'];
|
215 |
+
}
|
216 |
+
|
217 |
+
|
218 |
+
|
219 |
+
|
220 |
+
|
221 |
+
|
222 |
+
|
223 |
+
public static function getRawData()
|
224 |
+
{
|
225 |
+
return self::$installed;
|
226 |
+
}
|
227 |
+
|
228 |
+
|
229 |
+
|
230 |
+
|
231 |
+
|
232 |
+
|
233 |
+
|
234 |
+
|
235 |
+
|
236 |
+
|
237 |
+
|
238 |
+
|
239 |
+
|
240 |
+
|
241 |
+
|
242 |
+
|
243 |
+
|
244 |
+
|
245 |
+
|
246 |
+
public static function reload($data)
|
247 |
+
{
|
248 |
+
self::$installed = $data;
|
249 |
+
}
|
250 |
+
}
|
vendor/composer/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
|
2 |
+
Copyright (c) Nils Adermann, Jordi Boggiano
|
3 |
+
|
4 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
5 |
+
of this software and associated documentation files (the "Software"), to deal
|
6 |
+
in the Software without restriction, including without limitation the rights
|
7 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
8 |
+
copies of the Software, and to permit persons to whom the Software is furnished
|
9 |
+
to do so, subject to the following conditions:
|
10 |
+
|
11 |
+
The above copyright notice and this permission notice shall be included in all
|
12 |
+
copies or substantial portions of the Software.
|
13 |
+
|
14 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
15 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
16 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
17 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
18 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
19 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
20 |
+
THE SOFTWARE.
|
21 |
+
|
vendor/composer/autoload_classmap.php
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
// autoload_classmap.php @generated by Composer
|
4 |
+
|
5 |
+
$vendorDir = dirname(dirname(__FILE__));
|
6 |
+
$baseDir = dirname($vendorDir);
|
7 |
+
|
8 |
+
return array(
|
9 |
+
'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
|
10 |
+
);
|
vendor/composer/autoload_namespaces.php
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
// autoload_namespaces.php @generated by Composer
|
4 |
+
|
5 |
+
$vendorDir = dirname(dirname(__FILE__));
|
6 |
+
$baseDir = dirname($vendorDir);
|
7 |
+
|
8 |
+
return array(
|
9 |
+
);
|
vendor/composer/autoload_psr4.php
ADDED
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
// autoload_psr4.php @generated by Composer
|
4 |
+
|
5 |
+
$vendorDir = dirname(dirname(__FILE__));
|
6 |
+
$baseDir = dirname($vendorDir);
|
7 |
+
|
8 |
+
return array(
|
9 |
+
'SkyVerge\\WooCommerce\\Facebook\\' => array($baseDir . '/includes'),
|
10 |
+
'Composer\\Installers\\' => array($vendorDir . '/composer/installers/src/Composer/Installers'),
|
11 |
+
'Automattic\\WooCommerce\\ActionSchedulerJobFramework\\' => array($vendorDir . '/woocommerce/action-scheduler-job-framework/src'),
|
12 |
+
);
|
vendor/composer/autoload_real.php
ADDED
@@ -0,0 +1,57 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
// autoload_real.php @generated by Composer
|
4 |
+
|
5 |
+
class ComposerAutoloaderInite5a9cceb09137b76082a540c9a14d271
|
6 |
+
{
|
7 |
+
private static $loader;
|
8 |
+
|
9 |
+
public static function loadClassLoader($class)
|
10 |
+
{
|
11 |
+
if ('Composer\Autoload\ClassLoader' === $class) {
|
12 |
+
require __DIR__ . '/ClassLoader.php';
|
13 |
+
}
|
14 |
+
}
|
15 |
+
|
16 |
+
/**
|
17 |
+
* @return \Composer\Autoload\ClassLoader
|
18 |
+
*/
|
19 |
+
public static function getLoader()
|
20 |
+
{
|
21 |
+
if (null !== self::$loader) {
|
22 |
+
return self::$loader;
|
23 |
+
}
|
24 |
+
|
25 |
+
require __DIR__ . '/platform_check.php';
|
26 |
+
|
27 |
+
spl_autoload_register(array('ComposerAutoloaderInite5a9cceb09137b76082a540c9a14d271', 'loadClassLoader'), true, true);
|
28 |
+
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
|
29 |
+
spl_autoload_unregister(array('ComposerAutoloaderInite5a9cceb09137b76082a540c9a14d271', 'loadClassLoader'));
|
30 |
+
|
31 |
+
$useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
|
32 |
+
if ($useStaticLoader) {
|
33 |
+
require __DIR__ . '/autoload_static.php';
|
34 |
+
|
35 |
+
call_user_func(\Composer\Autoload\ComposerStaticInite5a9cceb09137b76082a540c9a14d271::getInitializer($loader));
|
36 |
+
} else {
|
37 |
+
$map = require __DIR__ . '/autoload_namespaces.php';
|
38 |
+
foreach ($map as $namespace => $path) {
|
39 |
+
$loader->set($namespace, $path);
|
40 |
+
}
|
41 |
+
|
42 |
+
$map = require __DIR__ . '/autoload_psr4.php';
|
43 |
+
foreach ($map as $namespace => $path) {
|
44 |
+
$loader->setPsr4($namespace, $path);
|
45 |
+
}
|
46 |
+
|
47 |
+
$classMap = require __DIR__ . '/autoload_classmap.php';
|
48 |
+
if ($classMap) {
|
49 |
+
$loader->addClassMap($classMap);
|
50 |
+
}
|
51 |
+
}
|
52 |
+
|
53 |
+
$loader->register(true);
|
54 |
+
|
55 |
+
return $loader;
|
56 |
+
}
|
57 |
+
}
|
vendor/composer/autoload_static.php
ADDED
@@ -0,0 +1,52 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
// autoload_static.php @generated by Composer
|
4 |
+
|
5 |
+
namespace Composer\Autoload;
|
6 |
+
|
7 |
+
class ComposerStaticInite5a9cceb09137b76082a540c9a14d271
|
8 |
+
{
|
9 |
+
public static $prefixLengthsPsr4 = array (
|
10 |
+
'S' =>
|
11 |
+
array (
|
12 |
+
'SkyVerge\\WooCommerce\\Facebook\\' => 30,
|
13 |
+
),
|
14 |
+
'C' =>
|
15 |
+
array (
|
16 |
+
'Composer\\Installers\\' => 20,
|
17 |
+
),
|
18 |
+
'A' =>
|
19 |
+
array (
|
20 |
+
'Automattic\\WooCommerce\\ActionSchedulerJobFramework\\' => 51,
|
21 |
+
),
|
22 |
+
);
|
23 |
+
|
24 |
+
public static $prefixDirsPsr4 = array (
|
25 |
+
'SkyVerge\\WooCommerce\\Facebook\\' =>
|
26 |
+
array (
|
27 |
+
0 => __DIR__ . '/../..' . '/includes',
|
28 |
+
),
|
29 |
+
'Composer\\Installers\\' =>
|
30 |
+
array (
|
31 |
+
0 => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers',
|
32 |
+
),
|
33 |
+
'Automattic\\WooCommerce\\ActionSchedulerJobFramework\\' =>
|
34 |
+
array (
|
35 |
+
0 => __DIR__ . '/..' . '/woocommerce/action-scheduler-job-framework/src',
|
36 |
+
),
|
37 |
+
);
|
38 |
+
|
39 |
+
public static $classMap = array (
|
40 |
+
'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
|
41 |
+
);
|
42 |
+
|
43 |
+
public static function getInitializer(ClassLoader $loader)
|
44 |
+
{
|
45 |
+
return \Closure::bind(function () use ($loader) {
|
46 |
+
$loader->prefixLengthsPsr4 = ComposerStaticInite5a9cceb09137b76082a540c9a14d271::$prefixLengthsPsr4;
|
47 |
+
$loader->prefixDirsPsr4 = ComposerStaticInite5a9cceb09137b76082a540c9a14d271::$prefixDirsPsr4;
|
48 |
+
$loader->classMap = ComposerStaticInite5a9cceb09137b76082a540c9a14d271::$classMap;
|
49 |
+
|
50 |
+
}, null, ClassLoader::class);
|
51 |
+
}
|
52 |
+
}
|
vendor/composer/installed.json
ADDED
@@ -0,0 +1,231 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"packages": [
|
3 |
+
{
|
4 |
+
"name": "composer/installers",
|
5 |
+
"version": "v1.11.0",
|
6 |
+
"version_normalized": "1.11.0.0",
|
7 |
+
"source": {
|
8 |
+
"type": "git",
|
9 |
+
"url": "https://github.com/composer/installers.git",
|
10 |
+
"reference": "ae03311f45dfe194412081526be2e003960df74b"
|
11 |
+
},
|
12 |
+
"dist": {
|
13 |
+
"type": "zip",
|
14 |
+
"url": "https://api.github.com/repos/composer/installers/zipball/ae03311f45dfe194412081526be2e003960df74b",
|
15 |
+
"reference": "ae03311f45dfe194412081526be2e003960df74b",
|
16 |
+
"shasum": ""
|
17 |
+
},
|
18 |
+
"require": {
|
19 |
+
"composer-plugin-api": "^1.0 || ^2.0"
|
20 |
+
},
|
21 |
+
"replace": {
|
22 |
+
"roundcube/plugin-installer": "*",
|
23 |
+
"shama/baton": "*"
|
24 |
+
},
|
25 |
+
"require-dev": {
|
26 |
+
"composer/composer": "1.6.* || ^2.0",
|
27 |
+
"composer/semver": "^1 || ^3",
|
28 |
+
"phpstan/phpstan": "^0.12.55",
|
29 |
+
"phpstan/phpstan-phpunit": "^0.12.16",
|
30 |
+
"symfony/phpunit-bridge": "^4.2 || ^5",
|
31 |
+
"symfony/process": "^2.3"
|
32 |
+
},
|
33 |
+
"time": "2021-04-28T06:42:17+00:00",
|
34 |
+
"type": "composer-plugin",
|
35 |
+
"extra": {
|
36 |
+
"class": "Composer\\Installers\\Plugin",
|
37 |
+
"branch-alias": {
|
38 |
+
"dev-main": "1.x-dev"
|
39 |
+
}
|
40 |
+
},
|
41 |
+
"installation-source": "dist",
|
42 |
+
"autoload": {
|
43 |
+
"psr-4": {
|
44 |
+
"Composer\\Installers\\": "src/Composer/Installers"
|
45 |
+
}
|
46 |
+
},
|
47 |
+
"notification-url": "https://packagist.org/downloads/",
|
48 |
+
"license": [
|
49 |
+
"MIT"
|
50 |
+
],
|
51 |
+
"authors": [
|
52 |
+
{
|
53 |
+
"name": "Kyle Robinson Young",
|
54 |
+
"email": "kyle@dontkry.com",
|
55 |
+
"homepage": "https://github.com/shama"
|
56 |
+
}
|
57 |
+
],
|
58 |
+
"description": "A multi-framework Composer library installer",
|
59 |
+
"homepage": "https://composer.github.io/installers/",
|
60 |
+
"keywords": [
|
61 |
+
"Craft",
|
62 |
+
"Dolibarr",
|
63 |
+
"Eliasis",
|
64 |
+
"Hurad",
|
65 |
+
"ImageCMS",
|
66 |
+
"Kanboard",
|
67 |
+
"Lan Management System",
|
68 |
+
"MODX Evo",
|
69 |
+
"MantisBT",
|
70 |
+
"Mautic",
|
71 |
+
"Maya",
|
72 |
+
"OXID",
|
73 |
+
"Plentymarkets",
|
74 |
+
"Porto",
|
75 |
+
"RadPHP",
|
76 |
+
"SMF",
|
77 |
+
"Starbug",
|
78 |
+
"Thelia",
|
79 |
+
"Whmcs",
|
80 |
+
"WolfCMS",
|
81 |
+
"agl",
|
82 |
+
"aimeos",
|
83 |
+
"annotatecms",
|
84 |
+
"attogram",
|
85 |
+
"bitrix",
|
86 |
+
"cakephp",
|
87 |
+
"chef",
|
88 |
+
"cockpit",
|
89 |
+
"codeigniter",
|
90 |
+
"concrete5",
|
91 |
+
"croogo",
|
92 |
+
"dokuwiki",
|
93 |
+
"drupal",
|
94 |
+
"eZ Platform",
|
95 |
+
"elgg",
|
96 |
+
"expressionengine",
|
97 |
+
"fuelphp",
|
98 |
+
"grav",
|
99 |
+
"installer",
|
100 |
+
"itop",
|
101 |
+
"joomla",
|
102 |
+
"known",
|
103 |
+
"kohana",
|
104 |
+
"laravel",
|
105 |
+
"lavalite",
|
106 |
+
"lithium",
|
107 |
+
"magento",
|
108 |
+
"majima",
|
109 |
+
"mako",
|
110 |
+
"mediawiki",
|
111 |
+
"miaoxing",
|
112 |
+
"modulework",
|
113 |
+
"modx",
|
114 |
+
"moodle",
|
115 |
+
"osclass",
|
116 |
+
"phpbb",
|
117 |
+
"piwik",
|
118 |
+
"ppi",
|
119 |
+
"processwire",
|
120 |
+
"puppet",
|
121 |
+
"pxcms",
|
122 |
+
"reindex",
|
123 |
+
"roundcube",
|
124 |
+
"shopware",
|
125 |
+
"silverstripe",
|
126 |
+
"sydes",
|
127 |
+
"sylius",
|
128 |
+
"symfony",
|
129 |
+
"tastyigniter",
|
130 |
+
"typo3",
|
131 |
+
"wordpress",
|
132 |
+
"yawik",
|
133 |
+
"zend",
|
134 |
+
"zikula"
|
135 |
+
],
|
136 |
+
"support": {
|
137 |
+
"issues": "https://github.com/composer/installers/issues",
|
138 |
+
"source": "https://github.com/composer/installers/tree/v1.11.0"
|
139 |
+
},
|
140 |
+
"funding": [
|
141 |
+
{
|
142 |
+
"url": "https://packagist.com",
|
143 |
+
"type": "custom"
|
144 |
+
},
|
145 |
+
{
|
146 |
+
"url": "https://github.com/composer",
|
147 |
+
"type": "github"
|
148 |
+
},
|
149 |
+
{
|
150 |
+
"url": "https://tidelift.com/funding/github/packagist/composer/composer",
|
151 |
+
"type": "tidelift"
|
152 |
+
}
|
153 |
+
],
|
154 |
+
"install-path": "./installers"
|
155 |
+
},
|
156 |
+
{
|
157 |
+
"name": "skyverge/wc-plugin-framework",
|
158 |
+
"version": "5.10.0",
|
159 |
+
"version_normalized": "5.10.0.0",
|
160 |
+
"source": {
|
161 |
+
"type": "git",
|
162 |
+
"url": "https://github.com/skyverge/wc-plugin-framework.git",
|
163 |
+
"reference": "e230d7c40286854e49c0cafeec3398cbf2427a64"
|
164 |
+
},
|
165 |
+
"dist": {
|
166 |
+
"type": "zip",
|
167 |
+
"url": "https://api.github.com/repos/skyverge/wc-plugin-framework/zipball/e230d7c40286854e49c0cafeec3398cbf2427a64",
|
168 |
+
"reference": "e230d7c40286854e49c0cafeec3398cbf2427a64",
|
169 |
+
"shasum": ""
|
170 |
+
},
|
171 |
+
"require-dev": {
|
172 |
+
"lucatume/wp-browser": "^2.1"
|
173 |
+
},
|
174 |
+
"time": "2020-11-06T21:25:49+00:00",
|
175 |
+
"type": "library",
|
176 |
+
"installation-source": "dist",
|
177 |
+
"description": "The official SkyVerge WooCommerce plugin framework",
|
178 |
+
"support": {
|
179 |
+
"source": "https://github.com/skyverge/wc-plugin-framework/tree/5.10.0",
|
180 |
+
"issues": "https://github.com/skyverge/wc-plugin-framework/issues"
|
181 |
+
},
|
182 |
+
"install-path": "../skyverge/wc-plugin-framework"
|
183 |
+
},
|
184 |
+
{
|
185 |
+
"name": "woocommerce/action-scheduler-job-framework",
|
186 |
+
"version": "1.0.0",
|
187 |
+
"version_normalized": "1.0.0.0",
|
188 |
+
"source": {
|
189 |
+
"type": "git",
|
190 |
+
"url": "https://github.com/woocommerce/action-scheduler-job-framework.git",
|
191 |
+
"reference": "718594e15d7ba2d56f8a37743bda6d7a8296e1c8"
|
192 |
+
},
|
193 |
+
"dist": {
|
194 |
+
"type": "zip",
|
195 |
+
"url": "https://api.github.com/repos/woocommerce/action-scheduler-job-framework/zipball/718594e15d7ba2d56f8a37743bda6d7a8296e1c8",
|
196 |
+
"reference": "718594e15d7ba2d56f8a37743bda6d7a8296e1c8",
|
197 |
+
"shasum": ""
|
198 |
+
},
|
199 |
+
"require": {
|
200 |
+
"php": ">=7.0"
|
201 |
+
},
|
202 |
+
"require-dev": {
|
203 |
+
"woocommerce/woocommerce-sniffs": "0.1.0"
|
204 |
+
},
|
205 |
+
"time": "2021-05-05T02:11:38+00:00",
|
206 |
+
"type": "library",
|
207 |
+
"installation-source": "dist",
|
208 |
+
"autoload": {
|
209 |
+
"psr-4": {
|
210 |
+
"Automattic\\WooCommerce\\ActionSchedulerJobFramework\\": "src/"
|
211 |
+
}
|
212 |
+
},
|
213 |
+
"scripts": {
|
214 |
+
"phpcs": [
|
215 |
+
"phpcs -s -p"
|
216 |
+
]
|
217 |
+
},
|
218 |
+
"license": [
|
219 |
+
"GNU"
|
220 |
+
],
|
221 |
+
"description": "A job framework for Action Scheduler (actionscheduler.org)",
|
222 |
+
"support": {
|
223 |
+
"source": "https://github.com/woocommerce/action-scheduler-job-framework/tree/1.0.0",
|
224 |
+
"issues": "https://github.com/woocommerce/action-scheduler-job-framework/issues"
|
225 |
+
},
|
226 |
+
"install-path": "../woocommerce/action-scheduler-job-framework"
|
227 |
+
}
|
228 |
+
],
|
229 |
+
"dev": false,
|
230 |
+
"dev-package-names": []
|
231 |
+
}
|
vendor/composer/installed.php
ADDED
@@ -0,0 +1,65 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php return array (
|
2 |
+
'root' =>
|
3 |
+
array (
|
4 |
+
'pretty_version' => '2.5.0',
|
5 |
+
'version' => '2.5.0.0',
|
6 |
+
'aliases' =>
|
7 |
+
array (
|
8 |
+
),
|
9 |
+
'reference' => 'c221784785ff1288e22452fea34cc2b1674e7ef8',
|
10 |
+
'name' => 'facebookincubator/facebook-for-woocommerce',
|
11 |
+
),
|
12 |
+
'versions' =>
|
13 |
+
array (
|
14 |
+
'composer/installers' =>
|
15 |
+
array (
|
16 |
+
'pretty_version' => 'v1.11.0',
|
17 |
+
'version' => '1.11.0.0',
|
18 |
+
'aliases' =>
|
19 |
+
array (
|
20 |
+
),
|
21 |
+
'reference' => 'ae03311f45dfe194412081526be2e003960df74b',
|
22 |
+
),
|
23 |
+
'facebookincubator/facebook-for-woocommerce' =>
|
24 |
+
array (
|
25 |
+
'pretty_version' => '2.5.0',
|
26 |
+
'version' => '2.5.0.0',
|
27 |
+
'aliases' =>
|
28 |
+
array (
|
29 |
+
),
|
30 |
+
'reference' => 'c221784785ff1288e22452fea34cc2b1674e7ef8',
|
31 |
+
),
|
32 |
+
'roundcube/plugin-installer' =>
|
33 |
+
array (
|
34 |
+
'replaced' =>
|
35 |
+
array (
|
36 |
+
0 => '*',
|
37 |
+
),
|
38 |
+
),
|
39 |
+
'shama/baton' =>
|
40 |
+
array (
|
41 |
+
'replaced' =>
|
42 |
+
array (
|
43 |
+
0 => '*',
|
44 |
+
),
|
45 |
+
),
|
46 |
+
'skyverge/wc-plugin-framework' =>
|
47 |
+
array (
|
48 |
+
'pretty_version' => '5.10.0',
|
49 |
+
'version' => '5.10.0.0',
|
50 |
+
'aliases' =>
|
51 |
+
array (
|
52 |
+
),
|
53 |
+
'reference' => 'e230d7c40286854e49c0cafeec3398cbf2427a64',
|
54 |
+
),
|
55 |
+
'woocommerce/action-scheduler-job-framework' =>
|
56 |
+
array (
|
57 |
+
'pretty_version' => '1.0.0',
|
58 |
+
'version' => '1.0.0.0',
|
59 |
+
'aliases' =>
|
60 |
+
array (
|
61 |
+
),
|
62 |
+
'reference' => '718594e15d7ba2d56f8a37743bda6d7a8296e1c8',
|
63 |
+
),
|
64 |
+
),
|
65 |
+
);
|
vendor/composer/installers/LICENSE
ADDED
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Copyright (c) 2012 Kyle Robinson Young
|
2 |
+
|
3 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4 |
+
of this software and associated documentation files (the "Software"), to deal
|
5 |
+
in the Software without restriction, including without limitation the rights
|
6 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7 |
+
copies of the Software, and to permit persons to whom the Software is furnished
|
8 |
+
to do so, subject to the following conditions:
|
9 |
+
|
10 |
+
The above copyright notice and this permission notice shall be included in all
|
11 |
+
copies or substantial portions of the Software.
|
12 |
+
|
13 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19 |
+
THE SOFTWARE.
|
vendor/composer/installers/phpstan.neon.dist
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
parameters:
|
2 |
+
level: 5
|
3 |
+
paths:
|
4 |
+
- src
|
5 |
+
- tests
|
6 |
+
excludes_analyse:
|
7 |
+
- tests/Composer/Installers/Test/PolyfillTestCase.php
|
8 |
+
|
9 |
+
includes:
|
10 |
+
- vendor/phpstan/phpstan-phpunit/extension.neon
|
vendor/composer/installers/src/Composer/Installers/AglInstaller.php
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
class AglInstaller extends BaseInstaller
|
5 |
+
{
|
6 |
+
protected $locations = array(
|
7 |
+
'module' => 'More/{$name}/',
|
8 |
+
);
|
9 |
+
|
10 |
+
/**
|
11 |
+
* Format package name to CamelCase
|
12 |
+
*/
|
13 |
+
public function inflectPackageVars($vars)
|
14 |
+
{
|
15 |
+
$vars['name'] = preg_replace_callback('/(?:^|_|-)(.?)/', function ($matches) {
|
16 |
+
return strtoupper($matches[1]);
|
17 |
+
}, $vars['name']);
|
18 |
+
|
19 |
+
return $vars;
|
20 |
+
}
|
21 |
+
}
|
vendor/composer/installers/src/Composer/Installers/AimeosInstaller.php
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
class AimeosInstaller extends BaseInstaller
|
5 |
+
{
|
6 |
+
protected $locations = array(
|
7 |
+
'extension' => 'ext/{$name}/',
|
8 |
+
);
|
9 |
+
}
|
vendor/composer/installers/src/Composer/Installers/AnnotateCmsInstaller.php
ADDED
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
class AnnotateCmsInstaller extends BaseInstaller
|
5 |
+
{
|
6 |
+
protected $locations = array(
|
7 |
+
'module' => 'addons/modules/{$name}/',
|
8 |
+
'component' => 'addons/components/{$name}/',
|
9 |
+
'service' => 'addons/services/{$name}/',
|
10 |
+
);
|
11 |
+
}
|
vendor/composer/installers/src/Composer/Installers/AsgardInstaller.php
ADDED
@@ -0,0 +1,49 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
class AsgardInstaller extends BaseInstaller
|
5 |
+
{
|
6 |
+
protected $locations = array(
|
7 |
+
'module' => 'Modules/{$name}/',
|
8 |
+
'theme' => 'Themes/{$name}/'
|
9 |
+
);
|
10 |
+
|
11 |
+
/**
|
12 |
+
* Format package name.
|
13 |
+
*
|
14 |
+
* For package type asgard-module, cut off a trailing '-plugin' if present.
|
15 |
+
*
|
16 |
+
* For package type asgard-theme, cut off a trailing '-theme' if present.
|
17 |
+
*
|
18 |
+
*/
|
19 |
+
public function inflectPackageVars($vars)
|
20 |
+
{
|
21 |
+
if ($vars['type'] === 'asgard-module') {
|
22 |
+
return $this->inflectPluginVars($vars);
|
23 |
+
}
|
24 |
+
|
25 |
+
if ($vars['type'] === 'asgard-theme') {
|
26 |
+
return $this->inflectThemeVars($vars);
|
27 |
+
}
|
28 |
+
|
29 |
+
return $vars;
|
30 |
+
}
|
31 |
+
|
32 |
+
protected function inflectPluginVars($vars)
|
33 |
+
{
|
34 |
+
$vars['name'] = preg_replace('/-module$/', '', $vars['name']);
|
35 |
+
$vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
|
36 |
+
$vars['name'] = str_replace(' ', '', ucwords($vars['name']));
|
37 |
+
|
38 |
+
return $vars;
|
39 |
+
}
|
40 |
+
|
41 |
+
protected function inflectThemeVars($vars)
|
42 |
+
{
|
43 |
+
$vars['name'] = preg_replace('/-theme$/', '', $vars['name']);
|
44 |
+
$vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
|
45 |
+
$vars['name'] = str_replace(' ', '', ucwords($vars['name']));
|
46 |
+
|
47 |
+
return $vars;
|
48 |
+
}
|
49 |
+
}
|
vendor/composer/installers/src/Composer/Installers/AttogramInstaller.php
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
class AttogramInstaller extends BaseInstaller
|
5 |
+
{
|
6 |
+
protected $locations = array(
|
7 |
+
'module' => 'modules/{$name}/',
|
8 |
+
);
|
9 |
+
}
|
vendor/composer/installers/src/Composer/Installers/BaseInstaller.php
ADDED
@@ -0,0 +1,137 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
use Composer\IO\IOInterface;
|
5 |
+
use Composer\Composer;
|
6 |
+
use Composer\Package\PackageInterface;
|
7 |
+
|
8 |
+
abstract class BaseInstaller
|
9 |
+
{
|
10 |
+
protected $locations = array();
|
11 |
+
protected $composer;
|
12 |
+
protected $package;
|
13 |
+
protected $io;
|
14 |
+
|
15 |
+
/**
|
16 |
+
* Initializes base installer.
|
17 |
+
*
|
18 |
+
* @param PackageInterface $package
|
19 |
+
* @param Composer $composer
|
20 |
+
* @param IOInterface $io
|
21 |
+
*/
|
22 |
+
public function __construct(PackageInterface $package = null, Composer $composer = null, IOInterface $io = null)
|
23 |
+
{
|
24 |
+
$this->composer = $composer;
|
25 |
+
$this->package = $package;
|
26 |
+
$this->io = $io;
|
27 |
+
}
|
28 |
+
|
29 |
+
/**
|
30 |
+
* Return the install path based on package type.
|
31 |
+
*
|
32 |
+
* @param PackageInterface $package
|
33 |
+
* @param string $frameworkType
|
34 |
+
* @return string
|
35 |
+
*/
|
36 |
+
public function getInstallPath(PackageInterface $package, $frameworkType = '')
|
37 |
+
{
|
38 |
+
$type = $this->package->getType();
|
39 |
+
|
40 |
+
$prettyName = $this->package->getPrettyName();
|
41 |
+
if (strpos($prettyName, '/') !== false) {
|
42 |
+
list($vendor, $name) = explode('/', $prettyName);
|
43 |
+
} else {
|
44 |
+
$vendor = '';
|
45 |
+
$name = $prettyName;
|
46 |
+
}
|
47 |
+
|
48 |
+
$availableVars = $this->inflectPackageVars(compact('name', 'vendor', 'type'));
|
49 |
+
|
50 |
+
$extra = $package->getExtra();
|
51 |
+
if (!empty($extra['installer-name'])) {
|
52 |
+
$availableVars['name'] = $extra['installer-name'];
|
53 |
+
}
|
54 |
+
|
55 |
+
if ($this->composer->getPackage()) {
|
56 |
+
$extra = $this->composer->getPackage()->getExtra();
|
57 |
+
if (!empty($extra['installer-paths'])) {
|
58 |
+
$customPath = $this->mapCustomInstallPaths($extra['installer-paths'], $prettyName, $type, $vendor);
|
59 |
+
if ($customPath !== false) {
|
60 |
+
return $this->templatePath($customPath, $availableVars);
|
61 |
+
}
|
62 |
+
}
|
63 |
+
}
|
64 |
+
|
65 |
+
$packageType = substr($type, strlen($frameworkType) + 1);
|
66 |
+
$locations = $this->getLocations();
|
67 |
+
if (!isset($locations[$packageType])) {
|
68 |
+
throw new \InvalidArgumentException(sprintf('Package type "%s" is not supported', $type));
|
69 |
+
}
|
70 |
+
|
71 |
+
return $this->templatePath($locations[$packageType], $availableVars);
|
72 |
+
}
|
73 |
+
|
74 |
+
/**
|
75 |
+
* For an installer to override to modify the vars per installer.
|
76 |
+
*
|
77 |
+
* @param array<string, string> $vars This will normally receive array{name: string, vendor: string, type: string}
|
78 |
+
* @return array<string, string>
|
79 |
+
*/
|
80 |
+
public function inflectPackageVars($vars)
|
81 |
+
{
|
82 |
+
return $vars;
|
83 |
+
}
|
84 |
+
|
85 |
+
/**
|
86 |
+
* Gets the installer's locations
|
87 |
+
*
|
88 |
+
* @return array<string, string> map of package types => install path
|
89 |
+
*/
|
90 |
+
public function getLocations()
|
91 |
+
{
|
92 |
+
return $this->locations;
|
93 |
+
}
|
94 |
+
|
95 |
+
/**
|
96 |
+
* Replace vars in a path
|
97 |
+
*
|
98 |
+
* @param string $path
|
99 |
+
* @param array<string, string> $vars
|
100 |
+
* @return string
|
101 |
+
*/
|
102 |
+
protected function templatePath($path, array $vars = array())
|
103 |
+
{
|
104 |
+
if (strpos($path, '{') !== false) {
|
105 |
+
extract($vars);
|
106 |
+
preg_match_all('@\{\$([A-Za-z0-9_]*)\}@i', $path, $matches);
|
107 |
+
if (!empty($matches[1])) {
|
108 |
+
foreach ($matches[1] as $var) {
|
109 |
+
$path = str_replace('{$' . $var . '}', $$var, $path);
|
110 |
+
}
|
111 |
+
}
|
112 |
+
}
|
113 |
+
|
114 |
+
return $path;
|
115 |
+
}
|
116 |
+
|
117 |
+
/**
|
118 |
+
* Search through a passed paths array for a custom install path.
|
119 |
+
*
|
120 |
+
* @param array $paths
|
121 |
+
* @param string $name
|
122 |
+
* @param string $type
|
123 |
+
* @param string $vendor = NULL
|
124 |
+
* @return string|false
|
125 |
+
*/
|
126 |
+
protected function mapCustomInstallPaths(array $paths, $name, $type, $vendor = NULL)
|
127 |
+
{
|
128 |
+
foreach ($paths as $path => $names) {
|
129 |
+
$names = (array) $names;
|
130 |
+
if (in_array($name, $names) || in_array('type:' . $type, $names) || in_array('vendor:' . $vendor, $names)) {
|
131 |
+
return $path;
|
132 |
+
}
|
133 |
+
}
|
134 |
+
|
135 |
+
return false;
|
136 |
+
}
|
137 |
+
}
|
vendor/composer/installers/src/Composer/Installers/BitrixInstaller.php
ADDED
@@ -0,0 +1,126 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace Composer\Installers;
|
4 |
+
|
5 |
+
use Composer\Util\Filesystem;
|
6 |
+
|
7 |
+
/**
|
8 |
+
* Installer for Bitrix Framework. Supported types of extensions:
|
9 |
+
* - `bitrix-d7-module` — copy the module to directory `bitrix/modules/<vendor>.<name>`.
|
10 |
+
* - `bitrix-d7-component` — copy the component to directory `bitrix/components/<vendor>/<name>`.
|
11 |
+
* - `bitrix-d7-template` — copy the template to directory `bitrix/templates/<vendor>_<name>`.
|
12 |
+
*
|
13 |
+
* You can set custom path to directory with Bitrix kernel in `composer.json`:
|
14 |
+
*
|
15 |
+
* ```json
|
16 |
+
* {
|
17 |
+
* "extra": {
|
18 |
+
* "bitrix-dir": "s1/bitrix"
|
19 |
+
* }
|
20 |
+
* }
|
21 |
+
* ```
|
22 |
+
*
|
23 |
+
* @author Nik Samokhvalov <nik@samokhvalov.info>
|
24 |
+
* @author Denis Kulichkin <onexhovia@gmail.com>
|
25 |
+
*/
|
26 |
+
class BitrixInstaller extends BaseInstaller
|
27 |
+
{
|
28 |
+
protected $locations = array(
|
29 |
+
'module' => '{$bitrix_dir}/modules/{$name}/', // deprecated, remove on the major release (Backward compatibility will be broken)
|
30 |
+
'component' => '{$bitrix_dir}/components/{$name}/', // deprecated, remove on the major release (Backward compatibility will be broken)
|
31 |
+
'theme' => '{$bitrix_dir}/templates/{$name}/', // deprecated, remove on the major release (Backward compatibility will be broken)
|
32 |
+
'd7-module' => '{$bitrix_dir}/modules/{$vendor}.{$name}/',
|
33 |
+
'd7-component' => '{$bitrix_dir}/components/{$vendor}/{$name}/',
|
34 |
+
'd7-template' => '{$bitrix_dir}/templates/{$vendor}_{$name}/',
|
35 |
+
);
|
36 |
+
|
37 |
+
/**
|
38 |
+
* @var array Storage for informations about duplicates at all the time of installation packages.
|
39 |
+
*/
|
40 |
+
private static $checkedDuplicates = array();
|
41 |
+
|
42 |
+
/**
|
43 |
+
* {@inheritdoc}
|
44 |
+
*/
|
45 |
+
public function inflectPackageVars($vars)
|
46 |
+
{
|
47 |
+
if ($this->composer->getPackage()) {
|
48 |
+
$extra = $this->composer->getPackage()->getExtra();
|
49 |
+
|
50 |
+
if (isset($extra['bitrix-dir'])) {
|
51 |
+
$vars['bitrix_dir'] = $extra['bitrix-dir'];
|
52 |
+
}
|
53 |
+
}
|
54 |
+
|
55 |
+
if (!isset($vars['bitrix_dir'])) {
|
56 |
+
$vars['bitrix_dir'] = 'bitrix';
|
57 |
+
}
|
58 |
+
|
59 |
+
return parent::inflectPackageVars($vars);
|
60 |
+
}
|
61 |
+
|
62 |
+
/**
|
63 |
+
* {@inheritdoc}
|
64 |
+
*/
|
65 |
+
protected function templatePath($path, array $vars = array())
|
66 |
+
{
|
67 |
+
$templatePath = parent::templatePath($path, $vars);
|
68 |
+
$this->checkDuplicates($templatePath, $vars);
|
69 |
+
|
70 |
+
return $templatePath;
|
71 |
+
}
|
72 |
+
|
73 |
+
/**
|
74 |
+
* Duplicates search packages.
|
75 |
+
*
|
76 |
+
* @param string $path
|
77 |
+
* @param array $vars
|
78 |
+
*/
|
79 |
+
protected function checkDuplicates($path, array $vars = array())
|
80 |
+
{
|
81 |
+
$packageType = substr($vars['type'], strlen('bitrix') + 1);
|
82 |
+
$localDir = explode('/', $vars['bitrix_dir']);
|
83 |
+
array_pop($localDir);
|
84 |
+
$localDir[] = 'local';
|
85 |
+
$localDir = implode('/', $localDir);
|
86 |
+
|
87 |
+
$oldPath = str_replace(
|
88 |
+
array('{$bitrix_dir}', '{$name}'),
|
89 |
+
array($localDir, $vars['name']),
|
90 |
+
$this->locations[$packageType]
|
91 |
+
);
|
92 |
+
|
93 |
+
if (in_array($oldPath, static::$checkedDuplicates)) {
|
94 |
+
return;
|
95 |
+
}
|
96 |
+
|
97 |
+
if ($oldPath !== $path && file_exists($oldPath) && $this->io && $this->io->isInteractive()) {
|
98 |
+
|
99 |
+
$this->io->writeError(' <error>Duplication of packages:</error>');
|
100 |
+
$this->io->writeError(' <info>Package ' . $oldPath . ' will be called instead package ' . $path . '</info>');
|
101 |
+
|
102 |
+
while (true) {
|
103 |
+
switch ($this->io->ask(' <info>Delete ' . $oldPath . ' [y,n,?]?</info> ', '?')) {
|
104 |
+
case 'y':
|
105 |
+
$fs = new Filesystem();
|
106 |
+
$fs->removeDirectory($oldPath);
|
107 |
+
break 2;
|
108 |
+
|
109 |
+
case 'n':
|
110 |
+
break 2;
|
111 |
+
|
112 |
+
case '?':
|
113 |
+
default:
|
114 |
+
$this->io->writeError(array(
|
115 |
+
' y - delete package ' . $oldPath . ' and to continue with the installation',
|
116 |
+
' n - don\'t delete and to continue with the installation',
|
117 |
+
));
|
118 |
+
$this->io->writeError(' ? - print help');
|
119 |
+
break;
|
120 |
+
}
|
121 |
+
}
|
122 |
+
}
|
123 |
+
|
124 |
+
static::$checkedDuplicates[] = $oldPath;
|
125 |
+
}
|
126 |
+
}
|
vendor/composer/installers/src/Composer/Installers/BonefishInstaller.php
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
class BonefishInstaller extends BaseInstaller
|
5 |
+
{
|
6 |
+
protected $locations = array(
|
7 |
+
'package' => 'Packages/{$vendor}/{$name}/'
|
8 |
+
);
|
9 |
+
}
|
vendor/composer/installers/src/Composer/Installers/CakePHPInstaller.php
ADDED
@@ -0,0 +1,65 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
use Composer\DependencyResolver\Pool;
|
5 |
+
use Composer\Semver\Constraint\Constraint;
|
6 |
+
|
7 |
+
class CakePHPInstaller extends BaseInstaller
|
8 |
+
{
|
9 |
+
protected $locations = array(
|
10 |
+
'plugin' => 'Plugin/{$name}/',
|
11 |
+
);
|
12 |
+
|
13 |
+
/**
|
14 |
+
* Format package name to CamelCase
|
15 |
+
*/
|
16 |
+
public function inflectPackageVars($vars)
|
17 |
+
{
|
18 |
+
if ($this->matchesCakeVersion('>=', '3.0.0')) {
|
19 |
+
return $vars;
|
20 |
+
}
|
21 |
+
|
22 |
+
$nameParts = explode('/', $vars['name']);
|
23 |
+
foreach ($nameParts as &$value) {
|
24 |
+
$value = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $value));
|
25 |
+
$value = str_replace(array('-', '_'), ' ', $value);
|
26 |
+
$value = str_replace(' ', '', ucwords($value));
|
27 |
+
}
|
28 |
+
$vars['name'] = implode('/', $nameParts);
|
29 |
+
|
30 |
+
return $vars;
|
31 |
+
}
|
32 |
+
|
33 |
+
/**
|
34 |
+
* Change the default plugin location when cakephp >= 3.0
|
35 |
+
*/
|
36 |
+
public function getLocations()
|
37 |
+
{
|
38 |
+
if ($this->matchesCakeVersion('>=', '3.0.0')) {
|
39 |
+
$this->locations['plugin'] = $this->composer->getConfig()->get('vendor-dir') . '/{$vendor}/{$name}/';
|
40 |
+
}
|
41 |
+
return $this->locations;
|
42 |
+
}
|
43 |
+
|
44 |
+
/**
|
45 |
+
* Check if CakePHP version matches against a version
|
46 |
+
*
|
47 |
+
* @param string $matcher
|
48 |
+
* @param string $version
|
49 |
+
* @return bool
|
50 |
+
*/
|
51 |
+
protected function matchesCakeVersion($matcher, $version)
|
52 |
+
{
|
53 |
+
$repositoryManager = $this->composer->getRepositoryManager();
|
54 |
+
if (! $repositoryManager) {
|
55 |
+
return false;
|
56 |
+
}
|
57 |
+
|
58 |
+
$repos = $repositoryManager->getLocalRepository();
|
59 |
+
if (!$repos) {
|
60 |
+
return false;
|
61 |
+
}
|
62 |
+
|
63 |
+
return $repos->findPackage('cakephp/cakephp', new Constraint($matcher, $version)) !== null;
|
64 |
+
}
|
65 |
+
}
|
vendor/composer/installers/src/Composer/Installers/ChefInstaller.php
ADDED
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
class ChefInstaller extends BaseInstaller
|
5 |
+
{
|
6 |
+
protected $locations = array(
|
7 |
+
'cookbook' => 'Chef/{$vendor}/{$name}/',
|
8 |
+
'role' => 'Chef/roles/{$name}/',
|
9 |
+
);
|
10 |
+
}
|
11 |
+
|
vendor/composer/installers/src/Composer/Installers/CiviCrmInstaller.php
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
class CiviCrmInstaller extends BaseInstaller
|
5 |
+
{
|
6 |
+
protected $locations = array(
|
7 |
+
'ext' => 'ext/{$name}/'
|
8 |
+
);
|
9 |
+
}
|
vendor/composer/installers/src/Composer/Installers/ClanCatsFrameworkInstaller.php
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
class ClanCatsFrameworkInstaller extends BaseInstaller
|
5 |
+
{
|
6 |
+
protected $locations = array(
|
7 |
+
'ship' => 'CCF/orbit/{$name}/',
|
8 |
+
'theme' => 'CCF/app/themes/{$name}/',
|
9 |
+
);
|
10 |
+
}
|
vendor/composer/installers/src/Composer/Installers/CockpitInstaller.php
ADDED
@@ -0,0 +1,32 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
class CockpitInstaller extends BaseInstaller
|
5 |
+
{
|
6 |
+
protected $locations = array(
|
7 |
+
'module' => 'cockpit/modules/addons/{$name}/',
|
8 |
+
);
|
9 |
+
|
10 |
+
/**
|
11 |
+
* Format module name.
|
12 |
+
*
|
13 |
+
* Strip `module-` prefix from package name.
|
14 |
+
*
|
15 |
+
* {@inheritDoc}
|
16 |
+
*/
|
17 |
+
public function inflectPackageVars($vars)
|
18 |
+
{
|
19 |
+
if ($vars['type'] == 'cockpit-module') {
|
20 |
+
return $this->inflectModuleVars($vars);
|
21 |
+
}
|
22 |
+
|
23 |
+
return $vars;
|
24 |
+
}
|
25 |
+
|
26 |
+
public function inflectModuleVars($vars)
|
27 |
+
{
|
28 |
+
$vars['name'] = ucfirst(preg_replace('/cockpit-/i', '', $vars['name']));
|
29 |
+
|
30 |
+
return $vars;
|
31 |
+
}
|
32 |
+
}
|
vendor/composer/installers/src/Composer/Installers/CodeIgniterInstaller.php
ADDED
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
class CodeIgniterInstaller extends BaseInstaller
|
5 |
+
{
|
6 |
+
protected $locations = array(
|
7 |
+
'library' => 'application/libraries/{$name}/',
|
8 |
+
'third-party' => 'application/third_party/{$name}/',
|
9 |
+
'module' => 'application/modules/{$name}/',
|
10 |
+
);
|
11 |
+
}
|
vendor/composer/installers/src/Composer/Installers/Concrete5Installer.php
ADDED
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
class Concrete5Installer extends BaseInstaller
|
5 |
+
{
|
6 |
+
protected $locations = array(
|
7 |
+
'core' => 'concrete/',
|
8 |
+
'block' => 'application/blocks/{$name}/',
|
9 |
+
'package' => 'packages/{$name}/',
|
10 |
+
'theme' => 'application/themes/{$name}/',
|
11 |
+
'update' => 'updates/{$name}/',
|
12 |
+
);
|
13 |
+
}
|
vendor/composer/installers/src/Composer/Installers/CraftInstaller.php
ADDED
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
/**
|
5 |
+
* Installer for Craft Plugins
|
6 |
+
*/
|
7 |
+
class CraftInstaller extends BaseInstaller
|
8 |
+
{
|
9 |
+
const NAME_PREFIX = 'craft';
|
10 |
+
const NAME_SUFFIX = 'plugin';
|
11 |
+
|
12 |
+
protected $locations = array(
|
13 |
+
'plugin' => 'craft/plugins/{$name}/',
|
14 |
+
);
|
15 |
+
|
16 |
+
/**
|
17 |
+
* Strip `craft-` prefix and/or `-plugin` suffix from package names
|
18 |
+
*
|
19 |
+
* @param array $vars
|
20 |
+
*
|
21 |
+
* @return array
|
22 |
+
*/
|
23 |
+
final public function inflectPackageVars($vars)
|
24 |
+
{
|
25 |
+
return $this->inflectPluginVars($vars);
|
26 |
+
}
|
27 |
+
|
28 |
+
private function inflectPluginVars($vars)
|
29 |
+
{
|
30 |
+
$vars['name'] = preg_replace('/-' . self::NAME_SUFFIX . '$/i', '', $vars['name']);
|
31 |
+
$vars['name'] = preg_replace('/^' . self::NAME_PREFIX . '-/i', '', $vars['name']);
|
32 |
+
|
33 |
+
return $vars;
|
34 |
+
}
|
35 |
+
}
|
vendor/composer/installers/src/Composer/Installers/CroogoInstaller.php
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
class CroogoInstaller extends BaseInstaller
|
5 |
+
{
|
6 |
+
protected $locations = array(
|
7 |
+
'plugin' => 'Plugin/{$name}/',
|
8 |
+
'theme' => 'View/Themed/{$name}/',
|
9 |
+
);
|
10 |
+
|
11 |
+
/**
|
12 |
+
* Format package name to CamelCase
|
13 |
+
*/
|
14 |
+
public function inflectPackageVars($vars)
|
15 |
+
{
|
16 |
+
$vars['name'] = strtolower(str_replace(array('-', '_'), ' ', $vars['name']));
|
17 |
+
$vars['name'] = str_replace(' ', '', ucwords($vars['name']));
|
18 |
+
|
19 |
+
return $vars;
|
20 |
+
}
|
21 |
+
}
|
vendor/composer/installers/src/Composer/Installers/DecibelInstaller.php
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
class DecibelInstaller extends BaseInstaller
|
5 |
+
{
|
6 |
+
/** @var array */
|
7 |
+
protected $locations = array(
|
8 |
+
'app' => 'app/{$name}/',
|
9 |
+
);
|
10 |
+
}
|
vendor/composer/installers/src/Composer/Installers/DframeInstaller.php
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace Composer\Installers;
|
4 |
+
|
5 |
+
class DframeInstaller extends BaseInstaller
|
6 |
+
{
|
7 |
+
protected $locations = array(
|
8 |
+
'module' => 'modules/{$vendor}/{$name}/',
|
9 |
+
);
|
10 |
+
}
|
vendor/composer/installers/src/Composer/Installers/DokuWikiInstaller.php
ADDED
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
class DokuWikiInstaller extends BaseInstaller
|
5 |
+
{
|
6 |
+
protected $locations = array(
|
7 |
+
'plugin' => 'lib/plugins/{$name}/',
|
8 |
+
'template' => 'lib/tpl/{$name}/',
|
9 |
+
);
|
10 |
+
|
11 |
+
/**
|
12 |
+
* Format package name.
|
13 |
+
*
|
14 |
+
* For package type dokuwiki-plugin, cut off a trailing '-plugin',
|
15 |
+
* or leading dokuwiki_ if present.
|
16 |
+
*
|
17 |
+
* For package type dokuwiki-template, cut off a trailing '-template' if present.
|
18 |
+
*
|
19 |
+
*/
|
20 |
+
public function inflectPackageVars($vars)
|
21 |
+
{
|
22 |
+
|
23 |
+
if ($vars['type'] === 'dokuwiki-plugin') {
|
24 |
+
return $this->inflectPluginVars($vars);
|
25 |
+
}
|
26 |
+
|
27 |
+
if ($vars['type'] === 'dokuwiki-template') {
|
28 |
+
return $this->inflectTemplateVars($vars);
|
29 |
+
}
|
30 |
+
|
31 |
+
return $vars;
|
32 |
+
}
|
33 |
+
|
34 |
+
protected function inflectPluginVars($vars)
|
35 |
+
{
|
36 |
+
$vars['name'] = preg_replace('/-plugin$/', '', $vars['name']);
|
37 |
+
$vars['name'] = preg_replace('/^dokuwiki_?-?/', '', $vars['name']);
|
38 |
+
|
39 |
+
return $vars;
|
40 |
+
}
|
41 |
+
|
42 |
+
protected function inflectTemplateVars($vars)
|
43 |
+
{
|
44 |
+
$vars['name'] = preg_replace('/-template$/', '', $vars['name']);
|
45 |
+
$vars['name'] = preg_replace('/^dokuwiki_?-?/', '', $vars['name']);
|
46 |
+
|
47 |
+
return $vars;
|
48 |
+
}
|
49 |
+
|
50 |
+
}
|
vendor/composer/installers/src/Composer/Installers/DolibarrInstaller.php
ADDED
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
/**
|
5 |
+
* Class DolibarrInstaller
|
6 |
+
*
|
7 |
+
* @package Composer\Installers
|
8 |
+
* @author Raphaël Doursenaud <rdoursenaud@gpcsolutions.fr>
|
9 |
+
*/
|
10 |
+
class DolibarrInstaller extends BaseInstaller
|
11 |
+
{
|
12 |
+
//TODO: Add support for scripts and themes
|
13 |
+
protected $locations = array(
|
14 |
+
'module' => 'htdocs/custom/{$name}/',
|
15 |
+
);
|
16 |
+
}
|
vendor/composer/installers/src/Composer/Installers/DrupalInstaller.php
ADDED
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
class DrupalInstaller extends BaseInstaller
|
5 |
+
{
|
6 |
+
protected $locations = array(
|
7 |
+
'core' => 'core/',
|
8 |
+
'module' => 'modules/{$name}/',
|
9 |
+
'theme' => 'themes/{$name}/',
|
10 |
+
'library' => 'libraries/{$name}/',
|
11 |
+
'profile' => 'profiles/{$name}/',
|
12 |
+
'database-driver' => 'drivers/lib/Drupal/Driver/Database/{$name}/',
|
13 |
+
'drush' => 'drush/{$name}/',
|
14 |
+
'custom-theme' => 'themes/custom/{$name}/',
|
15 |
+
'custom-module' => 'modules/custom/{$name}/',
|
16 |
+
'custom-profile' => 'profiles/custom/{$name}/',
|
17 |
+
'drupal-multisite' => 'sites/{$name}/',
|
18 |
+
'console' => 'console/{$name}/',
|
19 |
+
'console-language' => 'console/language/{$name}/',
|
20 |
+
'config' => 'config/sync/',
|
21 |
+
);
|
22 |
+
}
|
vendor/composer/installers/src/Composer/Installers/ElggInstaller.php
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
class ElggInstaller extends BaseInstaller
|
5 |
+
{
|
6 |
+
protected $locations = array(
|
7 |
+
'plugin' => 'mod/{$name}/',
|
8 |
+
);
|
9 |
+
}
|
vendor/composer/installers/src/Composer/Installers/EliasisInstaller.php
ADDED
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
class EliasisInstaller extends BaseInstaller
|
5 |
+
{
|
6 |
+
protected $locations = array(
|
7 |
+
'component' => 'components/{$name}/',
|
8 |
+
'module' => 'modules/{$name}/',
|
9 |
+
'plugin' => 'plugins/{$name}/',
|
10 |
+
'template' => 'templates/{$name}/',
|
11 |
+
);
|
12 |
+
}
|
vendor/composer/installers/src/Composer/Installers/ExpressionEngineInstaller.php
ADDED
@@ -0,0 +1,29 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
use Composer\Package\PackageInterface;
|
5 |
+
|
6 |
+
class ExpressionEngineInstaller extends BaseInstaller
|
7 |
+
{
|
8 |
+
|
9 |
+
protected $locations = array();
|
10 |
+
|
11 |
+
private $ee2Locations = array(
|
12 |
+
'addon' => 'system/expressionengine/third_party/{$name}/',
|
13 |
+
'theme' => 'themes/third_party/{$name}/',
|
14 |
+
);
|
15 |
+
|
16 |
+
private $ee3Locations = array(
|
17 |
+
'addon' => 'system/user/addons/{$name}/',
|
18 |
+
'theme' => 'themes/user/{$name}/',
|
19 |
+
);
|
20 |
+
|
21 |
+
public function getInstallPath(PackageInterface $package, $frameworkType = '')
|
22 |
+
{
|
23 |
+
|
24 |
+
$version = "{$frameworkType}Locations";
|
25 |
+
$this->locations = $this->$version;
|
26 |
+
|
27 |
+
return parent::getInstallPath($package, $frameworkType);
|
28 |
+
}
|
29 |
+
}
|
vendor/composer/installers/src/Composer/Installers/EzPlatformInstaller.php
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
class EzPlatformInstaller extends BaseInstaller
|
5 |
+
{
|
6 |
+
protected $locations = array(
|
7 |
+
'meta-assets' => 'web/assets/ezplatform/',
|
8 |
+
'assets' => 'web/assets/ezplatform/{$name}/',
|
9 |
+
);
|
10 |
+
}
|
vendor/composer/installers/src/Composer/Installers/FuelInstaller.php
ADDED
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
class FuelInstaller extends BaseInstaller
|
5 |
+
{
|
6 |
+
protected $locations = array(
|
7 |
+
'module' => 'fuel/app/modules/{$name}/',
|
8 |
+
'package' => 'fuel/packages/{$name}/',
|
9 |
+
'theme' => 'fuel/app/themes/{$name}/',
|
10 |
+
);
|
11 |
+
}
|
vendor/composer/installers/src/Composer/Installers/FuelphpInstaller.php
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
class FuelphpInstaller extends BaseInstaller
|
5 |
+
{
|
6 |
+
protected $locations = array(
|
7 |
+
'component' => 'components/{$name}/',
|
8 |
+
);
|
9 |
+
}
|
vendor/composer/installers/src/Composer/Installers/GravInstaller.php
ADDED
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
class GravInstaller extends BaseInstaller
|
5 |
+
{
|
6 |
+
protected $locations = array(
|
7 |
+
'plugin' => 'user/plugins/{$name}/',
|
8 |
+
'theme' => 'user/themes/{$name}/',
|
9 |
+
);
|
10 |
+
|
11 |
+
/**
|
12 |
+
* Format package name
|
13 |
+
*
|
14 |
+
* @param array $vars
|
15 |
+
*
|
16 |
+
* @return array
|
17 |
+
*/
|
18 |
+
public function inflectPackageVars($vars)
|
19 |
+
{
|
20 |
+
$restrictedWords = implode('|', array_keys($this->locations));
|
21 |
+
|
22 |
+
$vars['name'] = strtolower($vars['name']);
|
23 |
+
$vars['name'] = preg_replace('/^(?:grav-)?(?:(?:'.$restrictedWords.')-)?(.*?)(?:-(?:'.$restrictedWords.'))?$/ui',
|
24 |
+
'$1',
|
25 |
+
$vars['name']
|
26 |
+
);
|
27 |
+
|
28 |
+
return $vars;
|
29 |
+
}
|
30 |
+
}
|
vendor/composer/installers/src/Composer/Installers/HuradInstaller.php
ADDED
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
class HuradInstaller extends BaseInstaller
|
5 |
+
{
|
6 |
+
protected $locations = array(
|
7 |
+
'plugin' => 'plugins/{$name}/',
|
8 |
+
'theme' => 'plugins/{$name}/',
|
9 |
+
);
|
10 |
+
|
11 |
+
/**
|
12 |
+
* Format package name to CamelCase
|
13 |
+
*/
|
14 |
+
public function inflectPackageVars($vars)
|
15 |
+
{
|
16 |
+
$nameParts = explode('/', $vars['name']);
|
17 |
+
foreach ($nameParts as &$value) {
|
18 |
+
$value = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $value));
|
19 |
+
$value = str_replace(array('-', '_'), ' ', $value);
|
20 |
+
$value = str_replace(' ', '', ucwords($value));
|
21 |
+
}
|
22 |
+
$vars['name'] = implode('/', $nameParts);
|
23 |
+
return $vars;
|
24 |
+
}
|
25 |
+
}
|
vendor/composer/installers/src/Composer/Installers/ImageCMSInstaller.php
ADDED
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
class ImageCMSInstaller extends BaseInstaller
|
5 |
+
{
|
6 |
+
protected $locations = array(
|
7 |
+
'template' => 'templates/{$name}/',
|
8 |
+
'module' => 'application/modules/{$name}/',
|
9 |
+
'library' => 'application/libraries/{$name}/',
|
10 |
+
);
|
11 |
+
}
|
vendor/composer/installers/src/Composer/Installers/Installer.php
ADDED
@@ -0,0 +1,297 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace Composer\Installers;
|
4 |
+
|
5 |
+
use Composer\Composer;
|
6 |
+
use Composer\Installer\BinaryInstaller;
|
7 |
+
use Composer\Installer\LibraryInstaller;
|
8 |
+
use Composer\IO\IOInterface;
|
9 |
+
use Composer\Package\PackageInterface;
|
10 |
+
use Composer\Repository\InstalledRepositoryInterface;
|
11 |
+
use Composer\Util\Filesystem;
|
12 |
+
use React\Promise\PromiseInterface;
|
13 |
+
|
14 |
+
class Installer extends LibraryInstaller
|
15 |
+
{
|
16 |
+
|
17 |
+
/**
|
18 |
+
* Package types to installer class map
|
19 |
+
*
|
20 |
+
* @var array
|
21 |
+
*/
|
22 |
+
private $supportedTypes = array(
|
23 |
+
'aimeos' => 'AimeosInstaller',
|
24 |
+
'asgard' => 'AsgardInstaller',
|
25 |
+
'attogram' => 'AttogramInstaller',
|
26 |
+
'agl' => 'AglInstaller',
|
27 |
+
'annotatecms' => 'AnnotateCmsInstaller',
|
28 |
+
'bitrix' => 'BitrixInstaller',
|
29 |
+
'bonefish' => 'BonefishInstaller',
|
30 |
+
'cakephp' => 'CakePHPInstaller',
|
31 |
+
'chef' => 'ChefInstaller',
|
32 |
+
'civicrm' => 'CiviCrmInstaller',
|
33 |
+
'ccframework' => 'ClanCatsFrameworkInstaller',
|
34 |
+
'cockpit' => 'CockpitInstaller',
|
35 |
+
'codeigniter' => 'CodeIgniterInstaller',
|
36 |
+
'concrete5' => 'Concrete5Installer',
|
37 |
+
'craft' => 'CraftInstaller',
|
38 |
+
'croogo' => 'CroogoInstaller',
|
39 |
+
'dframe' => 'DframeInstaller',
|
40 |
+
'dokuwiki' => 'DokuWikiInstaller',
|
41 |
+
'dolibarr' => 'DolibarrInstaller',
|
42 |
+
'decibel' => 'DecibelInstaller',
|
43 |
+
'drupal' => 'DrupalInstaller',
|
44 |
+
'elgg' => 'ElggInstaller',
|
45 |
+
'eliasis' => 'EliasisInstaller',
|
46 |
+
'ee3' => 'ExpressionEngineInstaller',
|
47 |
+
'ee2' => 'ExpressionEngineInstaller',
|
48 |
+
'ezplatform' => 'EzPlatformInstaller',
|
49 |
+
'fuel' => 'FuelInstaller',
|
50 |
+
'fuelphp' => 'FuelphpInstaller',
|
51 |
+
'grav' => 'GravInstaller',
|
52 |
+
'hurad' => 'HuradInstaller',
|
53 |
+
'tastyigniter' => 'TastyIgniterInstaller',
|
54 |
+
'imagecms' => 'ImageCMSInstaller',
|
55 |
+
'itop' => 'ItopInstaller',
|
56 |
+
'joomla' => 'JoomlaInstaller',
|
57 |
+
'kanboard' => 'KanboardInstaller',
|
58 |
+
'kirby' => 'KirbyInstaller',
|
59 |
+
'known' => 'KnownInstaller',
|
60 |
+
'kodicms' => 'KodiCMSInstaller',
|
61 |
+
'kohana' => 'KohanaInstaller',
|
62 |
+
'lms' => 'LanManagementSystemInstaller',
|
63 |
+
'laravel' => 'LaravelInstaller',
|
64 |
+
'lavalite' => 'LavaLiteInstaller',
|
65 |
+
'lithium' => 'LithiumInstaller',
|
66 |
+
'magento' => 'MagentoInstaller',
|
67 |
+
'majima' => 'MajimaInstaller',
|
68 |
+
'mantisbt' => 'MantisBTInstaller',
|
69 |
+
'mako' => 'MakoInstaller',
|
70 |
+
'maya' => 'MayaInstaller',
|
71 |
+
'mautic' => 'MauticInstaller',
|
72 |
+
'mediawiki' => 'MediaWikiInstaller',
|
73 |
+
'miaoxing' => 'MiaoxingInstaller',
|
74 |
+
'microweber' => 'MicroweberInstaller',
|
75 |
+
'modulework' => 'MODULEWorkInstaller',
|
76 |
+
'modx' => 'ModxInstaller',
|
77 |
+
'modxevo' => 'MODXEvoInstaller',
|
78 |
+
'moodle' => 'MoodleInstaller',
|
79 |
+
'october' => 'OctoberInstaller',
|
80 |
+
'ontowiki' => 'OntoWikiInstaller',
|
81 |
+
'oxid' => 'OxidInstaller',
|
82 |
+
'osclass' => 'OsclassInstaller',
|
83 |
+
'pxcms' => 'PxcmsInstaller',
|
84 |
+
'phpbb' => 'PhpBBInstaller',
|
85 |
+
'pimcore' => 'PimcoreInstaller',
|
86 |
+
'piwik' => 'PiwikInstaller',
|
87 |
+
'plentymarkets'=> 'PlentymarketsInstaller',
|
88 |
+
'ppi' => 'PPIInstaller',
|
89 |
+
'puppet' => 'PuppetInstaller',
|
90 |
+
'radphp' => 'RadPHPInstaller',
|
91 |
+
'phifty' => 'PhiftyInstaller',
|
92 |
+
'porto' => 'PortoInstaller',
|
93 |
+
'processwire' => 'ProcessWireInstaller',
|
94 |
+
'redaxo' => 'RedaxoInstaller',
|
95 |
+
'redaxo5' => 'Redaxo5Installer',
|
96 |
+
'reindex' => 'ReIndexInstaller',
|
97 |
+
'roundcube' => 'RoundcubeInstaller',
|
98 |
+
'shopware' => 'ShopwareInstaller',
|
99 |
+
'sitedirect' => 'SiteDirectInstaller',
|
100 |
+
'silverstripe' => 'SilverStripeInstaller',
|
101 |
+
'smf' => 'SMFInstaller',
|
102 |
+
'starbug' => 'StarbugInstaller',
|
103 |
+
'sydes' => 'SyDESInstaller',
|
104 |
+
'sylius' => 'SyliusInstaller',
|
105 |
+
'symfony1' => 'Symfony1Installer',
|
106 |
+
'tao' => 'TaoInstaller',
|
107 |
+
'thelia' => 'TheliaInstaller',
|
108 |
+
'tusk' => 'TuskInstaller',
|
109 |
+
'typo3-cms' => 'TYPO3CmsInstaller',
|
110 |
+
'typo3-flow' => 'TYPO3FlowInstaller',
|
111 |
+
'userfrosting' => 'UserFrostingInstaller',
|
112 |
+
'vanilla' => 'VanillaInstaller',
|
113 |
+
'whmcs' => 'WHMCSInstaller',
|
114 |
+
'winter' => 'WinterInstaller',
|
115 |
+
'wolfcms' => 'WolfCMSInstaller',
|
116 |
+
'wordpress' => 'WordPressInstaller',
|
117 |
+
'yawik' => 'YawikInstaller',
|
118 |
+
'zend' => 'ZendInstaller',
|
119 |
+
'zikula' => 'ZikulaInstaller',
|
120 |
+
'prestashop' => 'PrestashopInstaller'
|
121 |
+
);
|
122 |
+
|
123 |
+
/**
|
124 |
+
* Installer constructor.
|
125 |
+
*
|
126 |
+
* Disables installers specified in main composer extra installer-disable
|
127 |
+
* list
|
128 |
+
*
|
129 |
+
* @param IOInterface $io
|
130 |
+
* @param Composer $composer
|
131 |
+
* @param string $type
|
132 |
+
* @param Filesystem|null $filesystem
|
133 |
+
* @param BinaryInstaller|null $binaryInstaller
|
134 |
+
*/
|
135 |
+
public function __construct(
|
136 |
+
IOInterface $io,
|
137 |
+
Composer $composer,
|
138 |
+
$type = 'library',
|
139 |
+
Filesystem $filesystem = null,
|
140 |
+
BinaryInstaller $binaryInstaller = null
|
141 |
+
) {
|
142 |
+
parent::__construct($io, $composer, $type, $filesystem,
|
143 |
+
$binaryInstaller);
|
144 |
+
$this->removeDisabledInstallers();
|
145 |
+
}
|
146 |
+
|
147 |
+
/**
|
148 |
+
* {@inheritDoc}
|
149 |
+
*/
|
150 |
+
public function getInstallPath(PackageInterface $package)
|
151 |
+
{
|
152 |
+
$type = $package->getType();
|
153 |
+
$frameworkType = $this->findFrameworkType($type);
|
154 |
+
|
155 |
+
if ($frameworkType === false) {
|
156 |
+
throw new \InvalidArgumentException(
|
157 |
+
'Sorry the package type of this package is not yet supported.'
|
158 |
+
);
|
159 |
+
}
|
160 |
+
|
161 |
+
$class = 'Composer\\Installers\\' . $this->supportedTypes[$frameworkType];
|
162 |
+
$installer = new $class($package, $this->composer, $this->getIO());
|
163 |
+
|
164 |
+
return $installer->getInstallPath($package, $frameworkType);
|
165 |
+
}
|
166 |
+
|
167 |
+
public function uninstall(InstalledRepositoryInterface $repo, PackageInterface $package)
|
168 |
+
{
|
169 |
+
$installPath = $this->getPackageBasePath($package);
|
170 |
+
$io = $this->io;
|
171 |
+
$outputStatus = function () use ($io, $installPath) {
|
172 |
+
$io->write(sprintf('Deleting %s - %s', $installPath, !file_exists($installPath) ? '<comment>deleted</comment>' : '<error>not deleted</error>'));
|
173 |
+
};
|
174 |
+
|
175 |
+
$promise = parent::uninstall($repo, $package);
|
176 |
+
|
177 |
+
// Composer v2 might return a promise here
|
178 |
+
if ($promise instanceof PromiseInterface) {
|
179 |
+
return $promise->then($outputStatus);
|
180 |
+
}
|
181 |
+
|
182 |
+
// If not, execute the code right away as parent::uninstall executed synchronously (composer v1, or v2 without async)
|
183 |
+
$outputStatus();
|
184 |
+
|
185 |
+
return null;
|
186 |
+
}
|
187 |
+
|
188 |
+
/**
|
189 |
+
* {@inheritDoc}
|
190 |
+
*/
|
191 |
+
public function supports($packageType)
|
192 |
+
{
|
193 |
+
$frameworkType = $this->findFrameworkType($packageType);
|
194 |
+
|
195 |
+
if ($frameworkType === false) {
|
196 |
+
return false;
|
197 |
+
}
|
198 |
+
|
199 |
+
$locationPattern = $this->getLocationPattern($frameworkType);
|
200 |
+
|
201 |
+
return preg_match('#' . $frameworkType . '-' . $locationPattern . '#', $packageType, $matches) === 1;
|
202 |
+
}
|
203 |
+
|
204 |
+
/**
|
205 |
+
* Finds a supported framework type if it exists and returns it
|
206 |
+
*
|
207 |
+
* @param string $type
|
208 |
+
* @return string|false
|
209 |
+
*/
|
210 |
+
protected function findFrameworkType($type)
|
211 |
+
{
|
212 |
+
krsort($this->supportedTypes);
|
213 |
+
|
214 |
+
foreach ($this->supportedTypes as $key => $val) {
|
215 |
+
if ($key === substr($type, 0, strlen($key))) {
|
216 |
+
return substr($type, 0, strlen($key));
|
217 |
+
}
|
218 |
+
}
|
219 |
+
|
220 |
+
return false;
|
221 |
+
}
|
222 |
+
|
223 |
+
/**
|
224 |
+
* Get the second part of the regular expression to check for support of a
|
225 |
+
* package type
|
226 |
+
*
|
227 |
+
* @param string $frameworkType
|
228 |
+
* @return string
|
229 |
+
*/
|
230 |
+
protected function getLocationPattern($frameworkType)
|
231 |
+
{
|
232 |
+
$pattern = false;
|
233 |
+
if (!empty($this->supportedTypes[$frameworkType])) {
|
234 |
+
$frameworkClass = 'Composer\\Installers\\' . $this->supportedTypes[$frameworkType];
|
235 |
+
/** @var BaseInstaller $framework */
|
236 |
+
$framework = new $frameworkClass(null, $this->composer, $this->getIO());
|
237 |
+
$locations = array_keys($framework->getLocations());
|
238 |
+
$pattern = $locations ? '(' . implode('|', $locations) . ')' : false;
|
239 |
+
}
|
240 |
+
|
241 |
+
return $pattern ? : '(\w+)';
|
242 |
+
}
|
243 |
+
|
244 |
+
/**
|
245 |
+
* Get I/O object
|
246 |
+
*
|
247 |
+
* @return IOInterface
|
248 |
+
*/
|
249 |
+
private function getIO()
|
250 |
+
{
|
251 |
+
return $this->io;
|
252 |
+
}
|
253 |
+
|
254 |
+
/**
|
255 |
+
* Look for installers set to be disabled in composer's extra config and
|
256 |
+
* remove them from the list of supported installers.
|
257 |
+
*
|
258 |
+
* Globals:
|
259 |
+
* - true, "all", and "*" - disable all installers.
|
260 |
+
* - false - enable all installers (useful with
|
261 |
+
* wikimedia/composer-merge-plugin or similar)
|
262 |
+
*
|
263 |
+
* @return void
|
264 |
+
*/
|
265 |
+
protected function removeDisabledInstallers()
|
266 |
+
{
|
267 |
+
$extra = $this->composer->getPackage()->getExtra();
|
268 |
+
|
269 |
+
if (!isset($extra['installer-disable']) || $extra['installer-disable'] === false) {
|
270 |
+
// No installers are disabled
|
271 |
+
return;
|
272 |
+
}
|
273 |
+
|
274 |
+
// Get installers to disable
|
275 |
+
$disable = $extra['installer-disable'];
|
276 |
+
|
277 |
+
// Ensure $disabled is an array
|
278 |
+
if (!is_array($disable)) {
|
279 |
+
$disable = array($disable);
|
280 |
+
}
|
281 |
+
|
282 |
+
// Check which installers should be disabled
|
283 |
+
$all = array(true, "all", "*");
|
284 |
+
$intersect = array_intersect($all, $disable);
|
285 |
+
if (!empty($intersect)) {
|
286 |
+
// Disable all installers
|
287 |
+
$this->supportedTypes = array();
|
288 |
+
} else {
|
289 |
+
// Disable specified installers
|
290 |
+
foreach ($disable as $key => $installer) {
|
291 |
+
if (is_string($installer) && key_exists($installer, $this->supportedTypes)) {
|
292 |
+
unset($this->supportedTypes[$installer]);
|
293 |
+
}
|
294 |
+
}
|
295 |
+
}
|
296 |
+
}
|
297 |
+
}
|
vendor/composer/installers/src/Composer/Installers/ItopInstaller.php
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
class ItopInstaller extends BaseInstaller
|
5 |
+
{
|
6 |
+
protected $locations = array(
|
7 |
+
'extension' => 'extensions/{$name}/',
|
8 |
+
);
|
9 |
+
}
|
vendor/composer/installers/src/Composer/Installers/JoomlaInstaller.php
ADDED
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
class JoomlaInstaller extends BaseInstaller
|
5 |
+
{
|
6 |
+
protected $locations = array(
|
7 |
+
'component' => 'components/{$name}/',
|
8 |
+
'module' => 'modules/{$name}/',
|
9 |
+
'template' => 'templates/{$name}/',
|
10 |
+
'plugin' => 'plugins/{$name}/',
|
11 |
+
'library' => 'libraries/{$name}/',
|
12 |
+
);
|
13 |
+
|
14 |
+
// TODO: Add inflector for mod_ and com_ names
|
15 |
+
}
|
vendor/composer/installers/src/Composer/Installers/KanboardInstaller.php
ADDED
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
/**
|
5 |
+
*
|
6 |
+
* Installer for kanboard plugins
|
7 |
+
*
|
8 |
+
* kanboard.net
|
9 |
+
*
|
10 |
+
* Class KanboardInstaller
|
11 |
+
* @package Composer\Installers
|
12 |
+
*/
|
13 |
+
class KanboardInstaller extends BaseInstaller
|
14 |
+
{
|
15 |
+
protected $locations = array(
|
16 |
+
'plugin' => 'plugins/{$name}/',
|
17 |
+
);
|
18 |
+
}
|
vendor/composer/installers/src/Composer/Installers/KirbyInstaller.php
ADDED
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
class KirbyInstaller extends BaseInstaller
|
5 |
+
{
|
6 |
+
protected $locations = array(
|
7 |
+
'plugin' => 'site/plugins/{$name}/',
|
8 |
+
'field' => 'site/fields/{$name}/',
|
9 |
+
'tag' => 'site/tags/{$name}/'
|
10 |
+
);
|
11 |
+
}
|
vendor/composer/installers/src/Composer/Installers/KnownInstaller.php
ADDED
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
class KnownInstaller extends BaseInstaller
|
5 |
+
{
|
6 |
+
protected $locations = array(
|
7 |
+
'plugin' => 'IdnoPlugins/{$name}/',
|
8 |
+
'theme' => 'Themes/{$name}/',
|
9 |
+
'console' => 'ConsolePlugins/{$name}/',
|
10 |
+
);
|
11 |
+
}
|
vendor/composer/installers/src/Composer/Installers/KodiCMSInstaller.php
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
class KodiCMSInstaller extends BaseInstaller
|
5 |
+
{
|
6 |
+
protected $locations = array(
|
7 |
+
'plugin' => 'cms/plugins/{$name}/',
|
8 |
+
'media' => 'cms/media/vendor/{$name}/'
|
9 |
+
);
|
10 |
+
}
|
vendor/composer/installers/src/Composer/Installers/KohanaInstaller.php
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
class KohanaInstaller extends BaseInstaller
|
5 |
+
{
|
6 |
+
protected $locations = array(
|
7 |
+
'module' => 'modules/{$name}/',
|
8 |
+
);
|
9 |
+
}
|
vendor/composer/installers/src/Composer/Installers/LanManagementSystemInstaller.php
ADDED
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace Composer\Installers;
|
4 |
+
|
5 |
+
class LanManagementSystemInstaller extends BaseInstaller
|
6 |
+
{
|
7 |
+
|
8 |
+
protected $locations = array(
|
9 |
+
'plugin' => 'plugins/{$name}/',
|
10 |
+
'template' => 'templates/{$name}/',
|
11 |
+
'document-template' => 'documents/templates/{$name}/',
|
12 |
+
'userpanel-module' => 'userpanel/modules/{$name}/',
|
13 |
+
);
|
14 |
+
|
15 |
+
/**
|
16 |
+
* Format package name to CamelCase
|
17 |
+
*/
|
18 |
+
public function inflectPackageVars($vars)
|
19 |
+
{
|
20 |
+
$vars['name'] = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name']));
|
21 |
+
$vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
|
22 |
+
$vars['name'] = str_replace(' ', '', ucwords($vars['name']));
|
23 |
+
|
24 |
+
return $vars;
|
25 |
+
}
|
26 |
+
|
27 |
+
}
|
vendor/composer/installers/src/Composer/Installers/LaravelInstaller.php
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
class LaravelInstaller extends BaseInstaller
|
5 |
+
{
|
6 |
+
protected $locations = array(
|
7 |
+
'library' => 'libraries/{$name}/',
|
8 |
+
);
|
9 |
+
}
|
vendor/composer/installers/src/Composer/Installers/LavaLiteInstaller.php
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
class LavaLiteInstaller extends BaseInstaller
|
5 |
+
{
|
6 |
+
protected $locations = array(
|
7 |
+
'package' => 'packages/{$vendor}/{$name}/',
|
8 |
+
'theme' => 'public/themes/{$name}/',
|
9 |
+
);
|
10 |
+
}
|
vendor/composer/installers/src/Composer/Installers/LithiumInstaller.php
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
class LithiumInstaller extends BaseInstaller
|
5 |
+
{
|
6 |
+
protected $locations = array(
|
7 |
+
'library' => 'libraries/{$name}/',
|
8 |
+
'source' => 'libraries/_source/{$name}/',
|
9 |
+
);
|
10 |
+
}
|
vendor/composer/installers/src/Composer/Installers/MODULEWorkInstaller.php
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
class MODULEWorkInstaller extends BaseInstaller
|
5 |
+
{
|
6 |
+
protected $locations = array(
|
7 |
+
'module' => 'modules/{$name}/',
|
8 |
+
);
|
9 |
+
}
|
vendor/composer/installers/src/Composer/Installers/MODXEvoInstaller.php
ADDED
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
/**
|
5 |
+
* An installer to handle MODX Evolution specifics when installing packages.
|
6 |
+
*/
|
7 |
+
class MODXEvoInstaller extends BaseInstaller
|
8 |
+
{
|
9 |
+
protected $locations = array(
|
10 |
+
'snippet' => 'assets/snippets/{$name}/',
|
11 |
+
'plugin' => 'assets/plugins/{$name}/',
|
12 |
+
'module' => 'assets/modules/{$name}/',
|
13 |
+
'template' => 'assets/templates/{$name}/',
|
14 |
+
'lib' => 'assets/lib/{$name}/'
|
15 |
+
);
|
16 |
+
}
|
vendor/composer/installers/src/Composer/Installers/MagentoInstaller.php
ADDED
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
class MagentoInstaller extends BaseInstaller
|
5 |
+
{
|
6 |
+
protected $locations = array(
|
7 |
+
'theme' => 'app/design/frontend/{$name}/',
|
8 |
+
'skin' => 'skin/frontend/default/{$name}/',
|
9 |
+
'library' => 'lib/{$name}/',
|
10 |
+
);
|
11 |
+
}
|
vendor/composer/installers/src/Composer/Installers/MajimaInstaller.php
ADDED
@@ -0,0 +1,37 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
/**
|
5 |
+
* Plugin/theme installer for majima
|
6 |
+
* @author David Neustadt
|
7 |
+
*/
|
8 |
+
class MajimaInstaller extends BaseInstaller
|
9 |
+
{
|
10 |
+
protected $locations = array(
|
11 |
+
'plugin' => 'plugins/{$name}/',
|
12 |
+
);
|
13 |
+
|
14 |
+
/**
|
15 |
+
* Transforms the names
|
16 |
+
* @param array $vars
|
17 |
+
* @return array
|
18 |
+
*/
|
19 |
+
public function inflectPackageVars($vars)
|
20 |
+
{
|
21 |
+
return $this->correctPluginName($vars);
|
22 |
+
}
|
23 |
+
|
24 |
+
/**
|
25 |
+
* Change hyphenated names to camelcase
|
26 |
+
* @param array $vars
|
27 |
+
* @return array
|
28 |
+
*/
|
29 |
+
private function correctPluginName($vars)
|
30 |
+
{
|
31 |
+
$camelCasedName = preg_replace_callback('/(-[a-z])/', function ($matches) {
|
32 |
+
return strtoupper($matches[0][1]);
|
33 |
+
}, $vars['name']);
|
34 |
+
$vars['name'] = ucfirst($camelCasedName);
|
35 |
+
return $vars;
|
36 |
+
}
|
37 |
+
}
|
vendor/composer/installers/src/Composer/Installers/MakoInstaller.php
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
class MakoInstaller extends BaseInstaller
|
5 |
+
{
|
6 |
+
protected $locations = array(
|
7 |
+
'package' => 'app/packages/{$name}/',
|
8 |
+
);
|
9 |
+
}
|
vendor/composer/installers/src/Composer/Installers/MantisBTInstaller.php
ADDED
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
use Composer\DependencyResolver\Pool;
|
5 |
+
|
6 |
+
class MantisBTInstaller extends BaseInstaller
|
7 |
+
{
|
8 |
+
protected $locations = array(
|
9 |
+
'plugin' => 'plugins/{$name}/',
|
10 |
+
);
|
11 |
+
|
12 |
+
/**
|
13 |
+
* Format package name to CamelCase
|
14 |
+
*/
|
15 |
+
public function inflectPackageVars($vars)
|
16 |
+
{
|
17 |
+
$vars['name'] = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name']));
|
18 |
+
$vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
|
19 |
+
$vars['name'] = str_replace(' ', '', ucwords($vars['name']));
|
20 |
+
|
21 |
+
return $vars;
|
22 |
+
}
|
23 |
+
}
|
vendor/composer/installers/src/Composer/Installers/MauticInstaller.php
ADDED
@@ -0,0 +1,48 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
use Composer\Package\PackageInterface;
|
5 |
+
|
6 |
+
class MauticInstaller extends BaseInstaller
|
7 |
+
{
|
8 |
+
protected $locations = array(
|
9 |
+
'plugin' => 'plugins/{$name}/',
|
10 |
+
'theme' => 'themes/{$name}/',
|
11 |
+
'core' => 'app/',
|
12 |
+
);
|
13 |
+
|
14 |
+
private function getDirectoryName()
|
15 |
+
{
|
16 |
+
$extra = $this->package->getExtra();
|
17 |
+
if (!empty($extra['install-directory-name'])) {
|
18 |
+
return $extra['install-directory-name'];
|
19 |
+
}
|
20 |
+
|
21 |
+
return $this->toCamelCase($this->package->getPrettyName());
|
22 |
+
}
|
23 |
+
|
24 |
+
/**
|
25 |
+
* @param string $packageName
|
26 |
+
*
|
27 |
+
* @return string
|
28 |
+
*/
|
29 |
+
private function toCamelCase($packageName)
|
30 |
+
{
|
31 |
+
return str_replace(' ', '', ucwords(str_replace('-', ' ', basename($packageName))));
|
32 |
+
}
|
33 |
+
|
34 |
+
/**
|
35 |
+
* Format package name of mautic-plugins to CamelCase
|
36 |
+
*/
|
37 |
+
public function inflectPackageVars($vars)
|
38 |
+
{
|
39 |
+
|
40 |
+
if ($vars['type'] == 'mautic-plugin' || $vars['type'] == 'mautic-theme') {
|
41 |
+
$directoryName = $this->getDirectoryName();
|
42 |
+
$vars['name'] = $directoryName;
|
43 |
+
}
|
44 |
+
|
45 |
+
return $vars;
|
46 |
+
}
|
47 |
+
|
48 |
+
}
|
vendor/composer/installers/src/Composer/Installers/MayaInstaller.php
ADDED
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
class MayaInstaller extends BaseInstaller
|
5 |
+
{
|
6 |
+
protected $locations = array(
|
7 |
+
'module' => 'modules/{$name}/',
|
8 |
+
);
|
9 |
+
|
10 |
+
/**
|
11 |
+
* Format package name.
|
12 |
+
*
|
13 |
+
* For package type maya-module, cut off a trailing '-module' if present.
|
14 |
+
*
|
15 |
+
*/
|
16 |
+
public function inflectPackageVars($vars)
|
17 |
+
{
|
18 |
+
if ($vars['type'] === 'maya-module') {
|
19 |
+
return $this->inflectModuleVars($vars);
|
20 |
+
}
|
21 |
+
|
22 |
+
return $vars;
|
23 |
+
}
|
24 |
+
|
25 |
+
protected function inflectModuleVars($vars)
|
26 |
+
{
|
27 |
+
$vars['name'] = preg_replace('/-module$/', '', $vars['name']);
|
28 |
+
$vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
|
29 |
+
$vars['name'] = str_replace(' ', '', ucwords($vars['name']));
|
30 |
+
|
31 |
+
return $vars;
|
32 |
+
}
|
33 |
+
}
|
vendor/composer/installers/src/Composer/Installers/MediaWikiInstaller.php
ADDED
@@ -0,0 +1,51 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
class MediaWikiInstaller extends BaseInstaller
|
5 |
+
{
|
6 |
+
protected $locations = array(
|
7 |
+
'core' => 'core/',
|
8 |
+
'extension' => 'extensions/{$name}/',
|
9 |
+
'skin' => 'skins/{$name}/',
|
10 |
+
);
|
11 |
+
|
12 |
+
/**
|
13 |
+
* Format package name.
|
14 |
+
*
|
15 |
+
* For package type mediawiki-extension, cut off a trailing '-extension' if present and transform
|
16 |
+
* to CamelCase keeping existing uppercase chars.
|
17 |
+
*
|
18 |
+
* For package type mediawiki-skin, cut off a trailing '-skin' if present.
|
19 |
+
*
|
20 |
+
*/
|
21 |
+
public function inflectPackageVars($vars)
|
22 |
+
{
|
23 |
+
|
24 |
+
if ($vars['type'] === 'mediawiki-extension') {
|
25 |
+
return $this->inflectExtensionVars($vars);
|
26 |
+
}
|
27 |
+
|
28 |
+
if ($vars['type'] === 'mediawiki-skin') {
|
29 |
+
return $this->inflectSkinVars($vars);
|
30 |
+
}
|
31 |
+
|
32 |
+
return $vars;
|
33 |
+
}
|
34 |
+
|
35 |
+
protected function inflectExtensionVars($vars)
|
36 |
+
{
|
37 |
+
$vars['name'] = preg_replace('/-extension$/', '', $vars['name']);
|
38 |
+
$vars['name'] = str_replace('-', ' ', $vars['name']);
|
39 |
+
$vars['name'] = str_replace(' ', '', ucwords($vars['name']));
|
40 |
+
|
41 |
+
return $vars;
|
42 |
+
}
|
43 |
+
|
44 |
+
protected function inflectSkinVars($vars)
|
45 |
+
{
|
46 |
+
$vars['name'] = preg_replace('/-skin$/', '', $vars['name']);
|
47 |
+
|
48 |
+
return $vars;
|
49 |
+
}
|
50 |
+
|
51 |
+
}
|
vendor/composer/installers/src/Composer/Installers/MiaoxingInstaller.php
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace Composer\Installers;
|
4 |
+
|
5 |
+
class MiaoxingInstaller extends BaseInstaller
|
6 |
+
{
|
7 |
+
protected $locations = array(
|
8 |
+
'plugin' => 'plugins/{$name}/',
|
9 |
+
);
|
10 |
+
}
|
vendor/composer/installers/src/Composer/Installers/MicroweberInstaller.php
ADDED
@@ -0,0 +1,119 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
class MicroweberInstaller extends BaseInstaller
|
5 |
+
{
|
6 |
+
protected $locations = array(
|
7 |
+
'module' => 'userfiles/modules/{$install_item_dir}/',
|
8 |
+
'module-skin' => 'userfiles/modules/{$install_item_dir}/templates/',
|
9 |
+
'template' => 'userfiles/templates/{$install_item_dir}/',
|
10 |
+
'element' => 'userfiles/elements/{$install_item_dir}/',
|
11 |
+
'vendor' => 'vendor/{$install_item_dir}/',
|
12 |
+
'components' => 'components/{$install_item_dir}/'
|
13 |
+
);
|
14 |
+
|
15 |
+
/**
|
16 |
+
* Format package name.
|
17 |
+
*
|
18 |
+
* For package type microweber-module, cut off a trailing '-module' if present
|
19 |
+
*
|
20 |
+
* For package type microweber-template, cut off a trailing '-template' if present.
|
21 |
+
*
|
22 |
+
*/
|
23 |
+
public function inflectPackageVars($vars)
|
24 |
+
{
|
25 |
+
|
26 |
+
|
27 |
+
if ($this->package->getTargetDir()) {
|
28 |
+
$vars['install_item_dir'] = $this->package->getTargetDir();
|
29 |
+
} else {
|
30 |
+
$vars['install_item_dir'] = $vars['name'];
|
31 |
+
if ($vars['type'] === 'microweber-template') {
|
32 |
+
return $this->inflectTemplateVars($vars);
|
33 |
+
}
|
34 |
+
if ($vars['type'] === 'microweber-templates') {
|
35 |
+
return $this->inflectTemplatesVars($vars);
|
36 |
+
}
|
37 |
+
if ($vars['type'] === 'microweber-core') {
|
38 |
+
return $this->inflectCoreVars($vars);
|
39 |
+
}
|
40 |
+
if ($vars['type'] === 'microweber-adapter') {
|
41 |
+
return $this->inflectCoreVars($vars);
|
42 |
+
}
|
43 |
+
if ($vars['type'] === 'microweber-module') {
|
44 |
+
return $this->inflectModuleVars($vars);
|
45 |
+
}
|
46 |
+
if ($vars['type'] === 'microweber-modules') {
|
47 |
+
return $this->inflectModulesVars($vars);
|
48 |
+
}
|
49 |
+
if ($vars['type'] === 'microweber-skin') {
|
50 |
+
return $this->inflectSkinVars($vars);
|
51 |
+
}
|
52 |
+
if ($vars['type'] === 'microweber-element' or $vars['type'] === 'microweber-elements') {
|
53 |
+
return $this->inflectElementVars($vars);
|
54 |
+
}
|
55 |
+
}
|
56 |
+
|
57 |
+
|
58 |
+
return $vars;
|
59 |
+
}
|
60 |
+
|
61 |
+
protected function inflectTemplateVars($vars)
|
62 |
+
{
|
63 |
+
$vars['install_item_dir'] = preg_replace('/-template$/', '', $vars['install_item_dir']);
|
64 |
+
$vars['install_item_dir'] = preg_replace('/template-$/', '', $vars['install_item_dir']);
|
65 |
+
|
66 |
+
return $vars;
|
67 |
+
}
|
68 |
+
|
69 |
+
protected function inflectTemplatesVars($vars)
|
70 |
+
{
|
71 |
+
$vars['install_item_dir'] = preg_replace('/-templates$/', '', $vars['install_item_dir']);
|
72 |
+
$vars['install_item_dir'] = preg_replace('/templates-$/', '', $vars['install_item_dir']);
|
73 |
+
|
74 |
+
return $vars;
|
75 |
+
}
|
76 |
+
|
77 |
+
protected function inflectCoreVars($vars)
|
78 |
+
{
|
79 |
+
$vars['install_item_dir'] = preg_replace('/-providers$/', '', $vars['install_item_dir']);
|
80 |
+
$vars['install_item_dir'] = preg_replace('/-provider$/', '', $vars['install_item_dir']);
|
81 |
+
$vars['install_item_dir'] = preg_replace('/-adapter$/', '', $vars['install_item_dir']);
|
82 |
+
|
83 |
+
return $vars;
|
84 |
+
}
|
85 |
+
|
86 |
+
protected function inflectModuleVars($vars)
|
87 |
+
{
|
88 |
+
$vars['install_item_dir'] = preg_replace('/-module$/', '', $vars['install_item_dir']);
|
89 |
+
$vars['install_item_dir'] = preg_replace('/module-$/', '', $vars['install_item_dir']);
|
90 |
+
|
91 |
+
return $vars;
|
92 |
+
}
|
93 |
+
|
94 |
+
protected function inflectModulesVars($vars)
|
95 |
+
{
|
96 |
+
$vars['install_item_dir'] = preg_replace('/-modules$/', '', $vars['install_item_dir']);
|
97 |
+
$vars['install_item_dir'] = preg_replace('/modules-$/', '', $vars['install_item_dir']);
|
98 |
+
|
99 |
+
return $vars;
|
100 |
+
}
|
101 |
+
|
102 |
+
protected function inflectSkinVars($vars)
|
103 |
+
{
|
104 |
+
$vars['install_item_dir'] = preg_replace('/-skin$/', '', $vars['install_item_dir']);
|
105 |
+
$vars['install_item_dir'] = preg_replace('/skin-$/', '', $vars['install_item_dir']);
|
106 |
+
|
107 |
+
return $vars;
|
108 |
+
}
|
109 |
+
|
110 |
+
protected function inflectElementVars($vars)
|
111 |
+
{
|
112 |
+
$vars['install_item_dir'] = preg_replace('/-elements$/', '', $vars['install_item_dir']);
|
113 |
+
$vars['install_item_dir'] = preg_replace('/elements-$/', '', $vars['install_item_dir']);
|
114 |
+
$vars['install_item_dir'] = preg_replace('/-element$/', '', $vars['install_item_dir']);
|
115 |
+
$vars['install_item_dir'] = preg_replace('/element-$/', '', $vars['install_item_dir']);
|
116 |
+
|
117 |
+
return $vars;
|
118 |
+
}
|
119 |
+
}
|
vendor/composer/installers/src/Composer/Installers/ModxInstaller.php
ADDED
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
/**
|
5 |
+
* An installer to handle MODX specifics when installing packages.
|
6 |
+
*/
|
7 |
+
class ModxInstaller extends BaseInstaller
|
8 |
+
{
|
9 |
+
protected $locations = array(
|
10 |
+
'extra' => 'core/packages/{$name}/'
|
11 |
+
);
|
12 |
+
}
|
vendor/composer/installers/src/Composer/Installers/MoodleInstaller.php
ADDED
@@ -0,0 +1,59 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
class MoodleInstaller extends BaseInstaller
|
5 |
+
{
|
6 |
+
protected $locations = array(
|
7 |
+
'mod' => 'mod/{$name}/',
|
8 |
+
'admin_report' => 'admin/report/{$name}/',
|
9 |
+
'atto' => 'lib/editor/atto/plugins/{$name}/',
|
10 |
+
'tool' => 'admin/tool/{$name}/',
|
11 |
+
'assignment' => 'mod/assignment/type/{$name}/',
|
12 |
+
'assignsubmission' => 'mod/assign/submission/{$name}/',
|
13 |
+
'assignfeedback' => 'mod/assign/feedback/{$name}/',
|
14 |
+
'auth' => 'auth/{$name}/',
|
15 |
+
'availability' => 'availability/condition/{$name}/',
|
16 |
+
'block' => 'blocks/{$name}/',
|
17 |
+
'booktool' => 'mod/book/tool/{$name}/',
|
18 |
+
'cachestore' => 'cache/stores/{$name}/',
|
19 |
+
'cachelock' => 'cache/locks/{$name}/',
|
20 |
+
'calendartype' => 'calendar/type/{$name}/',
|
21 |
+
'fileconverter' => 'files/converter/{$name}/',
|
22 |
+
'format' => 'course/format/{$name}/',
|
23 |
+
'coursereport' => 'course/report/{$name}/',
|
24 |
+
'customcertelement' => 'mod/customcert/element/{$name}/',
|
25 |
+
'datafield' => 'mod/data/field/{$name}/',
|
26 |
+
'datapreset' => 'mod/data/preset/{$name}/',
|
27 |
+
'editor' => 'lib/editor/{$name}/',
|
28 |
+
'enrol' => 'enrol/{$name}/',
|
29 |
+
'filter' => 'filter/{$name}/',
|
30 |
+
'gradeexport' => 'grade/export/{$name}/',
|
31 |
+
'gradeimport' => 'grade/import/{$name}/',
|
32 |
+
'gradereport' => 'grade/report/{$name}/',
|
33 |
+
'gradingform' => 'grade/grading/form/{$name}/',
|
34 |
+
'local' => 'local/{$name}/',
|
35 |
+
'logstore' => 'admin/tool/log/store/{$name}/',
|
36 |
+
'ltisource' => 'mod/lti/source/{$name}/',
|
37 |
+
'ltiservice' => 'mod/lti/service/{$name}/',
|
38 |
+
'message' => 'message/output/{$name}/',
|
39 |
+
'mnetservice' => 'mnet/service/{$name}/',
|
40 |
+
'plagiarism' => 'plagiarism/{$name}/',
|
41 |
+
'portfolio' => 'portfolio/{$name}/',
|
42 |
+
'qbehaviour' => 'question/behaviour/{$name}/',
|
43 |
+
'qformat' => 'question/format/{$name}/',
|
44 |
+
'qtype' => 'question/type/{$name}/',
|
45 |
+
'quizaccess' => 'mod/quiz/accessrule/{$name}/',
|
46 |
+
'quiz' => 'mod/quiz/report/{$name}/',
|
47 |
+
'report' => 'report/{$name}/',
|
48 |
+
'repository' => 'repository/{$name}/',
|
49 |
+
'scormreport' => 'mod/scorm/report/{$name}/',
|
50 |
+
'search' => 'search/engine/{$name}/',
|
51 |
+
'theme' => 'theme/{$name}/',
|
52 |
+
'tinymce' => 'lib/editor/tinymce/plugins/{$name}/',
|
53 |
+
'profilefield' => 'user/profile/field/{$name}/',
|
54 |
+
'webservice' => 'webservice/{$name}/',
|
55 |
+
'workshopallocation' => 'mod/workshop/allocation/{$name}/',
|
56 |
+
'workshopeval' => 'mod/workshop/eval/{$name}/',
|
57 |
+
'workshopform' => 'mod/workshop/form/{$name}/'
|
58 |
+
);
|
59 |
+
}
|
vendor/composer/installers/src/Composer/Installers/OctoberInstaller.php
ADDED
@@ -0,0 +1,48 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
class OctoberInstaller extends BaseInstaller
|
5 |
+
{
|
6 |
+
protected $locations = array(
|
7 |
+
'module' => 'modules/{$name}/',
|
8 |
+
'plugin' => 'plugins/{$vendor}/{$name}/',
|
9 |
+
'theme' => 'themes/{$vendor}-{$name}/'
|
10 |
+
);
|
11 |
+
|
12 |
+
/**
|
13 |
+
* Format package name.
|
14 |
+
*
|
15 |
+
* For package type october-plugin, cut off a trailing '-plugin' if present.
|
16 |
+
*
|
17 |
+
* For package type october-theme, cut off a trailing '-theme' if present.
|
18 |
+
*
|
19 |
+
*/
|
20 |
+
public function inflectPackageVars($vars)
|
21 |
+
{
|
22 |
+
if ($vars['type'] === 'october-plugin') {
|
23 |
+
return $this->inflectPluginVars($vars);
|
24 |
+
}
|
25 |
+
|
26 |
+
if ($vars['type'] === 'october-theme') {
|
27 |
+
return $this->inflectThemeVars($vars);
|
28 |
+
}
|
29 |
+
|
30 |
+
return $vars;
|
31 |
+
}
|
32 |
+
|
33 |
+
protected function inflectPluginVars($vars)
|
34 |
+
{
|
35 |
+
$vars['name'] = preg_replace('/^oc-|-plugin$/', '', $vars['name']);
|
36 |
+
$vars['vendor'] = preg_replace('/[^a-z0-9_]/i', '', $vars['vendor']);
|
37 |
+
|
38 |
+
return $vars;
|
39 |
+
}
|
40 |
+
|
41 |
+
protected function inflectThemeVars($vars)
|
42 |
+
{
|
43 |
+
$vars['name'] = preg_replace('/^oc-|-theme$/', '', $vars['name']);
|
44 |
+
$vars['vendor'] = preg_replace('/[^a-z0-9_]/i', '', $vars['vendor']);
|
45 |
+
|
46 |
+
return $vars;
|
47 |
+
}
|
48 |
+
}
|
vendor/composer/installers/src/Composer/Installers/OntoWikiInstaller.php
ADDED
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
class OntoWikiInstaller extends BaseInstaller
|
5 |
+
{
|
6 |
+
protected $locations = array(
|
7 |
+
'extension' => 'extensions/{$name}/',
|
8 |
+
'theme' => 'extensions/themes/{$name}/',
|
9 |
+
'translation' => 'extensions/translations/{$name}/',
|
10 |
+
);
|
11 |
+
|
12 |
+
/**
|
13 |
+
* Format package name to lower case and remove ".ontowiki" suffix
|
14 |
+
*/
|
15 |
+
public function inflectPackageVars($vars)
|
16 |
+
{
|
17 |
+
$vars['name'] = strtolower($vars['name']);
|
18 |
+
$vars['name'] = preg_replace('/.ontowiki$/', '', $vars['name']);
|
19 |
+
$vars['name'] = preg_replace('/-theme$/', '', $vars['name']);
|
20 |
+
$vars['name'] = preg_replace('/-translation$/', '', $vars['name']);
|
21 |
+
|
22 |
+
return $vars;
|
23 |
+
}
|
24 |
+
}
|
vendor/composer/installers/src/Composer/Installers/OsclassInstaller.php
ADDED
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
|
5 |
+
class OsclassInstaller extends BaseInstaller
|
6 |
+
{
|
7 |
+
|
8 |
+
protected $locations = array(
|
9 |
+
'plugin' => 'oc-content/plugins/{$name}/',
|
10 |
+
'theme' => 'oc-content/themes/{$name}/',
|
11 |
+
'language' => 'oc-content/languages/{$name}/',
|
12 |
+
);
|
13 |
+
|
14 |
+
}
|
vendor/composer/installers/src/Composer/Installers/OxidInstaller.php
ADDED
@@ -0,0 +1,59 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
use Composer\Package\PackageInterface;
|
5 |
+
|
6 |
+
class OxidInstaller extends BaseInstaller
|
7 |
+
{
|
8 |
+
const VENDOR_PATTERN = '/^modules\/(?P<vendor>.+)\/.+/';
|
9 |
+
|
10 |
+
protected $locations = array(
|
11 |
+
'module' => 'modules/{$name}/',
|
12 |
+
'theme' => 'application/views/{$name}/',
|
13 |
+
'out' => 'out/{$name}/',
|
14 |
+
);
|
15 |
+
|
16 |
+
/**
|
17 |
+
* getInstallPath
|
18 |
+
*
|
19 |
+
* @param PackageInterface $package
|
20 |
+
* @param string $frameworkType
|
21 |
+
* @return string
|
22 |
+
*/
|
23 |
+
public function getInstallPath(PackageInterface $package, $frameworkType = '')
|
24 |
+
{
|
25 |
+
$installPath = parent::getInstallPath($package, $frameworkType);
|
26 |
+
$type = $this->package->getType();
|
27 |
+
if ($type === 'oxid-module') {
|
28 |
+
$this->prepareVendorDirectory($installPath);
|
29 |
+
}
|
30 |
+
return $installPath;
|
31 |
+
}
|
32 |
+
|
33 |
+
/**
|
34 |
+
* prepareVendorDirectory
|
35 |
+
*
|
36 |
+
* Makes sure there is a vendormetadata.php file inside
|
37 |
+
* the vendor folder if there is a vendor folder.
|
38 |
+
*
|
39 |
+
* @param string $installPath
|
40 |
+
* @return void
|
41 |
+
*/
|
42 |
+
protected function prepareVendorDirectory($installPath)
|
43 |
+
{
|
44 |
+
$matches = '';
|
45 |
+
$hasVendorDirectory = preg_match(self::VENDOR_PATTERN, $installPath, $matches);
|
46 |
+
if (!$hasVendorDirectory) {
|
47 |
+
return;
|
48 |
+
}
|
49 |
+
|
50 |
+
$vendorDirectory = $matches['vendor'];
|
51 |
+
$vendorPath = getcwd() . '/modules/' . $vendorDirectory;
|
52 |
+
if (!file_exists($vendorPath)) {
|
53 |
+
mkdir($vendorPath, 0755, true);
|
54 |
+
}
|
55 |
+
|
56 |
+
$vendorMetaDataPath = $vendorPath . '/vendormetadata.php';
|
57 |
+
touch($vendorMetaDataPath);
|
58 |
+
}
|
59 |
+
}
|
vendor/composer/installers/src/Composer/Installers/PPIInstaller.php
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
class PPIInstaller extends BaseInstaller
|
5 |
+
{
|
6 |
+
protected $locations = array(
|
7 |
+
'module' => 'modules/{$name}/',
|
8 |
+
);
|
9 |
+
}
|
vendor/composer/installers/src/Composer/Installers/PhiftyInstaller.php
ADDED
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
class PhiftyInstaller extends BaseInstaller
|
5 |
+
{
|
6 |
+
protected $locations = array(
|
7 |
+
'bundle' => 'bundles/{$name}/',
|
8 |
+
'library' => 'libraries/{$name}/',
|
9 |
+
'framework' => 'frameworks/{$name}/',
|
10 |
+
);
|
11 |
+
}
|
vendor/composer/installers/src/Composer/Installers/PhpBBInstaller.php
ADDED
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
class PhpBBInstaller extends BaseInstaller
|
5 |
+
{
|
6 |
+
protected $locations = array(
|
7 |
+
'extension' => 'ext/{$vendor}/{$name}/',
|
8 |
+
'language' => 'language/{$name}/',
|
9 |
+
'style' => 'styles/{$name}/',
|
10 |
+
);
|
11 |
+
}
|
vendor/composer/installers/src/Composer/Installers/PimcoreInstaller.php
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
class PimcoreInstaller extends BaseInstaller
|
5 |
+
{
|
6 |
+
protected $locations = array(
|
7 |
+
'plugin' => 'plugins/{$name}/',
|
8 |
+
);
|
9 |
+
|
10 |
+
/**
|
11 |
+
* Format package name to CamelCase
|
12 |
+
*/
|
13 |
+
public function inflectPackageVars($vars)
|
14 |
+
{
|
15 |
+
$vars['name'] = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name']));
|
16 |
+
$vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
|
17 |
+
$vars['name'] = str_replace(' ', '', ucwords($vars['name']));
|
18 |
+
|
19 |
+
return $vars;
|
20 |
+
}
|
21 |
+
}
|
vendor/composer/installers/src/Composer/Installers/PiwikInstaller.php
ADDED
@@ -0,0 +1,32 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
/**
|
5 |
+
* Class PiwikInstaller
|
6 |
+
*
|
7 |
+
* @package Composer\Installers
|
8 |
+
*/
|
9 |
+
class PiwikInstaller extends BaseInstaller
|
10 |
+
{
|
11 |
+
/**
|
12 |
+
* @var array
|
13 |
+
*/
|
14 |
+
protected $locations = array(
|
15 |
+
'plugin' => 'plugins/{$name}/',
|
16 |
+
);
|
17 |
+
|
18 |
+
/**
|
19 |
+
* Format package name to CamelCase
|
20 |
+
* @param array $vars
|
21 |
+
*
|
22 |
+
* @return array
|
23 |
+
*/
|
24 |
+
public function inflectPackageVars($vars)
|
25 |
+
{
|
26 |
+
$vars['name'] = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name']));
|
27 |
+
$vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
|
28 |
+
$vars['name'] = str_replace(' ', '', ucwords($vars['name']));
|
29 |
+
|
30 |
+
return $vars;
|
31 |
+
}
|
32 |
+
}
|
vendor/composer/installers/src/Composer/Installers/PlentymarketsInstaller.php
ADDED
@@ -0,0 +1,29 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
class PlentymarketsInstaller extends BaseInstaller
|
5 |
+
{
|
6 |
+
protected $locations = array(
|
7 |
+
'plugin' => '{$name}/'
|
8 |
+
);
|
9 |
+
|
10 |
+
/**
|
11 |
+
* Remove hyphen, "plugin" and format to camelcase
|
12 |
+
* @param array $vars
|
13 |
+
*
|
14 |
+
* @return array
|
15 |
+
*/
|
16 |
+
public function inflectPackageVars($vars)
|
17 |
+
{
|
18 |
+
$vars['name'] = explode("-", $vars['name']);
|
19 |
+
foreach ($vars['name'] as $key => $name) {
|
20 |
+
$vars['name'][$key] = ucfirst($vars['name'][$key]);
|
21 |
+
if (strcasecmp($name, "Plugin") == 0) {
|
22 |
+
unset($vars['name'][$key]);
|
23 |
+
}
|
24 |
+
}
|
25 |
+
$vars['name'] = implode("",$vars['name']);
|
26 |
+
|
27 |
+
return $vars;
|
28 |
+
}
|
29 |
+
}
|
vendor/composer/installers/src/Composer/Installers/Plugin.php
ADDED
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace Composer\Installers;
|
4 |
+
|
5 |
+
use Composer\Composer;
|
6 |
+
use Composer\IO\IOInterface;
|
7 |
+
use Composer\Plugin\PluginInterface;
|
8 |
+
|
9 |
+
class Plugin implements PluginInterface
|
10 |
+
{
|
11 |
+
private $installer;
|
12 |
+
|
13 |
+
public function activate(Composer $composer, IOInterface $io)
|
14 |
+
{
|
15 |
+
$this->installer = new Installer($io, $composer);
|
16 |
+
$composer->getInstallationManager()->addInstaller($this->installer);
|
17 |
+
}
|
18 |
+
|
19 |
+
public function deactivate(Composer $composer, IOInterface $io)
|
20 |
+
{
|
21 |
+
$composer->getInstallationManager()->removeInstaller($this->installer);
|
22 |
+
}
|
23 |
+
|
24 |
+
public function uninstall(Composer $composer, IOInterface $io)
|
25 |
+
{
|
26 |
+
}
|
27 |
+
}
|
vendor/composer/installers/src/Composer/Installers/PortoInstaller.php
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
class PortoInstaller extends BaseInstaller
|
5 |
+
{
|
6 |
+
protected $locations = array(
|
7 |
+
'container' => 'app/Containers/{$name}/',
|
8 |
+
);
|
9 |
+
}
|
vendor/composer/installers/src/Composer/Installers/PrestashopInstaller.php
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
class PrestashopInstaller extends BaseInstaller
|
5 |
+
{
|
6 |
+
protected $locations = array(
|
7 |
+
'module' => 'modules/{$name}/',
|
8 |
+
'theme' => 'themes/{$name}/',
|
9 |
+
);
|
10 |
+
}
|
vendor/composer/installers/src/Composer/Installers/ProcessWireInstaller.php
ADDED
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace Composer\Installers;
|
4 |
+
|
5 |
+
class ProcessWireInstaller extends BaseInstaller
|
6 |
+
{
|
7 |
+
protected $locations = array(
|
8 |
+
'module' => 'site/modules/{$name}/',
|
9 |
+
);
|
10 |
+
|
11 |
+
/**
|
12 |
+
* Format package name to CamelCase
|
13 |
+
*/
|
14 |
+
public function inflectPackageVars($vars)
|
15 |
+
{
|
16 |
+
$vars['name'] = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name']));
|
17 |
+
$vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
|
18 |
+
$vars['name'] = str_replace(' ', '', ucwords($vars['name']));
|
19 |
+
|
20 |
+
return $vars;
|
21 |
+
}
|
22 |
+
}
|
vendor/composer/installers/src/Composer/Installers/PuppetInstaller.php
ADDED
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace Composer\Installers;
|
4 |
+
|
5 |
+
class PuppetInstaller extends BaseInstaller
|
6 |
+
{
|
7 |
+
|
8 |
+
protected $locations = array(
|
9 |
+
'module' => 'modules/{$name}/',
|
10 |
+
);
|
11 |
+
}
|
vendor/composer/installers/src/Composer/Installers/PxcmsInstaller.php
ADDED
@@ -0,0 +1,63 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
class PxcmsInstaller extends BaseInstaller
|
5 |
+
{
|
6 |
+
protected $locations = array(
|
7 |
+
'module' => 'app/Modules/{$name}/',
|
8 |
+
'theme' => 'themes/{$name}/',
|
9 |
+
);
|
10 |
+
|
11 |
+
/**
|
12 |
+
* Format package name.
|
13 |
+
*
|
14 |
+
* @param array $vars
|
15 |
+
*
|
16 |
+
* @return array
|
17 |
+
*/
|
18 |
+
public function inflectPackageVars($vars)
|
19 |
+
{
|
20 |
+
if ($vars['type'] === 'pxcms-module') {
|
21 |
+
return $this->inflectModuleVars($vars);
|
22 |
+
}
|
23 |
+
|
24 |
+
if ($vars['type'] === 'pxcms-theme') {
|
25 |
+
return $this->inflectThemeVars($vars);
|
26 |
+
}
|
27 |
+
|
28 |
+
return $vars;
|
29 |
+
}
|
30 |
+
|
31 |
+
/**
|
32 |
+
* For package type pxcms-module, cut off a trailing '-plugin' if present.
|
33 |
+
*
|
34 |
+
* return string
|
35 |
+
*/
|
36 |
+
protected function inflectModuleVars($vars)
|
37 |
+
{
|
38 |
+
$vars['name'] = str_replace('pxcms-', '', $vars['name']); // strip out pxcms- just incase (legacy)
|
39 |
+
$vars['name'] = str_replace('module-', '', $vars['name']); // strip out module-
|
40 |
+
$vars['name'] = preg_replace('/-module$/', '', $vars['name']); // strip out -module
|
41 |
+
$vars['name'] = str_replace('-', '_', $vars['name']); // make -'s be _'s
|
42 |
+
$vars['name'] = ucwords($vars['name']); // make module name camelcased
|
43 |
+
|
44 |
+
return $vars;
|
45 |
+
}
|
46 |
+
|
47 |
+
|
48 |
+
/**
|
49 |
+
* For package type pxcms-module, cut off a trailing '-plugin' if present.
|
50 |
+
*
|
51 |
+
* return string
|
52 |
+
*/
|
53 |
+
protected function inflectThemeVars($vars)
|
54 |
+
{
|
55 |
+
$vars['name'] = str_replace('pxcms-', '', $vars['name']); // strip out pxcms- just incase (legacy)
|
56 |
+
$vars['name'] = str_replace('theme-', '', $vars['name']); // strip out theme-
|
57 |
+
$vars['name'] = preg_replace('/-theme$/', '', $vars['name']); // strip out -theme
|
58 |
+
$vars['name'] = str_replace('-', '_', $vars['name']); // make -'s be _'s
|
59 |
+
$vars['name'] = ucwords($vars['name']); // make module name camelcased
|
60 |
+
|
61 |
+
return $vars;
|
62 |
+
}
|
63 |
+
}
|
vendor/composer/installers/src/Composer/Installers/RadPHPInstaller.php
ADDED
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
class RadPHPInstaller extends BaseInstaller
|
5 |
+
{
|
6 |
+
protected $locations = array(
|
7 |
+
'bundle' => 'src/{$name}/'
|
8 |
+
);
|
9 |
+
|
10 |
+
/**
|
11 |
+
* Format package name to CamelCase
|
12 |
+
*/
|
13 |
+
public function inflectPackageVars($vars)
|
14 |
+
{
|
15 |
+
$nameParts = explode('/', $vars['name']);
|
16 |
+
foreach ($nameParts as &$value) {
|
17 |
+
$value = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $value));
|
18 |
+
$value = str_replace(array('-', '_'), ' ', $value);
|
19 |
+
$value = str_replace(' ', '', ucwords($value));
|
20 |
+
}
|
21 |
+
$vars['name'] = implode('/', $nameParts);
|
22 |
+
return $vars;
|
23 |
+
}
|
24 |
+
}
|
vendor/composer/installers/src/Composer/Installers/ReIndexInstaller.php
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
class ReIndexInstaller extends BaseInstaller
|
5 |
+
{
|
6 |
+
protected $locations = array(
|
7 |
+
'theme' => 'themes/{$name}/',
|
8 |
+
'plugin' => 'plugins/{$name}/'
|
9 |
+
);
|
10 |
+
}
|
vendor/composer/installers/src/Composer/Installers/Redaxo5Installer.php
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
class Redaxo5Installer extends BaseInstaller
|
5 |
+
{
|
6 |
+
protected $locations = array(
|
7 |
+
'addon' => 'redaxo/src/addons/{$name}/',
|
8 |
+
'bestyle-plugin' => 'redaxo/src/addons/be_style/plugins/{$name}/'
|
9 |
+
);
|
10 |
+
}
|
vendor/composer/installers/src/Composer/Installers/RedaxoInstaller.php
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
class RedaxoInstaller extends BaseInstaller
|
5 |
+
{
|
6 |
+
protected $locations = array(
|
7 |
+
'addon' => 'redaxo/include/addons/{$name}/',
|
8 |
+
'bestyle-plugin' => 'redaxo/include/addons/be_style/plugins/{$name}/'
|
9 |
+
);
|
10 |
+
}
|
vendor/composer/installers/src/Composer/Installers/RoundcubeInstaller.php
ADDED
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
class RoundcubeInstaller extends BaseInstaller
|
5 |
+
{
|
6 |
+
protected $locations = array(
|
7 |
+
'plugin' => 'plugins/{$name}/',
|
8 |
+
);
|
9 |
+
|
10 |
+
/**
|
11 |
+
* Lowercase name and changes the name to a underscores
|
12 |
+
*
|
13 |
+
* @param array $vars
|
14 |
+
* @return array
|
15 |
+
*/
|
16 |
+
public function inflectPackageVars($vars)
|
17 |
+
{
|
18 |
+
$vars['name'] = strtolower(str_replace('-', '_', $vars['name']));
|
19 |
+
|
20 |
+
return $vars;
|
21 |
+
}
|
22 |
+
}
|
vendor/composer/installers/src/Composer/Installers/SMFInstaller.php
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
class SMFInstaller extends BaseInstaller
|
5 |
+
{
|
6 |
+
protected $locations = array(
|
7 |
+
'module' => 'Sources/{$name}/',
|
8 |
+
'theme' => 'Themes/{$name}/',
|
9 |
+
);
|
10 |
+
}
|
vendor/composer/installers/src/Composer/Installers/ShopwareInstaller.php
ADDED
@@ -0,0 +1,60 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
/**
|
5 |
+
* Plugin/theme installer for shopware
|
6 |
+
* @author Benjamin Boit
|
7 |
+
*/
|
8 |
+
class ShopwareInstaller extends BaseInstaller
|
9 |
+
{
|
10 |
+
protected $locations = array(
|
11 |
+
'backend-plugin' => 'engine/Shopware/Plugins/Local/Backend/{$name}/',
|
12 |
+
'core-plugin' => 'engine/Shopware/Plugins/Local/Core/{$name}/',
|
13 |
+
'frontend-plugin' => 'engine/Shopware/Plugins/Local/Frontend/{$name}/',
|
14 |
+
'theme' => 'templates/{$name}/',
|
15 |
+
'plugin' => 'custom/plugins/{$name}/',
|
16 |
+
'frontend-theme' => 'themes/Frontend/{$name}/',
|
17 |
+
);
|
18 |
+
|
19 |
+
/**
|
20 |
+
* Transforms the names
|
21 |
+
* @param array $vars
|
22 |
+
* @return array
|
23 |
+
*/
|
24 |
+
public function inflectPackageVars($vars)
|
25 |
+
{
|
26 |
+
if ($vars['type'] === 'shopware-theme') {
|
27 |
+
return $this->correctThemeName($vars);
|
28 |
+
}
|
29 |
+
|
30 |
+
return $this->correctPluginName($vars);
|
31 |
+
}
|
32 |
+
|
33 |
+
/**
|
34 |
+
* Changes the name to a camelcased combination of vendor and name
|
35 |
+
* @param array $vars
|
36 |
+
* @return array
|
37 |
+
*/
|
38 |
+
private function correctPluginName($vars)
|
39 |
+
{
|
40 |
+
$camelCasedName = preg_replace_callback('/(-[a-z])/', function ($matches) {
|
41 |
+
return strtoupper($matches[0][1]);
|
42 |
+
}, $vars['name']);
|
43 |
+
|
44 |
+
$vars['name'] = ucfirst($vars['vendor']) . ucfirst($camelCasedName);
|
45 |
+
|
46 |
+
return $vars;
|
47 |
+
}
|
48 |
+
|
49 |
+
/**
|
50 |
+
* Changes the name to a underscore separated name
|
51 |
+
* @param array $vars
|
52 |
+
* @return array
|
53 |
+
*/
|
54 |
+
private function correctThemeName($vars)
|
55 |
+
{
|
56 |
+
$vars['name'] = str_replace('-', '_', $vars['name']);
|
57 |
+
|
58 |
+
return $vars;
|
59 |
+
}
|
60 |
+
}
|
vendor/composer/installers/src/Composer/Installers/SilverStripeInstaller.php
ADDED
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
use Composer\Package\PackageInterface;
|
5 |
+
|
6 |
+
class SilverStripeInstaller extends BaseInstaller
|
7 |
+
{
|
8 |
+
protected $locations = array(
|
9 |
+
'module' => '{$name}/',
|
10 |
+
'theme' => 'themes/{$name}/',
|
11 |
+
);
|
12 |
+
|
13 |
+
/**
|
14 |
+
* Return the install path based on package type.
|
15 |
+
*
|
16 |
+
* Relies on built-in BaseInstaller behaviour with one exception: silverstripe/framework
|
17 |
+
* must be installed to 'sapphire' and not 'framework' if the version is <3.0.0
|
18 |
+
*
|
19 |
+
* @param PackageInterface $package
|
20 |
+
* @param string $frameworkType
|
21 |
+
* @return string
|
22 |
+
*/
|
23 |
+
public function getInstallPath(PackageInterface $package, $frameworkType = '')
|
24 |
+
{
|
25 |
+
if (
|
26 |
+
$package->getName() == 'silverstripe/framework'
|
27 |
+
&& preg_match('/^\d+\.\d+\.\d+/', $package->getVersion())
|
28 |
+
&& version_compare($package->getVersion(), '2.999.999') < 0
|
29 |
+
) {
|
30 |
+
return $this->templatePath($this->locations['module'], array('name' => 'sapphire'));
|
31 |
+
}
|
32 |
+
|
33 |
+
return parent::getInstallPath($package, $frameworkType);
|
34 |
+
}
|
35 |
+
}
|
vendor/composer/installers/src/Composer/Installers/SiteDirectInstaller.php
ADDED
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace Composer\Installers;
|
4 |
+
|
5 |
+
class SiteDirectInstaller extends BaseInstaller
|
6 |
+
{
|
7 |
+
protected $locations = array(
|
8 |
+
'module' => 'modules/{$vendor}/{$name}/',
|
9 |
+
'plugin' => 'plugins/{$vendor}/{$name}/'
|
10 |
+
);
|
11 |
+
|
12 |
+
public function inflectPackageVars($vars)
|
13 |
+
{
|
14 |
+
return $this->parseVars($vars);
|
15 |
+
}
|
16 |
+
|
17 |
+
protected function parseVars($vars)
|
18 |
+
{
|
19 |
+
$vars['vendor'] = strtolower($vars['vendor']) == 'sitedirect' ? 'SiteDirect' : $vars['vendor'];
|
20 |
+
$vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
|
21 |
+
$vars['name'] = str_replace(' ', '', ucwords($vars['name']));
|
22 |
+
|
23 |
+
return $vars;
|
24 |
+
}
|
25 |
+
}
|
vendor/composer/installers/src/Composer/Installers/StarbugInstaller.php
ADDED
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
class StarbugInstaller extends BaseInstaller
|
5 |
+
{
|
6 |
+
protected $locations = array(
|
7 |
+
'module' => 'modules/{$name}/',
|
8 |
+
'theme' => 'themes/{$name}/',
|
9 |
+
'custom-module' => 'app/modules/{$name}/',
|
10 |
+
'custom-theme' => 'app/themes/{$name}/'
|
11 |
+
);
|
12 |
+
}
|
vendor/composer/installers/src/Composer/Installers/SyDESInstaller.php
ADDED
@@ -0,0 +1,47 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
class SyDESInstaller extends BaseInstaller
|
5 |
+
{
|
6 |
+
protected $locations = array(
|
7 |
+
'module' => 'app/modules/{$name}/',
|
8 |
+
'theme' => 'themes/{$name}/',
|
9 |
+
);
|
10 |
+
|
11 |
+
/**
|
12 |
+
* Format module name.
|
13 |
+
*
|
14 |
+
* Strip `sydes-` prefix and a trailing '-theme' or '-module' from package name if present.
|
15 |
+
*
|
16 |
+
* {@inerhitDoc}
|
17 |
+
*/
|
18 |
+
public function inflectPackageVars($vars)
|
19 |
+
{
|
20 |
+
if ($vars['type'] == 'sydes-module') {
|
21 |
+
return $this->inflectModuleVars($vars);
|
22 |
+
}
|
23 |
+
|
24 |
+
if ($vars['type'] === 'sydes-theme') {
|
25 |
+
return $this->inflectThemeVars($vars);
|
26 |
+
}
|
27 |
+
|
28 |
+
return $vars;
|
29 |
+
}
|
30 |
+
|
31 |
+
public function inflectModuleVars($vars)
|
32 |
+
{
|
33 |
+
$vars['name'] = preg_replace('/(^sydes-|-module$)/i', '', $vars['name']);
|
34 |
+
$vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
|
35 |
+
$vars['name'] = str_replace(' ', '', ucwords($vars['name']));
|
36 |
+
|
37 |
+
return $vars;
|
38 |
+
}
|
39 |
+
|
40 |
+
protected function inflectThemeVars($vars)
|
41 |
+
{
|
42 |
+
$vars['name'] = preg_replace('/(^sydes-|-theme$)/', '', $vars['name']);
|
43 |
+
$vars['name'] = strtolower($vars['name']);
|
44 |
+
|
45 |
+
return $vars;
|
46 |
+
}
|
47 |
+
}
|
vendor/composer/installers/src/Composer/Installers/SyliusInstaller.php
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
class SyliusInstaller extends BaseInstaller
|
5 |
+
{
|
6 |
+
protected $locations = array(
|
7 |
+
'theme' => 'themes/{$name}/',
|
8 |
+
);
|
9 |
+
}
|
vendor/composer/installers/src/Composer/Installers/Symfony1Installer.php
ADDED
@@ -0,0 +1,26 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
/**
|
5 |
+
* Plugin installer for symfony 1.x
|
6 |
+
*
|
7 |
+
* @author Jérôme Tamarelle <jerome@tamarelle.net>
|
8 |
+
*/
|
9 |
+
class Symfony1Installer extends BaseInstaller
|
10 |
+
{
|
11 |
+
protected $locations = array(
|
12 |
+
'plugin' => 'plugins/{$name}/',
|
13 |
+
);
|
14 |
+
|
15 |
+
/**
|
16 |
+
* Format package name to CamelCase
|
17 |
+
*/
|
18 |
+
public function inflectPackageVars($vars)
|
19 |
+
{
|
20 |
+
$vars['name'] = preg_replace_callback('/(-[a-z])/', function ($matches) {
|
21 |
+
return strtoupper($matches[0][1]);
|
22 |
+
}, $vars['name']);
|
23 |
+
|
24 |
+
return $vars;
|
25 |
+
}
|
26 |
+
}
|
vendor/composer/installers/src/Composer/Installers/TYPO3CmsInstaller.php
ADDED
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
/**
|
5 |
+
* Extension installer for TYPO3 CMS
|
6 |
+
*
|
7 |
+
* @deprecated since 1.0.25, use https://packagist.org/packages/typo3/cms-composer-installers instead
|
8 |
+
*
|
9 |
+
* @author Sascha Egerer <sascha.egerer@dkd.de>
|
10 |
+
*/
|
11 |
+
class TYPO3CmsInstaller extends BaseInstaller
|
12 |
+
{
|
13 |
+
protected $locations = array(
|
14 |
+
'extension' => 'typo3conf/ext/{$name}/',
|
15 |
+
);
|
16 |
+
}
|
vendor/composer/installers/src/Composer/Installers/TYPO3FlowInstaller.php
ADDED
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
/**
|
5 |
+
* An installer to handle TYPO3 Flow specifics when installing packages.
|
6 |
+
*/
|
7 |
+
class TYPO3FlowInstaller extends BaseInstaller
|
8 |
+
{
|
9 |
+
protected $locations = array(
|
10 |
+
'package' => 'Packages/Application/{$name}/',
|
11 |
+
'framework' => 'Packages/Framework/{$name}/',
|
12 |
+
'plugin' => 'Packages/Plugins/{$name}/',
|
13 |
+
'site' => 'Packages/Sites/{$name}/',
|
14 |
+
'boilerplate' => 'Packages/Boilerplates/{$name}/',
|
15 |
+
'build' => 'Build/{$name}/',
|
16 |
+
);
|
17 |
+
|
18 |
+
/**
|
19 |
+
* Modify the package name to be a TYPO3 Flow style key.
|
20 |
+
*
|
21 |
+
* @param array $vars
|
22 |
+
* @return array
|
23 |
+
*/
|
24 |
+
public function inflectPackageVars($vars)
|
25 |
+
{
|
26 |
+
$autoload = $this->package->getAutoload();
|
27 |
+
if (isset($autoload['psr-0']) && is_array($autoload['psr-0'])) {
|
28 |
+
$namespace = key($autoload['psr-0']);
|
29 |
+
$vars['name'] = str_replace('\\', '.', $namespace);
|
30 |
+
}
|
31 |
+
if (isset($autoload['psr-4']) && is_array($autoload['psr-4'])) {
|
32 |
+
$namespace = key($autoload['psr-4']);
|
33 |
+
$vars['name'] = rtrim(str_replace('\\', '.', $namespace), '.');
|
34 |
+
}
|
35 |
+
|
36 |
+
return $vars;
|
37 |
+
}
|
38 |
+
}
|
vendor/composer/installers/src/Composer/Installers/TaoInstaller.php
ADDED
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
/**
|
5 |
+
* An installer to handle TAO extensions.
|
6 |
+
*/
|
7 |
+
class TaoInstaller extends BaseInstaller
|
8 |
+
{
|
9 |
+
const EXTRA_TAO_EXTENSION_NAME = 'tao-extension-name';
|
10 |
+
|
11 |
+
protected $locations = array(
|
12 |
+
'extension' => '{$name}'
|
13 |
+
);
|
14 |
+
|
15 |
+
public function inflectPackageVars($vars)
|
16 |
+
{
|
17 |
+
$extra = $this->package->getExtra();
|
18 |
+
|
19 |
+
if (array_key_exists(self::EXTRA_TAO_EXTENSION_NAME, $extra)) {
|
20 |
+
$vars['name'] = $extra[self::EXTRA_TAO_EXTENSION_NAME];
|
21 |
+
return $vars;
|
22 |
+
}
|
23 |
+
|
24 |
+
$vars['name'] = str_replace('extension-', '', $vars['name']);
|
25 |
+
$vars['name'] = str_replace('-', ' ', $vars['name']);
|
26 |
+
$vars['name'] = lcfirst(str_replace(' ', '', ucwords($vars['name'])));
|
27 |
+
|
28 |
+
return $vars;
|
29 |
+
}
|
30 |
+
}
|
vendor/composer/installers/src/Composer/Installers/TastyIgniterInstaller.php
ADDED
@@ -0,0 +1,32 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace Composer\Installers;
|
4 |
+
|
5 |
+
class TastyIgniterInstaller extends BaseInstaller
|
6 |
+
{
|
7 |
+
protected $locations = array(
|
8 |
+
'extension' => 'extensions/{$vendor}/{$name}/',
|
9 |
+
'theme' => 'themes/{$name}/',
|
10 |
+
);
|
11 |
+
|
12 |
+
/**
|
13 |
+
* Format package name.
|
14 |
+
*
|
15 |
+
* Cut off leading 'ti-ext-' or 'ti-theme-' if present.
|
16 |
+
* Strip vendor name of characters that is not alphanumeric or an underscore
|
17 |
+
*
|
18 |
+
*/
|
19 |
+
public function inflectPackageVars($vars)
|
20 |
+
{
|
21 |
+
if ($vars['type'] === 'tastyigniter-extension') {
|
22 |
+
$vars['vendor'] = preg_replace('/[^a-z0-9_]/i', '', $vars['vendor']);
|
23 |
+
$vars['name'] = preg_replace('/^ti-ext-/', '', $vars['name']);
|
24 |
+
}
|
25 |
+
|
26 |
+
if ($vars['type'] === 'tastyigniter-theme') {
|
27 |
+
$vars['name'] = preg_replace('/^ti-theme-/', '', $vars['name']);
|
28 |
+
}
|
29 |
+
|
30 |
+
return $vars;
|
31 |
+
}
|
32 |
+
}
|
vendor/composer/installers/src/Composer/Installers/TheliaInstaller.php
ADDED
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
class TheliaInstaller extends BaseInstaller
|
5 |
+
{
|
6 |
+
protected $locations = array(
|
7 |
+
'module' => 'local/modules/{$name}/',
|
8 |
+
'frontoffice-template' => 'templates/frontOffice/{$name}/',
|
9 |
+
'backoffice-template' => 'templates/backOffice/{$name}/',
|
10 |
+
'email-template' => 'templates/email/{$name}/',
|
11 |
+
);
|
12 |
+
}
|
vendor/composer/installers/src/Composer/Installers/TuskInstaller.php
ADDED
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
/**
|
4 |
+
* Composer installer for 3rd party Tusk utilities
|
5 |
+
* @author Drew Ewing <drew@phenocode.com>
|
6 |
+
*/
|
7 |
+
class TuskInstaller extends BaseInstaller
|
8 |
+
{
|
9 |
+
protected $locations = array(
|
10 |
+
'task' => '.tusk/tasks/{$name}/',
|
11 |
+
'command' => '.tusk/commands/{$name}/',
|
12 |
+
'asset' => 'assets/tusk/{$name}/',
|
13 |
+
);
|
14 |
+
}
|
vendor/composer/installers/src/Composer/Installers/UserFrostingInstaller.php
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
class UserFrostingInstaller extends BaseInstaller
|
5 |
+
{
|
6 |
+
protected $locations = array(
|
7 |
+
'sprinkle' => 'app/sprinkles/{$name}/',
|
8 |
+
);
|
9 |
+
}
|
vendor/composer/installers/src/Composer/Installers/VanillaInstaller.php
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
class VanillaInstaller extends BaseInstaller
|
5 |
+
{
|
6 |
+
protected $locations = array(
|
7 |
+
'plugin' => 'plugins/{$name}/',
|
8 |
+
'theme' => 'themes/{$name}/',
|
9 |
+
);
|
10 |
+
}
|
vendor/composer/installers/src/Composer/Installers/VgmcpInstaller.php
ADDED
@@ -0,0 +1,49 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
class VgmcpInstaller extends BaseInstaller
|
5 |
+
{
|
6 |
+
protected $locations = array(
|
7 |
+
'bundle' => 'src/{$vendor}/{$name}/',
|
8 |
+
'theme' => 'themes/{$name}/'
|
9 |
+
);
|
10 |
+
|
11 |
+
/**
|
12 |
+
* Format package name.
|
13 |
+
*
|
14 |
+
* For package type vgmcp-bundle, cut off a trailing '-bundle' if present.
|
15 |
+
*
|
16 |
+
* For package type vgmcp-theme, cut off a trailing '-theme' if present.
|
17 |
+
*
|
18 |
+
*/
|
19 |
+
public function inflectPackageVars($vars)
|
20 |
+
{
|
21 |
+
if ($vars['type'] === 'vgmcp-bundle') {
|
22 |
+
return $this->inflectPluginVars($vars);
|
23 |
+
}
|
24 |
+
|
25 |
+
if ($vars['type'] === 'vgmcp-theme') {
|
26 |
+
return $this->inflectThemeVars($vars);
|
27 |
+
}
|
28 |
+
|
29 |
+
return $vars;
|
30 |
+
}
|
31 |
+
|
32 |
+
protected function inflectPluginVars($vars)
|
33 |
+
{
|
34 |
+
$vars['name'] = preg_replace('/-bundle$/', '', $vars['name']);
|
35 |
+
$vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
|
36 |
+
$vars['name'] = str_replace(' ', '', ucwords($vars['name']));
|
37 |
+
|
38 |
+
return $vars;
|
39 |
+
}
|
40 |
+
|
41 |
+
protected function inflectThemeVars($vars)
|
42 |
+
{
|
43 |
+
$vars['name'] = preg_replace('/-theme$/', '', $vars['name']);
|
44 |
+
$vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
|
45 |
+
$vars['name'] = str_replace(' ', '', ucwords($vars['name']));
|
46 |
+
|
47 |
+
return $vars;
|
48 |
+
}
|
49 |
+
}
|
vendor/composer/installers/src/Composer/Installers/WHMCSInstaller.php
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace Composer\Installers;
|
4 |
+
|
5 |
+
class WHMCSInstaller extends BaseInstaller
|
6 |
+
{
|
7 |
+
protected $locations = array(
|
8 |
+
'addons' => 'modules/addons/{$vendor}_{$name}/',
|
9 |
+
'fraud' => 'modules/fraud/{$vendor}_{$name}/',
|
10 |
+
'gateways' => 'modules/gateways/{$vendor}_{$name}/',
|
11 |
+
'notifications' => 'modules/notifications/{$vendor}_{$name}/',
|
12 |
+
'registrars' => 'modules/registrars/{$vendor}_{$name}/',
|
13 |
+
'reports' => 'modules/reports/{$vendor}_{$name}/',
|
14 |
+
'security' => 'modules/security/{$vendor}_{$name}/',
|
15 |
+
'servers' => 'modules/servers/{$vendor}_{$name}/',
|
16 |
+
'social' => 'modules/social/{$vendor}_{$name}/',
|
17 |
+
'support' => 'modules/support/{$vendor}_{$name}/',
|
18 |
+
'templates' => 'templates/{$vendor}_{$name}/',
|
19 |
+
'includes' => 'includes/{$vendor}_{$name}/'
|
20 |
+
);
|
21 |
+
}
|
vendor/composer/installers/src/Composer/Installers/WinterInstaller.php
ADDED
@@ -0,0 +1,58 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
class WinterInstaller extends BaseInstaller
|
5 |
+
{
|
6 |
+
protected $locations = array(
|
7 |
+
'module' => 'modules/{$name}/',
|
8 |
+
'plugin' => 'plugins/{$vendor}/{$name}/',
|
9 |
+
'theme' => 'themes/{$name}/'
|
10 |
+
);
|
11 |
+
|
12 |
+
/**
|
13 |
+
* Format package name.
|
14 |
+
*
|
15 |
+
* For package type winter-plugin, cut off a trailing '-plugin' if present.
|
16 |
+
*
|
17 |
+
* For package type winter-theme, cut off a trailing '-theme' if present.
|
18 |
+
*
|
19 |
+
*/
|
20 |
+
public function inflectPackageVars($vars)
|
21 |
+
{
|
22 |
+
if ($vars['type'] === 'winter-module') {
|
23 |
+
return $this->inflectModuleVars($vars);
|
24 |
+
}
|
25 |
+
|
26 |
+
if ($vars['type'] === 'winter-plugin') {
|
27 |
+
return $this->inflectPluginVars($vars);
|
28 |
+
}
|
29 |
+
|
30 |
+
if ($vars['type'] === 'winter-theme') {
|
31 |
+
return $this->inflectThemeVars($vars);
|
32 |
+
}
|
33 |
+
|
34 |
+
return $vars;
|
35 |
+
}
|
36 |
+
|
37 |
+
protected function inflectModuleVars($vars)
|
38 |
+
{
|
39 |
+
$vars['name'] = preg_replace('/^wn-|-module$/', '', $vars['name']);
|
40 |
+
|
41 |
+
return $vars;
|
42 |
+
}
|
43 |
+
|
44 |
+
protected function inflectPluginVars($vars)
|
45 |
+
{
|
46 |
+
$vars['name'] = preg_replace('/^wn-|-plugin$/', '', $vars['name']);
|
47 |
+
$vars['vendor'] = preg_replace('/[^a-z0-9_]/i', '', $vars['vendor']);
|
48 |
+
|
49 |
+
return $vars;
|
50 |
+
}
|
51 |
+
|
52 |
+
protected function inflectThemeVars($vars)
|
53 |
+
{
|
54 |
+
$vars['name'] = preg_replace('/^wn-|-theme$/', '', $vars['name']);
|
55 |
+
|
56 |
+
return $vars;
|
57 |
+
}
|
58 |
+
}
|
vendor/composer/installers/src/Composer/Installers/WolfCMSInstaller.php
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
class WolfCMSInstaller extends BaseInstaller
|
5 |
+
{
|
6 |
+
protected $locations = array(
|
7 |
+
'plugin' => 'wolf/plugins/{$name}/',
|
8 |
+
);
|
9 |
+
}
|
vendor/composer/installers/src/Composer/Installers/WordPressInstaller.php
ADDED
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
class WordPressInstaller extends BaseInstaller
|
5 |
+
{
|
6 |
+
protected $locations = array(
|
7 |
+
'plugin' => 'wp-content/plugins/{$name}/',
|
8 |
+
'theme' => 'wp-content/themes/{$name}/',
|
9 |
+
'muplugin' => 'wp-content/mu-plugins/{$name}/',
|
10 |
+
'dropin' => 'wp-content/{$name}/',
|
11 |
+
);
|
12 |
+
}
|
vendor/composer/installers/src/Composer/Installers/YawikInstaller.php
ADDED
@@ -0,0 +1,32 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Created by PhpStorm.
|
4 |
+
* User: cbleek
|
5 |
+
* Date: 25.03.16
|
6 |
+
* Time: 20:55
|
7 |
+
*/
|
8 |
+
|
9 |
+
namespace Composer\Installers;
|
10 |
+
|
11 |
+
|
12 |
+
class YawikInstaller extends BaseInstaller
|
13 |
+
{
|
14 |
+
protected $locations = array(
|
15 |
+
'module' => 'module/{$name}/',
|
16 |
+
);
|
17 |
+
|
18 |
+
/**
|
19 |
+
* Format package name to CamelCase
|
20 |
+
* @param array $vars
|
21 |
+
*
|
22 |
+
* @return array
|
23 |
+
*/
|
24 |
+
public function inflectPackageVars($vars)
|
25 |
+
{
|
26 |
+
$vars['name'] = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name']));
|
27 |
+
$vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
|
28 |
+
$vars['name'] = str_replace(' ', '', ucwords($vars['name']));
|
29 |
+
|
30 |
+
return $vars;
|
31 |
+
}
|
32 |
+
}
|
vendor/composer/installers/src/Composer/Installers/ZendInstaller.php
ADDED
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
class ZendInstaller extends BaseInstaller
|
5 |
+
{
|
6 |
+
protected $locations = array(
|
7 |
+
'library' => 'library/{$name}/',
|
8 |
+
'extra' => 'extras/library/{$name}/',
|
9 |
+
'module' => 'module/{$name}/',
|
10 |
+
);
|
11 |
+
}
|
vendor/composer/installers/src/Composer/Installers/ZikulaInstaller.php
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace Composer\Installers;
|
3 |
+
|
4 |
+
class ZikulaInstaller extends BaseInstaller
|
5 |
+
{
|
6 |
+
protected $locations = array(
|
7 |
+
'module' => 'modules/{$vendor}-{$name}/',
|
8 |
+
'theme' => 'themes/{$vendor}-{$name}/'
|
9 |
+
);
|
10 |
+
}
|
vendor/composer/installers/src/bootstrap.php
ADDED
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
function includeIfExists($file)
|
3 |
+
{
|
4 |
+
if (file_exists($file)) {
|
5 |
+
return include $file;
|
6 |
+
}
|
7 |
+
}
|
8 |
+
if ((!$loader = includeIfExists(__DIR__ . '/../vendor/autoload.php')) && (!$loader = includeIfExists(__DIR__ . '/../../../autoload.php'))) {
|
9 |
+
die('You must set up the project dependencies, run the following commands:'.PHP_EOL.
|
10 |
+
'curl -s http://getcomposer.org/installer | php'.PHP_EOL.
|
11 |
+
'php composer.phar install'.PHP_EOL);
|
12 |
+
}
|
13 |
+
return $loader;
|
vendor/composer/platform_check.php
ADDED
@@ -0,0 +1,26 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
// platform_check.php @generated by Composer
|
4 |
+
|
5 |
+
$issues = array();
|
6 |
+
|
7 |
+
if (!(PHP_VERSION_ID >= 70000)) {
|
8 |
+
$issues[] = 'Your Composer dependencies require a PHP version ">= 7.0.0". You are running ' . PHP_VERSION . '.';
|
9 |
+
}
|
10 |
+
|
11 |
+
if ($issues) {
|
12 |
+
if (!headers_sent()) {
|
13 |
+
header('HTTP/1.1 500 Internal Server Error');
|
14 |
+
}
|
15 |
+
if (!ini_get('display_errors')) {
|
16 |
+
if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
|
17 |
+
fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL);
|
18 |
+
} elseif (!headers_sent()) {
|
19 |
+
echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL;
|
20 |
+
}
|
21 |
+
}
|
22 |
+
trigger_error(
|
23 |
+
'Composer detected issues in your platform: ' . implode(' ', $issues),
|
24 |
+
E_USER_ERROR
|
25 |
+
);
|
26 |
+
}
|
vendor/woocommerce/action-scheduler-job-framework/LICENSE
ADDED
@@ -0,0 +1,674 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
GNU GENERAL PUBLIC LICENSE
|
2 |
+
Version 3, 29 June 2007
|
3 |
+
|
4 |
+
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
5 |
+
Everyone is permitted to copy and distribute verbatim copies
|
6 |
+
of this license document, but changing it is not allowed.
|
7 |
+
|
8 |
+
Preamble
|
9 |
+
|
10 |
+
The GNU General Public License is a free, copyleft license for
|
11 |
+
software and other kinds of works.
|
12 |
+
|
13 |
+
The licenses for most software and other practical works are designed
|
14 |
+
to take away your freedom to share and change the works. By contrast,
|
15 |
+
the GNU General Public License is intended to guarantee your freedom to
|
16 |
+
share and change all versions of a program--to make sure it remains free
|
17 |
+
software for all its users. We, the Free Software Foundation, use the
|
18 |
+
GNU General Public License for most of our software; it applies also to
|
19 |
+
any other work released this way by its authors. You can apply it to
|
20 |
+
your programs, too.
|
21 |
+
|
22 |
+
When we speak of free software, we are referring to freedom, not
|
23 |
+
price. Our General Public Licenses are designed to make sure that you
|
24 |
+
have the freedom to distribute copies of free software (and charge for
|
25 |
+
them if you wish), that you receive source code or can get it if you
|
26 |
+
want it, that you can change the software or use pieces of it in new
|
27 |
+
free programs, and that you know you can do these things.
|
28 |
+
|
29 |
+
To protect your rights, we need to prevent others from denying you
|
30 |
+
these rights or asking you to surrender the rights. Therefore, you have
|
31 |
+
certain responsibilities if you distribute copies of the software, or if
|
32 |
+
you modify it: responsibilities to respect the freedom of others.
|
33 |
+
|
34 |
+
For example, if you distribute copies of such a program, whether
|
35 |
+
gratis or for a fee, you must pass on to the recipients the same
|
36 |
+
freedoms that you received. You must make sure that they, too, receive
|
37 |
+
or can get the source code. And you must show them these terms so they
|
38 |
+
know their rights.
|
39 |
+
|
40 |
+
Developers that use the GNU GPL protect your rights with two steps:
|
41 |
+
(1) assert copyright on the software, and (2) offer you this License
|
42 |
+
giving you legal permission to copy, distribute and/or modify it.
|
43 |
+
|
44 |
+
For the developers' and authors' protection, the GPL clearly explains
|
45 |
+
that there is no warranty for this free software. For both users' and
|
46 |
+
authors' sake, the GPL requires that modified versions be marked as
|
47 |
+
changed, so that their problems will not be attributed erroneously to
|
48 |
+
authors of previous versions.
|
49 |
+
|
50 |
+
Some devices are designed to deny users access to install or run
|
51 |
+
modified versions of the software inside them, although the manufacturer
|
52 |
+
can do so. This is fundamentally incompatible with the aim of
|
53 |
+
protecting users' freedom to change the software. The systematic
|
54 |
+
pattern of such abuse occurs in the area of products for individuals to
|
55 |
+
use, which is precisely where it is most unacceptable. Therefore, we
|
56 |
+
have designed this version of the GPL to prohibit the practice for those
|
57 |
+
products. If such problems arise substantially in other domains, we
|
58 |
+
stand ready to extend this provision to those domains in future versions
|
59 |
+
of the GPL, as needed to protect the freedom of users.
|
60 |
+
|
61 |
+
Finally, every program is threatened constantly by software patents.
|
62 |
+
States should not allow patents to restrict development and use of
|
63 |
+
software on general-purpose computers, but in those that do, we wish to
|
64 |
+
avoid the special danger that patents applied to a free program could
|
65 |
+
make it effectively proprietary. To prevent this, the GPL assures that
|
66 |
+
patents cannot be used to render the program non-free.
|
67 |
+
|
68 |
+
The precise terms and conditions for copying, distribution and
|
69 |
+
modification follow.
|
70 |
+
|
71 |
+
TERMS AND CONDITIONS
|
72 |
+
|
73 |
+
0. Definitions.
|
74 |
+
|
75 |
+
"This License" refers to version 3 of the GNU General Public License.
|
76 |
+
|
77 |
+
"Copyright" also means copyright-like laws that apply to other kinds of
|
78 |
+
works, such as semiconductor masks.
|
79 |
+
|
80 |
+
"The Program" refers to any copyrightable work licensed under this
|
81 |
+
License. Each licensee is addressed as "you". "Licensees" and
|
82 |
+
"recipients" may be individuals or organizations.
|
83 |
+
|
84 |
+
To "modify" a work means to copy from or adapt all or part of the work
|
85 |
+
in a fashion requiring copyright permission, other than the making of an
|
86 |
+
exact copy. The resulting work is called a "modified version" of the
|
87 |
+
earlier work or a work "based on" the earlier work.
|
88 |
+
|
89 |
+
A "covered work" means either the unmodified Program or a work based
|
90 |
+
on the Program.
|
91 |
+
|
92 |
+
To "propagate" a work means to do anything with it that, without
|
93 |
+
permission, would make you directly or secondarily liable for
|
94 |
+
infringement under applicable copyright law, except executing it on a
|
95 |
+
computer or modifying a private copy. Propagation includes copying,
|
96 |
+
distribution (with or without modification), making available to the
|
97 |
+
public, and in some countries other activities as well.
|
98 |
+
|
99 |
+
To "convey" a work means any kind of propagation that enables other
|
100 |
+
parties to make or receive copies. Mere interaction with a user through
|
101 |
+
a computer network, with no transfer of a copy, is not conveying.
|
102 |
+
|
103 |
+
An interactive user interface displays "Appropriate Legal Notices"
|
104 |
+
to the extent that it includes a convenient and prominently visible
|
105 |
+
feature that (1) displays an appropriate copyright notice, and (2)
|
106 |
+
tells the user that there is no warranty for the work (except to the
|
107 |
+
extent that warranties are provided), that licensees may convey the
|
108 |
+
work under this License, and how to view a copy of this License. If
|
109 |
+
the interface presents a list of user commands or options, such as a
|
110 |
+
menu, a prominent item in the list meets this criterion.
|
111 |
+
|
112 |
+
1. Source Code.
|
113 |
+
|
114 |
+
The "source code" for a work means the preferred form of the work
|
115 |
+
for making modifications to it. "Object code" means any non-source
|
116 |
+
form of a work.
|
117 |
+
|
118 |
+
A "Standard Interface" means an interface that either is an official
|
119 |
+
standard defined by a recognized standards body, or, in the case of
|
120 |
+
interfaces specified for a particular programming language, one that
|
121 |
+
is widely used among developers working in that language.
|
122 |
+
|
123 |
+
The "System Libraries" of an executable work include anything, other
|
124 |
+
than the work as a whole, that (a) is included in the normal form of
|
125 |
+
packaging a Major Component, but which is not part of that Major
|
126 |
+
Component, and (b) serves only to enable use of the work with that
|
127 |
+
Major Component, or to implement a Standard Interface for which an
|
128 |
+
implementation is available to the public in source code form. A
|
129 |
+
"Major Component", in this context, means a major essential component
|
130 |
+
(kernel, window system, and so on) of the specific operating system
|
131 |
+
(if any) on which the executable work runs, or a compiler used to
|
132 |
+
produce the work, or an object code interpreter used to run it.
|
133 |
+
|
134 |
+
The "Corresponding Source" for a work in object code form means all
|
135 |
+
the source code needed to generate, install, and (for an executable
|
136 |
+
work) run the object code and to modify the work, including scripts to
|
137 |
+
control those activities. However, it does not include the work's
|
138 |
+
System Libraries, or general-purpose tools or generally available free
|
139 |
+
programs which are used unmodified in performing those activities but
|
140 |
+
which are not part of the work. For example, Corresponding Source
|
141 |
+
includes interface definition files associated with source files for
|
142 |
+
the work, and the source code for shared libraries and dynamically
|
143 |
+
linked subprograms that the work is specifically designed to require,
|
144 |
+
such as by intimate data communication or control flow between those
|
145 |
+
subprograms and other parts of the work.
|
146 |
+
|
147 |
+
The Corresponding Source need not include anything that users
|
148 |
+
can regenerate automatically from other parts of the Corresponding
|
149 |
+
Source.
|
150 |
+
|
151 |
+
The Corresponding Source for a work in source code form is that
|
152 |
+
same work.
|
153 |
+
|
154 |
+
2. Basic Permissions.
|
155 |
+
|
156 |
+
All rights granted under this License are granted for the term of
|
157 |
+
copyright on the Program, and are irrevocable provided the stated
|
158 |
+
conditions are met. This License explicitly affirms your unlimited
|
159 |
+
permission to run the unmodified Program. The output from running a
|
160 |
+
covered work is covered by this License only if the output, given its
|
161 |
+
content, constitutes a covered work. This License acknowledges your
|
162 |
+
rights of fair use or other equivalent, as provided by copyright law.
|
163 |
+
|
164 |
+
You may make, run and propagate covered works that you do not
|
165 |
+
convey, without conditions so long as your license otherwise remains
|
166 |
+
in force. You may convey covered works to others for the sole purpose
|
167 |
+
of having them make modifications exclusively for you, or provide you
|
168 |
+
with facilities for running those works, provided that you comply with
|
169 |
+
the terms of this License in conveying all material for which you do
|
170 |
+
not control copyright. Those thus making or running the covered works
|
171 |
+
for you must do so exclusively on your behalf, under your direction
|
172 |
+
and control, on terms that prohibit them from making any copies of
|
173 |
+
your copyrighted material outside their relationship with you.
|
174 |
+
|
175 |
+
Conveying under any other circumstances is permitted solely under
|
176 |
+
the conditions stated below. Sublicensing is not allowed; section 10
|
177 |
+
makes it unnecessary.
|
178 |
+
|
179 |
+
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
180 |
+
|
181 |
+
No covered work shall be deemed part of an effective technological
|
182 |
+
measure under any applicable law fulfilling obligations under article
|
183 |
+
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
184 |
+
similar laws prohibiting or restricting circumvention of such
|
185 |
+
measures.
|
186 |
+
|
187 |
+
When you convey a covered work, you waive any legal power to forbid
|
188 |
+
circumvention of technological measures to the extent such circumvention
|
189 |
+
is effected by exercising rights under this License with respect to
|
190 |
+
the covered work, and you disclaim any intention to limit operation or
|
191 |
+
modification of the work as a means of enforcing, against the work's
|
192 |
+
users, your or third parties' legal rights to forbid circumvention of
|
193 |
+
technological measures.
|
194 |
+
|
195 |
+
4. Conveying Verbatim Copies.
|
196 |
+
|
197 |
+
You may convey verbatim copies of the Program's source code as you
|
198 |
+
receive it, in any medium, provided that you conspicuously and
|
199 |
+
appropriately publish on each copy an appropriate copyright notice;
|
200 |
+
keep intact all notices stating that this License and any
|
201 |
+
non-permissive terms added in accord with section 7 apply to the code;
|
202 |
+
keep intact all notices of the absence of any warranty; and give all
|
203 |
+
recipients a copy of this License along with the Program.
|
204 |
+
|
205 |
+
You may charge any price or no price for each copy that you convey,
|
206 |
+
and you may offer support or warranty protection for a fee.
|
207 |
+
|
208 |
+
5. Conveying Modified Source Versions.
|
209 |
+
|
210 |
+
You may convey a work based on the Program, or the modifications to
|
211 |
+
produce it from the Program, in the form of source code under the
|
212 |
+
terms of section 4, provided that you also meet all of these conditions:
|
213 |
+
|
214 |
+
a) The work must carry prominent notices stating that you modified
|
215 |
+
it, and giving a relevant date.
|
216 |
+
|
217 |
+
b) The work must carry prominent notices stating that it is
|
218 |
+
released under this License and any conditions added under section
|
219 |
+
7. This requirement modifies the requirement in section 4 to
|
220 |
+
"keep intact all notices".
|
221 |
+
|
222 |
+
c) You must license the entire work, as a whole, under this
|
223 |
+
License to anyone who comes into possession of a copy. This
|
224 |
+
License will therefore apply, along with any applicable section 7
|
225 |
+
additional terms, to the whole of the work, and all its parts,
|
226 |
+
regardless of how they are packaged. This License gives no
|
227 |
+
permission to license the work in any other way, but it does not
|
228 |
+
invalidate such permission if you have separately received it.
|
229 |
+
|
230 |
+
d) If the work has interactive user interfaces, each must display
|
231 |
+
Appropriate Legal Notices; however, if the Program has interactive
|
232 |
+
interfaces that do not display Appropriate Legal Notices, your
|
233 |
+
work need not make them do so.
|
234 |
+
|
235 |
+
A compilation of a covered work with other separate and independent
|
236 |
+
works, which are not by their nature extensions of the covered work,
|
237 |
+
and which are not combined with it such as to form a larger program,
|
238 |
+
in or on a volume of a storage or distribution medium, is called an
|
239 |
+
"aggregate" if the compilation and its resulting copyright are not
|
240 |
+
used to limit the access or legal rights of the compilation's users
|
241 |
+
beyond what the individual works permit. Inclusion of a covered work
|
242 |
+
in an aggregate does not cause this License to apply to the other
|
243 |
+
parts of the aggregate.
|
244 |
+
|
245 |
+
6. Conveying Non-Source Forms.
|
246 |
+
|
247 |
+
You may convey a covered work in object code form under the terms
|
248 |
+
of sections 4 and 5, provided that you also convey the
|
249 |
+
machine-readable Corresponding Source under the terms of this License,
|
250 |
+
in one of these ways:
|
251 |
+
|
252 |
+
a) Convey the object code in, or embodied in, a physical product
|
253 |
+
(including a physical distribution medium), accompanied by the
|
254 |
+
Corresponding Source fixed on a durable physical medium
|
255 |
+
customarily used for software interchange.
|
256 |
+
|
257 |
+
b) Convey the object code in, or embodied in, a physical product
|
258 |
+
(including a physical distribution medium), accompanied by a
|
259 |
+
written offer, valid for at least three years and valid for as
|
260 |
+
long as you offer spare parts or customer support for that product
|
261 |
+
model, to give anyone who possesses the object code either (1) a
|
262 |
+
copy of the Corresponding Source for all the software in the
|
263 |
+
product that is covered by this License, on a durable physical
|
264 |
+
medium customarily used for software interchange, for a price no
|
265 |
+
more than your reasonable cost of physically performing this
|
266 |
+
conveying of source, or (2) access to copy the
|
267 |
+
Corresponding Source from a network server at no charge.
|
268 |
+
|
269 |
+
c) Convey individual copies of the object code with a copy of the
|
270 |
+
written offer to provide the Corresponding Source. This
|
271 |
+
alternative is allowed only occasionally and noncommercially, and
|
272 |
+
only if you received the object code with such an offer, in accord
|
273 |
+
with subsection 6b.
|
274 |
+
|
275 |
+
d) Convey the object code by offering access from a designated
|
276 |
+
place (gratis or for a charge), and offer equivalent access to the
|
277 |
+
Corresponding Source in the same way through the same place at no
|
278 |
+
further charge. You need not require recipients to copy the
|
279 |
+
Corresponding Source along with the object code. If the place to
|
280 |
+
copy the object code is a network server, the Corresponding Source
|
281 |
+
may be on a different server (operated by you or a third party)
|
282 |
+
that supports equivalent copying facilities, provided you maintain
|
283 |
+
clear directions next to the object code saying where to find the
|
284 |
+
Corresponding Source. Regardless of what server hosts the
|
285 |
+
Corresponding Source, you remain obligated to ensure that it is
|
286 |
+
available for as long as needed to satisfy these requirements.
|
287 |
+
|
288 |
+
e) Convey the object code using peer-to-peer transmission, provided
|
289 |
+
you inform other peers where the object code and Corresponding
|
290 |
+
Source of the work are being offered to the general public at no
|
291 |
+
charge under subsection 6d.
|
292 |
+
|
293 |
+
A separable portion of the object code, whose source code is excluded
|
294 |
+
from the Corresponding Source as a System Library, need not be
|
295 |
+
included in conveying the object code work.
|
296 |
+
|
297 |
+
A "User Product" is either (1) a "consumer product", which means any
|
298 |
+
tangible personal property which is normally used for personal, family,
|
299 |
+
or household purposes, or (2) anything designed or sold for incorporation
|
300 |
+
into a dwelling. In determining whether a product is a consumer product,
|
301 |
+
doubtful cases shall be resolved in favor of coverage. For a particular
|
302 |
+
product received by a particular user, "normally used" refers to a
|
303 |
+
typical or common use of that class of product, regardless of the status
|
304 |
+
of the particular user or of the way in which the particular user
|
305 |
+
actually uses, or expects or is expected to use, the product. A product
|
306 |
+
is a consumer product regardless of whether the product has substantial
|
307 |
+
commercial, industrial or non-consumer uses, unless such uses represent
|
308 |
+
the only significant mode of use of the product.
|
309 |
+
|
310 |
+
"Installation Information" for a User Product means any methods,
|
311 |
+
procedures, authorization keys, or other information required to install
|
312 |
+
and execute modified versions of a covered work in that User Product from
|
313 |
+
a modified version of its Corresponding Source. The information must
|
314 |
+
suffice to ensure that the continued functioning of the modified object
|
315 |
+
code is in no case prevented or interfered with solely because
|
316 |
+
modification has been made.
|
317 |
+
|
318 |
+
If you convey an object code work under this section in, or with, or
|
319 |
+
specifically for use in, a User Product, and the conveying occurs as
|
320 |
+
part of a transaction in which the right of possession and use of the
|
321 |
+
User Product is transferred to the recipient in perpetuity or for a
|
322 |
+
fixed term (regardless of how the transaction is characterized), the
|
323 |
+
Corresponding Source conveyed under this section must be accompanied
|
324 |
+
by the Installation Information. But this requirement does not apply
|
325 |
+
if neither you nor any third party retains the ability to install
|
326 |
+
modified object code on the User Product (for example, the work has
|
327 |
+
been installed in ROM).
|
328 |
+
|
329 |
+
The requirement to provide Installation Information does not include a
|
330 |
+
requirement to continue to provide support service, warranty, or updates
|
331 |
+
for a work that has been modified or installed by the recipient, or for
|
332 |
+
the User Product in which it has been modified or installed. Access to a
|
333 |
+
network may be denied when the modification itself materially and
|
334 |
+
adversely affects the operation of the network or violates the rules and
|
335 |
+
protocols for communication across the network.
|
336 |
+
|
337 |
+
Corresponding Source conveyed, and Installation Information provided,
|
338 |
+
in accord with this section must be in a format that is publicly
|
339 |
+
documented (and with an implementation available to the public in
|
340 |
+
source code form), and must require no special password or key for
|
341 |
+
unpacking, reading or copying.
|
342 |
+
|
343 |
+
7. Additional Terms.
|
344 |
+
|
345 |
+
"Additional permissions" are terms that supplement the terms of this
|
346 |
+
License by making exceptions from one or more of its conditions.
|
347 |
+
Additional permissions that are applicable to the entire Program shall
|
348 |
+
be treated as though they were included in this License, to the extent
|
349 |
+
that they are valid under applicable law. If additional permissions
|
350 |
+
apply only to part of the Program, that part may be used separately
|
351 |
+
under those permissions, but the entire Program remains governed by
|
352 |
+
this License without regard to the additional permissions.
|
353 |
+
|
354 |
+
When you convey a copy of a covered work, you may at your option
|
355 |
+
remove any additional permissions from that copy, or from any part of
|
356 |
+
it. (Additional permissions may be written to require their own
|
357 |
+
removal in certain cases when you modify the work.) You may place
|
358 |
+
additional permissions on material, added by you to a covered work,
|
359 |
+
for which you have or can give appropriate copyright permission.
|
360 |
+
|
361 |
+
Notwithstanding any other provision of this License, for material you
|
362 |
+
add to a covered work, you may (if authorized by the copyright holders of
|
363 |
+
that material) supplement the terms of this License with terms:
|
364 |
+
|
365 |
+
a) Disclaiming warranty or limiting liability differently from the
|
366 |
+
terms of sections 15 and 16 of this License; or
|
367 |
+
|
368 |
+
b) Requiring preservation of specified reasonable legal notices or
|
369 |
+
author attributions in that material or in the Appropriate Legal
|
370 |
+
Notices displayed by works containing it; or
|
371 |
+
|
372 |
+
c) Prohibiting misrepresentation of the origin of that material, or
|
373 |
+
requiring that modified versions of such material be marked in
|
374 |
+
reasonable ways as different from the original version; or
|
375 |
+
|
376 |
+
d) Limiting the use for publicity purposes of names of licensors or
|
377 |
+
authors of the material; or
|
378 |
+
|
379 |
+
e) Declining to grant rights under trademark law for use of some
|
380 |
+
trade names, trademarks, or service marks; or
|
381 |
+
|
382 |
+
f) Requiring indemnification of licensors and authors of that
|
383 |
+
material by anyone who conveys the material (or modified versions of
|
384 |
+
it) with contractual assumptions of liability to the recipient, for
|
385 |
+
any liability that these contractual assumptions directly impose on
|
386 |
+
those licensors and authors.
|
387 |
+
|
388 |
+
All other non-permissive additional terms are considered "further
|
389 |
+
restrictions" within the meaning of section 10. If the Program as you
|
390 |
+
received it, or any part of it, contains a notice stating that it is
|
391 |
+
governed by this License along with a term that is a further
|
392 |
+
restriction, you may remove that term. If a license document contains
|
393 |
+
a further restriction but permits relicensing or conveying under this
|
394 |
+
License, you may add to a covered work material governed by the terms
|
395 |
+
of that license document, provided that the further restriction does
|
396 |
+
not survive such relicensing or conveying.
|
397 |
+
|
398 |
+
If you add terms to a covered work in accord with this section, you
|
399 |
+
must place, in the relevant source files, a statement of the
|
400 |
+
additional terms that apply to those files, or a notice indicating
|
401 |
+
where to find the applicable terms.
|
402 |
+
|
403 |
+
Additional terms, permissive or non-permissive, may be stated in the
|
404 |
+
form of a separately written license, or stated as exceptions;
|
405 |
+
the above requirements apply either way.
|
406 |
+
|
407 |
+
8. Termination.
|
408 |
+
|
409 |
+
You may not propagate or modify a covered work except as expressly
|
410 |
+
provided under this License. Any attempt otherwise to propagate or
|
411 |
+
modify it is void, and will automatically terminate your rights under
|
412 |
+
this License (including any patent licenses granted under the third
|
413 |
+
paragraph of section 11).
|
414 |
+
|
415 |
+
However, if you cease all violation of this License, then your
|
416 |
+
license from a particular copyright holder is reinstated (a)
|
417 |
+
provisionally, unless and until the copyright holder explicitly and
|
418 |
+
finally terminates your license, and (b) permanently, if the copyright
|
419 |
+
holder fails to notify you of the violation by some reasonable means
|
420 |
+
prior to 60 days after the cessation.
|
421 |
+
|
422 |
+
Moreover, your license from a particular copyright holder is
|
423 |
+
reinstated permanently if the copyright holder notifies you of the
|
424 |
+
violation by some reasonable means, this is the first time you have
|
425 |
+
received notice of violation of this License (for any work) from that
|
426 |
+
copyright holder, and you cure the violation prior to 30 days after
|
427 |
+
your receipt of the notice.
|
428 |
+
|
429 |
+
Termination of your rights under this section does not terminate the
|
430 |
+
licenses of parties who have received copies or rights from you under
|
431 |
+
this License. If your rights have been terminated and not permanently
|
432 |
+
reinstated, you do not qualify to receive new licenses for the same
|
433 |
+
material under section 10.
|
434 |
+
|
435 |
+
9. Acceptance Not Required for Having Copies.
|
436 |
+
|
437 |
+
You are not required to accept this License in order to receive or
|
438 |
+
run a copy of the Program. Ancillary propagation of a covered work
|
439 |
+
occurring solely as a consequence of using peer-to-peer transmission
|
440 |
+
to receive a copy likewise does not require acceptance. However,
|
441 |
+
nothing other than this License grants you permission to propagate or
|
442 |
+
modify any covered work. These actions infringe copyright if you do
|
443 |
+
not accept this License. Therefore, by modifying or propagating a
|
444 |
+
covered work, you indicate your acceptance of this License to do so.
|
445 |
+
|
446 |
+
10. Automatic Licensing of Downstream Recipients.
|
447 |
+
|
448 |
+
Each time you convey a covered work, the recipient automatically
|
449 |
+
receives a license from the original licensors, to run, modify and
|
450 |
+
propagate that work, subject to this License. You are not responsible
|
451 |
+
for enforcing compliance by third parties with this License.
|
452 |
+
|
453 |
+
An "entity transaction" is a transaction transferring control of an
|
454 |
+
organization, or substantially all assets of one, or subdividing an
|
455 |
+
organization, or merging organizations. If propagation of a covered
|
456 |
+
work results from an entity transaction, each party to that
|
457 |
+
transaction who receives a copy of the work also receives whatever
|
458 |
+
licenses to the work the party's predecessor in interest had or could
|
459 |
+
give under the previous paragraph, plus a right to possession of the
|
460 |
+
Corresponding Source of the work from the predecessor in interest, if
|
461 |
+
the predecessor has it or can get it with reasonable efforts.
|
462 |
+
|
463 |
+
You may not impose any further restrictions on the exercise of the
|
464 |
+
rights granted or affirmed under this License. For example, you may
|
465 |
+
not impose a license fee, royalty, or other charge for exercise of
|
466 |
+
rights granted under this License, and you may not initiate litigation
|
467 |
+
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
468 |
+
any patent claim is infringed by making, using, selling, offering for
|
469 |
+
sale, or importing the Program or any portion of it.
|
470 |
+
|
471 |
+
11. Patents.
|
472 |
+
|
473 |
+
A "contributor" is a copyright holder who authorizes use under this
|
474 |
+
License of the Program or a work on which the Program is based. The
|
475 |
+
work thus licensed is called the contributor's "contributor version".
|
476 |
+
|
477 |
+
A contributor's "essential patent claims" are all patent claims
|
478 |
+
owned or controlled by the contributor, whether already acquired or
|
479 |
+
hereafter acquired, that would be infringed by some manner, permitted
|
480 |
+
by this License, of making, using, or selling its contributor version,
|
481 |
+
but do not include claims that would be infringed only as a
|
482 |
+
consequence of further modification of the contributor version. For
|
483 |
+
purposes of this definition, "control" includes the right to grant
|
484 |
+
patent sublicenses in a manner consistent with the requirements of
|
485 |
+
this License.
|
486 |
+
|
487 |
+
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
488 |
+
patent license under the contributor's essential patent claims, to
|
489 |
+
make, use, sell, offer for sale, import and otherwise run, modify and
|
490 |
+
propagate the contents of its contributor version.
|
491 |
+
|
492 |
+
In the following three paragraphs, a "patent license" is any express
|
493 |
+
agreement or commitment, however denominated, not to enforce a patent
|
494 |
+
(such as an express permission to practice a patent or covenant not to
|
495 |
+
sue for patent infringement). To "grant" such a patent license to a
|
496 |
+
party means to make such an agreement or commitment not to enforce a
|
497 |
+
patent against the party.
|
498 |
+
|
499 |
+
If you convey a covered work, knowingly relying on a patent license,
|
500 |
+
and the Corresponding Source of the work is not available for anyone
|
501 |
+
to copy, free of charge and under the terms of this License, through a
|
502 |
+
publicly available network server or other readily accessible means,
|
503 |
+
then you must either (1) cause the Corresponding Source to be so
|
504 |
+
available, or (2) arrange to deprive yourself of the benefit of the
|
505 |
+
patent license for this particular work, or (3) arrange, in a manner
|
506 |
+
consistent with the requirements of this License, to extend the patent
|
507 |
+
license to downstream recipients. "Knowingly relying" means you have
|
508 |
+
actual knowledge that, but for the patent license, your conveying the
|
509 |
+
covered work in a country, or your recipient's use of the covered work
|
510 |
+
in a country, would infringe one or more identifiable patents in that
|
511 |
+
country that you have reason to believe are valid.
|
512 |
+
|
513 |
+
If, pursuant to or in connection with a single transaction or
|
514 |
+
arrangement, you convey, or propagate by procuring conveyance of, a
|
515 |
+
covered work, and grant a patent license to some of the parties
|
516 |
+
receiving the covered work authorizing them to use, propagate, modify
|
517 |
+
or convey a specific copy of the covered work, then the patent license
|
518 |
+
you grant is automatically extended to all recipients of the covered
|
519 |
+
work and works based on it.
|
520 |
+
|
521 |
+
A patent license is "discriminatory" if it does not include within
|
522 |
+
the scope of its coverage, prohibits the exercise of, or is
|
523 |
+
conditioned on the non-exercise of one or more of the rights that are
|
524 |
+
specifically granted under this License. You may not convey a covered
|
525 |
+
work if you are a party to an arrangement with a third party that is
|
526 |
+
in the business of distributing software, under which you make payment
|
527 |
+
to the third party based on the extent of your activity of conveying
|
528 |
+
the work, and under which the third party grants, to any of the
|
529 |
+
parties who would receive the covered work from you, a discriminatory
|
530 |
+
patent license (a) in connection with copies of the covered work
|
531 |
+
conveyed by you (or copies made from those copies), or (b) primarily
|
532 |
+
for and in connection with specific products or compilations that
|
533 |
+
contain the covered work, unless you entered into that arrangement,
|
534 |
+
or that patent license was granted, prior to 28 March 2007.
|
535 |
+
|
536 |
+
Nothing in this License shall be construed as excluding or limiting
|
537 |
+
any implied license or other defenses to infringement that may
|
538 |
+
otherwise be available to you under applicable patent law.
|
539 |
+
|
540 |
+
12. No Surrender of Others' Freedom.
|
541 |
+
|
542 |
+
If conditions are imposed on you (whether by court order, agreement or
|
543 |
+
otherwise) that contradict the conditions of this License, they do not
|
544 |
+
excuse you from the conditions of this License. If you cannot convey a
|
545 |
+
covered work so as to satisfy simultaneously your obligations under this
|
546 |
+
License and any other pertinent obligations, then as a consequence you may
|
547 |
+
not convey it at all. For example, if you agree to terms that obligate you
|
548 |
+
to collect a royalty for further conveying from those to whom you convey
|
549 |
+
the Program, the only way you could satisfy both those terms and this
|
550 |
+
License would be to refrain entirely from conveying the Program.
|
551 |
+
|
552 |
+
13. Use with the GNU Affero General Public License.
|
553 |
+
|
554 |
+
Notwithstanding any other provision of this License, you have
|
555 |
+
permission to link or combine any covered work with a work licensed
|
556 |
+
under version 3 of the GNU Affero General Public License into a single
|
557 |
+
combined work, and to convey the resulting work. The terms of this
|
558 |
+
License will continue to apply to the part which is the covered work,
|
559 |
+
but the special requirements of the GNU Affero General Public License,
|
560 |
+
section 13, concerning interaction through a network will apply to the
|
561 |
+
combination as such.
|
562 |
+
|
563 |
+
14. Revised Versions of this License.
|
564 |
+
|
565 |
+
The Free Software Foundation may publish revised and/or new versions of
|
566 |
+
the GNU General Public License from time to time. Such new versions will
|
567 |
+
be similar in spirit to the present version, but may differ in detail to
|
568 |
+
address new problems or concerns.
|
569 |
+
|
570 |
+
Each version is given a distinguishing version number. If the
|
571 |
+
Program specifies that a certain numbered version of the GNU General
|
572 |
+
Public License "or any later version" applies to it, you have the
|
573 |
+
option of following the terms and conditions either of that numbered
|
574 |
+
version or of any later version published by the Free Software
|
575 |
+
Foundation. If the Program does not specify a version number of the
|
576 |
+
GNU General Public License, you may choose any version ever published
|
577 |
+
by the Free Software Foundation.
|
578 |
+
|
579 |
+
If the Program specifies that a proxy can decide which future
|
580 |
+
versions of the GNU General Public License can be used, that proxy's
|
581 |
+
public statement of acceptance of a version permanently authorizes you
|
582 |
+
to choose that version for the Program.
|
583 |
+
|
584 |
+
Later license versions may give you additional or different
|
585 |
+
permissions. However, no additional obligations are imposed on any
|
586 |
+
author or copyright holder as a result of your choosing to follow a
|
587 |
+
later version.
|
588 |
+
|
589 |
+
15. Disclaimer of Warranty.
|
590 |
+
|
591 |
+
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
592 |
+
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
593 |
+
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
594 |
+
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
595 |
+
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
596 |
+
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
597 |
+
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
598 |
+
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
599 |
+
|
600 |
+
16. Limitation of Liability.
|
601 |
+
|
602 |
+
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
603 |
+
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
604 |
+
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
605 |
+
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
606 |
+
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
607 |
+
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
608 |
+
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
609 |
+
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
610 |
+
SUCH DAMAGES.
|
611 |
+
|
612 |
+
17. Interpretation of Sections 15 and 16.
|
613 |
+
|
614 |
+
If the disclaimer of warranty and limitation of liability provided
|
615 |
+
above cannot be given local legal effect according to their terms,
|
616 |
+
reviewing courts shall apply local law that most closely approximates
|
617 |
+
an absolute waiver of all civil liability in connection with the
|
618 |
+
Program, unless a warranty or assumption of liability accompanies a
|
619 |
+
copy of the Program in return for a fee.
|
620 |
+
|
621 |
+
END OF TERMS AND CONDITIONS
|
622 |
+
|
623 |
+
How to Apply These Terms to Your New Programs
|
624 |
+
|
625 |
+
If you develop a new program, and you want it to be of the greatest
|
626 |
+
possible use to the public, the best way to achieve this is to make it
|
627 |
+
free software which everyone can redistribute and change under these terms.
|
628 |
+
|
629 |
+
To do so, attach the following notices to the program. It is safest
|
630 |
+
to attach them to the start of each source file to most effectively
|
631 |
+
state the exclusion of warranty; and each file should have at least
|
632 |
+
the "copyright" line and a pointer to where the full notice is found.
|
633 |
+
|
634 |
+
<one line to give the program's name and a brief idea of what it does.>
|
635 |
+
Copyright (C) <year> <name of author>
|
636 |
+
|
637 |
+
This program is free software: you can redistribute it and/or modify
|
638 |
+
it under the terms of the GNU General Public License as published by
|
639 |
+
the Free Software Foundation, either version 3 of the License, or
|
640 |
+
(at your option) any later version.
|
641 |
+
|
642 |
+
This program is distributed in the hope that it will be useful,
|
643 |
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
644 |
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
645 |
+
GNU General Public License for more details.
|
646 |
+
|
647 |
+
You should have received a copy of the GNU General Public License
|
648 |
+
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
649 |
+
|
650 |
+
Also add information on how to contact you by electronic and paper mail.
|
651 |
+
|
652 |
+
If the program does terminal interaction, make it output a short
|
653 |
+
notice like this when it starts in an interactive mode:
|
654 |
+
|
655 |
+
<program> Copyright (C) <year> <name of author>
|
656 |
+
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
657 |
+
This is free software, and you are welcome to redistribute it
|
658 |
+
under certain conditions; type `show c' for details.
|
659 |
+
|
660 |
+
The hypothetical commands `show w' and `show c' should show the appropriate
|
661 |
+
parts of the General Public License. Of course, your program's commands
|
662 |
+
might be different; for a GUI interface, you would use an "about box".
|
663 |
+
|
664 |
+
You should also get your employer (if you work as a programmer) or school,
|
665 |
+
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
666 |
+
For more information on this, and how to apply and follow the GNU GPL, see
|
667 |
+
<https://www.gnu.org/licenses/>.
|
668 |
+
|
669 |
+
The GNU General Public License does not permit incorporating your program
|
670 |
+
into proprietary programs. If your program is a subroutine library, you
|
671 |
+
may consider it more useful to permit linking proprietary applications with
|
672 |
+
the library. If this is what you want to do, use the GNU Lesser General
|
673 |
+
Public License instead of this License. But first, please read
|
674 |
+
<https://www.gnu.org/licenses/why-not-lgpl.html>.
|
vendor/woocommerce/action-scheduler-job-framework/README.md
ADDED
@@ -0,0 +1,116 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Action Scheduler Job Framework
|
2 |
+
|
3 |
+
## Requirements
|
4 |
+
|
5 |
+
- PHP 7.0+
|
6 |
+
|
7 |
+
## Chained Jobs
|
8 |
+
|
9 |
+
A "chained job" is a kind of batched job that creates follow-up actions in a chain until a set of items has been processed.
|
10 |
+
|
11 |
+
Each "batch" in the job is a separate "scheduled action". Each batch is numbered and should be limited to process a set number of items.
|
12 |
+
|
13 |
+
### Methods
|
14 |
+
|
15 |
+
- `::handle_start()` - Runs before a job instance starts.
|
16 |
+
- `::handle_end()` - Runs after a job instance ends.
|
17 |
+
- `::get_items_for_batch()` - Gets a set of items for the batch to process.
|
18 |
+
- `::process_item()` - Processes a single item.
|
19 |
+
- `::get_name()` - Get the unique name/ID of the job.
|
20 |
+
- `::get_number_of_items_processed()` - Get the number of items that have been processed by the currently running instance of the job.
|
21 |
+
- `::is_running()` - Check if this job is currently running. Checks if there is any "start" or "batch" actions `pending` or `in-progress` for the job.
|
22 |
+
|
23 |
+
### Example:
|
24 |
+
|
25 |
+
```php
|
26 |
+
|
27 |
+
class GenerateProductFeed extends Automattic\WooCommerce\ActionSchedulerJobFramework\AbstractChainedJob {
|
28 |
+
|
29 |
+
use Automattic\WooCommerce\ActionSchedulerJobFramework\Utilities\BatchQueryOffset;
|
30 |
+
|
31 |
+
/**
|
32 |
+
* Runs before starting the job.
|
33 |
+
*/
|
34 |
+
protected function handle_start() {
|
35 |
+
// Optionally do something when starting the job.
|
36 |
+
}
|
37 |
+
|
38 |
+
/**
|
39 |
+
* Runs after the finishing the job.
|
40 |
+
*/
|
41 |
+
protected function handle_end() {
|
42 |
+
// Optionally do something when ending the job.
|
43 |
+
}
|
44 |
+
|
45 |
+
/**
|
46 |
+
* Get a set of items for the batch.
|
47 |
+
*
|
48 |
+
* NOTE: when using an OFFSET based query to retrieve items it's recommended to order by the item ID while
|
49 |
+
* ASCENDING. This is so that any newly added items will not disrupt the query offset.
|
50 |
+
*
|
51 |
+
* @param int $batch_number The batch number increments for each new batch in the job cycle.
|
52 |
+
* @param array $args The args for the job.
|
53 |
+
*
|
54 |
+
* @throws Exception On error. The failure will be logged by Action Scheduler and the job chain will stop.
|
55 |
+
*/
|
56 |
+
protected function get_items_for_batch( int $batch_number, array $args ): array {
|
57 |
+
$product_args = [
|
58 |
+
'fields' => 'ids',
|
59 |
+
'post_status' => 'publish',
|
60 |
+
'post_type' => [ 'product', 'product_variation' ],
|
61 |
+
'posts_per_page' => $this->get_batch_size(),
|
62 |
+
'offset' => $this->get_query_offset( $batch_number ),
|
63 |
+
'orderby' => 'ID',
|
64 |
+
'order' => 'ASC',
|
65 |
+
];
|
66 |
+
|
67 |
+
$query = new WP_Query( $product_args );
|
68 |
+
return $query->posts;
|
69 |
+
}
|
70 |
+
|
71 |
+
/**
|
72 |
+
* Process a single item.
|
73 |
+
*
|
74 |
+
* @param string|int|array $item A single item from the get_items_for_batch() method.
|
75 |
+
* @param array $args The args for the job.
|
76 |
+
*
|
77 |
+
* @throws Exception On error. The failure will be logged by Action Scheduler and the job chain will stop.
|
78 |
+
*/
|
79 |
+
protected function process_item( $item, array $args ) {
|
80 |
+
// Process each item here.
|
81 |
+
}
|
82 |
+
|
83 |
+
/**
|
84 |
+
* Get the name/slug of the job.
|
85 |
+
*
|
86 |
+
* @return string
|
87 |
+
*/
|
88 |
+
public function get_name(): string {
|
89 |
+
return 'generate_feed';
|
90 |
+
}
|
91 |
+
|
92 |
+
/**
|
93 |
+
* Get the name/slug of the plugin that owns the job.
|
94 |
+
*
|
95 |
+
* @return string
|
96 |
+
*/
|
97 |
+
public function get_plugin_name(): string {
|
98 |
+
return 'facebook_for_woocommerce';
|
99 |
+
}
|
100 |
+
|
101 |
+
}
|
102 |
+
|
103 |
+
|
104 |
+
add_action( 'init', function() {
|
105 |
+
$job = new GenerateProductFeed(
|
106 |
+
new \Automattic\WooCommerce\ActionSchedulerJobFramework\Proxies\ActionScheduler()
|
107 |
+
);
|
108 |
+
$job->init();
|
109 |
+
|
110 |
+
// Start the job if it's not already running
|
111 |
+
if ( ! $job->is_running() ) {
|
112 |
+
$job->queue_start();
|
113 |
+
}
|
114 |
+
});
|
115 |
+
|
116 |
+
```
|
vendor/woocommerce/action-scheduler-job-framework/phpcs.xml.dist
ADDED
@@ -0,0 +1,57 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
<ruleset name="WordPress Coding Standards">
|
3 |
+
<!-- See https://github.com/squizlabs/PHP_CodeSniffer/wiki/Annotated-ruleset.xml -->
|
4 |
+
<!-- See https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/blob/develop/WordPress-Core/ruleset.xml -->
|
5 |
+
|
6 |
+
<description>WooCommerce dev PHP_CodeSniffer ruleset.</description>
|
7 |
+
|
8 |
+
<!-- Exclude paths -->
|
9 |
+
<exclude-pattern>*/node_modules/*</exclude-pattern>
|
10 |
+
<exclude-pattern>*/vendor/*</exclude-pattern>
|
11 |
+
<exclude-pattern>bin/*</exclude-pattern>
|
12 |
+
|
13 |
+
<!-- Configs -->
|
14 |
+
<config name="minimum_supported_wp_version" value="4.7" />
|
15 |
+
<config name="testVersion" value="5.6-"/>
|
16 |
+
|
17 |
+
<!-- Rules -->
|
18 |
+
<rule ref="WooCommerce-Core" />
|
19 |
+
|
20 |
+
<rule ref="WordPress.WP.I18n">
|
21 |
+
<properties>
|
22 |
+
<property name="text_domain" type="array" value="action-scheduler-job-framework" />
|
23 |
+
</properties>
|
24 |
+
</rule>
|
25 |
+
|
26 |
+
<rule ref="PHPCompatibility">
|
27 |
+
<exclude-pattern>tests/</exclude-pattern>
|
28 |
+
</rule>
|
29 |
+
|
30 |
+
<rule ref="WordPress.Files.FileName.InvalidClassFileName">
|
31 |
+
<exclude-pattern>src/*</exclude-pattern>
|
32 |
+
<exclude-pattern>tests/*</exclude-pattern>
|
33 |
+
</rule>
|
34 |
+
|
35 |
+
<rule ref="WordPress.Files.FileName.NotHyphenatedLowercase">
|
36 |
+
<exclude-pattern>src/*</exclude-pattern>
|
37 |
+
</rule>
|
38 |
+
|
39 |
+
<rule ref="Generic.Arrays.DisallowShortArraySyntax.Found">
|
40 |
+
<exclude-pattern>src/*</exclude-pattern>
|
41 |
+
<exclude-pattern>tests/*</exclude-pattern>
|
42 |
+
</rule>
|
43 |
+
|
44 |
+
<rule ref="Generic.Commenting">
|
45 |
+
<exclude-pattern>tests/</exclude-pattern>
|
46 |
+
</rule>
|
47 |
+
<rule ref="Squiz.Commenting.FileComment.MissingPackageTag">
|
48 |
+
<exclude-pattern>src/</exclude-pattern>
|
49 |
+
<exclude-pattern>tests/</exclude-pattern>
|
50 |
+
</rule>
|
51 |
+
<rule ref="Squiz.Commenting.FileComment.Missing">
|
52 |
+
<exclude-pattern>src/</exclude-pattern>
|
53 |
+
<exclude-pattern>tests/</exclude-pattern>
|
54 |
+
</rule>
|
55 |
+
|
56 |
+
<arg name="basepath" value="."/>
|
57 |
+
</ruleset>
|
vendor/woocommerce/action-scheduler-job-framework/src/AbstractChainedJob.php
ADDED
@@ -0,0 +1,251 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
declare( strict_types=1 );
|
3 |
+
|
4 |
+
namespace Automattic\WooCommerce\ActionSchedulerJobFramework;
|
5 |
+
|
6 |
+
use ActionScheduler_Action;
|
7 |
+
use Automattic\WooCommerce\ActionSchedulerJobFramework\Utilities\BatchSize;
|
8 |
+
use Exception;
|
9 |
+
|
10 |
+
defined( 'ABSPATH' ) || exit;
|
11 |
+
|
12 |
+
/**
|
13 |
+
* Class AbstractChainedJob.
|
14 |
+
*
|
15 |
+
* A "chained job" is a kind of batched job that creates follow-up actions until all items in the job have been processed.
|
16 |
+
*
|
17 |
+
* Each "batch" in the job is a separate "scheduled action". Each batch is numbered and should be limited to process a
|
18 |
+
* set number of items.
|
19 |
+
*
|
20 |
+
* Only a single chained job can run at any one time.
|
21 |
+
*
|
22 |
+
* @since 1.0.0
|
23 |
+
*/
|
24 |
+
abstract class AbstractChainedJob extends AbstractJob implements ChainedJobInterface {
|
25 |
+
|
26 |
+
use BatchSize;
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Get a set of items for the batch.
|
30 |
+
*
|
31 |
+
* NOTE: when using an OFFSET based query to retrieve items it's recommended to order by the item ID while
|
32 |
+
* ASCENDING. This is so that any newly added items will not disrupt the query offset.
|
33 |
+
*
|
34 |
+
* @param int $batch_number The batch number increments for each new batch in the job cycle.
|
35 |
+
* @param array $args The args for the job.
|
36 |
+
*
|
37 |
+
* @throws Exception On error. The failure will be logged by Action Scheduler and the job chain will stop.
|
38 |
+
*/
|
39 |
+
abstract protected function get_items_for_batch( int $batch_number, array $args ): array;
|
40 |
+
|
41 |
+
/**
|
42 |
+
* Process a single item.
|
43 |
+
*
|
44 |
+
* @param string|int|array $item A single item from the get_items_for_batch() method.
|
45 |
+
* @param array $args The args for the job.
|
46 |
+
*
|
47 |
+
* @throws Exception On error. The failure will be logged by Action Scheduler and the job chain will stop.
|
48 |
+
*/
|
49 |
+
abstract protected function process_item( $item, array $args );
|
50 |
+
|
51 |
+
/**
|
52 |
+
* Called before starting the job.
|
53 |
+
*/
|
54 |
+
protected function handle_start() {
|
55 |
+
// Optionally override this method in child class.
|
56 |
+
}
|
57 |
+
|
58 |
+
/**
|
59 |
+
* Called after the finishing the job.
|
60 |
+
*/
|
61 |
+
protected function handle_end() {
|
62 |
+
// Optionally override this method in child class.
|
63 |
+
}
|
64 |
+
|
65 |
+
/**
|
66 |
+
* Init the job, register necessary WP actions.
|
67 |
+
*/
|
68 |
+
public function init() {
|
69 |
+
add_action( $this->get_action_full_name( self::CHAIN_START ), [ $this, 'handle_start_action' ] );
|
70 |
+
add_action( $this->get_action_full_name( self::CHAIN_BATCH ), [ $this, 'handle_batch_action' ], 10, 2 );
|
71 |
+
add_action( $this->get_action_full_name( self::CHAIN_END ), [ $this, 'handle_end_action' ] );
|
72 |
+
}
|
73 |
+
|
74 |
+
/**
|
75 |
+
* Queue the job to be started in the background.
|
76 |
+
*
|
77 |
+
* @param array $args The args for the job.
|
78 |
+
*/
|
79 |
+
public function queue_start( array $args = [] ) {
|
80 |
+
$this->schedule_immediate_action( self::CHAIN_START, [ $args ] );
|
81 |
+
}
|
82 |
+
|
83 |
+
/**
|
84 |
+
* Queue a batch to be processed immediately.
|
85 |
+
*
|
86 |
+
* @param int $batch_number The batch number for the new batch.
|
87 |
+
* @param array $args The args for the job.
|
88 |
+
*/
|
89 |
+
protected function queue_batch( int $batch_number, array $args ) {
|
90 |
+
$this->schedule_immediate_action( self::CHAIN_BATCH, [ $batch_number, $args ] );
|
91 |
+
}
|
92 |
+
|
93 |
+
/**
|
94 |
+
* Queue the job to be ended.
|
95 |
+
*
|
96 |
+
* Should be called once all items are processed.
|
97 |
+
*
|
98 |
+
* @param array $args The args for the job.
|
99 |
+
*/
|
100 |
+
protected function queue_end( array $args = [] ) {
|
101 |
+
$this->schedule_immediate_action( self::CHAIN_END, [ $args ] );
|
102 |
+
}
|
103 |
+
|
104 |
+
/**
|
105 |
+
* Handles job start action.
|
106 |
+
*
|
107 |
+
* @hooked {plugin_name}/jobs/{job_name}/chain_start
|
108 |
+
*
|
109 |
+
* @param array $args The args for the job.
|
110 |
+
*
|
111 |
+
* @throws Exception On error. The failure will be logged by Action Scheduler and the job chain will stop.
|
112 |
+
*/
|
113 |
+
public function handle_start_action( array $args ) {
|
114 |
+
// Prevent starting if a job already has scheduled batch actions
|
115 |
+
$batch_action_name = $this->get_action_full_name( self::CHAIN_BATCH );
|
116 |
+
if ( $this->action_scheduler->next_scheduled_action( $batch_action_name, null, $this->get_group_name() ) ) {
|
117 |
+
throw new Exception( 'This job is already running.' );
|
118 |
+
}
|
119 |
+
|
120 |
+
$this->handle_start();
|
121 |
+
$this->queue_batch( 1, $args );
|
122 |
+
}
|
123 |
+
|
124 |
+
/**
|
125 |
+
* Handle processing a chain batch.
|
126 |
+
*
|
127 |
+
* @hooked {plugin_name}/jobs/{job_name}/chain_batch
|
128 |
+
*
|
129 |
+
* @param int $batch_number The batch number for the new batch.
|
130 |
+
* @param array $args The args for the job.
|
131 |
+
*
|
132 |
+
* @throws Exception On error. The failure will be logged by Action Scheduler and the job chain will stop.
|
133 |
+
*/
|
134 |
+
public function handle_batch_action( int $batch_number, array $args ) {
|
135 |
+
$items = $this->get_items_for_batch( $batch_number, $args );
|
136 |
+
|
137 |
+
if ( empty( $items ) ) {
|
138 |
+
// No more items to process so end the job chain
|
139 |
+
$this->queue_end( $args );
|
140 |
+
} else {
|
141 |
+
$items = $this->filter_items_before_processing( $items );
|
142 |
+
|
143 |
+
foreach ( $items as $item ) {
|
144 |
+
$this->process_item( $item, $args );
|
145 |
+
}
|
146 |
+
|
147 |
+
// If there were items, queue another batch.
|
148 |
+
$this->queue_batch( $batch_number + 1, $args );
|
149 |
+
}
|
150 |
+
}
|
151 |
+
|
152 |
+
/**
|
153 |
+
* Filter-like function that runs before items in a batch are processed.
|
154 |
+
*
|
155 |
+
* This could be useful if the results from the initial batch query need to be filtered in an additional query.
|
156 |
+
*
|
157 |
+
* @param array $items
|
158 |
+
*
|
159 |
+
* @return array
|
160 |
+
*/
|
161 |
+
protected function filter_items_before_processing( array $items ): array {
|
162 |
+
return $items;
|
163 |
+
}
|
164 |
+
|
165 |
+
/**
|
166 |
+
* Handles job end action.
|
167 |
+
*
|
168 |
+
* @hooked {plugin_name}/jobs/{job_name}/chain_end
|
169 |
+
*
|
170 |
+
* @param array $args The args for the job.
|
171 |
+
*
|
172 |
+
* @throws Exception On error. The failure will be logged by Action Scheduler.
|
173 |
+
*/
|
174 |
+
public function handle_end_action( array $args ) {
|
175 |
+
$this->handle_end();
|
176 |
+
}
|
177 |
+
|
178 |
+
/**
|
179 |
+
* Check if this job is running.
|
180 |
+
*
|
181 |
+
* Checks if there is any "start" or "batch" actions pending or in-progress for this job.
|
182 |
+
*
|
183 |
+
* @return bool
|
184 |
+
*/
|
185 |
+
public function is_running(): bool {
|
186 |
+
$start_action = $this->get_action_full_name( self::CHAIN_START );
|
187 |
+
$batch_action = $this->get_action_full_name( self::CHAIN_BATCH );
|
188 |
+
|
189 |
+
if ( $this->action_scheduler->next_scheduled_action( $start_action, null, $this->get_group_name() ) ) {
|
190 |
+
return true;
|
191 |
+
}
|
192 |
+
if ( $this->action_scheduler->next_scheduled_action( $batch_action, null, $this->get_group_name() ) ) {
|
193 |
+
return true;
|
194 |
+
}
|
195 |
+
|
196 |
+
return false;
|
197 |
+
}
|
198 |
+
|
199 |
+
/**
|
200 |
+
* Get the number of items processed by the currently running job.
|
201 |
+
*
|
202 |
+
* @return int Returns the number of items processed. Will return zero if the job isn't running.
|
203 |
+
*/
|
204 |
+
public function get_number_of_items_processed(): int {
|
205 |
+
$batch_action_name = $this->get_action_full_name( self::CHAIN_BATCH );
|
206 |
+
|
207 |
+
$in_progress_actions = $this->action_scheduler->search(
|
208 |
+
[
|
209 |
+
'hook' => $batch_action_name,
|
210 |
+
'per_page' => 1,
|
211 |
+
'status' => $this->action_scheduler::STATUS_RUNNING,
|
212 |
+
]
|
213 |
+
);
|
214 |
+
|
215 |
+
if ( $in_progress_actions ) {
|
216 |
+
return $this->calculate_items_processed_from_batch_action( current( $in_progress_actions ) );
|
217 |
+
}
|
218 |
+
|
219 |
+
$pending_actions = $this->action_scheduler->search(
|
220 |
+
[
|
221 |
+
'hook' => $batch_action_name,
|
222 |
+
'per_page' => 1,
|
223 |
+
'status' => $this->action_scheduler::STATUS_PENDING,
|
224 |
+
]
|
225 |
+
);
|
226 |
+
|
227 |
+
if ( $pending_actions ) {
|
228 |
+
return $this->calculate_items_processed_from_batch_action( current( $pending_actions ) );
|
229 |
+
}
|
230 |
+
|
231 |
+
return 0;
|
232 |
+
}
|
233 |
+
|
234 |
+
/**
|
235 |
+
* Calculate the number of items processed by the job based on a given scheduled batch action.
|
236 |
+
*
|
237 |
+
* @param ActionScheduler_Action $action The most recent batch action.
|
238 |
+
*
|
239 |
+
* @return int
|
240 |
+
*/
|
241 |
+
protected function calculate_items_processed_from_batch_action( ActionScheduler_Action $action ): int {
|
242 |
+
$args = $action->get_args();
|
243 |
+
|
244 |
+
// The batch number is the first action arg, take 1 because it's not been fully processed yet
|
245 |
+
$number_of_batches_processed = $args[0] - 1;
|
246 |
+
|
247 |
+
// Use max() to not allow a negative value
|
248 |
+
return max( 0, $this->get_batch_size() * $number_of_batches_processed );
|
249 |
+
}
|
250 |
+
|
251 |
+
}
|
vendor/woocommerce/action-scheduler-job-framework/src/AbstractJob.php
ADDED
@@ -0,0 +1,76 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
declare( strict_types=1 );
|
3 |
+
|
4 |
+
namespace Automattic\WooCommerce\ActionSchedulerJobFramework;
|
5 |
+
|
6 |
+
use Automattic\WooCommerce\ActionSchedulerJobFramework\Proxies\ActionSchedulerInterface;
|
7 |
+
|
8 |
+
defined( 'ABSPATH' ) || exit;
|
9 |
+
|
10 |
+
/**
|
11 |
+
* AbstractJob class.
|
12 |
+
*
|
13 |
+
* Abstract class for jobs that use ActionScheduler.
|
14 |
+
*
|
15 |
+
* @since 1.0.0
|
16 |
+
*/
|
17 |
+
abstract class AbstractJob implements JobInterface {
|
18 |
+
|
19 |
+
/**
|
20 |
+
* @var ActionSchedulerInterface
|
21 |
+
*/
|
22 |
+
protected $action_scheduler;
|
23 |
+
|
24 |
+
/**
|
25 |
+
* AbstractJob constructor.
|
26 |
+
*
|
27 |
+
* @param ActionSchedulerInterface $action_scheduler
|
28 |
+
*/
|
29 |
+
public function __construct( ActionSchedulerInterface $action_scheduler ) {
|
30 |
+
$this->action_scheduler = $action_scheduler;
|
31 |
+
}
|
32 |
+
|
33 |
+
/**
|
34 |
+
* Get the base name for the job's scheduled actions.
|
35 |
+
*
|
36 |
+
* @return string
|
37 |
+
*/
|
38 |
+
protected function get_action_basename(): string {
|
39 |
+
return "{$this->get_plugin_name()}/jobs/{$this->get_name()}/";
|
40 |
+
}
|
41 |
+
|
42 |
+
/**
|
43 |
+
* Get a job action's full name.
|
44 |
+
*
|
45 |
+
* @param string $short_name The name of the action without the basename.
|
46 |
+
*
|
47 |
+
* @return string The full hook name with the basename prepended.
|
48 |
+
*/
|
49 |
+
protected function get_action_full_name( string $short_name ): string {
|
50 |
+
return $this->get_action_basename() . $short_name;
|
51 |
+
}
|
52 |
+
|
53 |
+
/**
|
54 |
+
* Schedule an immediate action for the job.
|
55 |
+
*
|
56 |
+
* @param string $action_short_name
|
57 |
+
* @param array $args
|
58 |
+
*/
|
59 |
+
protected function schedule_immediate_action( string $action_short_name, array $args ) {
|
60 |
+
$this->action_scheduler->schedule_immediate(
|
61 |
+
$this->get_action_full_name( $action_short_name ),
|
62 |
+
$args,
|
63 |
+
$this->get_group_name()
|
64 |
+
);
|
65 |
+
}
|
66 |
+
|
67 |
+
/**
|
68 |
+
* Get the action group name/slug for the job.
|
69 |
+
*
|
70 |
+
* @return string
|
71 |
+
*/
|
72 |
+
public function get_group_name(): string {
|
73 |
+
return '';
|
74 |
+
}
|
75 |
+
|
76 |
+
}
|
vendor/woocommerce/action-scheduler-job-framework/src/ChainedJobInterface.php
ADDED
@@ -0,0 +1,72 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
declare( strict_types=1 );
|
3 |
+
|
4 |
+
namespace Automattic\WooCommerce\ActionSchedulerJobFramework;
|
5 |
+
|
6 |
+
use Exception;
|
7 |
+
|
8 |
+
defined( 'ABSPATH' ) || exit;
|
9 |
+
|
10 |
+
/**
|
11 |
+
* Interface ChainedJobInterface.
|
12 |
+
*
|
13 |
+
* @see AbstractChainedJob
|
14 |
+
*
|
15 |
+
* @since 1.0.0
|
16 |
+
*/
|
17 |
+
interface ChainedJobInterface extends JobInterface {
|
18 |
+
|
19 |
+
const CHAIN_START = 'chain_start';
|
20 |
+
const CHAIN_BATCH = 'chain_batch';
|
21 |
+
const CHAIN_END = 'chain_end';
|
22 |
+
|
23 |
+
/**
|
24 |
+
* Queue the job to be started in the background.
|
25 |
+
*
|
26 |
+
* @param array $args Set args to be available during the job.
|
27 |
+
*/
|
28 |
+
public function queue_start( array $args = [] );
|
29 |
+
|
30 |
+
/**
|
31 |
+
* Handles job start action.
|
32 |
+
*
|
33 |
+
* @hooked {plugin_name}/jobs/{job_name}/chain_start
|
34 |
+
*
|
35 |
+
* @param array $args The args for the job.
|
36 |
+
*
|
37 |
+
* @throws Exception If an error occurs. Exceptions will be logged by Action Scheduler.
|
38 |
+
*/
|
39 |
+
public function handle_start_action( array $args );
|
40 |
+
|
41 |
+
/**
|
42 |
+
* Handles job process batch action.
|
43 |
+
*
|
44 |
+
* @hooked {plugin_name}/jobs/{job_name}/chain_batch
|
45 |
+
*
|
46 |
+
* @param int $batch_number The batch number for the new batch.
|
47 |
+
* @param array $args The args for the job.
|
48 |
+
*
|
49 |
+
* @throws Exception If an error occurs. Exceptions will be logged by Action Scheduler.
|
50 |
+
*/
|
51 |
+
public function handle_batch_action( int $batch_number, array $args );
|
52 |
+
|
53 |
+
/**
|
54 |
+
* Handles job end action.
|
55 |
+
*
|
56 |
+
* @hooked {plugin_name}/jobs/{job_name}/chain_end
|
57 |
+
*
|
58 |
+
* @param array $args The args for the job.
|
59 |
+
*
|
60 |
+
* @throws Exception If an error occurs. Exceptions will be logged by Action Scheduler.
|
61 |
+
*/
|
62 |
+
public function handle_end_action( array $args );
|
63 |
+
|
64 |
+
/**
|
65 |
+
* Get the number of items processed by the currently running job.
|
66 |
+
*
|
67 |
+
* @return int Returns the number of items processed. Will return zero if the job isn't running.
|
68 |
+
*/
|
69 |
+
public function get_number_of_items_processed(): int;
|
70 |
+
|
71 |
+
|
72 |
+
}
|
vendor/woocommerce/action-scheduler-job-framework/src/JobInterface.php
ADDED
@@ -0,0 +1,48 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
declare( strict_types=1 );
|
3 |
+
|
4 |
+
namespace Automattic\WooCommerce\ActionSchedulerJobFramework;
|
5 |
+
|
6 |
+
defined( 'ABSPATH' ) || exit;
|
7 |
+
|
8 |
+
/**
|
9 |
+
* Interface JobInterface.
|
10 |
+
*
|
11 |
+
* @since 1.0.0
|
12 |
+
*/
|
13 |
+
interface JobInterface {
|
14 |
+
|
15 |
+
/**
|
16 |
+
* Init the job, register necessary WP actions.
|
17 |
+
*/
|
18 |
+
public function init();
|
19 |
+
|
20 |
+
/**
|
21 |
+
* Get the name/slug of the job.
|
22 |
+
*
|
23 |
+
* @return string
|
24 |
+
*/
|
25 |
+
public function get_name(): string;
|
26 |
+
|
27 |
+
/**
|
28 |
+
* Get the name/slug of the plugin that owns the job.
|
29 |
+
*
|
30 |
+
* @return string
|
31 |
+
*/
|
32 |
+
public function get_plugin_name(): string;
|
33 |
+
|
34 |
+
/**
|
35 |
+
* Get the action group name/slug for the job.
|
36 |
+
*
|
37 |
+
* @return string
|
38 |
+
*/
|
39 |
+
public function get_group_name(): string;
|
40 |
+
|
41 |
+
/**
|
42 |
+
* Check if this job is running.
|
43 |
+
*
|
44 |
+
* @return bool
|
45 |
+
*/
|
46 |
+
public function is_running(): bool;
|
47 |
+
|
48 |
+
}
|
vendor/woocommerce/action-scheduler-job-framework/src/Proxies/ActionScheduler.php
ADDED
@@ -0,0 +1,97 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
declare( strict_types=1 );
|
3 |
+
|
4 |
+
namespace Automattic\WooCommerce\ActionSchedulerJobFramework\Proxies;
|
5 |
+
|
6 |
+
defined( 'ABSPATH' ) || exit;
|
7 |
+
|
8 |
+
/**
|
9 |
+
* Class ActionScheduler
|
10 |
+
*
|
11 |
+
* Proxy for ActionScheduler's public functions.
|
12 |
+
*
|
13 |
+
* @since 1.0.0
|
14 |
+
*/
|
15 |
+
class ActionScheduler implements ActionSchedulerInterface {
|
16 |
+
|
17 |
+
/**
|
18 |
+
* Schedule an action to run once at some time in the future
|
19 |
+
*
|
20 |
+
* @param int $timestamp When the job will run.
|
21 |
+
* @param string $hook The hook to trigger.
|
22 |
+
* @param array $args Arguments to pass when the hook triggers.
|
23 |
+
* @param string $group The group to assign this job to.
|
24 |
+
*
|
25 |
+
* @return string The action ID.
|
26 |
+
*/
|
27 |
+
public function schedule_single( $timestamp, $hook, $args = [], string $group = '' ) {
|
28 |
+
return as_schedule_single_action( $timestamp, $hook, $args, $group );
|
29 |
+
}
|
30 |
+
|
31 |
+
/**
|
32 |
+
* Schedule an action to run now i.e. in the next available batch.
|
33 |
+
*
|
34 |
+
* This differs from async actions by having a scheduled time rather than being set for '0000-00-00 00:00:00'.
|
35 |
+
* We could use an async action instead but they can't be viewed easily in the admin area
|
36 |
+
* because the table is sorted by schedule date.
|
37 |
+
*
|
38 |
+
* @param string $hook The hook to trigger.
|
39 |
+
* @param array $args Arguments to pass when the hook triggers.
|
40 |
+
* @param string $group The group to assign this job to.
|
41 |
+
*
|
42 |
+
* @return string The action ID.
|
43 |
+
*/
|
44 |
+
public function schedule_immediate( string $hook, $args = [], string $group = '' ) {
|
45 |
+
return as_schedule_single_action( gmdate( 'U' ) - 1, $hook, $args, $group );
|
46 |
+
}
|
47 |
+
|
48 |
+
/**
|
49 |
+
* Check if there is an existing action in the queue with a given hook, args and group combination.
|
50 |
+
*
|
51 |
+
* An action in the queue could be pending, in-progress or async. If the is pending for a time in
|
52 |
+
* future, its scheduled date will be returned as a timestamp. If it is currently being run, or an
|
53 |
+
* async action sitting in the queue waiting to be processed, in which case boolean true will be
|
54 |
+
* returned. Or there may be no async, in-progress or pending action for this hook, in which case,
|
55 |
+
* boolean false will be the return value.
|
56 |
+
*
|
57 |
+
* @param string $hook
|
58 |
+
* @param array $args
|
59 |
+
* @param string $group The group to check for jobs.
|
60 |
+
*
|
61 |
+
* @return int|bool The timestamp for the next occurrence of a pending scheduled action, true for an async or in-progress action or false if there is no matching action.
|
62 |
+
*/
|
63 |
+
public function next_scheduled_action( $hook, $args = null, string $group = '' ) {
|
64 |
+
return as_next_scheduled_action( $hook, $args, $group );
|
65 |
+
}
|
66 |
+
|
67 |
+
/**
|
68 |
+
* Search for scheduled actions.
|
69 |
+
*
|
70 |
+
* @param array $args See as_get_scheduled_actions() for possible arguments.
|
71 |
+
* @param string $return_format OBJECT, ARRAY_A, or ids.
|
72 |
+
* @param string $group The group to search for jobs.
|
73 |
+
*
|
74 |
+
* @return array
|
75 |
+
*/
|
76 |
+
public function search( $args = [], $return_format = OBJECT, string $group = '' ) {
|
77 |
+
$args['group'] = $group;
|
78 |
+
|
79 |
+
return as_get_scheduled_actions( $args, $return_format );
|
80 |
+
}
|
81 |
+
|
82 |
+
/**
|
83 |
+
* Cancel the next scheduled instance of an action with a matching hook (and optionally matching args and group).
|
84 |
+
*
|
85 |
+
* Any recurring actions with a matching hook should also be cancelled, not just the next scheduled action.
|
86 |
+
*
|
87 |
+
* @param string $hook The hook that the job will trigger.
|
88 |
+
* @param array $args Args that would have been passed to the job.
|
89 |
+
* @param string $group The group the job is assigned to.
|
90 |
+
*
|
91 |
+
* @return string|null The scheduled action ID if a scheduled action was found, or null if no matching action found.
|
92 |
+
*/
|
93 |
+
public function cancel( string $hook, $args = [], string $group = '' ) {
|
94 |
+
return as_unschedule_action( $hook, $args, $group );
|
95 |
+
}
|
96 |
+
|
97 |
+
}
|
vendor/woocommerce/action-scheduler-job-framework/src/Proxies/ActionSchedulerInterface.php
ADDED
@@ -0,0 +1,89 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
declare( strict_types=1 );
|
3 |
+
|
4 |
+
namespace Automattic\WooCommerce\ActionSchedulerJobFramework\Proxies;
|
5 |
+
|
6 |
+
/**
|
7 |
+
* Interface ActionSchedulerInterface
|
8 |
+
*
|
9 |
+
* Proxy for ActionScheduler's public functions.
|
10 |
+
*
|
11 |
+
* @since 1.0.0
|
12 |
+
*/
|
13 |
+
interface ActionSchedulerInterface {
|
14 |
+
|
15 |
+
const STATUS_COMPLETE = 'complete';
|
16 |
+
const STATUS_PENDING = 'pending';
|
17 |
+
const STATUS_RUNNING = 'in-progress';
|
18 |
+
const STATUS_FAILED = 'failed';
|
19 |
+
const STATUS_CANCELED = 'canceled';
|
20 |
+
|
21 |
+
/**
|
22 |
+
* Schedule an action to run once at some time in the future
|
23 |
+
*
|
24 |
+
* @param int $timestamp When the job will run.
|
25 |
+
* @param string $hook The hook to trigger.
|
26 |
+
* @param array $args Arguments to pass when the hook triggers.
|
27 |
+
* @param string $group The group to assign this job to.
|
28 |
+
*
|
29 |
+
* @return string The action ID.
|
30 |
+
*/
|
31 |
+
public function schedule_single( $timestamp, $hook, $args = [], string $group = '' );
|
32 |
+
|
33 |
+
/**
|
34 |
+
* Schedule an action to run now i.e. in the next available batch.
|
35 |
+
*
|
36 |
+
* This differs from async actions by having a scheduled time rather than being set for '0000-00-00 00:00:00'.
|
37 |
+
* We could use an async action instead but they can't be viewed easily in the admin area
|
38 |
+
* because the table is sorted by schedule date.
|
39 |
+
*
|
40 |
+
* @param string $hook The hook to trigger.
|
41 |
+
* @param array $args Arguments to pass when the hook triggers.
|
42 |
+
* @param string $group The group to assign this job to.
|
43 |
+
*
|
44 |
+
* @return string The action ID.
|
45 |
+
*/
|
46 |
+
public function schedule_immediate( string $hook, $args = [], string $group = '' );
|
47 |
+
|
48 |
+
/**
|
49 |
+
* Check if there is an existing action in the queue with a given hook, args and group combination.
|
50 |
+
*
|
51 |
+
* An action in the queue could be pending, in-progress or async. If the is pending for a time in
|
52 |
+
* future, its scheduled date will be returned as a timestamp. If it is currently being run, or an
|
53 |
+
* async action sitting in the queue waiting to be processed, in which case boolean true will be
|
54 |
+
* returned. Or there may be no async, in-progress or pending action for this hook, in which case,
|
55 |
+
* boolean false will be the return value.
|
56 |
+
*
|
57 |
+
* @param string $hook
|
58 |
+
* @param array $args
|
59 |
+
* @param string $group The group to check for jobs.
|
60 |
+
*
|
61 |
+
* @return int|bool The timestamp for the next occurrence of a pending scheduled action, true for an async or in-progress action or false if there is no matching action.
|
62 |
+
*/
|
63 |
+
public function next_scheduled_action( $hook, $args = null, string $group = '' );
|
64 |
+
|
65 |
+
/**
|
66 |
+
* Search for scheduled actions.
|
67 |
+
*
|
68 |
+
* @param array $args See as_get_scheduled_actions() for possible arguments.
|
69 |
+
* @param string $return_format OBJECT, ARRAY_A, or ids.
|
70 |
+
* @param string $group The group to search for jobs.
|
71 |
+
*
|
72 |
+
* @return array
|
73 |
+
*/
|
74 |
+
public function search( $args = [], $return_format = OBJECT, string $group = '' );
|
75 |
+
|
76 |
+
/**
|
77 |
+
* Cancel the next scheduled instance of an action with a matching hook (and optionally matching args and group).
|
78 |
+
*
|
79 |
+
* Any recurring actions with a matching hook should also be cancelled, not just the next scheduled action.
|
80 |
+
*
|
81 |
+
* @param string $hook The hook that the job will trigger.
|
82 |
+
* @param array $args Args that would have been passed to the job.
|
83 |
+
* @param string $group The group the job is assigned to.
|
84 |
+
*
|
85 |
+
* @return string|null The scheduled action ID if a scheduled action was found, or null if no matching action found.
|
86 |
+
*/
|
87 |
+
public function cancel( string $hook, $args = [], string $group = '' );
|
88 |
+
|
89 |
+
}
|
vendor/woocommerce/action-scheduler-job-framework/src/Utilities/BatchQueryOffset.php
ADDED
@@ -0,0 +1,26 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
declare( strict_types=1 );
|
3 |
+
|
4 |
+
namespace Automattic\WooCommerce\ActionSchedulerJobFramework\Utilities;
|
5 |
+
|
6 |
+
/**
|
7 |
+
* Trait BatchQueryOffset
|
8 |
+
*
|
9 |
+
* @since 1.0.0
|
10 |
+
*/
|
11 |
+
trait BatchQueryOffset {
|
12 |
+
|
13 |
+
use BatchSize;
|
14 |
+
|
15 |
+
/**
|
16 |
+
* Get the query offset based on a given batch number and the specified batch size.
|
17 |
+
*
|
18 |
+
* @param int $batch_number
|
19 |
+
*
|
20 |
+
* @return int
|
21 |
+
*/
|
22 |
+
protected function get_query_offset( int $batch_number ): int {
|
23 |
+
return $this->get_batch_size() * ( $batch_number - 1 );
|
24 |
+
}
|
25 |
+
|
26 |
+
}
|
vendor/woocommerce/action-scheduler-job-framework/src/Utilities/BatchSize.php
ADDED
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
declare( strict_types=1 );
|
3 |
+
|
4 |
+
namespace Automattic\WooCommerce\ActionSchedulerJobFramework\Utilities;
|
5 |
+
|
6 |
+
/**
|
7 |
+
* Trait BatchSize
|
8 |
+
*
|
9 |
+
* @since 1.0.0
|
10 |
+
*/
|
11 |
+
trait BatchSize {
|
12 |
+
|
13 |
+
/**
|
14 |
+
* Get the job's batch size.
|
15 |
+
*
|
16 |
+
* @return int
|
17 |
+
*/
|
18 |
+
protected function get_batch_size(): int {
|
19 |
+
return 10;
|
20 |
+
}
|
21 |
+
|
22 |
+
}
|
webpack.config.js
ADDED
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
// Load the default @wordpress/scripts config object
|
2 |
+
const defaultConfig = require( '@wordpress/scripts/config/webpack.config' );
|
3 |
+
|
4 |
+
// Legacy jQuery UI powered admin files
|
5 |
+
const jQueryUIAdminFileNames = [
|
6 |
+
'google-product-category-fields',
|
7 |
+
'infobanner',
|
8 |
+
'metabox',
|
9 |
+
'modal',
|
10 |
+
'orders',
|
11 |
+
'product-categories',
|
12 |
+
'product-sets-admin',
|
13 |
+
'products-admin',
|
14 |
+
'settings-commerce',
|
15 |
+
'settings-sync',
|
16 |
+
];
|
17 |
+
|
18 |
+
const jQueryUIAdminFileEntries = {};
|
19 |
+
|
20 |
+
jQueryUIAdminFileNames.forEach( ( name ) => {
|
21 |
+
jQueryUIAdminFileEntries[ `admin/${ name }` ] = `./assets/js/admin/${ name }.js`;
|
22 |
+
} );
|
23 |
+
|
24 |
+
module.exports = {
|
25 |
+
...defaultConfig,
|
26 |
+
entry: {
|
27 |
+
// Use admin/index.js for any new React-powered UI
|
28 |
+
'admin/index': './assets/js/admin/index.js',
|
29 |
+
...jQueryUIAdminFileEntries,
|
30 |
+
},
|
31 |
+
output: {
|
32 |
+
filename: '[name].js',
|
33 |
+
path: __dirname + '/assets/build',
|
34 |
+
},
|
35 |
+
};
|