{"action":"created","issue":{"url":"https://api.github.com/repos/woocommerce/woocommerce/issues/12138","repository_url":"https://api.github.com/repos/woocommerce/woocommerce","labels_url":"https://api.github.com/repos/woocommerce/woocommerce/issues/12138/labels{/name}","comments_url":"https://api.github.com/repos/woocommerce/woocommerce/issues/12138/comments","events_url":"https://api.github.com/repos/woocommerce/woocommerce/issues/12138/events","html_url":"https://github.com/woocommerce/woocommerce/issues/12138","id":184021419,"number":12138,"title":"Cart.js hijacking forms when used with WOOCOMMERCE_CART constant","user":{"login":"SukcesStrony","id":17356161,"avatar_url":"https://avatars.githubusercontent.com/u/17356161?v=3","gravatar_id":"","url":"https://api.github.com/users/SukcesStrony","html_url":"https://github.com/SukcesStrony","followers_url":"https://api.github.com/users/SukcesStrony/followers","following_url":"https://api.github.com/users/SukcesStrony/following{/other_user}","gists_url":"https://api.github.com/users/SukcesStrony/gists{/gist_id}","starred_url":"https://api.github.com/users/SukcesStrony/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/SukcesStrony/subscriptions","organizations_url":"https://api.github.com/users/SukcesStrony/orgs","repos_url":"https://api.github.com/users/SukcesStrony/repos","events_url":"https://api.github.com/users/SukcesStrony/events{/privacy}","received_events_url":"https://api.github.com/users/SukcesStrony/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/woocommerce/woocommerce/labels/Refactor","name":"Refactor","color":"eb6420"}],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":{"url":"https://api.github.com/repos/woocommerce/woocommerce/milestones/53","html_url":"https://github.com/woocommerce/woocommerce/milestones/2.7","labels_url":"https://api.github.com/repos/woocommerce/woocommerce/milestones/53/labels","id":1537224,"number":53,"title":"2.7","description":"2.7 will focus on API + CRUD improvements.","creator":{"login":"mikejolley","id":90977,"avatar_url":"https://avatars.githubusercontent.com/u/90977?v=3","gravatar_id":"","url":"https://api.github.com/users/mikejolley","html_url":"https://github.com/mikejolley","followers_url":"https://api.github.com/users/mikejolley/followers","following_url":"https://api.github.com/users/mikejolley/following{/other_user}","gists_url":"https://api.github.com/users/mikejolley/gists{/gist_id}","starred_url":"https://api.github.com/users/mikejolley/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mikejolley/subscriptions","organizations_url":"https://api.github.com/users/mikejolley/orgs","repos_url":"https://api.github.com/users/mikejolley/repos","events_url":"https://api.github.com/users/mikejolley/events{/privacy}","received_events_url":"https://api.github.com/users/mikejolley/received_events","type":"User","site_admin":false},"open_issues":9,"closed_issues":161,"state":"open","created_at":"2016-01-22T23:35:12Z","updated_at":"2016-10-21T14:29:50Z","due_on":"2016-10-22T00:00:00Z","closed_at":null},"comments":6,"created_at":"2016-10-19T17:09:42Z","updated_at":"2016-10-21T15:28:11Z","closed_at":null,"body":"## EXPLANATION OF THE ISSUE\r\n\r\nSome plugins (especially the ones which change the prices of products) require recalculating the cart contents. In order to run `WC()->cart->calculate_totals();` they need to first `define('WOOCOMMERCE_CART', true);`, which is also done in the WC core. The code to recalculate the cart becomes:\r\n```\r\nif(!defined('WOOCOMMERCE_CART')){\r\n\tdefine('WOOCOMMERCE_CART', true);\r\n}\r\nWC()->cart->calculate_totals();\r\n```\r\n\r\nSetting the `WOOCOMMERCE_CART` constant to true means, that `is_cart()` will return true. This enqueues the `cart.js` file. Let's say we're not on the Cart page (for example it's a \"my account\" page, because we've just logged in and the plugin changes the prices for logged in users).\r\n\r\nThe problem is, `cart.js` hijacks all form submissions, no matter if that form is actually the cart form or any other form. So, if we're on the \"Edit billing address\" page or even on the Cart page itself but there are other forms present, the `cart.js` will prevent any forms from submitting (excluding the cart form of course).\r\n\r\n## HOW TO FIX THE ISSUE\r\n\r\nThe main culprit is in https://github.com/woocommerce/woocommerce/blob/c1d989df2ce62e154ca16d85e1385229739d0d12/assets/js/frontend/cart.js#L292\r\nThe selector needs to be `div.woocommerce-cart:not(.widget_product_search) > form` in order to be sure we're actually on the cart page, and in order to ensure we're targeting the proper form, it should target the `.cart` class, which is a child of the form element. This would require either adding a class for the form element (like `.cart-form`) or selecting the form element as a parent of `.cart` with jQuery (the 1st option seems a lot better).\r\n`Cart.js` has a few other hijacks, like hijacking the Return key. This should be reviewed and scoped to include only the actual cart form, not any form there is on the page.\r\n\r\n## WORKAROUND FOR DEVELOPERS\r\nWe just check if we're actually on the Cart page before setting the constant and later on we dequeue the `Cart.js` file if we're not actually on the Cart page.\r\n```\r\n$is_really_a_cart_page = false; // We assume we're not on the Cart page\r\nif(is_cart()){ // We check if we're on the Cart page\r\n\t$is_really_a_cart_page = true;\r\n}\r\nif(!defined('WOOCOMMERCE_CART')){ // We set this constant to true to enable calculating totals in the cart\r\n\tdefine('WOOCOMMERCE_CART', true);\r\n}\r\nWC()->cart->calculate_totals();\r\nif(!$is_really_a_cart_page){ // If we're not on the Cart page, the cart.js file would hijack form submissions\r\n\tfunction dequeue_wc_cart_js(){\r\n\t\twp_dequeue_script('wc-cart');// We dequeue the cart.js file\r\n\t}\r\n\tadd_action('wp_enqueue_scripts', 'dequeue_wc_cart_js', 15); // We dequeue the file with a lower priority than when it is enqueued\r\n}\r\n```"},"comment":{"url":"https://api.github.com/repos/woocommerce/woocommerce/issues/comments/255408215","html_url":"https://github.com/woocommerce/woocommerce/issues/12138#issuecomment-255408215","issue_url":"https://api.github.com/repos/woocommerce/woocommerce/issues/12138","id":255408215,"user":{"login":"jameskoster","id":846565,"avatar_url":"https://avatars.githubusercontent.com/u/846565?v=3","gravatar_id":"","url":"https://api.github.com/users/jameskoster","html_url":"https://github.com/jameskoster","followers_url":"https://api.github.com/users/jameskoster/followers","following_url":"https://api.github.com/users/jameskoster/following{/other_user}","gists_url":"https://api.github.com/users/jameskoster/gists{/gist_id}","starred_url":"https://api.github.com/users/jameskoster/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jameskoster/subscriptions","organizations_url":"https://api.github.com/users/jameskoster/orgs","repos_url":"https://api.github.com/users/jameskoster/repos","events_url":"https://api.github.com/users/jameskoster/events{/privacy}","received_events_url":"https://api.github.com/users/jameskoster/received_events","type":"User","site_admin":false},"created_at":"2016-10-21T15:28:10Z","updated_at":"2016-10-21T15:28:10Z","body":"Conflicting with the class on the body will cause issues. How irksome.\r\n\r\n`.woocommerce-cart-form` works I suppose.\r\n\r\n"}}
{"actor":{"display_login":"jameskoster"}}