├── .github └── ISSUE_TEMPLATE │ ├── bug-report.yml │ └── config.yml ├── Block ├── Adminhtml │ ├── Info.php │ ├── Setup.php │ └── System │ │ └── Config │ │ ├── CategoryFeed.php │ │ └── ProductFeed.php └── Pixel │ ├── AddToCart.php │ ├── Common.php │ ├── Head.php │ ├── InitiateCheckout.php │ ├── Purchase.php │ ├── Search.php │ ├── ViewCategory.php │ └── ViewContent.php ├── CODEOFCONDUCT.md ├── CONTRIBUTING.md ├── Controller ├── Adminhtml │ ├── Ajax │ │ ├── AbstractAjax.php │ │ ├── CategoryUpload.php │ │ ├── Fbaamsettings.php │ │ ├── Fbcategorypush.php │ │ ├── Fbdeleteasset.php │ │ ├── Fbfeedpush.php │ │ ├── Fbpixel.php │ │ ├── Fbprofiles.php │ │ ├── Fbtoken.php │ │ └── ProductFeedUpload.php │ ├── Info │ │ └── Index.php │ └── Setup │ │ └── Index.php └── Pixel │ └── ProductInfoForAddToCart.php ├── Cron ├── AAMSettingsCron.php └── CategorySyncCron.php ├── Helper ├── AAMFieldsExtractorHelper.php ├── AAMSettingsFields.php ├── EventIdGenerator.php ├── FBEHelper.php ├── HttpClient.php ├── LogOrganization.php ├── MagentoDataHelper.php ├── ServerEventFactory.php └── ServerSideHelper.php ├── LICENSE ├── Logger ├── Handler.php └── Logger.php ├── Model ├── Config.php ├── Config │ ├── ProductAttributes.php │ └── Source │ │ └── Product │ │ ├── AgeGroup.php │ │ ├── Assembly.php │ │ ├── DecorStyle.php │ │ ├── Gender.php │ │ ├── GoogleProductCategory.php │ │ └── Pattern.php ├── Feed │ ├── CategoryCollection.php │ └── EnhancedCatalogHelper.php ├── Product │ └── Feed │ │ ├── Builder.php │ │ ├── Builder │ │ ├── Inventory.php │ │ └── Tools.php │ │ ├── Method │ │ └── BatchApi.php │ │ ├── ProductRetriever │ │ ├── Configurable.php │ │ └── Simple.php │ │ ├── ProductRetrieverInterface.php │ │ └── Uploader.php ├── ResourceModel │ ├── Config.php │ └── Config │ │ └── Collection.php └── System │ └── Config.php ├── Observer ├── AddToCart.php ├── InitiateCheckout.php ├── ProcessCategoryAfterDeleteEventObserver.php ├── ProcessCategoryAfterSaveEventObserver.php ├── ProcessProductAfterDeleteEventObserver.php ├── ProcessProductAfterSaveEventObserver.php ├── Purchase.php ├── Search.php ├── ViewCategory.php └── ViewContent.php ├── Plugin └── CAPIEventsModifierPlugin.php ├── README.md ├── Setup ├── InstallSchema.php ├── Uninstall.php └── UpgradeData.php ├── Test ├── Mftf │ ├── ActionGroup │ │ ├── FillCustomerInformationActionGroup.xml │ │ └── SearchPixelEventActionGroup.xml │ ├── Data │ │ ├── CategoryData.xml │ │ ├── CustomAttributeData.xml │ │ ├── CustomerData.xml │ │ ├── PluginInfoData.xml │ │ ├── ProductData.xml │ │ ├── ProductExtensionAttributeData.xml │ │ ├── SearchPixelEventData.xml │ │ └── StockItemData.xml │ ├── Metadata │ │ ├── CategoryMeta.xml │ │ ├── CustomAttributeMeta.xml │ │ ├── ProductExtensionAttributeMeta.xml │ │ ├── ProductMeta.xml │ │ └── StockItemMeta.xml │ └── Test │ │ ├── AddToCartPixelEventCreatedTest.xml │ │ ├── InitiateCheckoutPixelEventCreatedTest.xml │ │ ├── PurchasePixelEventCreatedTest.xml │ │ ├── SearchPixelEventCreatedTest.xml │ │ ├── ViewCategoryPixelEventCreatedTest.xml │ │ └── ViewContentPixelEventCreatedTest.xml └── Unit │ ├── Block │ └── Pixel │ │ └── HeadTest.php │ ├── Controller │ └── Adminhtml │ │ └── Ajax │ │ ├── FbaamsettingsTest.php │ │ ├── FbdeleteassetTest.php │ │ ├── FbfeedpushTest.php │ │ ├── FbpixelTest.php │ │ ├── FbprofilesTest.php │ │ └── FbtokenTest.php │ ├── Cron │ ├── AAMSettingsCronTest.php │ └── CategorySyncCronTest.php │ ├── Helper │ ├── AAMFieldsExtractorHelperTest.php │ ├── EventIdGeneratorTest.php │ ├── FBEHelperTest.php │ ├── ServerEventFactoryTest.php │ └── ServerSideHelperTest.php │ └── Observer │ ├── AddToCartTest.php │ ├── CommonTest.php │ ├── InitiateCheckoutTest.php │ ├── ProcessCategoryAfterDeleteEventObserverTest.php │ ├── ProcessCategoryAfterSaveEventObserverTest.php │ ├── ProcessProductAfterDeleteEventObserverTest.php │ ├── ProcessProductAfterSaveEventObserverTest.php │ ├── PurchaseTest.php │ ├── SearchTest.php │ ├── ViewCategoryTest.php │ └── ViewContentTest.php ├── composer.json ├── etc ├── acl.xml ├── adminhtml │ ├── events.xml │ ├── menu.xml │ ├── routes.xml │ └── system.xml ├── config.xml ├── crontab.xml ├── csp_whitelist.xml ├── di.xml ├── frontend │ ├── events.xml │ └── routes.xml └── module.xml ├── install-facebook-business-extension.sh ├── registration.php ├── tests ├── docker-compose.yml ├── docker-installation-instructions.md └── env └── view ├── adminhtml ├── layout │ ├── fbeadmin_info_index.xml │ └── fbeadmin_setup_index.xml ├── templates │ ├── info.phtml │ ├── setup.phtml │ └── system │ │ └── config │ │ ├── category_feed.phtml │ │ └── product_feed.phtml ├── ui_component │ └── category_form.xml └── web │ ├── css │ ├── fbe.css │ └── images │ │ ├── ads.png │ │ ├── bar-chart.png │ │ ├── down-arrow.png │ │ ├── facebook-icon.png │ │ ├── group.png │ │ ├── setup-success.png │ │ ├── shopping.png │ │ ├── small-store.png │ │ └── up-arrow.png │ └── js │ ├── fbe_allinone.js │ └── lib │ ├── IEOverlay.js │ ├── Modal.js │ ├── compile_fbe_allinone.sh │ ├── fbe.js │ ├── react-dom.js │ ├── react.js │ └── utils.js └── frontend ├── layout ├── catalog_category_view.xml ├── catalog_product_view.xml ├── catalogsearch_result_index.xml ├── checkout_index_index.xml ├── checkout_onepage_success.xml └── default.xml └── templates └── pixel ├── add_to_cart.phtml ├── head.phtml ├── initiate_checkout.phtml ├── purchase.phtml ├── search.phtml ├── view_category.phtml └── view_content.phtml /.github/ISSUE_TEMPLATE/bug-report.yml: -------------------------------------------------------------------------------- 1 | name: Bug Report 2 | description: File a bug report / issue 3 | title: "[Bug]: " 4 | labels: [bug, triage] 5 | body: 6 | - type: markdown 7 | attributes: 8 | value: | 9 | Thanks for taking the time to fill out this bug report! 10 | - type: input 11 | id: contact 12 | attributes: 13 | label: Contact Details 14 | description: How can we get in touch with you if we need more info? 15 | placeholder: ex. email@example.com 16 | validations: 17 | required: false 18 | - type: textarea 19 | id: what-happened 20 | attributes: 21 | label: What happened? 22 | description: Also tell us, what did you expect to happen? 23 | placeholder: Tell us what you see! 24 | validations: 25 | required: true 26 | - type: input 27 | id: magento_version 28 | attributes: 29 | label: Magento Version 30 | description: What version of the Magento software are you running? 31 | validations: 32 | required: true 33 | - type: input 34 | id: plugin_version 35 | attributes: 36 | label: Plugin Version 37 | description: What version of the plugin are you running? 38 | validations: 39 | required: true 40 | - type: textarea 41 | id: logs 42 | attributes: 43 | label: Relevant log output 44 | description: Please copy and paste any relevant log output. Use info tab page for logs (for version 1.4.3 onwards). 45 | render: shell 46 | - type: checkboxes 47 | id: terms 48 | attributes: 49 | label: Code of Conduct 50 | description: By submitting this issue, you agree to follow our [Code of Conduct](https://opensource.fb.com/code-of-conduct/) that we expect project participants to adhere to. 51 | options: 52 | - label: I agree to follow this project's Code of Conduct 53 | required: true 54 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: Bug Report With Sensitive Information 4 | url: https://www.facebook.com/help/contact/224834796277182 5 | about: Please report issues here in case you want to provide sensitive information, like Pixel ID and logs, that will help us better understand the context. 6 | -------------------------------------------------------------------------------- /Block/Adminhtml/Setup.php: -------------------------------------------------------------------------------- 1 | fbeHelper = $fbeHelper; 28 | parent::__construct($context, $data); 29 | } 30 | 31 | /** 32 | * @return mixed 33 | */ 34 | public function getPixelAjaxRoute() 35 | { 36 | return $this->fbeHelper->getUrl('fbeadmin/ajax/fbpixel'); 37 | } 38 | 39 | /** 40 | * @return mixed 41 | */ 42 | public function getAccessTokenAjaxRoute() 43 | { 44 | return $this->fbeHelper->getUrl('fbeadmin/ajax/fbtoken'); 45 | } 46 | 47 | /** 48 | * @return mixed 49 | */ 50 | public function getProfilesAjaxRoute() 51 | { 52 | return $this->fbeHelper->getUrl('fbeadmin/ajax/fbprofiles'); 53 | } 54 | 55 | /** 56 | * @return mixed 57 | */ 58 | public function getAAMSettingsRoute() 59 | { 60 | return $this->fbeHelper->getUrl('fbeadmin/ajax/fbaamsettings'); 61 | } 62 | 63 | /** 64 | * @return string|null 65 | */ 66 | public function fetchPixelId() 67 | { 68 | return $this->fbeHelper->getConfigValue('fbpixel/id'); 69 | } 70 | 71 | /** 72 | * @return string|null 73 | * @throws \Magento\Framework\Exception\NoSuchEntityException 74 | */ 75 | public function getExternalBusinessId() 76 | { 77 | return $this->fbeHelper->getFBEExternalBusinessId(); 78 | } 79 | 80 | /** 81 | * @return mixed 82 | */ 83 | public function getFeedPushAjaxRoute() 84 | { 85 | return $this->fbeHelper->getUrl('fbeadmin/ajax/fbfeedpush'); 86 | } 87 | 88 | /** 89 | * @return mixed 90 | */ 91 | public function getDeleteAssetIdsAjaxRoute() 92 | { 93 | return $this->fbeHelper->getUrl('fbeadmin/ajax/fbdeleteasset'); 94 | } 95 | 96 | /** 97 | * @return mixed 98 | * @throws \Magento\Framework\Exception\NoSuchEntityException 99 | */ 100 | public function getCurrencyCode() 101 | { 102 | return $this->fbeHelper->getStoreCurrencyCode(); 103 | } 104 | 105 | /** 106 | * @return string 107 | */ 108 | public function isFBEInstalled() 109 | { 110 | return $this->fbeHelper->isFBEInstalled(); 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /Block/Adminhtml/System/Config/CategoryFeed.php: -------------------------------------------------------------------------------- 1 | unsScope()->unsCanUseWebsiteValue()->unsCanUseDefaultValue(); 28 | return parent::render($element); 29 | } 30 | 31 | /** 32 | * @todo move to helper 33 | * @return string 34 | */ 35 | public function getAjaxUrl() 36 | { 37 | return $this->getUrl('fbeadmin/ajax/categoryUpload'); 38 | } 39 | 40 | /** 41 | * @param AbstractElement $element 42 | * @return string 43 | */ 44 | protected function _getElementHtml(AbstractElement $element) 45 | { 46 | return $this->_toHtml(); 47 | } 48 | 49 | /** 50 | * @return string 51 | * @throws \Magento\Framework\Exception\LocalizedException 52 | */ 53 | public function getButtonHtml() 54 | { 55 | /** @var Button $button */ 56 | $button = $this->getLayout()->createBlock(Button::class); 57 | return $button->setData(['id' => 'fb_category_upload_btn', 'label' => __('Upload to Facebook')]) 58 | ->toHtml(); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /Block/Adminhtml/System/Config/ProductFeed.php: -------------------------------------------------------------------------------- 1 | unsScope()->unsCanUseWebsiteValue()->unsCanUseDefaultValue(); 28 | return parent::render($element); 29 | } 30 | 31 | /** 32 | * @todo move to helper 33 | * @return string 34 | */ 35 | public function getAjaxUrl() 36 | { 37 | return $this->getUrl('fbeadmin/ajax/productFeedUpload'); 38 | } 39 | 40 | /** 41 | * @param AbstractElement $element 42 | * @return string 43 | */ 44 | protected function _getElementHtml(AbstractElement $element) 45 | { 46 | return $this->_toHtml(); 47 | } 48 | 49 | /** 50 | * @return string 51 | * @throws \Magento\Framework\Exception\LocalizedException 52 | */ 53 | public function getButtonHtml() 54 | { 55 | /** @var Button $button */ 56 | $button = $this->getLayout()->createBlock(Button::class); 57 | return $button->setData(['id' => 'fb_feed_upload_btn', 'label' => __('Upload to Facebook')]) 58 | ->toHtml(); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /Block/Pixel/AddToCart.php: -------------------------------------------------------------------------------- 1 | fbeHelper->getBaseUrl()); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Block/Pixel/Head.php: -------------------------------------------------------------------------------- 1 | aamFieldsExtractorHelper = $aamFieldsExtractorHelper; 44 | } 45 | 46 | /** 47 | * Returns the user data that will be added in the pixel init code 48 | * @return string 49 | */ 50 | public function getPixelInitCode() 51 | { 52 | $userDataArray = $this->aamFieldsExtractorHelper->getNormalizedUserData(); 53 | 54 | if ($userDataArray) { 55 | return json_encode(array_filter($userDataArray), JSON_PRETTY_PRINT | JSON_FORCE_OBJECT); 56 | } 57 | return '{}'; 58 | } 59 | 60 | /** 61 | * Create JS code with the data processing options if required 62 | * To learn about this options in Meta Pixel, read: 63 | * https://developers.facebook.com/docs/marketing-apis/data-processing-options 64 | * @return string 65 | */ 66 | public function getDataProcessingOptionsJSCode() 67 | { 68 | return ''; 69 | } 70 | 71 | /** 72 | * Create the data processing options passed in the Pixel image tag 73 | * Read about this options in: 74 | * https://developers.facebook.com/docs/marketing-apis/data-processing-options 75 | * @return string 76 | */ 77 | public function getDataProcessingOptionsImgTag() 78 | { 79 | return ''; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /Block/Pixel/InitiateCheckout.php: -------------------------------------------------------------------------------- 1 | fbeHelper->getObject(\Magento\Checkout\Model\Cart::class); 17 | $items = $cart->getQuote()->getAllVisibleItems(); 18 | foreach ($items as $item) { 19 | $product = $item->getProduct(); 20 | $productIds[] = $product->getId(); 21 | } 22 | return $this->arrayToCommaSeparatedStringValues($productIds); 23 | } 24 | 25 | public function getValue() 26 | { 27 | $cart = $this->fbeHelper->getObject(\Magento\Checkout\Model\Cart::class); 28 | if (!$cart || !$cart->getQuote()) { 29 | return null; 30 | } 31 | $subtotal = $cart->getQuote()->getSubtotal(); 32 | if ($subtotal) { 33 | $priceHelper = $this->fbeHelper->getObject(\Magento\Framework\Pricing\Helper\Data::class); 34 | return $priceHelper->currency($subtotal, false, false); 35 | } else { 36 | return null; 37 | } 38 | } 39 | 40 | /** 41 | * @return string 42 | */ 43 | public function getContents() 44 | { 45 | $cart = $this->fbeHelper->getObject(\Magento\Checkout\Model\Cart::class); 46 | if (!$cart || !$cart->getQuote()) { 47 | return ''; 48 | } 49 | $contents = []; 50 | $items = $cart->getQuote()->getAllVisibleItems(); 51 | $priceHelper = $this->objectManager->get(\Magento\Framework\Pricing\Helper\Data::class); 52 | foreach ($items as $item) { 53 | $product = $item->getProduct(); 54 | $price = $priceHelper->currency($product->getFinalPrice(), false, false); 55 | $content = '{id:"' . $product->getId() . '",quantity:' . (int)$item->getQty() 56 | . ',item_price:' . $price . "}"; 57 | $contents[] = $content; 58 | } 59 | return implode(',', $contents); 60 | } 61 | 62 | /** 63 | * @return int|null 64 | */ 65 | public function getNumItems() 66 | { 67 | $cart = $this->fbeHelper->getObject(\Magento\Checkout\Model\Cart::class); 68 | if (!$cart || !$cart->getQuote()) { 69 | return null; 70 | } 71 | $numItems = 0; 72 | $items = $cart->getQuote()->getAllVisibleItems(); 73 | foreach ($items as $item) { 74 | $numItems += $item->getQty(); 75 | } 76 | return $numItems; 77 | } 78 | 79 | /** 80 | * @return string 81 | */ 82 | public function getEventToObserveName() 83 | { 84 | return 'facebook_businessextension_ssapi_initiate_checkout'; 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /Block/Pixel/Purchase.php: -------------------------------------------------------------------------------- 1 | fbeHelper->getObject(\Magento\Checkout\Model\Session::class)->getLastRealOrder(); 21 | if ($order) { 22 | $items = $order->getItemsCollection(); 23 | foreach ($items as $item) { 24 | $product = $item->getProduct(); 25 | $productIds[] = $product->getId(); 26 | } 27 | } 28 | return $this->arrayToCommaSeparatedStringValues($productIds); 29 | } 30 | 31 | public function getValue() 32 | { 33 | $order = $this->fbeHelper->getObject(\Magento\Checkout\Model\Session::class)->getLastRealOrder(); 34 | /** @var Order $order */ 35 | if ($order) { 36 | $subtotal = $order->getSubTotal(); 37 | if ($subtotal) { 38 | $priceHelper = $this->fbeHelper->getObject(\Magento\Framework\Pricing\Helper\Data::class); 39 | return $priceHelper->currency($subtotal, false, false); 40 | } 41 | } else { 42 | return null; 43 | } 44 | } 45 | 46 | public function getContents() 47 | { 48 | $contents = []; 49 | $order = $this->fbeHelper->getObject(\Magento\Checkout\Model\Session::class)->getLastRealOrder(); 50 | /** @var Order $order */ 51 | if ($order) { 52 | $priceHelper = $this->objectManager->get(\Magento\Framework\Pricing\Helper\Data::class); 53 | $items = $order->getItemsCollection(); 54 | foreach ($items as $item) { 55 | /** @var Product $product */ 56 | // @todo reuse results from self::getContentIDs() 57 | $product = $item->getProduct(); 58 | $price = $priceHelper->currency($product->getFinalPrice(), false, false); 59 | $content = '{id:"' . $product->getId() . '",quantity:' . (int)$item->getQtyOrdered() 60 | . ',item_price:' . $price . '}'; 61 | $contents[] = $content; 62 | } 63 | } 64 | return implode(',', $contents); 65 | } 66 | 67 | /** 68 | * @return string 69 | */ 70 | public function getEventToObserveName() 71 | { 72 | return 'facebook_businessextension_ssapi_purchase'; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /Block/Pixel/Search.php: -------------------------------------------------------------------------------- 1 | getRequest()->getParam('q'), 17 | ENT_QUOTES, 18 | 'UTF-8' 19 | ); 20 | } 21 | 22 | /** 23 | * @return string 24 | */ 25 | public function getEventToObserveName() 26 | { 27 | return 'facebook_businessextension_ssapi_search'; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Block/Pixel/ViewCategory.php: -------------------------------------------------------------------------------- 1 | registry->registry('current_category'); 16 | if ($category) { 17 | return $this->escapeQuotes($category->getName()); 18 | } else { 19 | return null; 20 | } 21 | } 22 | 23 | /** 24 | * @return string 25 | */ 26 | public function getEventToObserveName() 27 | { 28 | return 'facebook_businessextension_ssapi_view_category'; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Block/Pixel/ViewContent.php: -------------------------------------------------------------------------------- 1 | registry->registry('current_product'); 19 | if ($product && $product->getId()) { 20 | $product_ids[] = $product->getId(); 21 | } 22 | return $this->arrayToCommaSeparatedStringValues($product_ids); 23 | } 24 | 25 | /** 26 | * @return string|null 27 | */ 28 | public function getContentName() 29 | { 30 | $product = $this->registry->registry('current_product'); 31 | if ($product && $product->getId()) { 32 | return $this->escapeQuotes($product->getName()); 33 | } else { 34 | return null; 35 | } 36 | } 37 | 38 | /** 39 | * @return string 40 | */ 41 | public function getContentType() 42 | { 43 | $product = $this->registry->registry('current_product'); 44 | return ($product->getTypeId() == Configurable::TYPE_CODE) ? 'product_group' : 'product'; 45 | } 46 | 47 | /** 48 | * @return string|null 49 | */ 50 | public function getContentCategory() 51 | { 52 | $product = $this->registry->registry('current_product'); 53 | $categoryIds = $product->getCategoryIds(); 54 | if (count($categoryIds) > 0) { 55 | $categoryNames = []; 56 | $categoryModel = $this->fbeHelper->getObject(\Magento\Catalog\Model\Category::class); 57 | foreach ($categoryIds as $category_id) { 58 | // @todo do not load category model in loop - this can be a performance killer, use category collection 59 | $category = $categoryModel->load($category_id); 60 | $categoryNames[] = $category->getName(); 61 | } 62 | return $this->escapeQuotes(implode(',', $categoryNames)); 63 | } else { 64 | return null; 65 | } 66 | } 67 | 68 | public function getValue() 69 | { 70 | $product = $this->registry->registry('current_product'); 71 | if ($product && $product->getId()) { 72 | $price = $product->getFinalPrice(); 73 | $priceHelper = $this->fbeHelper->getObject(\Magento\Framework\Pricing\Helper\Data::class); 74 | return $priceHelper->currency($price, false, false); 75 | } else { 76 | return null; 77 | } 78 | } 79 | 80 | /** 81 | * @return string 82 | */ 83 | public function getEventToObserveName() 84 | { 85 | return 'facebook_businessextension_ssapi_view_content'; 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /CODEOFCONDUCT.md: -------------------------------------------------------------------------------- 1 | # Code of Conduct 2 | 3 | Facebook has adopted a Code of Conduct that we expect project participants to adhere to. 4 | Please read the [full text](https://code.fb.com/codeofconduct/) 5 | so that you can understand what actions will and will not be tolerated. 6 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to Facebook Business Extension For Magento2 2 | We want to make contributing to this project as easy and transparent as 3 | possible. 4 | 5 | ## Pull Requests 6 | We actively welcome your pull requests. 7 | 8 | 1. Fork the repo and create your branch from `master`. 9 | 2. If you've added code that should be tested, add tests. 10 | 3. If you've changed APIs, update the documentation. 11 | 4. Make sure your code lints. 12 | 5. If you haven't already, complete the Contributor License Agreement ("CLA"). 13 | 14 | ## Contributor License Agreement ("CLA") 15 | In order to accept your pull request, we need you to submit a CLA. You only need 16 | to do this once to work on any of Facebook's open source projects. 17 | 18 | Complete your CLA here: 19 | 20 | ## Issues 21 | We use GitHub issues to track public bugs. Please ensure your description is 22 | clear and has sufficient instructions to be able to reproduce the issue. 23 | 24 | Facebook has a [bounty program](https://www.facebook.com/whitehat/) for the safe 25 | disclosure of security bugs. In those cases, please go through the process 26 | outlined on that page and do not file a public issue. 27 | 28 | ## Coding Style 29 | * 4 spaces for indentation rather than tabs 30 | * 80 character line length 31 | 32 | ## License 33 | By contributing to Facebook Business Extension For Magento2, you agree that your contributions 34 | will be licensed under the LICENSE file in the root directory of 35 | this source tree. 36 | -------------------------------------------------------------------------------- /Controller/Adminhtml/Ajax/AbstractAjax.php: -------------------------------------------------------------------------------- 1 | _resultJsonFactory = $resultJsonFactory; 26 | $this->_fbeHelper = $fbeHelper; 27 | } 28 | 29 | abstract protected function executeForJson(); 30 | 31 | public function execute() 32 | { 33 | $result = $this->_resultJsonFactory->create(); 34 | // TODO : Move all String objects to constants. 35 | $admin_session = $this->_fbeHelper 36 | ->createObject(AdminSessionsManager::class) 37 | ->getCurrentSession(); 38 | if (!$admin_session && $admin_session->getStatus() != 1) { 39 | throw new \Exception('Oops, this endpoint is for logged in admin and ajax only!'); 40 | } else { 41 | try { 42 | $json = $this->executeForJson(); 43 | return $result->setData($json); 44 | } catch (\Exception $e) { 45 | // Uncomment once the logger is added 46 | // $this->_fbeHelper->logException($e); 47 | throw new Exception( 48 | 'Oops, there was error while processing your request.' . 49 | ' Please contact admin for more details.' 50 | ); 51 | } 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /Controller/Adminhtml/Ajax/CategoryUpload.php: -------------------------------------------------------------------------------- 1 | categoryCollection = $categoryCollection; 30 | } 31 | 32 | public function executeForJson() 33 | { 34 | $response = []; 35 | 36 | if (!$this->_fbeHelper->getAccessToken()) { 37 | $response['success'] = false; 38 | $response['message'] = __('Set up the extension before uploading category.'); 39 | return $response; 40 | } 41 | 42 | try { 43 | $feedPushResponse = $this->categoryCollection->pushAllCategoriesToFbCollections(); 44 | $response['success'] = true; 45 | $response['feed_push_response'] = $feedPushResponse; 46 | } catch (Exception $e) { 47 | $response['success'] = false; 48 | $response['message'] = $e->getMessage(); 49 | } 50 | return $response; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /Controller/Adminhtml/Ajax/Fbaamsettings.php: -------------------------------------------------------------------------------- 1 | false, 23 | 'settings' => null, 24 | ]; 25 | $pixelId = $this->getRequest()->getParam('pixelId'); 26 | if ($pixelId) { 27 | $settingsAsString = $this->_fbeHelper->fetchAndSaveAAMSettings($pixelId); 28 | if ($settingsAsString) { 29 | $response['success'] = true; 30 | $response['settings'] = $settingsAsString; 31 | } 32 | } 33 | return $response; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Controller/Adminhtml/Ajax/Fbcategorypush.php: -------------------------------------------------------------------------------- 1 | _customerSession = $customerSession; 22 | } 23 | 24 | public function executeForJson() 25 | { 26 | $response = []; 27 | try { 28 | $catalog_id = $this->getRequest()->getParam('catalogId'); 29 | $category_obj = $this->_fbeHelper->getObject(CategoryCollection::class); 30 | $category_obj->saveCatalogId($catalog_id); 31 | $category_obj->pushAllCategoriesToFbCollections(); 32 | $response['success'] = true; 33 | return $response; 34 | } catch (\Exception $e) { 35 | $response['success'] = false; 36 | $response['message'] = $e->getMessage(); 37 | $this->_fbeHelper->logException($e); 38 | return $response; 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Controller/Adminhtml/Ajax/Fbdeleteasset.php: -------------------------------------------------------------------------------- 1 | _fbeHelper->deleteConfigKeys(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Controller/Adminhtml/Ajax/Fbpixel.php: -------------------------------------------------------------------------------- 1 | _fbeHelper->getConfigValue('fbpixel/id'); 26 | $response = [ 27 | 'success' => false, 28 | 'pixelId' => $old_pixel_id 29 | //'pixelUsePii' => $this->_fbeHelper->getConfigValue('fbpixel/pixel_use_pii') 30 | ]; 31 | $pixel_id = $this->getRequest()->getParam('pixelId'); 32 | //$pixel_use_pii = $this->getRequest()->getParam('pixelUsePii'); 33 | if ($pixel_id && $this->_fbeHelper->isValidFBID($pixel_id)) { 34 | $this->_fbeHelper->saveConfig('fbpixel/id', $pixel_id); 35 | $this->_fbeHelper->saveConfig('fbe/installed', true); 36 | // $this->_fbeHelper->saveConfig('fbpixel/pixel_use_pii', $pixel_use_pii === 'true'? '1' : '0'); 37 | $response['success'] = true; 38 | $response['pixelId'] = $pixel_id; 39 | // $response['pixelUsePii'] = $pixel_use_pii; 40 | if ($old_pixel_id != $pixel_id) { 41 | $this->_fbeHelper->log(sprintf("Pixel id updated from %d to %d", $old_pixel_id, $pixel_id)); 42 | $datetime = $this->_fbeHelper->createObject(DateTime::class); 43 | $this->_fbeHelper->saveConfig( 44 | 'fbpixel/install_time', 45 | $datetime->gmtDate('Y-m-d H:i:s') 46 | ); 47 | } 48 | } 49 | return $response; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Controller/Adminhtml/Ajax/Fbprofiles.php: -------------------------------------------------------------------------------- 1 | _fbeHelper->getConfigValue('fbprofile/ids'); 24 | $response = [ 25 | 'success' => false, 26 | 'profiles' => $old_profiles 27 | ]; 28 | $profiles = $this->getRequest()->getParam('profiles'); 29 | if ($profiles) { 30 | $this->_fbeHelper->saveConfig('fbprofile/ids', $profiles); 31 | $response['success'] = true; 32 | $response['profiles'] = $profiles; 33 | if ($old_profiles != $profiles) { 34 | $datetime = $this->_fbeHelper->createObject(DateTime::class); 35 | $this->_fbeHelper->saveConfig( 36 | 'fbprofiles/creation_time', 37 | $datetime->gmtDate('Y-m-d H:i:s') 38 | ); 39 | } 40 | } 41 | return $response; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /Controller/Adminhtml/Ajax/Fbtoken.php: -------------------------------------------------------------------------------- 1 | _fbeHelper->getConfigValue('fbaccess/token'); 24 | $response = [ 25 | 'success' => false, 26 | 'accessToken' => $old_access_token 27 | ]; 28 | $access_token = $this->getRequest()->getParam('accessToken'); 29 | if ($access_token) { 30 | $this->_fbeHelper->saveConfig('fbaccess/token', $access_token); 31 | $response['success'] = true; 32 | $response['accessToken'] = $access_token; 33 | if ($old_access_token != $access_token) { 34 | $this->_fbeHelper->log("Updated Access token..."); 35 | $datetime = $this->_fbeHelper->createObject(DateTime::class); 36 | $this->_fbeHelper->saveConfig( 37 | 'fbaccesstoken/creation_time', 38 | $datetime->gmtDate('Y-m-d H:i:s') 39 | ); 40 | } 41 | } 42 | return $response; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Controller/Adminhtml/Ajax/ProductFeedUpload.php: -------------------------------------------------------------------------------- 1 | uploader = $uploader; 29 | } 30 | 31 | public function executeForJson() 32 | { 33 | $response = []; 34 | 35 | if (!$this->_fbeHelper->getAccessToken()) { 36 | $response['success'] = false; 37 | $response['message'] = __('Set up the extension before uploading products.'); 38 | return $response; 39 | } 40 | 41 | try { 42 | $feedPushResponse = $this->uploader->uploadFullCatalog(); 43 | $response['success'] = true; 44 | $response['feed_push_response'] = $feedPushResponse; 45 | } catch (Exception $e) { 46 | $response['success'] = false; 47 | $response['message'] = $e->getMessage(); 48 | } 49 | return $response; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Controller/Adminhtml/Info/Index.php: -------------------------------------------------------------------------------- 1 | resultPageFactory = $resultPageFactory; 37 | } 38 | 39 | /** 40 | * Load the page defined in view/adminhtml/layout/exampleadminnewpage_helloworld_index.xml 41 | * 42 | * @return Page 43 | */ 44 | public function execute() 45 | { 46 | $resultPage = $this->resultPageFactory->create(); 47 | $resultPage->getConfig()->getTitle()->prepend(__('Info')); 48 | 49 | return $resultPage; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Controller/Adminhtml/Setup/Index.php: -------------------------------------------------------------------------------- 1 | resultPageFactory = $resultPageFactory; 31 | } 32 | 33 | /** 34 | * Load the page defined in view/adminhtml/layout/fbeadmin_setup_index.xml 35 | * 36 | * @return Page 37 | */ 38 | public function execute() 39 | { 40 | return $resultPage = $this->resultPageFactory->create(); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Cron/AAMSettingsCron.php: -------------------------------------------------------------------------------- 1 | fbeHelper = $fbeHelper; 24 | } 25 | 26 | public function execute() 27 | { 28 | $pixelId = $this->fbeHelper->getPixelID(); 29 | $settingsAsString = null; 30 | if ($pixelId) { 31 | $settingsAsString = $this->fbeHelper->fetchAndSaveAAMSettings($pixelId); 32 | if (!$settingsAsString) { 33 | $this->fbeHelper->log('Error saving settings. Currently:', $settingsAsString); 34 | } 35 | } 36 | return $settingsAsString; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Cron/CategorySyncCron.php: -------------------------------------------------------------------------------- 1 | fbeHelper = $fbeHelper; 41 | $this->categoryCollection = $categoryCollection; 42 | $this->systemConfig = $systemConfig; 43 | } 44 | 45 | public function execute() 46 | { 47 | if ($this->systemConfig->isActiveCatalogSync() == true) { 48 | $this->categoryCollection->pushAllCategoriesToFbCollections(); 49 | return true; 50 | } 51 | return false; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /Helper/AAMSettingsFields.php: -------------------------------------------------------------------------------- 1 | fbeHelper = $helper; 31 | } 32 | 33 | /** 34 | * @param string $uri 35 | * the curl does not support delete api call, so have to use this low level lib 36 | * https://devdocs.magento.com/guides/v2.3/get-started/gs-web-api-request.html 37 | * @return string|null 38 | */ 39 | public function makeDeleteHttpCall(string $uri) 40 | { 41 | $httpHeaders = new Headers(); 42 | $httpHeaders->addHeaders([ 43 | 'Accept' => 'application/json', 44 | ]); 45 | $request = new Request(); 46 | $request->setHeaders($httpHeaders); 47 | $request->setUri($uri); 48 | $request->setMethod(Request::METHOD_DELETE); 49 | $client = new Client(); 50 | $res = $client->send($request); 51 | $response = Response::fromString($res); 52 | $this->fbeHelper->log("response:", $response); 53 | return $response->getBody(); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /Helper/ServerSideHelper.php: -------------------------------------------------------------------------------- 1 | fbeHelper = $fbeHelper; 47 | $this->aamFieldsExtractorHelper = $aamFieldsExtractorHelper; 48 | } 49 | 50 | /** 51 | * @param $event 52 | * @param null $userDataArray 53 | */ 54 | public function sendEvent($event, $userDataArray = null) 55 | { 56 | try { 57 | $api = Api::init(null, null, $this->fbeHelper->getAccessToken()); 58 | 59 | $event = $this->aamFieldsExtractorHelper->setUserData($event, $userDataArray); 60 | 61 | $this->trackedEvents[] = $event; 62 | 63 | $events = []; 64 | array_push($events, $event); 65 | 66 | $request = (new EventRequestAsync($this->fbeHelper->getPixelID())) 67 | ->setEvents($events) 68 | ->setPartnerAgent($this->fbeHelper->getPartnerAgent(true)); 69 | 70 | $this->fbeHelper->log('Sending event ' . $event->getEventId()); 71 | 72 | $request->execute() 73 | ->then( 74 | null, 75 | function (RequestException $e) { 76 | $this->fbeHelper->log("RequestException: " . $e->getMessage()); 77 | } 78 | ); 79 | } catch (\Exception $e) { 80 | $this->fbeHelper->log(json_encode($e)); 81 | } 82 | } 83 | 84 | /** 85 | * @return array 86 | */ 87 | public function getTrackedEvents() 88 | { 89 | return $this->trackedEvents; 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2004-present, Facebook, Inc. All rights reserved. 2 | 3 | You are hereby granted a non-exclusive, worldwide, royalty-free license to use, 4 | copy, modify, and distribute this software in source code or binary form for use 5 | in connection with the web services and APIs provided by Facebook. 6 | 7 | As with any software that integrates with the Facebook platform, your use of 8 | this software is subject to the Facebook Platform Policy 9 | [http://developers.facebook.com/policy/]. This copyright notice shall be 10 | included in all copies or substantial portions of the software. 11 | 12 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 14 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 15 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 16 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 17 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 18 | -------------------------------------------------------------------------------- /Logger/Handler.php: -------------------------------------------------------------------------------- 1 | create(Handler::class); 21 | parent::__construct('FBE', [$handler]); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Model/Config.php: -------------------------------------------------------------------------------- 1 | _init('Facebook\BusinessExtension\Model\ResourceModel\Config'); 18 | } 19 | 20 | /** 21 | * @return array 22 | */ 23 | public function getIdentities() 24 | { 25 | return [self::CACHE_TAG . '_' . $this->getConfigKey()]; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Model/Config/Source/Product/AgeGroup.php: -------------------------------------------------------------------------------- 1 | _options === null) { 20 | $this->_options = [ 21 | ['value' => '', 'label' => __('Please Select')], 22 | ['value' => 'adult', 'label' => __('adult')], 23 | ['value' => 'all ages', 'label' => __('all ages')], 24 | ['value' => 'teen', 'label' => __('teen')], 25 | ['value' => 'kids', 'label' => __('kids')], 26 | ['value' => 'toddler', 'label' => __('toddler')], 27 | ['value' => 'infant', 'label' => __('infant')], 28 | ['value' => 'newborn', 'label' => __('newborn')], 29 | ]; 30 | } 31 | return $this->_options; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Model/Config/Source/Product/Assembly.php: -------------------------------------------------------------------------------- 1 | _options === null) { 20 | $this->_options = [ 21 | ['value' => '', 'label' => __('Please Select')], 22 | ['value' => 'yes', 'label' => __('Yes')], 23 | ['value' => 'no', 'label' => __('No')], 24 | ]; 25 | } 26 | return $this->_options; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Model/Config/Source/Product/DecorStyle.php: -------------------------------------------------------------------------------- 1 | _options === null) { 21 | $this->_options = [ 22 | ['value' => '', 'label' => __('Please Select')], 23 | ['value' => 'Bohemian', 'label' => __('Bohemian')], 24 | ['value' => 'Contemporary', 'label' => __('Contemporary')], 25 | ['value' => 'Industrial', 'label' => __('Industrial')], 26 | ['value' => 'Mid-Century', 'label' => __('Mid-Century')], 27 | ['value' => 'Modern', 'label' => __('Modern')], 28 | ['value' => 'Rustic', 'label' => __('Rustic')], 29 | ['value' => 'Vintage', 'label' => __('Vintage')], 30 | ]; 31 | } 32 | return $this->_options; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Model/Config/Source/Product/Gender.php: -------------------------------------------------------------------------------- 1 | _options === null) { 20 | $this->_options = [ 21 | ['value' => '', 'label' => __('Please Select')], 22 | ['value' => 'Male', 'label' => __('Male')], 23 | ['value' => 'Female', 'label' => __('Female')], 24 | ['value' => 'Unisex', 'label' => __('Unisex')], 25 | ]; 26 | } 27 | return $this->_options; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Model/Config/Source/Product/Pattern.php: -------------------------------------------------------------------------------- 1 | _options === null) { 20 | $this->_options = [ 21 | ['value' => '', 'label' => __('Please Select')], 22 | ['value' => 'Plaid', 'label' => __('Plaid')], 23 | ['value' => 'Polka', 'label' => __('Polka')], 24 | ['value' => 'Dot', 'label' => __('Dot')], 25 | ['value' => 'Gingham', 'label' => __('Gingham')], 26 | ['value' => 'Chevron', 'label' => __('Chevron')], 27 | ]; 28 | } 29 | return $this->_options; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Model/Feed/EnhancedCatalogHelper.php: -------------------------------------------------------------------------------- 1 | attributeConfig = $attributeConfig; 32 | $this->fbeHelper = $fbeHelper; 33 | } 34 | 35 | /** 36 | * @param Product $product 37 | * @param array $requests 38 | * @return null 39 | */ 40 | public function assignECAttribute(Product $product, array &$requests) 41 | { 42 | $attrConfig = $this->attributeConfig->getAttributesConfig(); 43 | foreach ($attrConfig as $attrCode => $config) { 44 | $data = $product->getData($attrCode); 45 | if ($data) { 46 | // facebook_capacity -> capacity 47 | $trimmedAttrCode = substr($attrCode, 9); 48 | $requests[$trimmedAttrCode] = $data; 49 | } 50 | } 51 | return null; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /Model/Product/Feed/Builder/Tools.php: -------------------------------------------------------------------------------- 1 | priceCurrency = $priceCurrency; 25 | } 26 | 27 | /** 28 | * @param $string 29 | * @return false|string|string[]|null 30 | */ 31 | public function lowercaseIfAllCaps($string) 32 | { 33 | // if contains lowercase, don't update string 34 | if (!preg_match('/[a-z]/', $string)) { 35 | if (mb_strtoupper($string, 'utf-8') === $string) { 36 | return mb_strtolower($string, 'utf-8'); 37 | } 38 | } 39 | return $string; 40 | } 41 | 42 | /** 43 | * @param $value 44 | * @return string 45 | */ 46 | public function htmlDecode($value) 47 | { 48 | return strip_tags(html_entity_decode($value)); 49 | } 50 | 51 | /** 52 | * Return formatted price with currency code. Examples: "9.99 USD", "27.02 GBP" 53 | * 54 | * @param $price 55 | * @param null $storeId 56 | * @return string 57 | */ 58 | public function formatPrice($price, $storeId = null) 59 | { 60 | $currencyModel = $this->priceCurrency->getCurrency($storeId); 61 | $amount = $this->priceCurrency->convert($price, $storeId, $currencyModel); 62 | try { 63 | return sprintf( 64 | '%s %s', 65 | $currencyModel->formatTxt($amount, ['display' => Currency::NO_SYMBOL]), 66 | $currencyModel->getCode() 67 | ); 68 | } catch (Exception $e) { 69 | return ''; 70 | } 71 | } 72 | 73 | /** 74 | * Facebook product feed validator will throw an error 75 | * if a local URL like https://localhost/product.html was provided 76 | * so replacing with a dummy URL to allow for local testing 77 | * 78 | * @param string $url 79 | * @return string 80 | */ 81 | public function replaceLocalUrlWithDummyUrl($url) 82 | { 83 | return str_replace('localhost', 'magento.com', $url); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /Model/Product/Feed/ProductRetriever/Simple.php: -------------------------------------------------------------------------------- 1 | fbeHelper = $fbeHelper; 35 | $this->productCollectionFactory = $productCollectionFactory; 36 | } 37 | 38 | /** 39 | * @inheritDoc 40 | */ 41 | public function getProductType() 42 | { 43 | return ProductType::TYPE_SIMPLE; 44 | } 45 | 46 | /** 47 | * @param int $offset 48 | * @param int $limit 49 | * @return array 50 | */ 51 | public function retrieve($offset = 1, $limit = self::LIMIT): array 52 | { 53 | $storeId = $this->fbeHelper->getStore()->getId(); 54 | 55 | $collection = $this->productCollectionFactory->create(); 56 | $collection->addAttributeToSelect('*') 57 | ->addAttributeToFilter('status', Status::STATUS_ENABLED) 58 | ->addAttributeToFilter('visibility', ['neq' => Visibility::VISIBILITY_NOT_VISIBLE]) 59 | ->addAttributeToFilter('type_id', $this->getProductType()) 60 | ->setStoreId($storeId); 61 | 62 | $collection 63 | ->getSelect()->joinLeft(['l' => 'catalog_product_super_link'], 'e.entity_id = l.product_id') 64 | ->where('l.product_id IS NULL') 65 | ->order(new \Zend_Db_Expr('e.updated_at desc')) 66 | ->limit($limit, $offset); 67 | 68 | return $collection->getItems(); 69 | } 70 | 71 | /** 72 | * @inheritDoc 73 | */ 74 | public function getLimit() 75 | { 76 | return self::LIMIT; 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /Model/Product/Feed/ProductRetrieverInterface.php: -------------------------------------------------------------------------------- 1 | methodBatchApi = $methodBatchApi; 24 | } 25 | 26 | /** 27 | * @return array 28 | * @throws Exception 29 | */ 30 | public function uploadFullCatalog() 31 | { 32 | return $this->methodBatchApi->generateProductRequestData(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Model/ResourceModel/Config.php: -------------------------------------------------------------------------------- 1 | _init('facebook_business_extension_config', 'config_key'); 15 | $this->_isPkAutoIncrement = false; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Model/ResourceModel/Config/Collection.php: -------------------------------------------------------------------------------- 1 | _init( 15 | 'Facebook\BusinessExtension\Model\Config', 16 | 'Facebook\BusinessExtension\Model\ResourceModel\Config' 17 | ); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Observer/AddToCart.php: -------------------------------------------------------------------------------- 1 | fbeHelper = $fbeHelper; 53 | $this->magentoDataHelper = $magentoDataHelper; 54 | $this->serverSideHelper = $serverSideHelper; 55 | $this->request = $request; 56 | } 57 | 58 | /** 59 | * Execute action method for the Observer 60 | * 61 | * @param Observer $observer 62 | * @return $this 63 | */ 64 | public function execute(Observer $observer) 65 | { 66 | try { 67 | $eventId = $observer->getData('eventId'); 68 | $productSku = $this->request->getParam('product_sku', null); 69 | $product = $this->magentoDataHelper->getProductWithSku($productSku); 70 | if ($product->getId()) { 71 | $customData = [ 72 | 'currency' => $this->magentoDataHelper->getCurrency(), 73 | 'value' => $this->magentoDataHelper->getValueForProduct($product), 74 | 'content_type' => 'product', 75 | 'content_ids' => [$product->getId()], 76 | 'content_category' => $this->magentoDataHelper->getCategoriesForProduct($product), 77 | 'content_name' => $product->getName() 78 | ]; 79 | $event = ServerEventFactory::createEvent('AddToCart', $customData, $eventId); 80 | $this->serverSideHelper->sendEvent($event); 81 | } 82 | } catch (\Exception $e) { 83 | $this->fbeHelper->log(json_encode($e)); 84 | } 85 | return $this; 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /Observer/InitiateCheckout.php: -------------------------------------------------------------------------------- 1 | fbeHelper = $fbeHelper; 46 | $this->magentoDataHelper = $magentoDataHelper; 47 | $this->serverSideHelper = $serverSideHelper; 48 | } 49 | 50 | /** 51 | * Execute action method for the Observer 52 | * 53 | * @param Observer $observer 54 | * @return $this 55 | */ 56 | public function execute(Observer $observer) 57 | { 58 | try { 59 | $eventId = $observer->getData('eventId'); 60 | $customData = [ 61 | 'currency' => $this->magentoDataHelper->getCurrency(), 62 | 'value' => $this->magentoDataHelper->getCartTotal(), 63 | 'content_type' => 'product', 64 | 'content_ids' => $this->magentoDataHelper->getCartContentIds(), 65 | 'num_items' => $this->magentoDataHelper->getCartNumItems(), 66 | 'contents' => $this->magentoDataHelper->getCartContents() 67 | ]; 68 | $event = ServerEventFactory::createEvent('InitiateCheckout', array_filter($customData), $eventId); 69 | $this->serverSideHelper->sendEvent($event); 70 | } catch (\Exception $e) { 71 | $this->fbeHelper->log(json_encode($e)); 72 | } 73 | return $this; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /Observer/ProcessCategoryAfterDeleteEventObserver.php: -------------------------------------------------------------------------------- 1 | fbeHelper = $helper; 36 | $this->systemConfig = $systemConfig; 37 | } 38 | 39 | /** 40 | * Call an API to category delete from facebook catalog 41 | * after delete category from Magento 42 | * 43 | * @param Observer $observer 44 | */ 45 | public function execute(Observer $observer) 46 | { 47 | if ($this->systemConfig->isActiveCatalogSync() == false) { 48 | return; 49 | } 50 | $category = $observer->getEvent()->getCategory(); 51 | $this->fbeHelper->log("delete category: ".$category->getName()); 52 | /** @var CategoryCollection $categoryObj */ 53 | $categoryObj = $this->fbeHelper->getObject(CategoryCollection::class); 54 | $categoryObj->deleteCategoryAndSubCategoryFromFB($category); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /Observer/ProcessCategoryAfterSaveEventObserver.php: -------------------------------------------------------------------------------- 1 | _fbeHelper = $helper; 28 | } 29 | 30 | /** 31 | * Call an API to category save from facebook catalog 32 | * after save category from Magento 33 | * 34 | * @param Observer $observer 35 | * @return 36 | */ 37 | public function execute(Observer $observer) 38 | { 39 | $category = $observer->getEvent()->getCategory(); 40 | $this->_fbeHelper->log("save category: ".$category->getName()); 41 | /** @var CategoryCollection $categoryObj */ 42 | $categoryObj = $this->_fbeHelper->getObject(CategoryCollection::class); 43 | $syncEnabled =$category->getData("sync_to_facebook_catalog"); 44 | if ($syncEnabled === "0") { 45 | $this->_fbeHelper->log("user disabled category sync"); 46 | return; 47 | } 48 | 49 | $response = $categoryObj->makeHttpRequestAfterCategorySave($category); 50 | return $response; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /Observer/ProcessProductAfterDeleteEventObserver.php: -------------------------------------------------------------------------------- 1 | fbeHelper = $helper; 42 | $this->batchApi = $batchApi; 43 | $this->systemConfig = $systemConfig; 44 | } 45 | 46 | /** 47 | * Call an API to product delete from facebook catalog 48 | * after delete product from Magento 49 | * 50 | * @param Observer $observer 51 | */ 52 | public function execute(Observer $observer) 53 | { 54 | if ($this->systemConfig->isActiveCatalogSync() == false) { 55 | return; 56 | } 57 | 58 | $product = $observer->getEvent()->getProduct(); 59 | 60 | if ($product->getId()) { 61 | 62 | try { 63 | $this->fbeHelper->log("deleting product: ". $product->getId()); 64 | $requestData = $this->batchApi->buildProductRequest($product, $method='DELETE'); 65 | $requestParams = []; 66 | $requestParams[0] = $requestData; 67 | $this->fbeHelper->log(json_encode($requestParams)); 68 | $response = $this->fbeHelper->makeHttpRequest($requestParams, null); 69 | $this->fbeHelper->log("deletion responses: ".json_encode($response)); 70 | } catch (\Exception $e) { 71 | $this->fbeHelper->logException($e); 72 | } 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /Observer/ProcessProductAfterSaveEventObserver.php: -------------------------------------------------------------------------------- 1 | fbeHelper = $helper; 45 | $this->batchApi = $batchApi; 46 | $this->systemConfig = $systemConfig; 47 | } 48 | 49 | /** 50 | * Call an API to product save from facebook catalog 51 | * after save product from Magento 52 | * 53 | * @param Observer $observer 54 | */ 55 | public function execute(Observer $observer) 56 | { 57 | if ($this->systemConfig->isActiveCatalogSync() == false) { 58 | return; 59 | } 60 | /** @var Product $product */ 61 | $product = $observer->getEvent()->getProduct(); 62 | if (!$product->getId()) { 63 | return; 64 | } 65 | $storeId = $product->getStoreId(); 66 | $product->setStoreId($this->fbeHelper->getStore()->getId()); 67 | 68 | try { 69 | $requestData = $this->batchApi->buildProductRequest($product); 70 | $requestParams = []; 71 | $requestParams[0] = $requestData; 72 | $this->fbeHelper->makeHttpRequest($requestParams, null); 73 | } catch (Exception $e) { 74 | $this->fbeHelper->logException($e); 75 | } 76 | 77 | $product->setStoreId($storeId); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /Observer/Purchase.php: -------------------------------------------------------------------------------- 1 | fbeHelper = $fbeHelper; 46 | $this->magentoDataHelper = $magentoDataHelper; 47 | $this->serverSideHelper = $serverSideHelper; 48 | } 49 | 50 | /** 51 | * Execute action method for the Observer 52 | * 53 | * @param Observer $observer 54 | * @return $this 55 | */ 56 | public function execute(Observer $observer) 57 | { 58 | try { 59 | $eventId = $observer->getData('eventId'); 60 | $customData = [ 61 | 'currency' => $this->magentoDataHelper->getCurrency(), 62 | 'value' => $this->magentoDataHelper->getOrderTotal(), 63 | 'content_type' => 'product', 64 | 'content_ids' => $this->magentoDataHelper->getOrderContentIds(), 65 | 'contents' => $this->magentoDataHelper->getOrderContents(), 66 | 'order_id' => (string)$this->magentoDataHelper->getOrderId() 67 | ]; 68 | $event = ServerEventFactory::createEvent('Purchase', array_filter($customData), $eventId); 69 | $userDataFromOrder = $this->magentoDataHelper->getUserDataFromOrder(); 70 | $this->serverSideHelper->sendEvent($event, $userDataFromOrder); 71 | } catch (\Exception $e) { 72 | $this->fbeHelper->log(json_encode($e)); 73 | } 74 | return $this; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /Observer/Search.php: -------------------------------------------------------------------------------- 1 | fbeHelper = $fbeHelper; 46 | $this->request = $request; 47 | $this->serverSideHelper = $serverSideHelper; 48 | } 49 | 50 | /** 51 | * @return string 52 | */ 53 | public function getSearchQuery() 54 | { 55 | return htmlspecialchars( 56 | $this->request->getParam('q'), 57 | ENT_QUOTES, 58 | 'UTF-8' 59 | ); 60 | } 61 | 62 | public function execute(Observer $observer) 63 | { 64 | try { 65 | $eventId = $observer->getData('eventId'); 66 | $customData = [ 67 | 'search_string' => $this->getSearchQuery() 68 | ]; 69 | $event = ServerEventFactory::createEvent('Search', $customData, $eventId); 70 | $this->serverSideHelper->sendEvent($event); 71 | } catch (\Exception $e) { 72 | $this->fbeHelper->log(json_encode($e)); 73 | } 74 | return $this; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /Observer/ViewCategory.php: -------------------------------------------------------------------------------- 1 | fbeHelper = $fbeHelper; 38 | $this->registry = $registry; 39 | $this->serverSideHelper = $serverSideHelper; 40 | } 41 | 42 | public function execute(Observer $observer) 43 | { 44 | try { 45 | $eventId = $observer->getData('eventId'); 46 | $customData = []; 47 | $category = $this->registry->registry('current_category'); 48 | if ($category) { 49 | $customData['content_category'] = addslashes($category->getName()); 50 | } 51 | $event = ServerEventFactory::createEvent('ViewCategory', $customData, $eventId); 52 | $this->serverSideHelper->sendEvent($event); 53 | } catch (\Exception $e) { 54 | $this->fbeHelper->log(json_encode($e)); 55 | } 56 | return $this; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /Observer/ViewContent.php: -------------------------------------------------------------------------------- 1 | fbeHelper = $fbeHelper; 46 | $this->registry = $registry; 47 | $this->serverSideHelper = $serverSideHelper; 48 | $this->_magentoDataHelper = $magentoDataHelper; 49 | } 50 | 51 | public function execute(Observer $observer) 52 | { 53 | try { 54 | $eventId = $observer->getData('eventId'); 55 | $customData = [ 56 | 'currency' => $this->_magentoDataHelper->getCurrency() 57 | ]; 58 | $product = $this->registry->registry('current_product'); 59 | if ($product && $product->getId()) { 60 | $customData['value'] = $this->_magentoDataHelper->getValueForProduct($product); 61 | $customData['content_ids'] = [$product->getId()]; 62 | $customData['content_category'] = $this->_magentoDataHelper->getCategoriesForProduct($product); 63 | $customData['content_name'] = $product->getName(); 64 | $customData['contents'] = [ 65 | [ 66 | 'product_id' => $product->getId(), 67 | 'item_price' => $this->_magentoDataHelper->getValueForProduct($product) 68 | ] 69 | ]; 70 | $customData['content_type'] = ($product->getTypeId() == Configurable::TYPE_CODE) ? 71 | 'product_group' : 'product'; 72 | } 73 | $event = ServerEventFactory::createEvent('ViewContent', array_filter($customData), $eventId); 74 | $this->serverSideHelper->sendEvent($event); 75 | } catch (\Exception $e) { 76 | $this->fbeHelper->log(json_encode($e)); 77 | } 78 | return $this; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /Plugin/CAPIEventsModifierPlugin.php: -------------------------------------------------------------------------------- 1 | setDataProcessingOptions(['LDU']) 27 | * ->setDataProcessingOptionsCountry(1) 28 | * ->setDataProcessingOptionsState(1000); 29 | * Read more about data processing options in: 30 | * https://developers.facebook.com/docs/marketing-apis/data-processing-options 31 | */ 32 | return [$event, $user_data]; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Setup/InstallSchema.php: -------------------------------------------------------------------------------- 1 | startSetup(); 19 | $installer->getConnection()->dropTable($installer->getTable(self::FBE_CONFIG_TABLE_NAME)); 20 | $table = $installer->getConnection()->newTable( 21 | $installer->getTable(self::FBE_CONFIG_TABLE_NAME) 22 | )->addColumn( 23 | 'config_key', 24 | \Magento\Framework\DB\Ddl\Table::TYPE_TEXT, 25 | 255, 26 | ['nullable' => false, 'primary' => true], 27 | 'Config Key' 28 | )->addColumn( 29 | 'config_value', 30 | \Magento\Framework\DB\Ddl\Table::TYPE_TEXT, 31 | 255, 32 | ['nullable' => false, 'default' => ''], 33 | 'Config Value' 34 | )->addColumn( 35 | 'creation_time', 36 | \Magento\Framework\DB\Ddl\Table::TYPE_TIMESTAMP, 37 | null, 38 | [ 39 | ], 40 | 'Creation Time' 41 | )->addColumn( 42 | 'update_time', 43 | \Magento\Framework\DB\Ddl\Table::TYPE_TIMESTAMP, 44 | null, 45 | [ 46 | ], 47 | 'Modification Time' 48 | ); 49 | $installer->getConnection()->createTable($table); 50 | $installer->endSetup(); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /Test/Mftf/ActionGroup/FillCustomerInformationActionGroup.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /Test/Mftf/ActionGroup/SearchPixelEventActionGroup.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /Test/Mftf/Data/CategoryData.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | consoles 7 | true 8 | 2 9 | true 10 | 11 | 12 | -------------------------------------------------------------------------------- /Test/Mftf/Data/CustomAttributeData.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | category_ids 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /Test/Mftf/Data/CustomerData.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | homero@simpson.com 7 | Homer 8 | Simpson 9 | 1234 Evergreen Ave 10 | Springfield 11 | Ohio 12 | 45501 13 | 5889372 14 | 15 | 16 | -------------------------------------------------------------------------------- /Test/Mftf/Data/PluginInfoData.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | magento2 7 | 1.4.7 8 | 9 | 10 | -------------------------------------------------------------------------------- /Test/Mftf/Data/ProductData.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | CON1 7 | Console1 8 | 500 9 | 1 10 | 4 11 | simple 12 | 4 13 | 10 14 | _defaultEAVStock 15 | CustomAttributeCategoryIds 16 | 17 | 18 | -------------------------------------------------------------------------------- /Test/Mftf/Data/ProductExtensionAttributeData.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | _defaultStockItem 7 | 8 | 9 | -------------------------------------------------------------------------------- /Test/Mftf/Data/SearchPixelEventData.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | book 7 | 8 | 9 | -------------------------------------------------------------------------------- /Test/Mftf/Data/StockItemData.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 100 7 | true 8 | 9 | 10 | -------------------------------------------------------------------------------- /Test/Mftf/Metadata/CategoryMeta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | application/json 7 | 8 | integer 9 | string 10 | boolean 11 | integer 12 | integer 13 | string 14 | string 15 | string 16 | string 17 | boolean 18 | 19 | string 20 | 21 | empty_extension_attribute 22 | 23 | custom_attribute 24 | 25 | 26 | integer 27 | 28 | 29 | -------------------------------------------------------------------------------- /Test/Mftf/Metadata/CustomAttributeMeta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | string 7 | 8 | string 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /Test/Mftf/Metadata/ProductExtensionAttributeMeta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | stockItem 7 | 8 | 9 | -------------------------------------------------------------------------------- /Test/Mftf/Metadata/ProductMeta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | application/json 7 | 8 | integer 9 | string 10 | string 11 | number 12 | integer 13 | integer 14 | string 15 | integer 16 | integer 17 | productExtensionAttribute 18 | 19 | customAttributeArray 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /Test/Mftf/Metadata/StockItemMeta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | integer 7 | boolean 8 | 9 | 10 | -------------------------------------------------------------------------------- /Test/Mftf/Test/AddToCartPixelEventCreatedTest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 8 | 9 | 10 | <description value="The product page should contain a fbq call with an add to cart pixel event."/> 11 | <severity value="MAJOR"/> 12 | <group value="Pixel"/> 13 | <skip> 14 | <issueId value="PixelMustBeInstalled"/> 15 | </skip> 16 | </annotations> 17 | <before> 18 | <!-- Create sample product --> 19 | <createData entity="_defaultCategory" stepKey="createCategory"/> 20 | <createData entity="_defaultProduct" stepKey="createProduct"> 21 | <requiredEntity createDataKey="createCategory"/> 22 | </createData> 23 | </before> 24 | <after> 25 | <!-- Delete sample product --> 26 | <deleteData createDataKey="createProduct" stepKey="deleteProduct"/> 27 | <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> 28 | </after> 29 | 30 | <!-- Navigate to Home page --> 31 | <amOnPage url="" stepKey="openHomePage"/> 32 | <waitForPageLoad stepKey="waitForHomePageLoad" time="60" /> 33 | <!-- Navigate to product page --> 34 | <amOnPage url="/{{_defaultProduct.name}}2.html" stepKey="openProductPage" /> 35 | <waitForPageLoad stepKey="waitForProductPageLoad" time="60" /> 36 | <!-- Submit add to cart form --> 37 | <submitForm selector="#product_addtocart_form" parameterArray="[]" stepKey="submitAddToCartForm"/> 38 | 39 | <!-- Check event inside page--> 40 | <grabPageSource stepKey="grabPageSource" /> 41 | <assertRegExp message="Cannot find add to cart event in page source" stepKey="assertAddToCartPixelEventFound"> 42 | <actualResult type="string">{$grabPageSource}</actualResult> 43 | <expectedResult type="string">/.*fbq\('set', 'agent', '{{_pluginInfo.source}}-2(.[0-9]+)+-{{_pluginInfo.pluginVersion}}', '[0-9]+'\);\s+fbq\('track',\s*'AddToCart'\s*,\s*{\s*source: "{{_pluginInfo.source}}",\s*version: "2(.[0-9]+)+",\s*pluginVersion: "{{_pluginInfo.pluginVersion}}"\s*,\s*content_type: "product",\s*currency: "[A-Z]+"\s*,\s*content_ids: content_ids\s*,\s*content_name: content_name\s*,\s*content_category: content_category\s*,\s*value: value.*/</expectedResult> 44 | </assertRegExp> 45 | </test> 46 | </tests> 47 | -------------------------------------------------------------------------------- /Test/Mftf/Test/SearchPixelEventCreatedTest.xml: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" encoding="UTF-8"?> 2 | 3 | <tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 | xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> 5 | <test name="SearchPixelEventCreatedTest"> 6 | <annotations> 7 | <features value="Pixel"/> 8 | <stories value="Search Pixel Event"/> 9 | <title value="The page has a pixel search event."/> 10 | <description value="The page should contain a fbq call with a search pixel event."/> 11 | <severity value="MAJOR"/> 12 | <group value="Pixel"/> 13 | <skip> 14 | <issueId value="PixelMustBeInstalled"/> 15 | </skip> 16 | </annotations> 17 | <before> 18 | </before> 19 | <after> 20 | </after> 21 | 22 | <!-- Navigate to Home page --> 23 | <amOnPage url="" stepKey="openMainPage" /> 24 | <waitForPageLoad stepKey="waitForMainPageLoaded" /> 25 | 26 | <!-- Fill and submit search form --> 27 | <actionGroup ref="fillSearchForm" stepKey="fillSearchForm"> 28 | <argument name="searchQuery" value="_defaultSearch" /> 29 | </actionGroup> 30 | 31 | <!-- Check event inside page--> 32 | <grabPageSource stepKey="grabPageSource" /> 33 | <assertRegExp message="Cannot find search event in page source" stepKey="assertSearchPixelEventFound"> 34 | <actualResult type="string">{$grabPageSource}</actualResult> 35 | <expectedResult type="string">/.*fbq\('set', 'agent', '{{_pluginInfo.source}}-2(.[0-9]+)+-{{_pluginInfo.pluginVersion}}', '[0-9]+'\);\s+fbq\('track',\s*'Search',\s*{\s*source: "{{_pluginInfo.source}}",\s*version: "2(.[0-9]+)+",\s*pluginVersion: "{{_pluginInfo.pluginVersion}}",\s*search_string: "{{_defaultSearch.query}}".*/</expectedResult> 36 | </assertRegExp> 37 | </test> 38 | </tests> 39 | -------------------------------------------------------------------------------- /Test/Mftf/Test/ViewCategoryPixelEventCreatedTest.xml: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" encoding="UTF-8"?> 2 | 3 | <tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 | xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> 5 | <test name="ViewCategoryPixelEventCreatedTest"> 6 | <annotations> 7 | <features value="Pixel"/> 8 | <stories value="View Category Pixel Event"/> 9 | <title value="The page has a view category pixel event."/> 10 | <description value="The page should contain a fbq call with a view category pixel event."/> 11 | <severity value="MAJOR"/> 12 | <group value="Pixel"/> 13 | <skip> 14 | <issueId value="PixelMustBeInstalled"/> 15 | </skip> 16 | </annotations> 17 | <before> 18 | <!-- Create sample category --> 19 | <createData entity="_defaultCategory" stepKey="createCategory"/> 20 | </before> 21 | <after> 22 | <!-- Delete sample category --> 23 | <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> 24 | </after> 25 | 26 | <!-- Navigate to category page --> 27 | <amOnPage url="/{{_defaultCategory.name}}2.html" stepKey="openCategoryPage" /> 28 | <waitForPageLoad stepKey="waitForCategoryPageLoad" /> 29 | 30 | <!-- Check event inside page--> 31 | <grabPageSource stepKey="grabPageSource" /> 32 | <assertRegExp message="Cannot find view category event in page source" stepKey="assertViewCategoryPixelEventFound"> 33 | <actualResult type="string">{$grabPageSource}</actualResult> 34 | <expectedResult type="string">/.*fbq\('set', 'agent', '{{_pluginInfo.source}}-2(.[0-9]+)+-{{_pluginInfo.pluginVersion}}', '[0-9]+'\);\s+fbq\('trackCustom',\s*'ViewCategory',\s*{\s*source: "{{_pluginInfo.source}}",\s*version: "2(.[0-9]+)+",\s*pluginVersion: "{{_pluginInfo.pluginVersion}}"\s*,\s*content_category: "{{_defaultCategory.name}}2".*/</expectedResult> 35 | </assertRegExp> 36 | </test> 37 | </tests> 38 | -------------------------------------------------------------------------------- /Test/Mftf/Test/ViewContentPixelEventCreatedTest.xml: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" encoding="UTF-8"?> 2 | 3 | <tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 | xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> 5 | <test name="ViewContentPixelEventCreatedTest"> 6 | <annotations> 7 | <features value="Pixel"/> 8 | <stories value="View Content Pixel Event"/> 9 | <title value="The page has a view content pixel event."/> 10 | <description value="The product page should contain a fbq call with a view content pixel event."/> 11 | <severity value="MAJOR"/> 12 | <group value="Pixel"/> 13 | <skip> 14 | <issueId value="PixelMustBeInstalled"/> 15 | </skip> 16 | </annotations> 17 | <before> 18 | <!-- Create sample product --> 19 | <createData entity="_defaultCategory" stepKey="createCategory"/> 20 | <createData entity="_defaultProduct" stepKey="createProduct"> 21 | <requiredEntity createDataKey="createCategory"/> 22 | </createData> 23 | </before> 24 | <after> 25 | <!-- Delete sample product --> 26 | <deleteData createDataKey="createProduct" stepKey="deleteProduct"/> 27 | <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> 28 | </after> 29 | 30 | <!-- Navigate to Home page --> 31 | <amOnPage url="" stepKey="openHomePage"/> 32 | <waitForPageLoad stepKey="waitForHomePageLoad" time="60" /> 33 | <!-- Navigate to product page --> 34 | <amOnPage url="/{{_defaultProduct.name}}2.html" stepKey="openProductPage" /> 35 | <waitForPageLoad stepKey="waitForProductPageLoad" time="60" /> 36 | 37 | <!-- Check event inside page--> 38 | <grabPageSource stepKey="grabPageSource" /> 39 | <assertRegExp message="Cannot find view content event in page source" stepKey="assertViewContentPixelEventFound"> 40 | <actualResult type="string">{$grabPageSource}</actualResult> 41 | <expectedResult type="string">/.*fbq\('set', 'agent', '{{_pluginInfo.source}}-2(.[0-9]+)+-{{_pluginInfo.pluginVersion}}', '[0-9]+'\);\s+fbq\('track',\s*'ViewContent'\s*,\s*{\s*source: "{{_pluginInfo.source}}",\s*version: "2(.[0-9]+)+",\s*pluginVersion: "{{_pluginInfo.pluginVersion}}"\s*,\s*content_type: "product",\s*content_ids: \["[0-9]+"\]\s*,\s*content_name: "{{_defaultProduct.name}}2"\s*,\s*(content_category: "{{_defaultCategory.name}}2"\s*,\s*)?value: {{_defaultProduct.price}}\s*,\s*currency: "[A-Z]+".*/</expectedResult> 42 | </assertRegExp> 43 | </test> 44 | </tests> 45 | -------------------------------------------------------------------------------- /Test/Unit/Controller/Adminhtml/Ajax/FbdeleteassetTest.php: -------------------------------------------------------------------------------- 1 | <?php 2 | /** 3 | * Copyright (c) Meta Platforms, Inc. and affiliates. All Rights Reserved 4 | */ 5 | 6 | namespace Facebook\BusinessExtension\Test\Unit\Controller\Adminhtml\Ajax; 7 | 8 | use FacebookAds\Object\ServerSide\AdsPixelSettings; 9 | 10 | class FbdeleteassetTest extends \PHPUnit\Framework\TestCase 11 | { 12 | 13 | protected $fbeHelper; 14 | 15 | protected $context; 16 | 17 | protected $resultJsonFactory; 18 | 19 | protected $fbdeleteasset; 20 | 21 | protected $request; 22 | 23 | /** 24 | * Used to reset or change values after running a test 25 | * 26 | * @return void 27 | */ 28 | public function tearDown() 29 | { 30 | } 31 | 32 | /** 33 | * Used to set the values before running a test 34 | * 35 | * @return void 36 | */ 37 | public function setUp() 38 | { 39 | $this->context = $this->createMock(\Magento\Backend\App\Action\Context::class); 40 | $this->resultJsonFactory = $this->createMock(\Magento\Framework\Controller\Result\JsonFactory::class); 41 | $this->fbeHelper = $this->createMock(\Facebook\BusinessExtension\Helper\FBEHelper::class); 42 | $this->request = $this->createMock(\Magento\Framework\App\RequestInterface::class); 43 | $this->context->method('getRequest')->willReturn($this->request); 44 | $this->fbdeleteasset = new \Facebook\BusinessExtension\Controller\Adminhtml\Ajax\Fbdeleteasset( 45 | $this->context, 46 | $this->resultJsonFactory, 47 | $this->fbeHelper 48 | ); 49 | } 50 | 51 | /** 52 | * 53 | * @return void 54 | */ 55 | public function testExecuteForJsonNull() 56 | { 57 | $this->fbeHelper->method('deleteConfigKeys') 58 | ->willReturn(null); 59 | $result = $this->fbdeleteasset->executeForJson(); 60 | $this->assertNull($result); 61 | } 62 | 63 | /** 64 | * 65 | * @return void 66 | */ 67 | public function testExecuteForJsonNotNull() 68 | { 69 | $expected = [ 70 | 'success' => true, 71 | 'message' => 'dummy', 72 | ]; 73 | $this->fbeHelper->method('deleteConfigKeys') 74 | ->willReturn($expected); 75 | $result = $this->fbdeleteasset->executeForJson(); 76 | $this->assertNotNull($result); 77 | $this->assertTrue($result['success']); 78 | $this->assertEquals('dummy', $result['message']); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /Test/Unit/Controller/Adminhtml/Ajax/FbpixelTest.php: -------------------------------------------------------------------------------- 1 | <?php 2 | /** 3 | * Copyright (c) Meta Platforms, Inc. and affiliates. All Rights Reserved 4 | */ 5 | 6 | namespace Facebook\BusinessExtension\Test\Unit\Controller\Adminhtml\Ajax; 7 | 8 | use FacebookAds\Object\ServerSide\AdsPixelSettings; 9 | 10 | class FbpixelTest extends \PHPUnit\Framework\TestCase 11 | { 12 | 13 | protected $fbeHelper; 14 | 15 | protected $context; 16 | 17 | protected $resultJsonFactory; 18 | 19 | protected $fbPixelTest; 20 | 21 | protected $request; 22 | 23 | /** 24 | * Used to reset or change values after running a test 25 | * 26 | * @return void 27 | */ 28 | public function tearDown() 29 | { 30 | } 31 | 32 | /** 33 | * Used to set the values before running a test 34 | * 35 | * @return void 36 | */ 37 | public function setUp() 38 | { 39 | $this->context = $this->createMock(\Magento\Backend\App\Action\Context::class); 40 | $this->resultJsonFactory = $this->createMock(\Magento\Framework\Controller\Result\JsonFactory::class); 41 | $this->fbeHelper = $this->createMock(\Facebook\BusinessExtension\Helper\FBEHelper::class); 42 | $this->request = $this->createMock(\Magento\Framework\App\RequestInterface::class); 43 | $this->context->method('getRequest')->willReturn($this->request); 44 | $this->fbPixelTest = new \Facebook\BusinessExtension\Controller\Adminhtml\Ajax\Fbpixel( 45 | $this->context, 46 | $this->resultJsonFactory, 47 | $this->fbeHelper 48 | ); 49 | } 50 | 51 | /** 52 | * 53 | * @return void 54 | */ 55 | public function testExecuteForJsonNoPixel() 56 | { 57 | $pixelId = '1234'; 58 | $this->request->method('getParam') 59 | ->willReturn(null); 60 | $this->fbeHelper->method('getConfigValue') 61 | ->willReturn($pixelId); 62 | $result = $this->fbPixelTest->executeForJson(); 63 | $this->assertNotNull($result); 64 | $this->assertFalse($result['success']); 65 | $this->assertEquals($pixelId, $result['pixelId']); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /Test/Unit/Controller/Adminhtml/Ajax/FbprofilesTest.php: -------------------------------------------------------------------------------- 1 | <?php 2 | /** 3 | * Copyright (c) Meta Platforms, Inc. and affiliates. All Rights Reserved 4 | */ 5 | 6 | namespace Facebook\BusinessExtension\Test\Unit\Controller\Adminhtml\Ajax; 7 | 8 | use FacebookAds\Object\ServerSide\AdsPixelSettings; 9 | 10 | class FbprofilesTest extends \PHPUnit\Framework\TestCase 11 | { 12 | 13 | protected $fbeHelper; 14 | 15 | protected $context; 16 | 17 | protected $resultJsonFactory; 18 | 19 | protected $fbprofiles; 20 | 21 | protected $request; 22 | 23 | /** 24 | * Used to reset or change values after running a test 25 | * 26 | * @return void 27 | */ 28 | public function tearDown() 29 | { 30 | } 31 | 32 | /** 33 | * Used to set the values before running a test 34 | * 35 | * @return void 36 | */ 37 | public function setUp() 38 | { 39 | $this->context = $this->createMock(\Magento\Backend\App\Action\Context::class); 40 | $this->resultJsonFactory = $this->createMock(\Magento\Framework\Controller\Result\JsonFactory::class); 41 | $this->fbeHelper = $this->createMock(\Facebook\BusinessExtension\Helper\FBEHelper::class); 42 | $this->request = $this->createMock(\Magento\Framework\App\RequestInterface::class); 43 | $this->context->method('getRequest')->willReturn($this->request); 44 | $this->fbprofiles = new \Facebook\BusinessExtension\Controller\Adminhtml\Ajax\Fbprofiles( 45 | $this->context, 46 | $this->resultJsonFactory, 47 | $this->fbeHelper 48 | ); 49 | } 50 | 51 | /** 52 | * 53 | * @return void 54 | */ 55 | public function testExecuteForJson() 56 | { 57 | $profiles = '1234'; 58 | $this->request->method('getParam') 59 | ->willReturn($profiles); 60 | $this->fbeHelper->method('getConfigValue') 61 | ->willReturn($profiles); 62 | $result = $this->fbprofiles->executeForJson(); 63 | $this->assertNotNull($result); 64 | $this->assertTrue($result['success']); 65 | $this->assertEquals($profiles, $result['profiles']); 66 | } 67 | 68 | /** 69 | * 70 | * @return void 71 | */ 72 | public function testExecuteForJsonNoProfiles() 73 | { 74 | $profiles = '1234'; 75 | $this->request->method('getParam')->willReturn(null); 76 | $this->fbeHelper->method('getConfigValue') 77 | ->willReturn($profiles); 78 | $result = $this->fbprofiles->executeForJson(); 79 | $this->assertNotNull($result); 80 | $this->assertFalse($result['success']); 81 | $this->assertEquals($profiles, $result['profiles']); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /Test/Unit/Controller/Adminhtml/Ajax/FbtokenTest.php: -------------------------------------------------------------------------------- 1 | <?php 2 | /** 3 | * Copyright (c) Meta Platforms, Inc. and affiliates. All Rights Reserved 4 | */ 5 | 6 | namespace Facebook\BusinessExtension\Test\Unit\Controller\Adminhtml\Ajax; 7 | 8 | use FacebookAds\Object\ServerSide\AdsPixelSettings; 9 | 10 | class FbtokenTest extends \PHPUnit\Framework\TestCase 11 | { 12 | 13 | protected $fbeHelper; 14 | 15 | protected $context; 16 | 17 | protected $resultJsonFactory; 18 | 19 | protected $fbtoken; 20 | 21 | protected $request; 22 | 23 | /** 24 | * Used to reset or change values after running a test 25 | * 26 | * @return void 27 | */ 28 | public function tearDown() 29 | { 30 | } 31 | 32 | /** 33 | * Used to set the values before running a test 34 | * 35 | * @return void 36 | */ 37 | public function setUp() 38 | { 39 | $this->context = $this->createMock(\Magento\Backend\App\Action\Context::class); 40 | $this->resultJsonFactory = $this->createMock(\Magento\Framework\Controller\Result\JsonFactory::class); 41 | $this->fbeHelper = $this->createMock(\Facebook\BusinessExtension\Helper\FBEHelper::class); 42 | $this->request = $this->createMock(\Magento\Framework\App\RequestInterface::class); 43 | $this->context->method('getRequest')->willReturn($this->request); 44 | $this->fbtoken = new \Facebook\BusinessExtension\Controller\Adminhtml\Ajax\Fbtoken( 45 | $this->context, 46 | $this->resultJsonFactory, 47 | $this->fbeHelper 48 | ); 49 | } 50 | 51 | /** 52 | * 53 | * @return void 54 | */ 55 | public function testExecuteForJson() 56 | { 57 | $accessToken = 'abcd'; 58 | $this->request->method('getParam') 59 | ->willReturn($accessToken); 60 | $this->fbeHelper->method('getConfigValue') 61 | ->willReturn($accessToken); 62 | $result = $this->fbtoken->executeForJson(); 63 | $this->assertNotNull($result); 64 | $this->assertTrue($result['success']); 65 | $this->assertEquals($accessToken, $result['accessToken']); 66 | } 67 | 68 | /** 69 | * 70 | * @return void 71 | */ 72 | public function testExecuteForJsonNoProfiles() 73 | { 74 | $accessToken = 'abcd'; 75 | $this->request->method('getParam') 76 | ->willReturn(null); 77 | $this->fbeHelper->method('getConfigValue') 78 | ->willReturn($accessToken); 79 | $result = $this->fbtoken->executeForJson(); 80 | $this->assertNotNull($result); 81 | $this->assertFalse($result['success']); 82 | $this->assertEquals($accessToken, $result['accessToken']); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /Test/Unit/Cron/AAMSettingsCronTest.php: -------------------------------------------------------------------------------- 1 | <?php 2 | /** 3 | * Copyright (c) Meta Platforms, Inc. and affiliates. All Rights Reserved 4 | */ 5 | 6 | namespace Facebook\BusinessExtension\Test\Unit\Cron; 7 | 8 | use FacebookAds\Object\ServerSide\AdsPixelSettings; 9 | 10 | use \Facebook\BusinessExtension\Helper\FBEHelper; 11 | use \Facebook\BusinessExtension\Cron\AAMSettingsCron; 12 | 13 | class EventIdGeneratorTest extends \PHPUnit\Framework\TestCase 14 | { 15 | 16 | protected $aamSettingsCron; 17 | 18 | protected $fbeHelper; 19 | /** 20 | * Used to reset or change values after running a test 21 | * 22 | * @return void 23 | */ 24 | public function tearDown() 25 | { 26 | } 27 | 28 | /** 29 | * Used to set the values before running a test 30 | * 31 | * @return void 32 | */ 33 | public function setUp() 34 | { 35 | $this->fbeHelper = $this->createMock(\Facebook\BusinessExtension\Helper\FBEHelper::class); 36 | $this->aamSettingsCron = new \Facebook\BusinessExtension\Cron\AAMSettingsCron($this->fbeHelper); 37 | } 38 | 39 | /** 40 | * Test that the settings returned by the cron object are null when there is no pixel in the db 41 | * 42 | * @return void 43 | */ 44 | public function testNullSettingsWhenNoPixelPresent() 45 | { 46 | $pixelId = null; 47 | 48 | $this->fbeHelper->method('getPixelID')->willReturn($pixelId); 49 | 50 | $result = $this->aamSettingsCron->execute(); 51 | 52 | $this->assertNull($result); 53 | } 54 | 55 | /** 56 | * Test that the settings returned by the cron object are null when they cannot be fetched 57 | * 58 | * @return void 59 | */ 60 | public function testNullSettingsWhenAAMSettingsNotFetched() 61 | { 62 | $pixelId = '1234'; 63 | 64 | $this->fbeHelper->method('getPixelID')->willReturn($pixelId); 65 | $this->fbeHelper->method('fetchAndSaveAAMSettings')->willReturn(null); 66 | 67 | $result = $this->aamSettingsCron->execute(); 68 | 69 | $this->assertNull($result); 70 | } 71 | 72 | /** 73 | * Test that the settings returned by the cron object are not null when pixel and aam settings are valid 74 | * 75 | * @return void 76 | */ 77 | public function testSettingsNotNullWhenPixelAndAAMSettingsAreValid() 78 | { 79 | $pixelId = '1234'; 80 | $settingsAsArray = [ 81 | "enableAutomaticMatching"=>false, 82 | "enabledAutomaticMatchingFields"=>['em'], 83 | "pixelId"=>$pixelId 84 | ]; 85 | $settingsAsString = json_encode($settingsAsArray); 86 | 87 | $this->fbeHelper->method('getPixelID')->willReturn($pixelId); 88 | $this->fbeHelper->method('fetchAndSaveAAMSettings')->willReturn($settingsAsString); 89 | 90 | $result = $this->aamSettingsCron->execute(); 91 | 92 | $this->assertEquals($settingsAsString, $result); 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /Test/Unit/Cron/CategorySyncCronTest.php: -------------------------------------------------------------------------------- 1 | <?php 2 | /** 3 | * Copyright (c) Meta Platforms, Inc. and affiliates. All Rights Reserved 4 | */ 5 | 6 | namespace Facebook\BusinessExtension\Test\Unit\Cron; 7 | 8 | use \Facebook\BusinessExtension\Helper\FBEHelper; 9 | use \Facebook\BusinessExtension\Cron\CategorySyncCron; 10 | use Facebook\BusinessExtension\Model\Feed\CategoryCollection; 11 | use Facebook\BusinessExtension\Model\System\Config as SystemConfig; 12 | 13 | class CronRunTest extends \PHPUnit\Framework\TestCase 14 | { 15 | 16 | protected $categorySyncCron; 17 | 18 | protected $fbeHelper; 19 | protected $categoryCollection; 20 | protected $systemConfig; 21 | /** 22 | * Used to reset or change values after running a test 23 | * 24 | * @return void 25 | */ 26 | public function tearDown() 27 | { 28 | } 29 | 30 | /** 31 | * Used to set the values before running a test 32 | * 33 | * @return void 34 | */ 35 | public function setUp() 36 | { 37 | $this->fbeHelper = $this->createMock(FBEHelper::class); 38 | $this->categoryCollection = $this->createMock(CategoryCollection::class); 39 | $this->systemConfig = $this->createMock(SystemConfig::class); 40 | $this->categorySyncCron = new \Facebook\BusinessExtension\Cron\CategorySyncCron( 41 | $this->fbeHelper, 42 | $this->categoryCollection, 43 | $this->systemConfig 44 | ); 45 | } 46 | 47 | /** 48 | * Test that the cron won't run when disabled by user 49 | * 50 | * @return void 51 | */ 52 | public function testNCronDisabled() 53 | { 54 | $this->systemConfig->method('isActiveCollectionsSync')->willReturn(false); 55 | 56 | $result = $this->categorySyncCron->execute(); 57 | 58 | $this->assertFalse($result); 59 | } 60 | 61 | /** 62 | * Test that cron will run when enabled by user 63 | * 64 | * @return void 65 | */ 66 | public function testNCronEnabled() 67 | { 68 | $this->systemConfig->method('isActiveCollectionsSync')->willReturn(true); 69 | 70 | $result = $this->categorySyncCron->execute(); 71 | 72 | $this->assertTrue($result); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /Test/Unit/Helper/EventIdGeneratorTest.php: -------------------------------------------------------------------------------- 1 | <?php 2 | /** 3 | * Copyright (c) Meta Platforms, Inc. and affiliates. All Rights Reserved 4 | */ 5 | 6 | namespace Facebook\BusinessExtension\Test\Unit\Helper; 7 | 8 | use \Facebook\BusinessExtension\Helper\EventIdGenerator; 9 | use PHPUnit\Framework\TestCase; 10 | 11 | class EventIdGeneratorTest extends TestCase 12 | { 13 | /** 14 | * Used to reset or change values after running a test 15 | * 16 | * @return void 17 | */ 18 | public function tearDown() 19 | { 20 | } 21 | 22 | /** 23 | * Used to set the values before running a test 24 | * 25 | * @return void 26 | */ 27 | public function setUp() 28 | { 29 | } 30 | 31 | /** 32 | * Test generation of unique event ids 33 | * 34 | * @return void 35 | */ 36 | public function testGeneratesUniqueValues() 37 | { 38 | $eventIds = []; 39 | for ($i = 0; $i < 100; $i++) { 40 | $eventIds[] = EventIdGenerator::guidv4(); 41 | } 42 | $eventIds = array_unique($eventIds); 43 | $this->assertEquals(100, count($eventIds)); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /Test/Unit/Helper/ServerSideHelperTest.php: -------------------------------------------------------------------------------- 1 | <?php 2 | /** 3 | * Copyright (c) Meta Platforms, Inc. and affiliates. All Rights Reserved 4 | */ 5 | 6 | namespace Facebook\BusinessExtension\Test\Unit\Helper; 7 | 8 | use Facebook\BusinessExtension\Helper\AAMFieldsExtractorHelper; 9 | use Facebook\BusinessExtension\Helper\FBEHelper; 10 | use \Facebook\BusinessExtension\Helper\ServerEventFactory; 11 | use Facebook\BusinessExtension\Helper\ServerSideHelper; 12 | use PHPUnit\Framework\TestCase; 13 | 14 | class ServerSideHelperTest extends TestCase 15 | { 16 | 17 | protected $fbeHelper; 18 | 19 | protected $serverSideHelper; 20 | 21 | protected $aamFieldsExtractorHelper; 22 | 23 | /** 24 | * Used to reset or change values after running a test 25 | * 26 | * @return void 27 | */ 28 | public function tearDown() 29 | { 30 | } 31 | 32 | /** 33 | * Used to set the values before running a test 34 | * 35 | * @return void 36 | */ 37 | public function setUp() 38 | { 39 | $this->fbeHelper = $this->createMock(FBEHelper::class); 40 | $this->aamFieldsExtractorHelper = 41 | $this->createMock(AAMFieldsExtractorHelper::class); 42 | $this->serverSideHelper = 43 | new ServerSideHelper($this->fbeHelper, $this->aamFieldsExtractorHelper); 44 | $this->fbeHelper->method('getAccessToken')->willReturn('abc'); 45 | $this->fbeHelper->method('getPixelID')->willReturn('123'); 46 | } 47 | 48 | public function testEventAddedToTrackedEvents() 49 | { 50 | $event = ServerEventFactory::createEvent('ViewContent', []); 51 | $this->aamFieldsExtractorHelper->method('setUserData')->willReturn($event); 52 | $this->serverSideHelper->sendEvent($event); 53 | $this->assertEquals(1, count($this->serverSideHelper->getTrackedEvents())); 54 | $event = $this->serverSideHelper->getTrackedEvents()[0]; 55 | $this->assertEquals('ViewContent', $event->getEventName()); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /Test/Unit/Observer/AddToCartTest.php: -------------------------------------------------------------------------------- 1 | <?php 2 | /** 3 | * Copyright (c) Meta Platforms, Inc. and affiliates. All Rights Reserved 4 | */ 5 | 6 | namespace Facebook\BusinessExtension\Test\Unit\Observer; 7 | 8 | use Facebook\BusinessExtension\Observer\AddToCart; 9 | use Magento\Framework\App\RequestInterface; 10 | use Magento\Framework\Event\Observer; 11 | 12 | class AddToCartTest extends CommonTest 13 | { 14 | 15 | protected $request; 16 | 17 | protected $addToCartObserver; 18 | 19 | /** 20 | * Used to reset or change values after running a test 21 | * 22 | * @return void 23 | */ 24 | public function tearDown() 25 | { 26 | } 27 | 28 | /** 29 | * Used to set the values before running a test 30 | * 31 | * @return void 32 | */ 33 | public function setUp() 34 | { 35 | parent::setUp(); 36 | $this->request = $this->createMock(RequestInterface::class); 37 | $this->addToCartObserver = new AddToCart( 38 | $this->fbeHelper, 39 | $this->magentoDataHelper, 40 | $this->serverSideHelper, 41 | $this->request 42 | ); 43 | } 44 | 45 | public function testAddToCartEventCreated() 46 | { 47 | $this->magentoDataHelper->method('getValueForProduct')->willReturn(12.99); 48 | $this->magentoDataHelper->method('getCategoriesForProduct')->willReturn('Electronics'); 49 | $product = $this->objectManager->getObject('\Magento\Catalog\Model\Product'); 50 | $product->setId(123); 51 | $product->setName('Earphones'); 52 | $this->request->method('getParam')->willReturn('123'); 53 | $this->magentoDataHelper->method('getProductWithSku')->willReturn($product); 54 | 55 | $observer = new Observer(['eventId' => '1234']); 56 | 57 | $this->addToCartObserver->execute($observer); 58 | 59 | $this->assertEquals(1, count($this->serverSideHelper->getTrackedEvents())); 60 | 61 | $event = $this->serverSideHelper->getTrackedEvents()[0]; 62 | 63 | $this->assertEquals('1234', $event->getEventId()); 64 | 65 | $customDataArray = [ 66 | 'currency' => 'USD', 67 | 'value' => 12.99, 68 | 'content_type' => 'product', 69 | 'content_ids' => [123], 70 | 'content_category' => 'Electronics', 71 | 'content_name' => 'Earphones' 72 | ]; 73 | 74 | $this->assertEqualsCustomData($customDataArray, $event->getCustomData()); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /Test/Unit/Observer/InitiateCheckoutTest.php: -------------------------------------------------------------------------------- 1 | <?php 2 | /** 3 | * Copyright (c) Meta Platforms, Inc. and affiliates. All Rights Reserved 4 | */ 5 | 6 | namespace Facebook\BusinessExtension\Test\Unit\Observer; 7 | 8 | use Facebook\BusinessExtension\Observer\InitiateCheckout; 9 | use Magento\Framework\Event\Observer; 10 | 11 | class InitiateCheckoutTest extends CommonTest 12 | { 13 | 14 | protected $initiateCheckoutObserver; 15 | 16 | /** 17 | * Used to reset or change values after running a test 18 | * 19 | * @return void 20 | */ 21 | public function tearDown() 22 | { 23 | } 24 | 25 | /** 26 | * Used to set the values before running a test 27 | * 28 | * @return void 29 | */ 30 | public function setUp() 31 | { 32 | parent::setUp(); 33 | $this->initiateCheckoutObserver = 34 | new InitiateCheckout( 35 | $this->fbeHelper, 36 | $this->magentoDataHelper, 37 | $this->serverSideHelper 38 | ); 39 | } 40 | 41 | public function testInitiateCheckoutEventCreated() 42 | { 43 | $this->magentoDataHelper->method('getCartTotal')->willReturn(170); 44 | $this->magentoDataHelper->method('getCartContentIds')->willReturn( 45 | [1, 2] 46 | ); 47 | $this->magentoDataHelper->method('getCartContents')->willReturn( 48 | [ 49 | [ 'product_id'=>1, 'quantity'=>1, 'item_price' =>20 ], 50 | [ 'product_id'=>2, 'quantity'=>3, 'item_price' =>50 ] 51 | ] 52 | ); 53 | $this->magentoDataHelper->method('getCartNumItems')->willReturn(4); 54 | 55 | $observer = new Observer(['eventId' => '1234']); 56 | 57 | $this->initiateCheckoutObserver->execute($observer); 58 | 59 | $this->assertEquals(1, count($this->serverSideHelper->getTrackedEvents())); 60 | 61 | $event = $this->serverSideHelper->getTrackedEvents()[0]; 62 | 63 | $this->assertEquals('1234', $event->getEventId()); 64 | 65 | $customDataArray = [ 66 | 'currency' => 'USD', 67 | 'value' => 170, 68 | 'content_type' => 'product', 69 | 'content_ids' => [1, 2], 70 | 'contents' => [ 71 | [ 'product_id'=>1, 'quantity'=>1, 'item_price' =>20 ], 72 | [ 'product_id'=>2, 'quantity'=>3, 'item_price' =>50 ] 73 | ], 74 | 'num_items' => 4 75 | ]; 76 | 77 | $this->assertEqualsCustomData($customDataArray, $event->getCustomData()); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /Test/Unit/Observer/ProcessCategoryAfterDeleteEventObserverTest.php: -------------------------------------------------------------------------------- 1 | <?php 2 | /** 3 | * Copyright (c) Meta Platforms, Inc. and affiliates. All Rights Reserved 4 | */ 5 | 6 | namespace Facebook\BusinessExtension\Test\Unit\Observer; 7 | 8 | use Facebook\BusinessExtension\Model\Feed\CategoryCollection; 9 | use Magento\Catalog\Model\Category; 10 | use Magento\Framework\Event; 11 | use PHPUnit\Framework\MockObject\MockObject; 12 | 13 | class ProcessCategoryAfterDeleteEventObserverTest extends CommonTest 14 | { 15 | 16 | protected $processCategoryAfterDeleteEventObserver; 17 | /** 18 | * @var MockObject 19 | */ 20 | private $_eventObserverMock; 21 | /** 22 | * @var MockObject 23 | */ 24 | private $_category; 25 | 26 | /** 27 | * Used to reset or change values after running a test 28 | * 29 | * @return void 30 | */ 31 | public function tearDown() 32 | { 33 | } 34 | 35 | /** 36 | * Used to set the values before running a test 37 | * 38 | * @return void 39 | */ 40 | public function setUp() 41 | { 42 | parent::setUp(); 43 | $this->_category = $this->createMock(Category::class); 44 | $event = $this->createPartialMock(Event::class, ['getCategory']); 45 | $event->expects($this->once())->method('getCategory')->will($this->returnValue($this->_category)); 46 | $this->_eventObserverMock = $this->createMock(\Magento\Framework\Event\Observer::class); 47 | $this->_eventObserverMock->expects($this->once())->method('getEvent')->will($this->returnValue($event)); 48 | $this->processCategoryAfterDeleteEventObserver = 49 | new \Facebook\BusinessExtension\Observer\ProcessCategoryAfterDeleteEventObserver($this->fbeHelper); 50 | } 51 | 52 | public function testExcution() 53 | { 54 | $categoryObj = $this->createMock(CategoryCollection::class); 55 | $this->fbeHelper->expects($this->once())->method('getObject')->willReturn($categoryObj); 56 | $this->fbeHelper->expects($this->once())->method('log')->willReturn(null); 57 | 58 | $categoryObj->expects($this->once())->method('deleteCategoryAndSubCategoryFromFB')->willReturn('good'); 59 | $this->processCategoryAfterDeleteEventObserver->execute($this->_eventObserverMock); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /Test/Unit/Observer/ProcessCategoryAfterSaveEventObserverTest.php: -------------------------------------------------------------------------------- 1 | <?php 2 | /** 3 | * Copyright (c) Meta Platforms, Inc. and affiliates. All Rights Reserved 4 | */ 5 | 6 | namespace Facebook\BusinessExtension\Test\Unit\Observer; 7 | 8 | class ProcessCategoryAfterSaveEventObserverTest extends CommonTest 9 | { 10 | 11 | protected $processCategoryAfterSaveEventObserver; 12 | /** 13 | * @var \PHPUnit\Framework\MockObject\MockObject 14 | */ 15 | private $_eventObserverMock; 16 | /** 17 | * @var \PHPUnit\Framework\MockObject\MockObject 18 | */ 19 | private $_category; 20 | 21 | /** 22 | * Used to reset or change values after running a test 23 | * 24 | * @return void 25 | */ 26 | public function tearDown() 27 | { 28 | } 29 | 30 | /** 31 | * Used to set the values before running a test 32 | * 33 | * @return void 34 | */ 35 | public function setUp() 36 | { 37 | parent::setUp(); 38 | $this->_category = $this->createMock(\Magento\Catalog\Model\Category::class); 39 | $event = $this->createPartialMock(\Magento\Framework\Event::class, ['getCategory']); 40 | $event->expects($this->once())->method('getCategory')->will($this->returnValue($this->_category)); 41 | $this->_eventObserverMock = $this->createMock(\Magento\Framework\Event\Observer::class); 42 | $this->_eventObserverMock->expects($this->once())->method('getEvent')->will($this->returnValue($event)); 43 | $this->processCategoryAfterSaveEventObserver = 44 | new \Facebook\BusinessExtension\Observer\ProcessCategoryAfterSaveEventObserver($this->fbeHelper); 45 | } 46 | 47 | public function testExcution() 48 | { 49 | $categoryObj = $this->createMock(\Facebook\BusinessExtension\Model\Feed\CategoryCollection::class); 50 | $this->fbeHelper->expects($this->once())->method('getObject')->willReturn($categoryObj); 51 | $this->fbeHelper->expects($this->once())->method('log'); 52 | 53 | $categoryObj->expects($this->once())->method('makeHttpRequestAfterCategorySave')->willReturn('good'); 54 | $res = $this->processCategoryAfterSaveEventObserver->execute($this->_eventObserverMock); 55 | $this->assertNotNull($res); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /Test/Unit/Observer/ProcessProductAfterDeleteEventObserverTest.php: -------------------------------------------------------------------------------- 1 | <?php 2 | /** 3 | * Copyright (c) Meta Platforms, Inc. and affiliates. All Rights Reserved 4 | */ 5 | 6 | namespace Facebook\BusinessExtension\Test\Unit\Observer; 7 | 8 | use Facebook\BusinessExtension\Observer\ProcessProductAfterDeleteEventObserver; 9 | use Magento\Catalog\Model\Product; 10 | use Magento\Framework\Event; 11 | use Magento\Framework\Event\Observer; 12 | use PHPUnit\Framework\MockObject\MockObject; 13 | 14 | class ProcessProductAfterDeleteEventObserverTest extends CommonTest 15 | { 16 | 17 | protected $processProductAfterDeleteEventObserver; 18 | /** 19 | * @var MockObject 20 | */ 21 | private $_eventObserverMock; 22 | /** 23 | * @var MockObject 24 | */ 25 | private $_product; 26 | 27 | /** 28 | * Used to reset or change values after running a test 29 | * 30 | * @return void 31 | */ 32 | public function tearDown() 33 | { 34 | } 35 | 36 | /** 37 | * Used to set the values before running a test 38 | * 39 | * @return void 40 | */ 41 | public function setUp() 42 | { 43 | parent::setUp(); 44 | $this->_product = $this->createMock(Product::class); 45 | $this->_product->expects($this->atLeastOnce())->method('getId')->will($this->returnValue("1234")); 46 | $this->_product->expects($this->never())->method('getSku'); 47 | 48 | $event = $this->createPartialMock(Event::class, ['getProduct']); 49 | $event->expects($this->once())->method('getProduct')->will($this->returnValue($this->_product)); 50 | $this->_eventObserverMock = $this->createMock(Observer::class); 51 | $this->_eventObserverMock->expects($this->once())->method('getEvent')->will($this->returnValue($event)); 52 | $this->processProductAfterDeleteEventObserver = 53 | new ProcessProductAfterDeleteEventObserver($this->fbeHelper); 54 | } 55 | 56 | public function testExcution() 57 | { 58 | $this->fbeHelper->expects($this->atLeastOnce())->method('makeHttpRequest'); 59 | $this->processProductAfterDeleteEventObserver->execute($this->_eventObserverMock); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /Test/Unit/Observer/ProcessProductAfterSaveEventObserverTest.php: -------------------------------------------------------------------------------- 1 | <?php 2 | /** 3 | * Copyright (c) Meta Platforms, Inc. and affiliates. All Rights Reserved 4 | */ 5 | 6 | namespace Facebook\BusinessExtension\Test\Unit\Observer; 7 | 8 | use Facebook\BusinessExtension\Model\Product\Feed\Method\BatchApi; 9 | use Facebook\BusinessExtension\Observer\ProcessProductAfterSaveEventObserver; 10 | use Magento\Catalog\Model\Product; 11 | use Magento\Framework\Event; 12 | use Magento\Framework\Event\Observer; 13 | use Magento\Store\Api\Data\StoreInterface; 14 | use PHPUnit\Framework\MockObject\MockObject; 15 | 16 | class ProcessProductAfterSaveEventObserverTest extends CommonTest 17 | { 18 | 19 | protected $processProductAfterSaveEventObserver; 20 | /** 21 | * @var MockObject 22 | */ 23 | private $_eventObserverMock; 24 | /** 25 | * @var MockObject 26 | */ 27 | private $_product; 28 | /** 29 | * @var MockObject 30 | */ 31 | private $store; 32 | /** 33 | * @var MockObject 34 | */ 35 | private $_batchApi; 36 | 37 | /** 38 | * Used to reset or change values after running a test 39 | * 40 | * @return void 41 | */ 42 | public function tearDown() 43 | { 44 | } 45 | 46 | /** 47 | * Used to set the values before running a test 48 | * 49 | * @return void 50 | */ 51 | public function setUp() 52 | { 53 | parent::setUp(); 54 | $this->store = $this->createMock(StoreInterface::class); 55 | $this->fbeHelper->expects($this->once())->method('getStore')->will($this->returnValue($this->store)); 56 | $this->_product = $this->createMock(Product::class); 57 | $this->_product->expects($this->once())->method('getId')->will($this->returnValue("1234")); 58 | $event = $this->createPartialMock(Event::class, ['getProduct']); 59 | $event->expects($this->once())->method('getProduct')->will($this->returnValue($this->_product)); 60 | $this->_eventObserverMock = $this->createMock(Observer::class); 61 | $this->_eventObserverMock->expects($this->once())->method('getEvent')->will($this->returnValue($event)); 62 | $this->_batchApi = $this->createMock(BatchApi::class); 63 | $this->processProductAfterSaveEventObserver = 64 | new ProcessProductAfterSaveEventObserver( 65 | $this->fbeHelper, 66 | $this->_batchApi 67 | ); 68 | } 69 | 70 | public function testExcution() 71 | { 72 | $this->_batchApi->expects($this->once())->method('buildProductRequest'); 73 | $this->fbeHelper->expects($this->atLeastOnce())->method('makeHttpRequest'); 74 | $this->processProductAfterSaveEventObserver->execute($this->_eventObserverMock); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /Test/Unit/Observer/PurchaseTest.php: -------------------------------------------------------------------------------- 1 | <?php 2 | /** 3 | * Copyright (c) Meta Platforms, Inc. and affiliates. All Rights Reserved 4 | */ 5 | 6 | namespace Facebook\BusinessExtension\Test\Unit\Observer; 7 | 8 | use Facebook\BusinessExtension\Observer\Purchase; 9 | use Magento\Framework\Event\Observer; 10 | 11 | class PurchaseTest extends CommonTest 12 | { 13 | 14 | protected $purchaseObserver; 15 | 16 | /** 17 | * Used to reset or change values after running a test 18 | * 19 | * @return void 20 | */ 21 | public function tearDown() 22 | { 23 | } 24 | 25 | /** 26 | * Used to set the values before running a test 27 | * 28 | * @return void 29 | */ 30 | public function setUp() 31 | { 32 | parent::setUp(); 33 | $this->purchaseObserver = 34 | new Purchase( 35 | $this->fbeHelper, 36 | $this->magentoDataHelper, 37 | $this->serverSideHelper 38 | ); 39 | } 40 | 41 | public function testPurchaseEventCreated() 42 | { 43 | $this->magentoDataHelper->method('getOrderTotal')->willReturn(170); 44 | $this->magentoDataHelper->method('getOrderContentIds')->willReturn( 45 | [1, 2] 46 | ); 47 | $this->magentoDataHelper->method('getOrderContents')->willReturn( 48 | [ 49 | [ 'product_id'=>1, 'quantity'=>1, 'item_price' =>20 ], 50 | [ 'product_id'=>2, 'quantity'=>3, 'item_price' =>50 ] 51 | ] 52 | ); 53 | $this->magentoDataHelper->method('getOrderId')->willReturn(1); 54 | 55 | $observer = new Observer(['eventId' => '1234']); 56 | 57 | $this->purchaseObserver->execute($observer); 58 | 59 | $this->assertEquals(1, count($this->serverSideHelper->getTrackedEvents())); 60 | 61 | $event = $this->serverSideHelper->getTrackedEvents()[0]; 62 | 63 | $this->assertEquals('1234', $event->getEventId()); 64 | 65 | $customDataArray = [ 66 | 'currency' => 'USD', 67 | 'value' => 170, 68 | 'content_type' => 'product', 69 | 'content_ids' => [1, 2], 70 | 'contents' => [ 71 | [ 'product_id'=>1, 'quantity'=>1, 'item_price' =>20 ], 72 | [ 'product_id'=>2, 'quantity'=>3, 'item_price' =>50 ] 73 | ], 74 | 'order_id' => 1 75 | ]; 76 | 77 | $this->assertEqualsCustomData($customDataArray, $event->getCustomData()); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /Test/Unit/Observer/SearchTest.php: -------------------------------------------------------------------------------- 1 | <?php 2 | /** 3 | * Copyright (c) Meta Platforms, Inc. and affiliates. All Rights Reserved 4 | */ 5 | 6 | namespace Facebook\BusinessExtension\Test\Unit\Observer; 7 | 8 | use Facebook\BusinessExtension\Observer\Search; 9 | use Magento\Framework\App\RequestInterface; 10 | use Magento\Framework\Event\Observer; 11 | 12 | class SearchTest extends CommonTest 13 | { 14 | 15 | protected $request; 16 | 17 | protected $searchObserver; 18 | 19 | /** 20 | * Used to reset or change values after running a test 21 | * 22 | * @return void 23 | */ 24 | public function tearDown() 25 | { 26 | } 27 | 28 | /** 29 | * Used to set the values before running a test 30 | * 31 | * @return void 32 | */ 33 | public function setUp() 34 | { 35 | parent::setUp(); 36 | $this->request = $this->createMock(RequestInterface::class); 37 | $this->searchObserver = 38 | new Search($this->fbeHelper, $this->serverSideHelper, $this->request); 39 | } 40 | 41 | public function testSearchEventCreated() 42 | { 43 | $this->request->method('getParam')->willReturn('Door'); 44 | 45 | $observer = new Observer(['eventId' => '1234']); 46 | 47 | $this->searchObserver->execute($observer); 48 | 49 | $this->assertEquals(1, count($this->serverSideHelper->getTrackedEvents())); 50 | 51 | $event = $this->serverSideHelper->getTrackedEvents()[0]; 52 | 53 | $this->assertEquals('1234', $event->getEventId()); 54 | 55 | $customDataArray = [ 56 | 'search_string' => 'Door' 57 | ]; 58 | 59 | $this->assertEqualsCustomData($customDataArray, $event->getCustomData()); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /Test/Unit/Observer/ViewCategoryTest.php: -------------------------------------------------------------------------------- 1 | <?php 2 | /** 3 | * Copyright (c) Meta Platforms, Inc. and affiliates. All Rights Reserved 4 | */ 5 | 6 | namespace Facebook\BusinessExtension\Test\Unit\Observer; 7 | 8 | use Facebook\BusinessExtension\Observer\ViewCategory; 9 | use Magento\Framework\Event\Observer; 10 | use Magento\Framework\Registry; 11 | 12 | class ViewCategoryTest extends CommonTest 13 | { 14 | 15 | protected $registry; 16 | 17 | protected $viewCategoryObserver; 18 | 19 | /** 20 | * Used to reset or change values after running a test 21 | * 22 | * @return void 23 | */ 24 | public function tearDown() 25 | { 26 | } 27 | 28 | /** 29 | * Used to set the values before running a test 30 | * 31 | * @return void 32 | */ 33 | public function setUp() 34 | { 35 | parent::setUp(); 36 | $this->registry = $this->createMock(Registry::class); 37 | $this->viewCategoryObserver = 38 | new ViewCategory( 39 | $this->fbeHelper, 40 | $this->serverSideHelper, 41 | $this->registry 42 | ); 43 | } 44 | 45 | public function testViewCategoryEventCreated() 46 | { 47 | $category = $this->objectManager->getObject('Magento\Catalog\Model\Category'); 48 | $category->setName('Electronics'); 49 | $this->registry->method('registry')->willReturn($category); 50 | 51 | $observer = new Observer(['eventId' => '1234']); 52 | 53 | $this->viewCategoryObserver->execute($observer); 54 | 55 | $this->assertEquals(1, count($this->serverSideHelper->getTrackedEvents())); 56 | 57 | $event = $this->serverSideHelper->getTrackedEvents()[0]; 58 | 59 | $this->assertEquals('1234', $event->getEventId()); 60 | 61 | $customDataArray = [ 62 | 'content_category' => 'Electronics' 63 | ]; 64 | 65 | $this->assertEqualsCustomData($customDataArray, $event->getCustomData()); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /Test/Unit/Observer/ViewContentTest.php: -------------------------------------------------------------------------------- 1 | <?php 2 | /** 3 | * Copyright (c) Meta Platforms, Inc. and affiliates. All Rights Reserved 4 | */ 5 | 6 | namespace Facebook\BusinessExtension\Test\Unit\Observer; 7 | 8 | use Facebook\BusinessExtension\Observer\ViewContent; 9 | use Magento\Framework\Event\Observer; 10 | use Magento\Framework\Registry; 11 | 12 | class ViewContentTest extends CommonTest 13 | { 14 | 15 | protected $registry; 16 | 17 | protected $viewContentObserver; 18 | 19 | /** 20 | * Used to reset or change values after running a test 21 | * 22 | * @return void 23 | */ 24 | public function tearDown() 25 | { 26 | } 27 | 28 | /** 29 | * Used to set the values before running a test 30 | * 31 | * @return void 32 | */ 33 | public function setUp() 34 | { 35 | parent::setUp(); 36 | $this->registry = $this->createMock(Registry::class); 37 | $this->viewContentObserver = 38 | new ViewContent( 39 | $this->fbeHelper, 40 | $this->serverSideHelper, 41 | $this->magentoDataHelper, 42 | $this->registry 43 | ); 44 | } 45 | 46 | public function testViewContentEventCreated() 47 | { 48 | $this->magentoDataHelper->method('getValueForProduct')->willReturn(12.99); 49 | $this->magentoDataHelper->method('getCategoriesForProduct')->willReturn('Electronics'); 50 | $product = $this->objectManager->getObject('\Magento\Catalog\Model\Product'); 51 | $product->setId(123); 52 | $product->setName('Earphones'); 53 | $this->registry->method('registry')->willReturn($product); 54 | 55 | $observer = new Observer(['eventId' => '1234']); 56 | 57 | $this->viewContentObserver->execute($observer); 58 | 59 | $this->assertEquals(1, count($this->serverSideHelper->getTrackedEvents())); 60 | 61 | $event = $this->serverSideHelper->getTrackedEvents()[0]; 62 | 63 | $this->assertEquals('1234', $event->getEventId()); 64 | 65 | $customDataArray = [ 66 | 'currency' => 'USD', 67 | 'value' => 12.99, 68 | 'content_type' => 'product', 69 | 'content_ids' => [123], 70 | 'content_category' => 'Electronics', 71 | 'content_name' => 'Earphones' 72 | ]; 73 | 74 | $this->assertEqualsCustomData($customDataArray, $event->getCustomData()); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "facebook/facebook-for-magento2", 3 | "description": "Facebook Business Extension for Magento 2", 4 | "type": "magento2-module", 5 | "license": "GPL-1.0-or-later", 6 | "version": "1.4.7", 7 | "require": { 8 | "facebook/php-business-sdk": ">=15.0.0" 9 | }, 10 | "repositories": [ 11 | { 12 | "type": "github", 13 | "url": "https://github.com/facebookincubator/facebook-for-magento2" 14 | } 15 | ], 16 | "conflict": { 17 | "meta/meta-for-magento2": "*" 18 | }, 19 | "abandoned": "meta/meta-for-magento2", 20 | "autoload": { 21 | "files": [ "registration.php" ], 22 | "psr-4": { 23 | "Facebook\\BusinessExtension\\": "" 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /etc/acl.xml: -------------------------------------------------------------------------------- 1 | <?xml version="1.0"?> 2 | <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Acl/etc/acl.xsd"> 3 | <acl> 4 | <resources> 5 | <resource id="Magento_Backend::admin"> 6 | <resource id="Facebook_BusinessExtension::facebook" title="Facebook Business Extension" sortOrder="51"> 7 | <resource id="Facebook_BusinessExtension::system_config" title="Setup" sortOrder="99" /> 8 | </resource> 9 | </resource> 10 | </resources> 11 | </acl> 12 | </config> 13 | -------------------------------------------------------------------------------- /etc/adminhtml/events.xml: -------------------------------------------------------------------------------- 1 | <?xml version="1.0"?> 2 | <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd"> 3 | <event name="catalog_product_delete_after_done"> 4 | <observer name="custom_delete_product" instance="Facebook\BusinessExtension\Observer\ProcessProductAfterDeleteEventObserver" /> 5 | </event> 6 | <event name="catalog_product_save_after"> 7 | <observer name="custom_save_product" instance="Facebook\BusinessExtension\Observer\ProcessProductAfterSaveEventObserver" /> 8 | </event> 9 | <event name="catalog_category_save_after"> 10 | <observer name="custom_save_category" instance="Facebook\BusinessExtension\Observer\ProcessCategoryAfterSaveEventObserver" /> 11 | </event> 12 | <event name="catalog_category_delete_after"> 13 | <observer name="custom_delete_category" instance="Facebook\BusinessExtension\Observer\ProcessCategoryAfterDeleteEventObserver" /> 14 | </event> 15 | </config> 16 | -------------------------------------------------------------------------------- /etc/adminhtml/menu.xml: -------------------------------------------------------------------------------- 1 | <?xml version="1.0"?> 2 | <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Backend:etc/menu.xsd"> 3 | <menu> 4 | <add 5 | id="Facebook_BusinessExtension::facebook" 6 | title="Facebook" 7 | translate="title" 8 | module="Facebook_BusinessExtension" 9 | parent="Magento_Backend::stores" 10 | sortOrder="50" 11 | dependsOnModule="Facebook_BusinessExtension" 12 | resource="Facebook_BusinessExtension::facebook"/> 13 | <add 14 | id="Facebook_BusinessExtension::facebook_business_extension" 15 | title="Setup" 16 | translate="title" 17 | module="Facebook_BusinessExtension" 18 | parent="Facebook_BusinessExtension::facebook" 19 | sortOrder="10" 20 | dependsOnModule="Facebook_BusinessExtension" 21 | action="fbeadmin/setup/index" 22 | resource="Facebook_BusinessExtension::facebook"/> 23 | <add 24 | id="Facebook_BusinessExtension::facebook_business_extension_info" 25 | title="Info" 26 | translate="title" 27 | module="Facebook_BusinessExtension" 28 | parent="Facebook_BusinessExtension::facebook" 29 | sortOrder="10" 30 | dependsOnModule="Facebook_BusinessExtension" 31 | action="fbeadmin/info/index" 32 | resource="Facebook_BusinessExtension::facebook"/> 33 | </menu> 34 | </config> 35 | -------------------------------------------------------------------------------- /etc/adminhtml/routes.xml: -------------------------------------------------------------------------------- 1 | <?xml version="1.0"?> 2 | <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd"> 3 | <router id="admin"> 4 | <route id="fbeadmin" frontName="fbeadmin"> 5 | <module name="Facebook_BusinessExtension"/> 6 | </route> 7 | </router> 8 | </config> 9 | -------------------------------------------------------------------------------- /etc/adminhtml/system.xml: -------------------------------------------------------------------------------- 1 | <?xml version="1.0"?> 2 | <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd"> 3 | <system> 4 | <tab id="facebook" translate="label" sortOrder="1000"> 5 | <label>Facebook</label> 6 | </tab> 7 | <section id="facebook_business_extension" translate="label" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1"> 8 | <class>separator-top</class> 9 | <label>Business Extension</label> 10 | <tab>facebook</tab> 11 | <resource>Facebook_BusinessExtension::system_config</resource> 12 | <group id="catalog_management" translate="label" type="text" sortOrder="20" showInDefault="1" showInWebsite="1" showInStore="1"> 13 | <label>Catalog Management</label> 14 | <field id="product_feed" translate="label" type="text" sortOrder="30" showInDefault="1" showInWebsite="1" showInStore="1"> 15 | <label>Push Products</label> 16 | <frontend_model>Facebook\BusinessExtension\Block\Adminhtml\System\Config\ProductFeed</frontend_model> 17 | </field> 18 | <field id="category_feed" translate="label" type="text" sortOrder="40" showInDefault="1" showInWebsite="1" showInStore="1"> 19 | <label>Push All Categories to Facebook Catalog</label> 20 | <frontend_model>Facebook\BusinessExtension\Block\Adminhtml\System\Config\CategoryFeed</frontend_model> 21 | </field> 22 | <field id="catalog_sync" translate="label comment" type="select" sortOrder="100" showInDefault="1" showInWebsite="1" showInStore="1"> 23 | <label>Enable Catalog Sync</label> 24 | <config_path>facebook/catalog_management/catalog_sync</config_path> 25 | <source_model>Magento\Config\Model\Config\Source\Yesno</source_model> 26 | <comment>Turns on/off catalog synchronization and incremental product uploads to Facebook</comment> 27 | </field> 28 | </group> 29 | <group id="inventory_management" translate="label" type="text" sortOrder="20" showInDefault="1" showInWebsite="1" showInStore="1"> 30 | <label>Inventory Management</label> 31 | <field id="out_of_stock_threshold" translate="label comment" type="text" sortOrder="20" showInDefault="1" showInWebsite="0" showInStore="1"> 32 | <label>Out-of-Stock Threshold</label> 33 | <config_path>facebook/inventory_management/out_of_stock_threshold</config_path> 34 | <comment>Product's availability will be out of stock if inventory count is lower than the specified threshold value</comment> 35 | </field> 36 | </group> 37 | </section> 38 | </system> 39 | </config> 40 | -------------------------------------------------------------------------------- /etc/config.xml: -------------------------------------------------------------------------------- 1 | <?xml version="1.0"?> 2 | <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Store:etc/config.xsd"> 3 | <default> 4 | <facebook> 5 | <catalog_management> 6 | <catalog_sync>1</catalog_sync> 7 | </catalog_management> 8 | <inventory_management> 9 | <out_of_stock_threshold>0</out_of_stock_threshold> 10 | </inventory_management> 11 | </facebook> 12 | </default> 13 | </config> 14 | -------------------------------------------------------------------------------- /etc/crontab.xml: -------------------------------------------------------------------------------- 1 | <?xml version="1.0"?> 2 | 3 | <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Cron:etc/crontab.xsd"> 4 | 5 | <group id="default"> 6 | 7 | <job name="facebook_business_extension_aam_settings_cronjob" instance="Facebook\BusinessExtension\Cron\AAMSettingsCron" method="execute"> 8 | 9 | <!--Check this document to read more about cron jobs in Magento: https://devdocs.magento.com/guides/v2.4/config-guide/cron/custom-cron-ref.html--> 10 | <schedule>*/20 * * * *</schedule> 11 | 12 | </job> 13 | <job name="facebook_business_extension_category_sync_cronjob" instance="Facebook\BusinessExtension\Cron\CategorySyncCron" method="execute"> 14 | <!-- daily at 0:0--> 15 | <schedule>0 0 * * *</schedule> 16 | 17 | </job> 18 | </group> 19 | 20 | </config> 21 | -------------------------------------------------------------------------------- /etc/csp_whitelist.xml: -------------------------------------------------------------------------------- 1 | <?xml version="1.0"?> 2 | <csp_whitelist xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Csp:etc/csp_whitelist.xsd"> 3 | <policies> 4 | <policy id="script-src"> 5 | <values> 6 | <value id="facebook" type="host">www.facebook.com</value> 7 | <value id="facebook-connect" type="host">connect.facebook.net</value> 8 | <value id="facebook-graph-api" type="host">graph.facebook.com</value> 9 | <value id="facebook-business" type="host">business.facebook.com</value> 10 | </values> 11 | </policy> 12 | <policy id="connect-src"> 13 | <values> 14 | <value id="facebook" type="host">www.facebook.com</value> 15 | <value id="facebook-connect" type="host">connect.facebook.net</value> 16 | <value id="facebook-graph-api" type="host">graph.facebook.com</value> 17 | <value id="facebook-business" type="host">business.facebook.com</value> 18 | </values> 19 | </policy> 20 | <policy id="frame-src"> 21 | <values> 22 | <value id="facebook" type="host">www.facebook.com</value> 23 | <value id="facebook-connect" type="host">connect.facebook.net</value> 24 | <value id="facebook-graph-api" type="host">graph.facebook.com</value> 25 | <value id="facebook-business" type="host">business.facebook.com</value> 26 | </values> 27 | </policy> 28 | <policy id="img-src"> 29 | <values> 30 | <value id="facebook" type="host">www.facebook.com</value> 31 | <value id="facebook-connect" type="host">connect.facebook.net</value> 32 | <value id="facebook-graph-api" type="host">graph.facebook.com</value> 33 | <value id="facebook-business" type="host">business.facebook.com</value> 34 | </values> 35 | </policy> 36 | </policies> 37 | </csp_whitelist> 38 | -------------------------------------------------------------------------------- /etc/di.xml: -------------------------------------------------------------------------------- 1 | <?xml version="1.0"?> 2 | <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 3 | xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> 4 | <type name="Facebook\BusinessExtension\Helper\ServerSideHelper"> 5 | <plugin name="capi_events_modifier_plugin" type="Facebook\BusinessExtension\Plugin\CAPIEventsModifierPlugin" sortOrder="1" disabled="false" /> 6 | </type> 7 | </config> 8 | -------------------------------------------------------------------------------- /etc/frontend/events.xml: -------------------------------------------------------------------------------- 1 | <?xml version="1.0"?> 2 | <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd"> 3 | <event name="facebook_businessextension_ssapi_add_to_cart"> 4 | <observer name="facebook_businessextension_ssapi_add_to_cart_after" instance="Facebook\BusinessExtension\Observer\AddToCart"/> 5 | </event> 6 | <event name="facebook_businessextension_ssapi_search"> 7 | <observer name="facebook_businessextension_ssapi_search_after" instance="Facebook\BusinessExtension\Observer\Search" /> 8 | </event> 9 | <event name="facebook_businessextension_ssapi_view_content"> 10 | <observer name="facebook_businessextension_ssapi_view_content_after" instance="Facebook\BusinessExtension\Observer\ViewContent" /> 11 | </event> 12 | <event name="facebook_businessextension_ssapi_view_category"> 13 | <observer name="facebook_businessextension_ssapi_view_category_after" instance="Facebook\BusinessExtension\Observer\ViewCategory" /> 14 | </event> 15 | <event name="facebook_businessextension_ssapi_initiate_checkout"> 16 | <observer name="facebook_businessextension_ssapi_initiate_checkout_after" instance="Facebook\BusinessExtension\Observer\InitiateCheckout" /> 17 | </event> 18 | <event name="facebook_businessextension_ssapi_purchase"> 19 | <observer name="facebook_businessextension_ssapi_purchase_after" instance="Facebook\BusinessExtension\Observer\Purchase" /> 20 | </event> 21 | </config> 22 | -------------------------------------------------------------------------------- /etc/frontend/routes.xml: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" ?> 2 | <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 3 | xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd"> 4 | <router id="standard"> 5 | <route frontName="fbe" id="fbe"> 6 | <module name="Facebook_BusinessExtension"/> 7 | </route> 8 | </router> 9 | </config> 10 | -------------------------------------------------------------------------------- /etc/module.xml: -------------------------------------------------------------------------------- 1 | <?xml version="1.0"?> 2 | <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd"> 3 | <module name="Facebook_BusinessExtension" setup_version="1.4.7"> 4 | </module> 5 | </config> 6 | -------------------------------------------------------------------------------- /install-facebook-business-extension.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Copyright (c) Meta Platforms, Inc. and affiliates. All Rights Reserved 4 | 5 | # Be sure to log in as the Magento files owner and browse to Magento root directory 6 | # Make this file executable with chmod +x install-facebook-business-extension.sh 7 | 8 | echo "Starting Facebook Business Extension installation" 9 | 10 | echo "Installing Facebook Business SDK..." 11 | composer require facebook/php-business-sdk 12 | 13 | echo "Enabling extension..." 14 | php bin/magento module:enable Facebook_BusinessExtension 15 | 16 | echo "Deploying static files..." 17 | php bin/magento setup:static-content:deploy 18 | 19 | echo "Installing component..." 20 | php bin/magento setup:upgrade 21 | 22 | echo "Compiling app..." 23 | php bin/magento setup:di:compile 24 | 25 | echo "Cleaning the cache..." 26 | php bin/magento cache:clean 27 | 28 | echo "Running cron job..." 29 | php bin/magento cron:run 30 | php bin/magento cron:run 31 | php bin/magento cron:run 32 | 33 | echo "Installation finished" 34 | -------------------------------------------------------------------------------- /registration.php: -------------------------------------------------------------------------------- 1 | <?php 2 | /** 3 | * Copyright (c) Meta Platforms, Inc. and affiliates. All Rights Reserved 4 | */ 5 | 6 | \Magento\Framework\Component\ComponentRegistrar::register( 7 | \Magento\Framework\Component\ComponentRegistrar::MODULE, 8 | 'Facebook_BusinessExtension', 9 | __DIR__ 10 | ); 11 | -------------------------------------------------------------------------------- /tests/docker-compose.yml: -------------------------------------------------------------------------------- 1 | # The MIT License (MIT) 2 | 3 | # Copyright (c) 2015 Fu Cheng 4 | 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | 12 | # The above copyright notice and this permission notice shall be included in all 13 | # copies or substantial portions of the Software. 14 | 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | # SOFTWARE. 22 | 23 | # The original file comes from this repository https://github.com/alexcheng1982/docker-magento2 24 | 25 | version: '3.0' 26 | services: 27 | web: 28 | image: josejia/magento2-testing:1.0 29 | ports: 30 | - "80:80" 31 | links: 32 | - db 33 | volumes: 34 | - magento_data:/var/www/html 35 | env_file: 36 | - env 37 | db: 38 | image: mariadb:10 39 | volumes: 40 | - db_data:/var/lib/mysql 41 | env_file: 42 | - env 43 | ports: 44 | - 3306 45 | phpmyadmin: 46 | image: phpmyadmin/phpmyadmin 47 | container_name: phpmyadmin 48 | ports: 49 | - "8580:80" 50 | links: 51 | - db 52 | 53 | volumes: 54 | db_data: 55 | magento_data: 56 | -------------------------------------------------------------------------------- /tests/docker-installation-instructions.md: -------------------------------------------------------------------------------- 1 | # Testing extension in your machine 2 | 3 | ## Installation instructions 4 | 5 | These instructions will start a set of Docker containers, containing a Magento 2 store with the Facebook Business Extension, in your local machine, so you can try its capabilities before deploying to your production environment. 6 | 7 | 1. Change your etc/hosts file. It's necessary to access the store. 8 | 9 | 1. Use this [tutorial](https://support.rackspace.com/how-to/modify-your-hosts-file/) to locate and edit it. 10 | 11 | 2. Add this line: 127.0.0.1 local.magento 12 | 13 | 2. Open a terminal and browse to this folder. 14 | 15 | 3. Start containers: `docker-compose up -d` 16 | 17 | 4. Copy magento extension to tests_web_1 container `docker cp <directory_containing_the_repo>/. tests_web_1:/var/www/html/app/code` 18 | 19 | 5. Enter to tests_web_1 container: `docker exec -it tests_web_1 /bin/bash` 20 | 21 | 6. Install Magento inside Web Container: `/usr/local/bin/install-magento` 22 | 23 | 7. Install extension: `/usr/local/bin/install-facebook-business-extension` 24 | 25 | ## Verify installation 26 | 27 | 1. Open your browser and go to http://local.magento/admin 28 | 29 | 2. Log in using: 30 | 31 | * username: admin 32 | 33 | * password: magentorocks1 34 | 35 | 3. Go to Stores -> Facebook -> Setup and configure the connection to Facebook. 36 | 37 | 4. Go to Magento frontend: http://local.magento/ 38 | 39 | 5. Open the Developer tools in your browser and select the Network tab. 40 | 41 | 6. Navigate through the store. You should see pixel event(`www.facebook.com/tr`) requests. 42 | -------------------------------------------------------------------------------- /tests/env: -------------------------------------------------------------------------------- 1 | # The MIT License (MIT) 2 | 3 | # Copyright (c) 2015 Fu Cheng 4 | 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | 12 | # The above copyright notice and this permission notice shall be included in all 13 | # copies or substantial portions of the Software. 14 | 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | # SOFTWARE. 22 | 23 | # The original file comes from this repository https://github.com/alexcheng1982/docker-magento2 24 | 25 | MYSQL_HOST=db 26 | MYSQL_ROOT_PASSWORD=myrootpassword 27 | MYSQL_USER=magento 28 | MYSQL_PASSWORD=magento 29 | MYSQL_DATABASE=magento 30 | 31 | MAGENTO_LANGUAGE=en_US 32 | MAGENTO_TIMEZONE=America/Los_Angeles 33 | MAGENTO_DEFAULT_CURRENCY=USD 34 | MAGENTO_URL=http://local.magento 35 | MAGENTO_BACKEND_FRONTNAME=admin 36 | MAGENTO_USE_SECURE=0 37 | MAGENTO_BASE_URL_SECURE=0 38 | MAGENTO_USE_SECURE_ADMIN=0 39 | 40 | MAGENTO_ADMIN_FIRSTNAME=Admin 41 | MAGENTO_ADMIN_LASTNAME=MyStore 42 | MAGENTO_ADMIN_EMAIL=admin@example.com 43 | MAGENTO_ADMIN_USERNAME=admin 44 | MAGENTO_ADMIN_PASSWORD=magentorocks1 45 | -------------------------------------------------------------------------------- /view/adminhtml/layout/fbeadmin_info_index.xml: -------------------------------------------------------------------------------- 1 | <?xml version="1.0"?> 2 | <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd"> 3 | <referenceBlock name="page.title"> 4 | <action method="setPageTitle"> 5 | <argument name="title" xsi:type="string">Information</argument> 6 | </action> 7 | </referenceBlock> 8 | <body> 9 | <referenceContainer name="content"> 10 | <block class="Facebook\BusinessExtension\Block\Adminhtml\Info" template="Facebook_BusinessExtension::info.phtml"/> 11 | </referenceContainer> 12 | </body> 13 | </page> -------------------------------------------------------------------------------- /view/adminhtml/layout/fbeadmin_setup_index.xml: -------------------------------------------------------------------------------- 1 | <?xml version="1.0"?> 2 | <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd"> 3 | <head> 4 | <title> 5 | Facebook Business Extension 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /view/adminhtml/templates/info.phtml: -------------------------------------------------------------------------------- 1 | 2 | 3 |

getMagentoVersion()) ?>

4 |

getFBEVersion()) ?>

5 | 6 |
7 |

8 | 9 | 10 | 11 |
12 |
13 | 14 |

15 |
16 |
17 | 18 |

19 |
20 |
21 | 22 |

23 | 24 |
25 |
26 | 27 |
28 | 29 | 32 | 33 | 53 | 54 | 81 | -------------------------------------------------------------------------------- /view/adminhtml/templates/setup.phtml: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 |
5 |
6 | 7 | 30 | 36 | -------------------------------------------------------------------------------- /view/adminhtml/templates/system/config/category_feed.phtml: -------------------------------------------------------------------------------- 1 | 2 | 51 | 52 | getButtonHtml() ?> 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /view/adminhtml/templates/system/config/product_feed.phtml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 51 | 52 | getButtonHtml() ?> 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /view/adminhtml/ui_component/category_form.xml: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 | 5 | 6 | 7 | boolean 8 | checkbox 9 | Sync To Facebook Catalog 10 | toggle 11 | 12 | 1 13 | 0 14 | 15 | 1 16 | 17 | 18 | 19 |
20 |
21 | -------------------------------------------------------------------------------- /view/adminhtml/web/css/images/ads.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/facebookarchive/facebook-for-magento2/4e4f42ca0eb91df8a3938cbd4fb4cb3f5120ef53/view/adminhtml/web/css/images/ads.png -------------------------------------------------------------------------------- /view/adminhtml/web/css/images/bar-chart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/facebookarchive/facebook-for-magento2/4e4f42ca0eb91df8a3938cbd4fb4cb3f5120ef53/view/adminhtml/web/css/images/bar-chart.png -------------------------------------------------------------------------------- /view/adminhtml/web/css/images/down-arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/facebookarchive/facebook-for-magento2/4e4f42ca0eb91df8a3938cbd4fb4cb3f5120ef53/view/adminhtml/web/css/images/down-arrow.png -------------------------------------------------------------------------------- /view/adminhtml/web/css/images/facebook-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/facebookarchive/facebook-for-magento2/4e4f42ca0eb91df8a3938cbd4fb4cb3f5120ef53/view/adminhtml/web/css/images/facebook-icon.png -------------------------------------------------------------------------------- /view/adminhtml/web/css/images/group.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/facebookarchive/facebook-for-magento2/4e4f42ca0eb91df8a3938cbd4fb4cb3f5120ef53/view/adminhtml/web/css/images/group.png -------------------------------------------------------------------------------- /view/adminhtml/web/css/images/setup-success.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/facebookarchive/facebook-for-magento2/4e4f42ca0eb91df8a3938cbd4fb4cb3f5120ef53/view/adminhtml/web/css/images/setup-success.png -------------------------------------------------------------------------------- /view/adminhtml/web/css/images/shopping.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/facebookarchive/facebook-for-magento2/4e4f42ca0eb91df8a3938cbd4fb4cb3f5120ef53/view/adminhtml/web/css/images/shopping.png -------------------------------------------------------------------------------- /view/adminhtml/web/css/images/small-store.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/facebookarchive/facebook-for-magento2/4e4f42ca0eb91df8a3938cbd4fb4cb3f5120ef53/view/adminhtml/web/css/images/small-store.png -------------------------------------------------------------------------------- /view/adminhtml/web/css/images/up-arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/facebookarchive/facebook-for-magento2/4e4f42ca0eb91df8a3938cbd4fb4cb3f5120ef53/view/adminhtml/web/css/images/up-arrow.png -------------------------------------------------------------------------------- /view/adminhtml/web/js/lib/IEOverlay.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the code directory. 8 | */ 9 | 'use strict'; 10 | 11 | var React = require('./react'); 12 | 13 | var IEOverlay = function () { 14 | var Overlay = React.createClass({ 15 | displayName: 'Overlay', 16 | 17 | render: function render() { 18 | var overLayStyles = { 19 | width: '600px', 20 | height: '150px', 21 | position: 'relative', 22 | top: '50%', 23 | left: '50%', 24 | marginTop: '-75px', 25 | marginLeft: '-300px', 26 | backgroundColor: 'white', 27 | textAlign: 'center', 28 | fontFamily: 'helvetica, arial, sans-serif', 29 | zIndex: '11' 30 | }; 31 | 32 | var h1Styles = { 33 | fontSize: '24px', 34 | lineHeight: '28px', 35 | color: '#141823', 36 | fontWeight: 'normal', 37 | paddingTop: '44px' 38 | }; 39 | 40 | var h2Styles = { 41 | fontSize: '14px', 42 | lineHeight: '20px', 43 | color: '#9197a3', 44 | fontWeight: 'normal' 45 | }; 46 | 47 | return React.createElement( 48 | 'div', 49 | { style: overLayStyles, id: 'ieOverlay' }, 50 | React.createElement( 51 | 'h1', 52 | { style: h1Styles }, 53 | 'Internet Explorer Is Not Supported' 54 | ), 55 | React.createElement( 56 | 'h2', 57 | { style: h2Styles }, 58 | 'Please use a modern browser such as Google Chrome or Mozilla Firefox' 59 | ) 60 | ); 61 | } 62 | }); 63 | 64 | return { 65 | render: function render() { 66 | var containerId = 'page:main-container'; 67 | var containerEl = document.getElementById(containerId); 68 | containerEl.style.position = 'relative'; 69 | 70 | var ieContainer = document.createElement('div'); 71 | ieContainer.id = 'ie-container'; 72 | 73 | ieContainer.style.width = '100%'; 74 | ieContainer.style.height = '100%'; 75 | ieContainer.style.position = 'absolute'; 76 | ieContainer.style.top = '0'; 77 | ieContainer.style.left = '0'; 78 | ieContainer.style.backgroundColor = 'rgba(0,0,0,0.3)'; 79 | 80 | containerEl.appendChild(ieContainer); 81 | ReactDOM.render(React.createElement(Overlay, null), ieContainer); 82 | } 83 | }; 84 | }(); 85 | 86 | module.exports = IEOverlay; 87 | -------------------------------------------------------------------------------- /view/adminhtml/web/js/lib/Modal.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the code directory. 8 | */ 9 | 'use strict'; 10 | 11 | var React = require('./react'); 12 | 13 | var FBModal = React.createClass({ 14 | displayName: 'Modal', 15 | 16 | render: function render() { 17 | return React.createElement( 18 | 'div', 19 | { className: 'modal-container' }, 20 | React.createElement( 21 | 'div', 22 | { className: 'modal' }, 23 | React.createElement( 24 | 'div', 25 | { className: 'modal-header' }, 26 | this.props.title 27 | ), 28 | React.createElement( 29 | 'div', 30 | { className: 'modal-content' }, 31 | this.props.message 32 | ), 33 | React.createElement( 34 | 'div', 35 | { className: 'modal-close' }, 36 | React.createElement( 37 | 'button', 38 | { onClick: this.props.onClose, className: 'medium blue' }, 39 | 'OK' 40 | ) 41 | ) 42 | ) 43 | ); 44 | } 45 | }); 46 | 47 | module.exports = FBModal; 48 | -------------------------------------------------------------------------------- /view/adminhtml/web/js/lib/compile_fbe_allinone.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Copyright (c) Meta Platforms, Inc. and affiliates. All Rights Reserved 3 | 4 | NODE_PATH=. browserify fbe.js > ../fbe_allinone.js 5 | -------------------------------------------------------------------------------- /view/adminhtml/web/js/lib/react-dom.js: -------------------------------------------------------------------------------- 1 | /** 2 | * ReactDOM v0.14.3 3 | * 4 | * Copyright (c) Meta Platforms, Inc. and affiliates. All Rights Reserved 5 | * 6 | * This source code is licensed under the BSD-style license found in the 7 | * LICENSE file in the root directory of this source tree. An additional grant 8 | * of patent rights can be found in the PATENTS file in the same directory. 9 | * 10 | */ 11 | // Based off https://github.com/ForbesLindesay/umd/blob/master/template.js 12 | ;(function(f) { 13 | // CommonJS 14 | if (typeof exports === "object" && typeof module !== "undefined") { 15 | module.exports = f(require('react')); 16 | 17 | // RequireJS 18 | } else if (typeof define === "function" && define.amd) { 19 | define(['react'], f); 20 | 21 | // 52 | logEvent($block->getFacebookPixelID(), 'AddToCart') ?> 53 | 54 | -------------------------------------------------------------------------------- /view/frontend/templates/pixel/head.phtml: -------------------------------------------------------------------------------- 1 | 2 | getFacebookPixelID()) { ?> 3 | 4 | 5 | 28 | 44 | 45 | 46 | 47 | 50 | 51 | -------------------------------------------------------------------------------- /view/frontend/templates/pixel/initiate_checkout.phtml: -------------------------------------------------------------------------------- 1 | getFacebookPixelID()) { 4 | $eventId = \Facebook\BusinessExtension\Helper\EventIdGenerator::guidv4(); 5 | $block->trackServerEvent($eventId); 6 | ?> 7 | 26 | logEvent($block->getFacebookPixelID(), 'InitiateCheckout') ?> 27 | 28 | -------------------------------------------------------------------------------- /view/frontend/templates/pixel/purchase.phtml: -------------------------------------------------------------------------------- 1 | getFacebookPixelID()) { 4 | $eventId = \Facebook\BusinessExtension\Helper\EventIdGenerator::guidv4(); 5 | $block->trackServerEvent($eventId); 6 | ?> 7 | 25 | logEvent($block->getFacebookPixelID(), 'Purchase') ?> 26 | 27 | -------------------------------------------------------------------------------- /view/frontend/templates/pixel/search.phtml: -------------------------------------------------------------------------------- 1 | getFacebookPixelID()) { 4 | $eventId = \Facebook\BusinessExtension\Helper\EventIdGenerator::guidv4(); 5 | $block->trackServerEvent($eventId); 6 | ?> 7 | 19 | logEvent($block->getFacebookPixelID(), 'Search') ?> 20 | 21 | -------------------------------------------------------------------------------- /view/frontend/templates/pixel/view_category.phtml: -------------------------------------------------------------------------------- 1 | getFacebookPixelID()) { 4 | $eventId = \Facebook\BusinessExtension\Helper\EventIdGenerator::guidv4(); 5 | $block->trackServerEvent($eventId); 6 | ?> 7 | 21 | logEvent($block->getFacebookPixelID(), 'ViewCategory') ?> 22 | 23 | -------------------------------------------------------------------------------- /view/frontend/templates/pixel/view_content.phtml: -------------------------------------------------------------------------------- 1 | getFacebookPixelID()) { 4 | $eventId = \Facebook\BusinessExtension\Helper\EventIdGenerator::guidv4(); 5 | $block->trackServerEvent($eventId); 6 | ?> 7 | 30 | logEvent($block->getFacebookPixelID(), 'ViewContent') ?> 31 | 32 | --------------------------------------------------------------------------------