Commit a341e67e6277ca5881be400a99bbbe90b8d3fda5
1 parent
912190c8
Exists in
master
and in
29 other branches
Checkpoint: validated the idea of keeping the cart in an indepent cookie
There are a couple of FIXME's there, plus the whole thing has to be
refactored:
* the shopping cart controller must be moved out of the profile
namespace, because we can't know to which profile we should make the
AJAX request to load the cart
* there are too many unecessary AJAX requests.
* most of the cart functionality must probably be encapsulate into
* proper objects.
Showing
6 changed files
with
60 additions
and
15 deletions
Show diff stats
plugins/shopping_cart/controllers/shopping_cart_plugin_profile_controller.rb
| 1 | +require 'base64' | |
| 2 | + | |
| 1 | 3 | include ShoppingCartPlugin::CartHelper |
| 2 | 4 | |
| 3 | 5 | class ShoppingCartPluginProfileController < ProfileController |
| ... | ... | @@ -6,6 +8,12 @@ class ShoppingCartPluginProfileController < ProfileController |
| 6 | 8 | |
| 7 | 9 | before_filter :login_required, :only => [] |
| 8 | 10 | |
| 11 | + def get | |
| 12 | + has_products = !cart.nil? && (cart[:items].keys.size > 0) || false | |
| 13 | + config = { 'enterprise' => profile.identifier, 'hasProducts' => has_products } | |
| 14 | + render :text => config.to_json | |
| 15 | + end | |
| 16 | + | |
| 9 | 17 | def add |
| 10 | 18 | self.cart = { :enterprise_id => profile.id, :items => {} } if self.cart.nil? |
| 11 | 19 | if validate_same_enterprise && product = validate_enterprise_has_product(params[:id]) |
| ... | ... | @@ -85,6 +93,7 @@ class ShoppingCartPluginProfileController < ProfileController |
| 85 | 93 | |
| 86 | 94 | def buy |
| 87 | 95 | @environment = profile.environment |
| 96 | + @cart = cart | |
| 88 | 97 | render :layout => false |
| 89 | 98 | end |
| 90 | 99 | |
| ... | ... | @@ -249,10 +258,31 @@ class ShoppingCartPluginProfileController < ProfileController |
| 249 | 258 | protected |
| 250 | 259 | |
| 251 | 260 | def cart |
| 252 | - session[:cart] | |
| 261 | + @cart ||= | |
| 262 | + begin | |
| 263 | + cookies[cookie_key] && YAML.load(Base64.decode64(cookies[cookie_key])) || nil | |
| 264 | + end | |
| 265 | + @cart | |
| 253 | 266 | end |
| 254 | 267 | |
| 255 | 268 | def cart=(data) |
| 256 | - session[:cart] = data | |
| 269 | + @cart = data | |
| 257 | 270 | end |
| 271 | + | |
| 272 | + after_filter :save_cookie | |
| 273 | + def save_cookie | |
| 274 | + if @cart.nil? && cookies[cookie_key] | |
| 275 | + cookies.delete(cookie_key) | |
| 276 | + else | |
| 277 | + cookies[cookie_key] = { | |
| 278 | + :value => Base64.encode64(@cart.to_yaml), | |
| 279 | + :path => "/profile/#{profile.identifier}/plugin/shopping_cart" | |
| 280 | + } | |
| 281 | + end | |
| 282 | + end | |
| 283 | + | |
| 284 | + def cookie_key | |
| 285 | + :_noosfero_session_shopping_cart | |
| 286 | + end | |
| 287 | + | |
| 258 | 288 | end | ... | ... |
plugins/shopping_cart/lib/shopping_cart_plugin.rb
plugins/shopping_cart/test/functional/shopping_cart_plugin_profile_controller_test.rb
| ... | ... | @@ -48,7 +48,7 @@ class ShoppingCartPluginProfileControllerTest < ActionController::TestCase |
| 48 | 48 | end |
| 49 | 49 | |
| 50 | 50 | should 'not try to remove a product if there is no cart' do |
| 51 | - instantiate_session | |
| 51 | + instantiate_cart | |
| 52 | 52 | assert !cart? |
| 53 | 53 | |
| 54 | 54 | assert_nothing_raised { get :remove, :profile => enterprise.identifier, :id => 9999 } |
| ... | ... | @@ -76,7 +76,7 @@ class ShoppingCartPluginProfileControllerTest < ActionController::TestCase |
| 76 | 76 | end |
| 77 | 77 | |
| 78 | 78 | should 'not try to list the cart if there is no cart' do |
| 79 | - instantiate_session | |
| 79 | + instantiate_cart | |
| 80 | 80 | assert !cart? |
| 81 | 81 | |
| 82 | 82 | assert_nothing_raised { get :list, :profile => enterprise.identifier } |
| ... | ... | @@ -100,7 +100,7 @@ class ShoppingCartPluginProfileControllerTest < ActionController::TestCase |
| 100 | 100 | end |
| 101 | 101 | |
| 102 | 102 | should 'not try to update quantity the quantity of a product if there is no cart' do |
| 103 | - instantiate_session | |
| 103 | + instantiate_cart | |
| 104 | 104 | assert !cart? |
| 105 | 105 | |
| 106 | 106 | assert_nothing_raised { get :update_quantity, :profile => enterprise.identifier, :id => 9999, :quantity => 3 } |
| ... | ... | @@ -139,7 +139,7 @@ class ShoppingCartPluginProfileControllerTest < ActionController::TestCase |
| 139 | 139 | end |
| 140 | 140 | |
| 141 | 141 | should 'not crash if there is no cart' do |
| 142 | - instantiate_session | |
| 142 | + instantiate_cart | |
| 143 | 143 | assert !cart? |
| 144 | 144 | assert_nothing_raised { get :clean, :profile => enterprise.identifier } |
| 145 | 145 | end |
| ... | ... | @@ -147,7 +147,7 @@ class ShoppingCartPluginProfileControllerTest < ActionController::TestCase |
| 147 | 147 | should 'register order on send request' do |
| 148 | 148 | product1 = fast_create(Product, :enterprise_id => enterprise.id, :price => 1.99) |
| 149 | 149 | product2 = fast_create(Product, :enterprise_id => enterprise.id, :price => 2.23) |
| 150 | - @controller.stubs(:session).returns({:cart => {:items => {product1.id => 1, product2.id => 2}}}) | |
| 150 | + @controller.stubs(:cart).returns({:items => {product1.id => 1, product2.id => 2}}) | |
| 151 | 151 | assert_difference ShoppingCartPlugin::PurchaseOrder, :count, 1 do |
| 152 | 152 | post :send_request, |
| 153 | 153 | :customer => {:name => "Manuel", :email => "manuel@ceu.com"}, |
| ... | ... | @@ -165,7 +165,7 @@ class ShoppingCartPluginProfileControllerTest < ActionController::TestCase |
| 165 | 165 | |
| 166 | 166 | should 'register order on send request and not crash if product is not defined' do |
| 167 | 167 | product1 = fast_create(Product, :enterprise_id => enterprise.id) |
| 168 | - @controller.stubs(:session).returns({:cart => {:items => {product1.id => 1}}}) | |
| 168 | + @controller.stubs(:cart).returns({:items => {product1.id => 1}}) | |
| 169 | 169 | assert_difference ShoppingCartPlugin::PurchaseOrder, :count, 1 do |
| 170 | 170 | post :send_request, |
| 171 | 171 | :customer => {:name => "Manuel", :email => "manuel@ceu.com"}, |
| ... | ... | @@ -184,15 +184,15 @@ class ShoppingCartPluginProfileControllerTest < ActionController::TestCase |
| 184 | 184 | end |
| 185 | 185 | |
| 186 | 186 | def cart? |
| 187 | - !session[:cart].nil? | |
| 187 | + @controller.send(:cart).nil? | |
| 188 | 188 | end |
| 189 | 189 | |
| 190 | 190 | def product_in_cart?(product) |
| 191 | - session[:cart][:items].has_key?(product.id) | |
| 191 | + @controller.send(:cart)[:items].has_key?(product.id) | |
| 192 | 192 | end |
| 193 | 193 | |
| 194 | 194 | def product_quantity(product) |
| 195 | - session[:cart][:items][product.id] | |
| 195 | + @controller.send(:cart)[:items][product.id] | |
| 196 | 196 | end |
| 197 | 197 | |
| 198 | 198 | def response_ok? |
| ... | ... | @@ -205,7 +205,7 @@ class ShoppingCartPluginProfileControllerTest < ActionController::TestCase |
| 205 | 205 | |
| 206 | 206 | # temporary hack...if I don't do this the session stays as an Array instead |
| 207 | 207 | # of a TestSession |
| 208 | - def instantiate_session | |
| 208 | + def instantiate_cart | |
| 209 | 209 | get :add, :profile => enterprise.identifier, :id => product.id |
| 210 | 210 | get :remove, :profile => enterprise.identifier, :id => product.id |
| 211 | 211 | end | ... | ... |
plugins/shopping_cart/views/cart.html.erb
| ... | ... | @@ -18,6 +18,19 @@ |
| 18 | 18 | |
| 19 | 19 | <script type="text/javascript"> |
| 20 | 20 | //<![CDATA[ |
| 21 | - new Cart({hasProducts:<%= !locals[:cart].nil? ? "true, enterprise:'#{Enterprise.find(locals[:cart][:enterprise_id]).identifier}'" : "false" %>}); | |
| 21 | + jQuery(function($) { | |
| 22 | + var profile = 'foo'; // FIXME | |
| 23 | + $.ajax({ | |
| 24 | + url: "/profile/" + profile + "/plugin/shopping_cart/get", | |
| 25 | + dataType: 'json', | |
| 26 | + success: function(data) { | |
| 27 | + new Cart(data); | |
| 28 | + }, | |
| 29 | + cache: false, | |
| 30 | + error: function(ajax, status, errorThrown) { | |
| 31 | + alert('Error getting shopping cart - HTTP '+status+': '+errorThrown); | |
| 32 | + } | |
| 33 | + }); | |
| 34 | + }); | |
| 22 | 35 | //]]> |
| 23 | 36 | </script> | ... | ... |
plugins/shopping_cart/views/shopping_cart_plugin_profile/buy.html.erb
| ... | ... | @@ -16,7 +16,7 @@ |
| 16 | 16 | <%= submit_button(:send, _('Send buy request')) %> |
| 17 | 17 | </div> |
| 18 | 18 | <% end %> |
| 19 | - <%= items_table(session[:cart][:items], profile) %> | |
| 19 | + <%= items_table(@cart[:items], profile) %> | |
| 20 | 20 | <%= link_to '', '#', :onclick => "Cart.colorbox_close(this);", :class => 'cart-box-close icon-cancel' %> |
| 21 | 21 | </div> |
| 22 | 22 | ... | ... |
vendor/plugins/noosfero_caching/init.rb
| ... | ... | @@ -38,6 +38,8 @@ module NoosferoHttpCaching |
| 38 | 38 | def call(env) |
| 39 | 39 | status, headers, body = @app.call(env) |
| 40 | 40 | if headers['X-Noosfero-Auth'] == 'false' |
| 41 | + # FIXME do not do this if there is any plugin cookie set (e.g. | |
| 42 | + # _noosfero_session_shopping_cart) | |
| 41 | 43 | headers.delete('Set-Cookie') |
| 42 | 44 | end |
| 43 | 45 | headers.delete('X-Noosfero-Auth') | ... | ... |