Commit a341e67e6277ca5881be400a99bbbe90b8d3fda5
1 parent
912190c8
Exists in
master
and in
28 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 | include ShoppingCartPlugin::CartHelper | 3 | include ShoppingCartPlugin::CartHelper |
2 | 4 | ||
3 | class ShoppingCartPluginProfileController < ProfileController | 5 | class ShoppingCartPluginProfileController < ProfileController |
@@ -6,6 +8,12 @@ class ShoppingCartPluginProfileController < ProfileController | @@ -6,6 +8,12 @@ class ShoppingCartPluginProfileController < ProfileController | ||
6 | 8 | ||
7 | before_filter :login_required, :only => [] | 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 | def add | 17 | def add |
10 | self.cart = { :enterprise_id => profile.id, :items => {} } if self.cart.nil? | 18 | self.cart = { :enterprise_id => profile.id, :items => {} } if self.cart.nil? |
11 | if validate_same_enterprise && product = validate_enterprise_has_product(params[:id]) | 19 | if validate_same_enterprise && product = validate_enterprise_has_product(params[:id]) |
@@ -85,6 +93,7 @@ class ShoppingCartPluginProfileController < ProfileController | @@ -85,6 +93,7 @@ class ShoppingCartPluginProfileController < ProfileController | ||
85 | 93 | ||
86 | def buy | 94 | def buy |
87 | @environment = profile.environment | 95 | @environment = profile.environment |
96 | + @cart = cart | ||
88 | render :layout => false | 97 | render :layout => false |
89 | end | 98 | end |
90 | 99 | ||
@@ -249,10 +258,31 @@ class ShoppingCartPluginProfileController < ProfileController | @@ -249,10 +258,31 @@ class ShoppingCartPluginProfileController < ProfileController | ||
249 | protected | 258 | protected |
250 | 259 | ||
251 | def cart | 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 | end | 266 | end |
254 | 267 | ||
255 | def cart=(data) | 268 | def cart=(data) |
256 | - session[:cart] = data | 269 | + @cart = data |
257 | end | 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 | end | 288 | end |
plugins/shopping_cart/lib/shopping_cart_plugin.rb
@@ -35,7 +35,7 @@ class ShoppingCartPlugin < Noosfero::Plugin | @@ -35,7 +35,7 @@ class ShoppingCartPlugin < Noosfero::Plugin | ||
35 | end | 35 | end |
36 | 36 | ||
37 | def body_beginning | 37 | def body_beginning |
38 | - expanded_template('cart.html.erb',{:cart => context.session[:cart]}) | 38 | + expanded_template('cart.html.erb') |
39 | end | 39 | end |
40 | 40 | ||
41 | def control_panel_buttons | 41 | def control_panel_buttons |
plugins/shopping_cart/test/functional/shopping_cart_plugin_profile_controller_test.rb
@@ -48,7 +48,7 @@ class ShoppingCartPluginProfileControllerTest < ActionController::TestCase | @@ -48,7 +48,7 @@ class ShoppingCartPluginProfileControllerTest < ActionController::TestCase | ||
48 | end | 48 | end |
49 | 49 | ||
50 | should 'not try to remove a product if there is no cart' do | 50 | should 'not try to remove a product if there is no cart' do |
51 | - instantiate_session | 51 | + instantiate_cart |
52 | assert !cart? | 52 | assert !cart? |
53 | 53 | ||
54 | assert_nothing_raised { get :remove, :profile => enterprise.identifier, :id => 9999 } | 54 | assert_nothing_raised { get :remove, :profile => enterprise.identifier, :id => 9999 } |
@@ -76,7 +76,7 @@ class ShoppingCartPluginProfileControllerTest < ActionController::TestCase | @@ -76,7 +76,7 @@ class ShoppingCartPluginProfileControllerTest < ActionController::TestCase | ||
76 | end | 76 | end |
77 | 77 | ||
78 | should 'not try to list the cart if there is no cart' do | 78 | should 'not try to list the cart if there is no cart' do |
79 | - instantiate_session | 79 | + instantiate_cart |
80 | assert !cart? | 80 | assert !cart? |
81 | 81 | ||
82 | assert_nothing_raised { get :list, :profile => enterprise.identifier } | 82 | assert_nothing_raised { get :list, :profile => enterprise.identifier } |
@@ -100,7 +100,7 @@ class ShoppingCartPluginProfileControllerTest < ActionController::TestCase | @@ -100,7 +100,7 @@ class ShoppingCartPluginProfileControllerTest < ActionController::TestCase | ||
100 | end | 100 | end |
101 | 101 | ||
102 | should 'not try to update quantity the quantity of a product if there is no cart' do | 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 | assert !cart? | 104 | assert !cart? |
105 | 105 | ||
106 | assert_nothing_raised { get :update_quantity, :profile => enterprise.identifier, :id => 9999, :quantity => 3 } | 106 | assert_nothing_raised { get :update_quantity, :profile => enterprise.identifier, :id => 9999, :quantity => 3 } |
@@ -139,7 +139,7 @@ class ShoppingCartPluginProfileControllerTest < ActionController::TestCase | @@ -139,7 +139,7 @@ class ShoppingCartPluginProfileControllerTest < ActionController::TestCase | ||
139 | end | 139 | end |
140 | 140 | ||
141 | should 'not crash if there is no cart' do | 141 | should 'not crash if there is no cart' do |
142 | - instantiate_session | 142 | + instantiate_cart |
143 | assert !cart? | 143 | assert !cart? |
144 | assert_nothing_raised { get :clean, :profile => enterprise.identifier } | 144 | assert_nothing_raised { get :clean, :profile => enterprise.identifier } |
145 | end | 145 | end |
@@ -147,7 +147,7 @@ class ShoppingCartPluginProfileControllerTest < ActionController::TestCase | @@ -147,7 +147,7 @@ class ShoppingCartPluginProfileControllerTest < ActionController::TestCase | ||
147 | should 'register order on send request' do | 147 | should 'register order on send request' do |
148 | product1 = fast_create(Product, :enterprise_id => enterprise.id, :price => 1.99) | 148 | product1 = fast_create(Product, :enterprise_id => enterprise.id, :price => 1.99) |
149 | product2 = fast_create(Product, :enterprise_id => enterprise.id, :price => 2.23) | 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 | assert_difference ShoppingCartPlugin::PurchaseOrder, :count, 1 do | 151 | assert_difference ShoppingCartPlugin::PurchaseOrder, :count, 1 do |
152 | post :send_request, | 152 | post :send_request, |
153 | :customer => {:name => "Manuel", :email => "manuel@ceu.com"}, | 153 | :customer => {:name => "Manuel", :email => "manuel@ceu.com"}, |
@@ -165,7 +165,7 @@ class ShoppingCartPluginProfileControllerTest < ActionController::TestCase | @@ -165,7 +165,7 @@ class ShoppingCartPluginProfileControllerTest < ActionController::TestCase | ||
165 | 165 | ||
166 | should 'register order on send request and not crash if product is not defined' do | 166 | should 'register order on send request and not crash if product is not defined' do |
167 | product1 = fast_create(Product, :enterprise_id => enterprise.id) | 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 | assert_difference ShoppingCartPlugin::PurchaseOrder, :count, 1 do | 169 | assert_difference ShoppingCartPlugin::PurchaseOrder, :count, 1 do |
170 | post :send_request, | 170 | post :send_request, |
171 | :customer => {:name => "Manuel", :email => "manuel@ceu.com"}, | 171 | :customer => {:name => "Manuel", :email => "manuel@ceu.com"}, |
@@ -184,15 +184,15 @@ class ShoppingCartPluginProfileControllerTest < ActionController::TestCase | @@ -184,15 +184,15 @@ class ShoppingCartPluginProfileControllerTest < ActionController::TestCase | ||
184 | end | 184 | end |
185 | 185 | ||
186 | def cart? | 186 | def cart? |
187 | - !session[:cart].nil? | 187 | + @controller.send(:cart).nil? |
188 | end | 188 | end |
189 | 189 | ||
190 | def product_in_cart?(product) | 190 | def product_in_cart?(product) |
191 | - session[:cart][:items].has_key?(product.id) | 191 | + @controller.send(:cart)[:items].has_key?(product.id) |
192 | end | 192 | end |
193 | 193 | ||
194 | def product_quantity(product) | 194 | def product_quantity(product) |
195 | - session[:cart][:items][product.id] | 195 | + @controller.send(:cart)[:items][product.id] |
196 | end | 196 | end |
197 | 197 | ||
198 | def response_ok? | 198 | def response_ok? |
@@ -205,7 +205,7 @@ class ShoppingCartPluginProfileControllerTest < ActionController::TestCase | @@ -205,7 +205,7 @@ class ShoppingCartPluginProfileControllerTest < ActionController::TestCase | ||
205 | 205 | ||
206 | # temporary hack...if I don't do this the session stays as an Array instead | 206 | # temporary hack...if I don't do this the session stays as an Array instead |
207 | # of a TestSession | 207 | # of a TestSession |
208 | - def instantiate_session | 208 | + def instantiate_cart |
209 | get :add, :profile => enterprise.identifier, :id => product.id | 209 | get :add, :profile => enterprise.identifier, :id => product.id |
210 | get :remove, :profile => enterprise.identifier, :id => product.id | 210 | get :remove, :profile => enterprise.identifier, :id => product.id |
211 | end | 211 | end |
plugins/shopping_cart/views/cart.html.erb
@@ -18,6 +18,19 @@ | @@ -18,6 +18,19 @@ | ||
18 | 18 | ||
19 | <script type="text/javascript"> | 19 | <script type="text/javascript"> |
20 | //<![CDATA[ | 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 | </script> | 36 | </script> |
plugins/shopping_cart/views/shopping_cart_plugin_profile/buy.html.erb
@@ -16,7 +16,7 @@ | @@ -16,7 +16,7 @@ | ||
16 | <%= submit_button(:send, _('Send buy request')) %> | 16 | <%= submit_button(:send, _('Send buy request')) %> |
17 | </div> | 17 | </div> |
18 | <% end %> | 18 | <% end %> |
19 | - <%= items_table(session[:cart][:items], profile) %> | 19 | + <%= items_table(@cart[:items], profile) %> |
20 | <%= link_to '', '#', :onclick => "Cart.colorbox_close(this);", :class => 'cart-box-close icon-cancel' %> | 20 | <%= link_to '', '#', :onclick => "Cart.colorbox_close(this);", :class => 'cart-box-close icon-cancel' %> |
21 | </div> | 21 | </div> |
22 | 22 |
vendor/plugins/noosfero_caching/init.rb
@@ -38,6 +38,8 @@ module NoosferoHttpCaching | @@ -38,6 +38,8 @@ module NoosferoHttpCaching | ||
38 | def call(env) | 38 | def call(env) |
39 | status, headers, body = @app.call(env) | 39 | status, headers, body = @app.call(env) |
40 | if headers['X-Noosfero-Auth'] == 'false' | 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 | headers.delete('Set-Cookie') | 43 | headers.delete('Set-Cookie') |
42 | end | 44 | end |
43 | headers.delete('X-Noosfero-Auth') | 45 | headers.delete('X-Noosfero-Auth') |