Storefront Sticky Add to Cart - Version 1.0.0

Version Description

  • 10.30.2015 = Initial release.
Download this release

Release Info

Developer jameskoster
Plugin Icon 128x128 Storefront Sticky Add to Cart
Version 1.0.0
Comparing to
See all releases

Version 1.0.0

assets/css/style.css ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @keyframes slideInDown {
2
+ from {
3
+ transform: translate3d(0, -100%, 0);
4
+ visibility: visible; }
5
+ to {
6
+ transform: translate3d(0, 0, 0); } }
7
+ .slideInDown {
8
+ animation-name: slideInDown; }
9
+
10
+ @keyframes slideOutUp {
11
+ from {
12
+ transform: translate3d(0, 0, 0); }
13
+ to {
14
+ visibility: hidden;
15
+ transform: translate3d(0, -100%, 0); } }
16
+ .slideOutUp {
17
+ animation-name: slideOutUp; }
18
+
19
+ .animated {
20
+ animation-duration: .5s;
21
+ animation-fill-mode: both; }
22
+
23
+ .animated.infinite {
24
+ animation-iteration-count: infinite; }
25
+
26
+ .ssatc-sticky-add-to-cart {
27
+ position: fixed;
28
+ top: 0;
29
+ left: 0;
30
+ right: 0;
31
+ z-index: 999999;
32
+ transform: translate3d(0, -100%, 0);
33
+ padding: 1.618em;
34
+ overflow: hidden;
35
+ zoom: 1;
36
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2); }
37
+ .ssatc-sticky-add-to-cart img {
38
+ max-height: 3.631em;
39
+ width: auto;
40
+ float: left;
41
+ margin: 0 1em 0 0; }
42
+ .ssatc-sticky-add-to-cart .ssatc-content {
43
+ position: relative; }
44
+ .ssatc-sticky-add-to-cart .price,
45
+ .ssatc-sticky-add-to-cart .stock {
46
+ font-size: .857em;
47
+ opacity: 0.75; }
48
+ .ssatc-sticky-add-to-cart .button {
49
+ margin-top: .53em; }
50
+ .ssatc-sticky-add-to-cart .price {
51
+ margin-right: 1em; }
52
+
53
+ @media screen and (min-width: 768px) {
54
+ .ssatc-sticky-add-to-cart .button {
55
+ position: absolute;
56
+ top: 0;
57
+ right: 0; } }
assets/css/style.scss ADDED
@@ -0,0 +1,92 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @import 'susy';
2
+ @import 'bourbon';
3
+ @import '../../../../themes/storefront/sass/utils/variables';
4
+
5
+ @keyframes slideInDown {
6
+ from {
7
+ transform: translate3d(0, -100%, 0);
8
+ visibility: visible;
9
+ }
10
+
11
+ to {
12
+ transform: translate3d(0, 0, 0);
13
+ }
14
+ }
15
+
16
+ .slideInDown {
17
+ animation-name: slideInDown;
18
+ }
19
+
20
+ @keyframes slideOutUp {
21
+ from {
22
+ transform: translate3d(0, 0, 0);
23
+ }
24
+
25
+ to {
26
+ visibility: hidden;
27
+ transform: translate3d(0, -100%, 0);
28
+ }
29
+ }
30
+
31
+ .slideOutUp {
32
+ animation-name: slideOutUp;
33
+ }
34
+
35
+ .animated {
36
+ animation-duration: .5s;
37
+ animation-fill-mode: both;
38
+ }
39
+
40
+ .animated.infinite {
41
+ animation-iteration-count: infinite;
42
+ }
43
+
44
+ .ssatc-sticky-add-to-cart {
45
+ position: fixed;
46
+ top: 0;
47
+ left: 0;
48
+ right: 0;
49
+ z-index: 999999;
50
+ transform: translate3d(0, -100%, 0);
51
+ padding: 1.618em;
52
+ overflow: hidden;
53
+ zoom: 1;
54
+ box-shadow: 0 1px 2px rgba(#000,.2);
55
+
56
+ img {
57
+ max-height: 3.631em;
58
+ width: auto;
59
+ float: left;
60
+ margin: 0 1em 0 0;
61
+ }
62
+
63
+ .ssatc-content {
64
+ position: relative;
65
+ }
66
+
67
+ .price,
68
+ .stock {
69
+ font-size: .857em;
70
+ opacity: 0.75;
71
+ }
72
+
73
+ .button {
74
+ margin-top: .53em;
75
+ }
76
+
77
+ .price {
78
+ margin-right: 1em;
79
+ }
80
+ }
81
+
82
+ @media screen and (min-width: 768px) {
83
+
84
+ // Styles for desktop
85
+ .ssatc-sticky-add-to-cart {
86
+ .button {
87
+ position: absolute;
88
+ top: 0;
89
+ right: 0;
90
+ }
91
+ }
92
+ }
assets/js/jquery.waypoints.min.js ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ /*!
2
+ Waypoints - 4.0.0
3
+ Copyright © 2011-2015 Caleb Troughton
4
+ Licensed under the MIT license.
5
+ https://github.com/imakewebthings/waypoints/blog/master/licenses.txt
6
+ */
7
+ !function(){"use strict";function t(o){if(!o)throw new Error("No options passed to Waypoint constructor");if(!o.element)throw new Error("No element option passed to Waypoint constructor");if(!o.handler)throw new Error("No handler option passed to Waypoint constructor");this.key="waypoint-"+e,this.options=t.Adapter.extend({},t.defaults,o),this.element=this.options.element,this.adapter=new t.Adapter(this.element),this.callback=o.handler,this.axis=this.options.horizontal?"horizontal":"vertical",this.enabled=this.options.enabled,this.triggerPoint=null,this.group=t.Group.findOrCreate({name:this.options.group,axis:this.axis}),this.context=t.Context.findOrCreateByElement(this.options.context),t.offsetAliases[this.options.offset]&&(this.options.offset=t.offsetAliases[this.options.offset]),this.group.add(this),this.context.add(this),i[this.key]=this,e+=1}var e=0,i={};t.prototype.queueTrigger=function(t){this.group.queueTrigger(this,t)},t.prototype.trigger=function(t){this.enabled&&this.callback&&this.callback.apply(this,t)},t.prototype.destroy=function(){this.context.remove(this),this.group.remove(this),delete i[this.key]},t.prototype.disable=function(){return this.enabled=!1,this},t.prototype.enable=function(){return this.context.refresh(),this.enabled=!0,this},t.prototype.next=function(){return this.group.next(this)},t.prototype.previous=function(){return this.group.previous(this)},t.invokeAll=function(t){var e=[];for(var o in i)e.push(i[o]);for(var n=0,r=e.length;r>n;n++)e[n][t]()},t.destroyAll=function(){t.invokeAll("destroy")},t.disableAll=function(){t.invokeAll("disable")},t.enableAll=function(){t.invokeAll("enable")},t.refreshAll=function(){t.Context.refreshAll()},t.viewportHeight=function(){return window.innerHeight||document.documentElement.clientHeight},t.viewportWidth=function(){return document.documentElement.clientWidth},t.adapters=[],t.defaults={context:window,continuous:!0,enabled:!0,group:"default",horizontal:!1,offset:0},t.offsetAliases={"bottom-in-view":function(){return this.context.innerHeight()-this.adapter.outerHeight()},"right-in-view":function(){return this.context.innerWidth()-this.adapter.outerWidth()}},window.Waypoint=t}(),function(){"use strict";function t(t){window.setTimeout(t,1e3/60)}function e(t){this.element=t,this.Adapter=n.Adapter,this.adapter=new this.Adapter(t),this.key="waypoint-context-"+i,this.didScroll=!1,this.didResize=!1,this.oldScroll={x:this.adapter.scrollLeft(),y:this.adapter.scrollTop()},this.waypoints={vertical:{},horizontal:{}},t.waypointContextKey=this.key,o[t.waypointContextKey]=this,i+=1,this.createThrottledScrollHandler(),this.createThrottledResizeHandler()}var i=0,o={},n=window.Waypoint,r=window.onload;e.prototype.add=function(t){var e=t.options.horizontal?"horizontal":"vertical";this.waypoints[e][t.key]=t,this.refresh()},e.prototype.checkEmpty=function(){var t=this.Adapter.isEmptyObject(this.waypoints.horizontal),e=this.Adapter.isEmptyObject(this.waypoints.vertical);t&&e&&(this.adapter.off(".waypoints"),delete o[this.key])},e.prototype.createThrottledResizeHandler=function(){function t(){e.handleResize(),e.didResize=!1}var e=this;this.adapter.on("resize.waypoints",function(){e.didResize||(e.didResize=!0,n.requestAnimationFrame(t))})},e.prototype.createThrottledScrollHandler=function(){function t(){e.handleScroll(),e.didScroll=!1}var e=this;this.adapter.on("scroll.waypoints",function(){(!e.didScroll||n.isTouch)&&(e.didScroll=!0,n.requestAnimationFrame(t))})},e.prototype.handleResize=function(){n.Context.refreshAll()},e.prototype.handleScroll=function(){var t={},e={horizontal:{newScroll:this.adapter.scrollLeft(),oldScroll:this.oldScroll.x,forward:"right",backward:"left"},vertical:{newScroll:this.adapter.scrollTop(),oldScroll:this.oldScroll.y,forward:"down",backward:"up"}};for(var i in e){var o=e[i],n=o.newScroll>o.oldScroll,r=n?o.forward:o.backward;for(var s in this.waypoints[i]){var a=this.waypoints[i][s],l=o.oldScroll<a.triggerPoint,h=o.newScroll>=a.triggerPoint,p=l&&h,u=!l&&!h;(p||u)&&(a.queueTrigger(r),t[a.group.id]=a.group)}}for(var c in t)t[c].flushTriggers();this.oldScroll={x:e.horizontal.newScroll,y:e.vertical.newScroll}},e.prototype.innerHeight=function(){return this.element==this.element.window?n.viewportHeight():this.adapter.innerHeight()},e.prototype.remove=function(t){delete this.waypoints[t.axis][t.key],this.checkEmpty()},e.prototype.innerWidth=function(){return this.element==this.element.window?n.viewportWidth():this.adapter.innerWidth()},e.prototype.destroy=function(){var t=[];for(var e in this.waypoints)for(var i in this.waypoints[e])t.push(this.waypoints[e][i]);for(var o=0,n=t.length;n>o;o++)t[o].destroy()},e.prototype.refresh=function(){var t,e=this.element==this.element.window,i=e?void 0:this.adapter.offset(),o={};this.handleScroll(),t={horizontal:{contextOffset:e?0:i.left,contextScroll:e?0:this.oldScroll.x,contextDimension:this.innerWidth(),oldScroll:this.oldScroll.x,forward:"right",backward:"left",offsetProp:"left"},vertical:{contextOffset:e?0:i.top,contextScroll:e?0:this.oldScroll.y,contextDimension:this.innerHeight(),oldScroll:this.oldScroll.y,forward:"down",backward:"up",offsetProp:"top"}};for(var r in t){var s=t[r];for(var a in this.waypoints[r]){var l,h,p,u,c,d=this.waypoints[r][a],f=d.options.offset,w=d.triggerPoint,y=0,g=null==w;d.element!==d.element.window&&(y=d.adapter.offset()[s.offsetProp]),"function"==typeof f?f=f.apply(d):"string"==typeof f&&(f=parseFloat(f),d.options.offset.indexOf("%")>-1&&(f=Math.ceil(s.contextDimension*f/100))),l=s.contextScroll-s.contextOffset,d.triggerPoint=y+l-f,h=w<s.oldScroll,p=d.triggerPoint>=s.oldScroll,u=h&&p,c=!h&&!p,!g&&u?(d.queueTrigger(s.backward),o[d.group.id]=d.group):!g&&c?(d.queueTrigger(s.forward),o[d.group.id]=d.group):g&&s.oldScroll>=d.triggerPoint&&(d.queueTrigger(s.forward),o[d.group.id]=d.group)}}return n.requestAnimationFrame(function(){for(var t in o)o[t].flushTriggers()}),this},e.findOrCreateByElement=function(t){return e.findByElement(t)||new e(t)},e.refreshAll=function(){for(var t in o)o[t].refresh()},e.findByElement=function(t){return o[t.waypointContextKey]},window.onload=function(){r&&r(),e.refreshAll()},n.requestAnimationFrame=function(e){var i=window.requestAnimationFrame||window.mozRequestAnimationFrame||window.webkitRequestAnimationFrame||t;i.call(window,e)},n.Context=e}(),function(){"use strict";function t(t,e){return t.triggerPoint-e.triggerPoint}function e(t,e){return e.triggerPoint-t.triggerPoint}function i(t){this.name=t.name,this.axis=t.axis,this.id=this.name+"-"+this.axis,this.waypoints=[],this.clearTriggerQueues(),o[this.axis][this.name]=this}var o={vertical:{},horizontal:{}},n=window.Waypoint;i.prototype.add=function(t){this.waypoints.push(t)},i.prototype.clearTriggerQueues=function(){this.triggerQueues={up:[],down:[],left:[],right:[]}},i.prototype.flushTriggers=function(){for(var i in this.triggerQueues){var o=this.triggerQueues[i],n="up"===i||"left"===i;o.sort(n?e:t);for(var r=0,s=o.length;s>r;r+=1){var a=o[r];(a.options.continuous||r===o.length-1)&&a.trigger([i])}}this.clearTriggerQueues()},i.prototype.next=function(e){this.waypoints.sort(t);var i=n.Adapter.inArray(e,this.waypoints),o=i===this.waypoints.length-1;return o?null:this.waypoints[i+1]},i.prototype.previous=function(e){this.waypoints.sort(t);var i=n.Adapter.inArray(e,this.waypoints);return i?this.waypoints[i-1]:null},i.prototype.queueTrigger=function(t,e){this.triggerQueues[e].push(t)},i.prototype.remove=function(t){var e=n.Adapter.inArray(t,this.waypoints);e>-1&&this.waypoints.splice(e,1)},i.prototype.first=function(){return this.waypoints[0]},i.prototype.last=function(){return this.waypoints[this.waypoints.length-1]},i.findOrCreate=function(t){return o[t.axis][t.name]||new i(t)},n.Group=i}(),function(){"use strict";function t(t){this.$element=e(t)}var e=window.jQuery,i=window.Waypoint;e.each(["innerHeight","innerWidth","off","offset","on","outerHeight","outerWidth","scrollLeft","scrollTop"],function(e,i){t.prototype[i]=function(){var t=Array.prototype.slice.call(arguments);return this.$element[i].apply(this.$element,t)}}),e.each(["extend","inArray","isEmptyObject"],function(i,o){t[o]=e[o]}),i.adapters.push({name:"jquery",Adapter:t}),i.Adapter=t}(),function(){"use strict";function t(t){return function(){var i=[],o=arguments[0];return t.isFunction(arguments[0])&&(o=t.extend({},arguments[1]),o.handler=arguments[0]),this.each(function(){var n=t.extend({},o,{element:this});"string"==typeof n.context&&(n.context=t(this).closest(n.context)[0]),i.push(new e(n))}),i}}var e=window.Waypoint;window.jQuery&&(window.jQuery.fn.waypoint=t(window.jQuery)),window.Zepto&&(window.Zepto.fn.waypoint=t(window.Zepto))}();
assets/js/waypoints.init.js ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ jQuery(document).ready(function($){
2
+
3
+ var waypoint = new Waypoint({
4
+ element: jQuery( 'form.cart' ),
5
+ handler: function( direction ) {
6
+ if ( 'up' == direction ) {
7
+ jQuery( '.ssatc-sticky-add-to-cart' ).addClass( 'slideOutUp' );
8
+ jQuery( '.ssatc-sticky-add-to-cart' ).removeClass( 'slideInDown' );
9
+ }
10
+
11
+ if ( 'down' == direction ) {
12
+ jQuery( '.ssatc-sticky-add-to-cart' ).addClass( 'slideInDown' );
13
+ jQuery( '.ssatc-sticky-add-to-cart' ).removeClass( 'slideOutUp' );
14
+ }
15
+ }
16
+ });
17
+
18
+ });
assets/js/waypoints.init.min.js ADDED
@@ -0,0 +1 @@
 
1
+ jQuery(document).ready(function($){var s=new Waypoint({element:jQuery("form.cart"),handler:function(s){"up"==s&&(jQuery(".ssatc-sticky-add-to-cart").addClass("slideOutUp"),jQuery(".ssatc-sticky-add-to-cart").removeClass("slideInDown")),"down"==s&&(jQuery(".ssatc-sticky-add-to-cart").addClass("slideInDown"),jQuery(".ssatc-sticky-add-to-cart").removeClass("slideOutUp"))}})});
changelog.txt ADDED
@@ -0,0 +1,4 @@
 
 
 
 
1
+ *** Storefront Sticky Add to Cart Changelog ***
2
+
3
+ 2015.10.29 - version 1.0.0
4
+ * Initial release
index.php ADDED
@@ -0,0 +1 @@
 
1
+ <?php // Silence is golden... ?>
languages/storefront-sticky-add-to-cart.pot ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright (C) 2015 Storefront Sticky Add to Cart
2
+ # This file is distributed under the same license as the Storefront Sticky Add to Cart package.
3
+ msgid ""
4
+ msgstr ""
5
+ "Project-Id-Version: Storefront Sticky Add to Cart 1.0.0\n"
6
+ "Report-Msgid-Bugs-To: http://wordpress.org/tag/storefront-sticky-add-to-"
7
+ "cart\n"
8
+ "POT-Creation-Date: 2015-10-30 10:08:29+00:00\n"
9
+ "MIME-Version: 1.0\n"
10
+ "Content-Type: text/plain; charset=UTF-8\n"
11
+ "Content-Transfer-Encoding: 8bit\n"
12
+ "PO-Revision-Date: 2015-MO-DA HO:MI+ZONE\n"
13
+ "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
14
+ "Language-Team: LANGUAGE <LL@li.org>\n"
15
+
16
+ #: storefront-sticky-add-to-cart.php:130 storefront-sticky-add-to-cart.php:139
17
+ msgid "Cheatin&#8217; huh?"
18
+ msgstr ""
19
+
20
+ #: storefront-sticky-add-to-cart.php:149
21
+ msgid "Support"
22
+ msgstr ""
23
+
24
+ #: storefront-sticky-add-to-cart.php:255
25
+ msgid "Placeholder"
26
+ msgstr ""
27
+
28
+ #: storefront-sticky-add-to-cart.php:288
29
+ msgid "You're viewing:"
30
+ msgstr ""
31
+
32
+ #. Plugin Name of the plugin/theme
33
+ msgid "Storefront Sticky Add to Cart"
34
+ msgstr ""
35
+
36
+ #. Plugin URI of the plugin/theme
37
+ msgid "https://wordpress.org/plugins/storefront-sticky-add-to-cart/"
38
+ msgstr ""
39
+
40
+ #. Description of the plugin/theme
41
+ msgid ""
42
+ "Adds a sticky add-to-cart bar in single product pages that is revealed as "
43
+ "the user scrolls down the page."
44
+ msgstr ""
45
+
46
+ #. Author of the plugin/theme
47
+ msgid "WooThemes"
48
+ msgstr ""
49
+
50
+ #. Author URI of the plugin/theme
51
+ msgid "http://woothemes.com/"
52
+ msgstr ""
readme.txt ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ === Storefront Sticky Add to Cart ===
2
+ Contributors: jameskoster, woothemes
3
+ Tags: woocommerce, ecommerce, storefront, sticky
4
+ Requires at least: 4.0
5
+ Tested up to: 4.3.1
6
+ Stable tag: 1.0.0
7
+ License: GPLv2 or later
8
+ License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
+
10
+ Storefront Sticky Add to Cart adds a convenient bar which sticks to the top of your product pages so that visitors can easily find and click the add to cart button.
11
+
12
+ == Description ==
13
+
14
+ Product pages can be long. Some products have long descriptions, lots of reviews, galleries, you name it. By the time a visitor has read all of the product content and decided to commit to purchasing the product, the add to cart button is often hidden way off screen at the top of the page. Not any more! The Storefront Sticky Add to Cart plugin reveals a small content bar at the top of the browser window which includes the product name, price, stock status and the all-important add to cart button. It subtly slides into view once the standard add-to-cart button has scrolled out of view. Now when your customers decide they want to buy your product they no longer have to go hunting to add it to their cart!
15
+
16
+ [youtube https://www.youtube.com/watch?v=v3daZU1kWJs]
17
+
18
+ As the name suggests this plugin has been designed to work with our [Storefront](http://wordpress.org/themes/storefront/) theme. The add-to-cart bar colors will be lifted from your Storefront configuration in the Customizer. The main background color is applied to the background, the main text color applied to the text and the main link color applied to links. If you want to use this plugin with another theme you'll have to build your own integration. More info in the FAQ.
19
+
20
+ == Installation ==
21
+
22
+ 1. Upload `storefront-sticky-add-to-cart` to the `/wp-content/plugins/` directory
23
+ 2. Activate the plugin through the 'Plugins' menu in WordPress
24
+ 3. Done!
25
+
26
+ == Frequently Asked Questions ==
27
+
28
+ = I only see the add-to-cart bar on simple products, why? =
29
+
30
+ Because grouped and variable products require additional input before they can be added to the cart reducing the effectiveness of this feature. I might look at including the variable product selectors in a future version.
31
+
32
+ = I want to integrate with a theme other than Storefront, how do I do it? =
33
+
34
+ It's very simple, most of the core styles are loaded regardless. You'll just need to apply a background color to the content bar like so; `.ssatc-sticky-add-to-cart { background-color: white; }`.
35
+
36
+ == Screenshots ==
37
+
38
+ 1. The sticky add to cart bar in action.
39
+
40
+ == Changelog ==
41
+
42
+ = 1.0.0 - 10.30.2015 =
43
+ Initial release.
storefront-sticky-add-to-cart.php ADDED
@@ -0,0 +1,302 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Plugin Name: Storefront Sticky Add to Cart
4
+ * Plugin URI: https://wordpress.org/plugins/storefront-sticky-add-to-cart/
5
+ * Description: Adds a sticky add-to-cart bar in single product pages that is revealed as the user scrolls down the page.
6
+ * Version: 1.0.0
7
+ * Author: WooThemes
8
+ * Author URI: http://woothemes.com/
9
+ * Requires at least: 4.0.0
10
+ * Tested up to: 4.0.0
11
+ *
12
+ * Text Domain: storefront-sticky-add-to-cart
13
+ * Domain Path: /languages/
14
+ *
15
+ * @package Storefront_Sticky_Add_to_Cart
16
+ * @category Core
17
+ * @author James Koster
18
+ */
19
+
20
+ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
21
+
22
+
23
+ /**
24
+ * Returns the main instance of Storefront_Sticky_Add_to_Cart to prevent the need to use globals.
25
+ *
26
+ * @since 1.0.0
27
+ * @return object Storefront_Sticky_Add_to_Cart
28
+ */
29
+ function Storefront_Sticky_Add_to_Cart() {
30
+ return Storefront_Sticky_Add_to_Cart::instance();
31
+ } // End Storefront_Sticky_Add_to_Cart()
32
+
33
+ Storefront_Sticky_Add_to_Cart();
34
+
35
+ /**
36
+ * Main Storefront_Sticky_Add_to_Cart Class
37
+ *
38
+ * @class Storefront_Sticky_Add_to_Cart
39
+ * @version 1.0.0
40
+ * @since 1.0.0
41
+ * @package Storefront_Sticky_Add_to_Cart
42
+ */
43
+ final class Storefront_Sticky_Add_to_Cart {
44
+ /**
45
+ * Storefront_Sticky_Add_to_Cart The single instance of Storefront_Sticky_Add_to_Cart.
46
+ * @var object
47
+ * @access private
48
+ * @since 1.0.0
49
+ */
50
+ private static $_instance = null;
51
+
52
+ /**
53
+ * The token.
54
+ * @var string
55
+ * @access public
56
+ * @since 1.0.0
57
+ */
58
+ public $token;
59
+
60
+ /**
61
+ * The version number.
62
+ * @var string
63
+ * @access public
64
+ * @since 1.0.0
65
+ */
66
+ public $version;
67
+
68
+ // Admin - Start
69
+ /**
70
+ * The admin object.
71
+ * @var object
72
+ * @access public
73
+ * @since 1.0.0
74
+ */
75
+ public $admin;
76
+
77
+ /**
78
+ * Constructor function.
79
+ * @access public
80
+ * @since 1.0.0
81
+ * @return void
82
+ */
83
+ public function __construct() {
84
+ $this->token = 'storefront-sticky-add-to-cart';
85
+ $this->plugin_url = plugin_dir_url( __FILE__ );
86
+ $this->plugin_path = plugin_dir_path( __FILE__ );
87
+ $this->version = '1.0.0';
88
+
89
+ register_activation_hook( __FILE__, array( $this, 'install' ) );
90
+
91
+ add_action( 'init', array( $this, 'ssatc_load_plugin_textdomain' ) );
92
+
93
+ add_action( 'init', array( $this, 'ssatc_setup' ) );
94
+
95
+ add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), array( $this, 'ssatc_plugin_links' ) );
96
+ }
97
+
98
+ /**
99
+ * Main Storefront_Sticky_Add_to_Cart Instance
100
+ *
101
+ * Ensures only one instance of Storefront_Sticky_Add_to_Cart is loaded or can be loaded.
102
+ *
103
+ * @since 1.0.0
104
+ * @static
105
+ * @see Storefront_Sticky_Add_to_Cart()
106
+ * @return Main Storefront_Sticky_Add_to_Cart instance
107
+ */
108
+ public static function instance() {
109
+ if ( is_null( self::$_instance ) )
110
+ self::$_instance = new self();
111
+ return self::$_instance;
112
+ } // End instance()
113
+
114
+ /**
115
+ * Load the localisation file.
116
+ * @access public
117
+ * @since 1.0.0
118
+ * @return void
119
+ */
120
+ public function ssatc_load_plugin_textdomain() {
121
+ load_plugin_textdomain( 'storefront-sticky-add-to-cart', false, dirname( plugin_basename( __FILE__ ) ) . '/languages/' );
122
+ }
123
+
124
+ /**
125
+ * Cloning is forbidden.
126
+ *
127
+ * @since 1.0.0
128
+ */
129
+ public function __clone() {
130
+ _doing_it_wrong( __FUNCTION__, __( 'Cheatin&#8217; huh?' ), '1.0.0' );
131
+ }
132
+
133
+ /**
134
+ * Unserializing instances of this class is forbidden.
135
+ *
136
+ * @since 1.0.0
137
+ */
138
+ public function __wakeup() {
139
+ _doing_it_wrong( __FUNCTION__, __( 'Cheatin&#8217; huh?' ), '1.0.0' );
140
+ }
141
+
142
+ /**
143
+ * Plugin page links
144
+ *
145
+ * @since 1.0.0
146
+ */
147
+ public function ssatc_plugin_links( $links ) {
148
+ $plugin_links = array(
149
+ '<a href="https://wordpress.org/support/plugin/storefront-sticky-add-to-cart">' . __( 'Support', 'storefront-sticky-add-to-cart' ) . '</a>',
150
+ );
151
+
152
+ return array_merge( $plugin_links, $links );
153
+ }
154
+
155
+ /**
156
+ * Installation.
157
+ * Runs on activation. Logs the version number.
158
+ * @access public
159
+ * @since 1.0.0
160
+ * @return void
161
+ */
162
+ public function install() {
163
+ $this->_log_version_number();
164
+ }
165
+
166
+ /**
167
+ * Log the plugin version number.
168
+ * @access private
169
+ * @since 1.0.0
170
+ * @return void
171
+ */
172
+ private function _log_version_number() {
173
+ // Log the version number.
174
+ update_option( $this->token . '-version', $this->version );
175
+ }
176
+
177
+ /**
178
+ * Setup all the things.
179
+ * @return void
180
+ */
181
+ public function ssatc_setup() {
182
+ add_action( 'wp_enqueue_scripts', array( $this, 'ssatc_script' ), 999 );
183
+ add_action( 'wp', array( $this, 'ssatc_load_add_to_cart_bar' ), 999 );
184
+ }
185
+
186
+ /**
187
+ * Enqueue CSS and custom styles.
188
+ * @since 1.0.0
189
+ * @return void
190
+ */
191
+ public function ssatc_script() {
192
+ $theme = wp_get_theme();
193
+
194
+ wp_enqueue_style( 'ssatc-styles', plugins_url( '/assets/css/style.css', __FILE__ ) );
195
+ wp_register_script( 'waypoints', plugins_url( '/assets/js/jquery.waypoints.min.js', __FILE__ ), array( 'jquery' ), '4.0.0' );
196
+ wp_register_script( 'waypoints-init', plugins_url( '/assets/js/waypoints.init.min.js', __FILE__ ), array( 'jquery' ) );
197
+
198
+ // If Storefront is the active parent theme, add some styles
199
+ if ( 'Storefront' == $theme->name || 'storefront' == $theme->template ) {
200
+
201
+ $content_bg_color = storefront_sanitize_hex_color( get_theme_mod( 'sd_content_background_color' ) );
202
+ $content_frame = get_theme_mod( 'sd_fixed_width' );
203
+
204
+
205
+ if ( $content_bg_color && 'true' == $content_frame && class_exists( 'Storefront_Designer' ) ) {
206
+ $bg_color = str_replace( '#', '', $content_bg_color );
207
+ } else {
208
+ $bg_color = str_replace( '#', '', get_theme_mod( 'background_color' ) );
209
+ }
210
+
211
+ $accent_color = storefront_sanitize_hex_color( get_theme_mod( 'storefront_accent_color', apply_filters( 'storefront_default_accent_color', '#96588a' ) ) );
212
+ $text_color = storefront_sanitize_hex_color( get_theme_mod( 'storefront_text_color', apply_filters( 'storefront_default_text_color', '#60646c' ) ) );
213
+
214
+
215
+ $ssatc_style = '
216
+ .ssatc-sticky-add-to-cart {
217
+ background-color: #' . $bg_color . ';
218
+ color: ' . $text_color . ';
219
+ }
220
+
221
+ .ssatc-sticky-add-to-cart a:not(.button) {
222
+ color: ' . $accent_color . ';
223
+ }';
224
+
225
+ wp_add_inline_style( 'ssatc-styles', $ssatc_style );
226
+ }
227
+ }
228
+
229
+ /**
230
+ * Hooks the add to cart bar into DOM
231
+ */
232
+ public function ssatc_load_add_to_cart_bar() {
233
+ add_action( 'storefront_after_footer', array( $this, 'ssatc_add_to_cart_bar' ), 999 );
234
+ }
235
+
236
+ /**
237
+ * Display the current product image
238
+ * @return void
239
+ */
240
+ public function ssatc_product_image() {
241
+ global $post;
242
+
243
+ if ( has_post_thumbnail() ) {
244
+
245
+ $image_title = esc_attr( get_the_title( get_post_thumbnail_id() ) );
246
+ $image = get_the_post_thumbnail( $post->ID, apply_filters( 'single_product_large_thumbnail_size', 'shop_catalog' ), array(
247
+ 'title' => $image_title,
248
+ 'alt' => $image_title
249
+ ) );
250
+
251
+ echo apply_filters( 'woocommerce_single_product_image_html', sprintf( '%s', $image ), $post->ID );
252
+
253
+ } else {
254
+
255
+ echo apply_filters( 'woocommerce_single_product_image_html', sprintf( '<img src="%s" alt="%s" />', wc_placeholder_img_src(), __( 'Placeholder', 'storefront-sticky-add-to-cart' ) ), $post->ID );
256
+
257
+ }
258
+ }
259
+
260
+ /**
261
+ * Display the add to cart bar
262
+ * @return void
263
+ */
264
+ function ssatc_add_to_cart_bar() {
265
+ global $product;
266
+
267
+ // Only execute if WooCommerce is installed
268
+ if ( class_exists( 'WooCommerce' ) ) {
269
+
270
+ // And if we're on a product page
271
+ if ( is_product() ) {
272
+ $_product = new WC_Product( $product->ID );
273
+ $availability = $product->get_availability();
274
+ $ssatc = new Storefront_Sticky_Add_to_Cart();
275
+ $availability_html = empty( $availability['availability'] ) ? '' : '<span class="stock ' . esc_attr( $availability['class'] ) . '">' . esc_html( $availability['availability'] ) . '</span>';
276
+
277
+ // And if the product isn't variable or grouped
278
+ if ( $product->is_type( 'simple' ) ) {
279
+ wp_enqueue_script( 'waypoints' );
280
+ wp_enqueue_script( 'waypoints-init' );
281
+
282
+ ?>
283
+ <section class="ssatc-sticky-add-to-cart animated">
284
+ <div class="col-full">
285
+ <?php
286
+ $ssatc->ssatc_product_image();
287
+ echo '<div class="ssatc-content">';
288
+ echo __( 'You\'re viewing:', 'storefront-sticky-add-to-cart' ) . ' <strong>' . get_the_title() . '</strong><br />';
289
+ echo '<span class="price">' . $product->get_price_html() . '</span> ';
290
+ echo apply_filters( 'woocommerce_stock_html', $availability_html, $availability['availability'], $product );
291
+ echo '<br /><a href="' . $product->add_to_cart_url() . '" class="button">' . $product->single_add_to_cart_text() . '</a>';
292
+ echo '</div>';
293
+ ?>
294
+ </div>
295
+ </section>
296
+ <?php
297
+ }
298
+ }
299
+ }
300
+ }
301
+
302
+ } // End Class