├── woocommerce-gateway-stripe ├── assets │ ├── images │ │ └── cards.png │ └── js │ │ ├── stripe_checkout.js │ │ └── stripe.js ├── readme.txt ├── woo-includes │ ├── class-wc-dependencies.php │ └── woo-functions.php ├── changelog.txt ├── gateway-stripe.php └── classes │ ├── class-wc-gateway-stripe-sponsorship.php │ ├── class-wc-gateway-stripe-subscriptions.php │ ├── class-wc-gateway-stripe-preorder │ └── class-wc-gateway-stripe.php ├── woo-includes ├── woo-functions.php └── class-wc-dependencies.php ├── classes ├── class-wc-sponsorship-sidebar.php ├── widgets │ ├── class-wc-sponsorship-levels-widget.php │ ├── class-wc-sponsorship-project-status-widget.php │ ├── class-wc-sponsorship-levels-template.php │ └── class-wc-sponsorship-project-status-template.php ├── class-wc-sponsorship-checkout.php ├── class-wc-sponsorship-order.php └── class-wc-sponsorship-product.php ├── README.md ├── assets └── css │ ├── admin.css │ └── wc-sponsorship.css └── woocommerce-sponsorship.php /woocommerce-gateway-stripe/assets/images/cards.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chrislema/WooSponsorship/HEAD/woocommerce-gateway-stripe/assets/images/cards.png -------------------------------------------------------------------------------- /woo-includes/woo-functions.php: -------------------------------------------------------------------------------- 1 | 2 |
'; 5 | echo '

'; 6 | __( 'Sponsorship Sidebar Widget Area' ); 7 | echo '

'; 8 | echo '

'; 9 | printf( __( 'This is the Sponsorship Sidebar Widget Area. You can add content to this area by visiting your Widgets Panel and adding new widgets to this area.' ), admin_url( 'widgets.php' ) ); 10 | echo '

'; 11 | echo '
'; 12 | } 13 | ?> 14 | -------------------------------------------------------------------------------- /woo-includes/class-wc-dependencies.php: -------------------------------------------------------------------------------- 1 | '; 13 | echo $before_title; 14 | echo $after_title; 15 | echo ''; 16 | 17 | include('class-wc-sponsorship-levels-template.php'); 18 | 19 | echo $after_widget; 20 | } 21 | 22 | function update($new_instance, $old_instance) { } 23 | 24 | function form($instance) { } 25 | 26 | function refresh() { } 27 | } 28 | ?> 29 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | === WooSponsorship === 2 | 3 | Contributors: chrislema & jdkussow 4 | 5 | Tags: woocommerce, woocommerce extension, kickstarter, stripe 6 | 7 | Requires at least: 3.0 8 | 9 | Tested up to: 3.5 10 | 11 | == Donation == 12 | 13 | http://chrislema.com/want-to-make-a-small-donation/ 14 | 15 | == Description == 16 | 17 | Creates a new kind of product (sponsorship product) for WooCommerce that allows you to gather sponsors and charge them when your product minimum is met. It only works with Stripe. Not Paypal. 18 | 19 | == Installation == 20 | 21 | 1. Download as zip. 22 | 2. Remove the internal folder for Stripe, to install separately. 23 | 3. Upload both WooSponsorship and Stripe extensions. 24 | 4. Activate the plugins through the plugins menu in WordPress. 25 | 5. Go into WooCommerce/Products and add a new product. 26 | 6. Change it to a Sponsorship product. 27 | -------------------------------------------------------------------------------- /classes/widgets/class-wc-sponsorship-project-status-widget.php: -------------------------------------------------------------------------------- 1 | '; 13 | echo $before_title; 14 | echo $after_title; 15 | echo ''; 16 | 17 | include('class-wc-sponsorship-project-status-template.php'); 18 | 19 | echo $after_widget; 20 | } 21 | 22 | function update($new_instance, $old_instance) { } 23 | 24 | function form($instance) { } 25 | 26 | function refresh() { } 27 | } 28 | ?> 29 | -------------------------------------------------------------------------------- /woocommerce-gateway-stripe/assets/js/stripe_checkout.js: -------------------------------------------------------------------------------- 1 | jQuery( function() { 2 | 3 | jQuery(document).on( 'click', '#stripe_payment_button', function(){ 4 | 5 | var $form = jQuery("form.checkout, form#order_review"); 6 | 7 | var token = $form.find('input.stripe_token'); 8 | 9 | if ( token && token.val() ) { 10 | $form.submit(); 11 | 12 | return false; 13 | } 14 | 15 | var token_action = function( res ) { 16 | $form.find('input.stripe_token').remove(); 17 | $form.append(""); 18 | $form.submit(); 19 | }; 20 | 21 | StripeCheckout.open({ 22 | key: wc_stripe_params.key, 23 | address: false, 24 | amount: jQuery(this).data( 'amount' ), 25 | name: jQuery(this).data( 'name' ), 26 | description: jQuery(this).data( 'description' ), 27 | panelLabel: jQuery(this).data( 'label' ), 28 | token: token_action 29 | }); 30 | 31 | return false; 32 | }); 33 | 34 | } ); -------------------------------------------------------------------------------- /woocommerce-gateway-stripe/changelog.txt: -------------------------------------------------------------------------------- 1 | *** Stripe Changelog *** 2 | 3 | 2013.01.24 - version 1.5.1 4 | * Add support for changing a subscription's recurring amount 5 | 6 | 2013.01.18 - version 1.5.0 7 | * Supports Stripe Checkout https://stripe.com/docs/checkout 8 | 9 | 2013.01.18 - version 1.4.0 10 | * WC 2.0 Compat 11 | 12 | 2012.12.05 - version 1.3.5 13 | * Pass address fields to stripe.js on pay page. 14 | 15 | 2012.12.05 - version 1.3.4 16 | * Updater 17 | 18 | 2012.10.22 - version 1.3.3 19 | * Fix CAD check 20 | 21 | 2012.10.15 - version 1.3.2 22 | * Fixed bug causing settings to not show when using CAD 23 | 24 | 2012.10.11 - version 1.3.1 25 | * Add support for changing subscription next payment date 26 | * Remove order meta from subscription renewal orders 27 | 28 | 2012.09.20 - version 1.3 29 | * Allowed canadian dollars - Stripe is beta testing support for Canada 30 | 31 | 2012.09.11 - version 1.2.1 32 | * Fix text mode SSL logic 33 | 34 | 2012.09.01 - version 1.2 35 | * SSL not required in TEST MODE 36 | * Saved cards - store customer tokens and let users pay again using the same card 37 | * Subscriptions use a single customer, rather than per-order 38 | * Only load JS on checkout 39 | 40 | 2012.06.19 - version 1.1 41 | * Update woo updater 42 | * Class name update 43 | * Stripe JS for added security - you will need to re-enter keys and ensure you are using WooCommerce 1.5.8 44 | * Subscriptions support (requires WC Subscriptions addon) 45 | 46 | 2011.12.08 - version 1.0 47 | * First Release -------------------------------------------------------------------------------- /classes/widgets/class-wc-sponsorship-levels-template.php: -------------------------------------------------------------------------------- 1 | 'product_variation', 6 | 'post_status' => array( 'private', 'publish' ), 7 | 'numberposts' => -1, 8 | 'orderby' => 'id', 9 | 'order' => 'asc', 10 | 'post_parent' => $post->ID 11 | ); 12 | $levels = get_posts( $args ); 13 | 14 | do_action( 'woocommerce_before_add_to_cart_button' ); 15 | ?> 16 |
17 |
18 | ID ); 21 | $level_data = get_post_custom( $level->ID ); 22 | ?> 23 |
24 | 25 |
26 | ID ); ?> 27 |
28 | $ 29 |
30 |
31 |
32 |

post_content; ?>

33 |
34 |
35 |
36 | 37 |
38 |
39 | 46 | -------------------------------------------------------------------------------- /classes/class-wc-sponsorship-checkout.php: -------------------------------------------------------------------------------- 1 | get_items() as $order_item ) { 38 | if ( WC_Sponsorship_Product::is_sponsorship_contribution_level( $order_item['product_id'] ) ) { 39 | $cl = get_post( $order_item['product_id'] ); 40 | if ( !in_array( $cl->post_parent, $projects ) ) { 41 | $projects[] = $cl->post_parent; 42 | } 43 | } 44 | } 45 | 46 | foreach ( $projects as $project ) { 47 | update_post_meta( $order->id, '_sponsorship_project', $project ); 48 | } 49 | } 50 | 51 | } 52 | 53 | $GLOBALS[ 'WC_Sponsorship_Checkout' ] = new WC_Sponsorship_Checkout(); // Init 54 | ?> 55 | -------------------------------------------------------------------------------- /classes/class-wc-sponsorship-order.php: -------------------------------------------------------------------------------- 1 | Your contribution has pushed the project over it\'s goal! Your payment will be processed soon.

'; 29 | } else { 30 | echo '

Your contribution will be processed when the project goal has been met.

'; 31 | } 32 | echo '

' . sprintf( 'View the status of your subscription in %syour account%s.', '', '' ) . '

'; 33 | } 34 | } 35 | 36 | public static function order_contains_sponsorship( $order ) { 37 | if ( ! is_object( $order ) ) 38 | $order = new WC_Order( $order ); 39 | 40 | $contains_contribution = false; 41 | 42 | foreach ( $order->get_items() as $order_item ) { 43 | if ( WC_Sponsorship_Product::is_sponsorship_contribution_level( $order_item['product_id'] ) ) { 44 | $contains_contribution = true; 45 | break; 46 | } 47 | } 48 | 49 | return $contains_contribution; 50 | } 51 | 52 | public static function cancel_order( $order, $note ) { 53 | if ( !is_object( $order ) ) 54 | $order = new WC_Order( $order ); 55 | 56 | if ( !WC_Sponsorship_Order::order_contains_sponsorship( $order ) ) 57 | return; 58 | 59 | $order->update_status( 'cancelled', $note ); 60 | update_post_meta( $order->id, '_stripe_customer_id', null); 61 | update_post_meta( $order->id, '_stripe_token', null); 62 | } 63 | 64 | public static function complete_order( $order, $project_id, $amount_to_charge ) { 65 | if ( ! is_object( $order ) ) 66 | $order = new WC_Order( $order ); 67 | 68 | if ( !WC_Sponsorship_Order::order_contains_sponsorship( $order ) ) 69 | return; 70 | 71 | do_action( 'complete_sponsorship_payment_' . $order->payment_method, $amount_to_charge, $order, $project_id ); 72 | } 73 | } 74 | 75 | $GLOBALS[ 'WC_Sponsorship_Order' ] = new WC_Sponsorship_Order(); 76 | ?> 77 | -------------------------------------------------------------------------------- /assets/css/admin.css: -------------------------------------------------------------------------------- 1 | /* 2 | Document : admin 3 | Created on : Jul 31, 2012, 9:56:38 PM 4 | Author : jd 5 | Description: 6 | Purpose of the stylesheet follows. 7 | */ 8 | 9 | root { 10 | display: block; 11 | } 12 | 13 | .wc-sponsorship-fix:after { 14 | content: " "; 15 | display: block; 16 | height: 0; 17 | clear: both; 18 | visibility: hidden; 19 | } 20 | 21 | .woocommerce_options_panel .nomargin { margin: 0; } 22 | .woocommerce_options_panel .nomargintop { margin-top: 0; } 23 | .woocommerce_options_panel .nomarginbottom { margin-bottom: 0; } 24 | 25 | .woocommerce_options_panel .autowidth{ 26 | width: auto; 27 | margin-right: 12px; 28 | } 29 | 30 | .woocommerce_options_panel .nolabel { 31 | margin-left: 150px; 32 | } 33 | 34 | .sponsorship_tab { 35 | line-height: 16px; 36 | } 37 | 38 | .level-delete-button, 39 | #sponsorship_level_add { 40 | cursor: pointer; 41 | } 42 | 43 | .form-field._levels_field { 44 | margin-top: 9px; 45 | padding: 5px 9px; 46 | } 47 | 48 | .sponsorship_levels_field { 49 | padding: 5px 9px; 50 | margin: 9px 0; 51 | font-size: 12px; 52 | line-height: 24px; 53 | } 54 | 55 | .woocommerce_options_panel .levels { 56 | float: left; 57 | width: 70%; 58 | list-style: none; 59 | margin-top: 0; 60 | } 61 | 62 | .woocommerce_options_panel .level { 63 | list-style-type: none; 64 | overflow: hidden; 65 | } 66 | 67 | .level table { 68 | border-spacing: 0; 69 | border-style: solid; 70 | border-width: 1px; 71 | border-color: #DFDFDF; 72 | background-color: #F9F9F9; 73 | margin: 0; 74 | width: 100%; 75 | } 76 | 77 | .level th.left, #postcustomstuff td.left { 78 | width: 38%; 79 | } 80 | 81 | .level thead th { 82 | background-color: #F1F1F1; 83 | padding: 5px 8px 8px; 84 | } 85 | 86 | .level thead th.level-title { 87 | padding: 3px; 88 | background-color: #ddd; 89 | } 90 | 91 | .level thead th.level-title input { 92 | font-size: 18px; 93 | font-weight: normal; 94 | margin: 0; 95 | width: 80%; 96 | } 97 | 98 | .level thead th.level-title span { 99 | width: 20%; 100 | color: #555555; 101 | line-height: 27px; 102 | } 103 | 104 | .level thead th label { 105 | float: none; 106 | } 107 | 108 | .level td { 109 | vertical-align: top; 110 | } 111 | 112 | .level table input, 113 | .level table select, 114 | .level table textarea { 115 | margin: 8px 0 8px 8px; 116 | width: 95%; 117 | } 118 | 119 | .level table textarea { 120 | height: 60px; 121 | } 122 | 123 | .level-submit input[type="submit"] { 124 | border-radius: 11px; 125 | } 126 | 127 | .add-level-button { 128 | text-align: right; 129 | } 130 | 131 | #_sponsorship_end_date .ui-state-active { 132 | border-color: #4AB915; 133 | } 134 | 135 | #sponsorship-progress { 136 | height: 14px; 137 | border: 1px solid #aaaaaa; 138 | margin-left: 160px; 139 | margin-bottom: 12px; 140 | width: 20%; 141 | border-radius: 4px; 142 | -moz-border-radius: 4px; 143 | -webkit-border-radius: 4px; 144 | display: inline-block; 145 | } 146 | 147 | #sponsorship-progress-percent { 148 | height: 14px; 149 | background-color: #4AB915; 150 | width: 0%; 151 | } 152 | 153 | .sponsorship-progress-desc { 154 | vertical-align: top 155 | } -------------------------------------------------------------------------------- /woocommerce-gateway-stripe/woo-includes/woo-functions.php: -------------------------------------------------------------------------------- 1 | file = $file; 29 | $plugin->file_id = $file_id; 30 | $plugin->product_id = $product_id; 31 | 32 | $woothemes_queued_updates[] = $plugin; 33 | } 34 | } 35 | 36 | /** 37 | * Load installer for the WooThemes Updater. 38 | * @return $api Object 39 | */ 40 | if ( ! class_exists( 'WooThemes_Updater' ) && ! function_exists( 'woothemes_updater_install' ) ) { 41 | function woothemes_updater_install( $api, $action, $args ) { 42 | $download_url = 'http://woodojo.s3.amazonaws.com/downloads/woothemes-updater/woothemes-updater.zip'; 43 | 44 | if ( 'plugin_information' != $action || 45 | false !== $api || 46 | ! isset( $args->slug ) || 47 | 'woothemes-updater' != $args->slug 48 | ) return $api; 49 | 50 | $api = new stdClass(); 51 | $api->name = 'WooThemes Updater'; 52 | $api->version = '1.0.0'; 53 | $api->download_link = esc_url( $download_url ); 54 | return $api; 55 | } 56 | 57 | add_filter( 'plugins_api', 'woothemes_updater_install', 10, 3 ); 58 | } 59 | 60 | /** 61 | * WooUpdater Installation Prompts 62 | */ 63 | if ( ! class_exists( 'WooThemes_Updater' ) && ! function_exists( 'woothemes_updater_notice' ) ) { 64 | 65 | /** 66 | * Display a notice if the "WooThemes Updater" plugin hasn't been installed. 67 | * @return void 68 | */ 69 | function woothemes_updater_notice() { 70 | $active_plugins = apply_filters( 'active_plugins', get_option('active_plugins' ) ); 71 | if ( in_array( 'woothemes-updater/woothemes-updater.php', $active_plugins ) ) return; 72 | 73 | $slug = 'woothemes-updater'; 74 | $install_url = wp_nonce_url( self_admin_url( 'update.php?action=install-plugin&plugin=' . $slug ), 'install-plugin_' . $slug ); 75 | $activate_url = 'plugins.php?action=activate&plugin=' . urlencode( 'woothemes-updater/woothemes-updater.php' ) . '&plugin_status=all&paged=1&s&_wpnonce=' . urlencode( wp_create_nonce( 'activate-plugin_woothemes-updater/woothemes-updater.php' ) ); 76 | 77 | $message = 'Install the WooThemes Updater plugin to get updates for your WooThemes plugins.'; 78 | $is_downloaded = false; 79 | $plugins = array_keys( get_plugins() ); 80 | foreach ( $plugins as $plugin ) { 81 | if ( strpos( $plugin, 'woothemes-updater.php' ) !== false ) { 82 | $is_downloaded = true; 83 | $message = 'Activate the WooThemes Updater plugin to get updates for your WooThemes plugins.'; 84 | } 85 | } 86 | echo '

' . $message . '

' . "\n"; 87 | } 88 | 89 | add_action( 'admin_notices', 'woothemes_updater_notice' ); 90 | } 91 | 92 | /** 93 | * Prevent conflicts with older versions 94 | */ 95 | if ( ! class_exists( 'WooThemes_Plugin_Updater' ) ) { 96 | class WooThemes_Plugin_Updater { function init() {} } 97 | } -------------------------------------------------------------------------------- /classes/widgets/class-wc-sponsorship-project-status-template.php: -------------------------------------------------------------------------------- 1 | ID, '_sponsorship', true ); 13 | 14 | $days_left = 0; 15 | if ( $data[ 'end' ][ 'date' ] ) { 16 | $now = strtotime( date( "Y-m-d" ) ); // or your date as well 17 | $then = strtotime( $data[ 'end' ][ 'date' ] ); 18 | $end_date = date( "l M j", $then ); 19 | $datediff = $then - $now; 20 | 21 | // add 1 additional day so if current day, it is not the last day 22 | $days_left = floor( $datediff / ( 60 * 60 * 24 ) ) + 1; 23 | 24 | if ( $days_left < 0 ) { 25 | $days_left = 0; 26 | } 27 | } 28 | 29 | $goal = $progress = $percent = 0; 30 | if ( array_key_exists( 'goal', $data ) ) { 31 | $goal = $data[ 'goal' ]; 32 | } 33 | 34 | if ( array_key_exists( 'progress', $data ) ) { 35 | $progress = $data[ 'progress' ]; 36 | if ( $goal ) { 37 | $percent = round( $data[ 'progress' ] / $data[ 'goal' ] * 100 ); 38 | } 39 | } 40 | 41 | if ( 100 < $percent ) { 42 | $percent = 100; 43 | } 44 | 45 | $backers = $wpdb->get_var( $wpdb->prepare(" 46 | select count(pm.post_id) 47 | from $wpdb->postmeta pm 48 | join $wpdb->postmeta pmCID on pm.post_id = pmCID.post_id and pmCID.meta_key = '_stripe_customer_id' 49 | join $wpdb->postmeta pmTotal on pm.post_id = pmTotal.post_id and pmTotal.meta_key = '_order_total' 50 | where pm.meta_key = '_sponsorship_project' and pm.meta_value = %d 51 | ", $product->id ) ); 52 | 53 | $min_level_id = $wpdb->get_var( $wpdb->prepare(" 54 | select pm.post_id 55 | from $wpdb->posts p 56 | join $wpdb->postmeta pm on pm.post_id = p.id and pm.meta_key = '_price' 57 | where p.post_parent = 272 58 | order by pm.meta_value 59 | limit 1; 60 | ", $product->id ) ); 61 | if ( $min_level_id ) { 62 | $min_level = new WC_Product_Variation( $min_level_id ); 63 | $min_level_data = get_post_custom( $min_level_id ); 64 | } 65 | ?> 66 |
67 |
68 |
69 |
70 | 71 | 72 | 73 |
74 | 75 | 76 | Backers 77 | 78 | 79 |
80 |
81 |
82 | 83 | $ 84 | 85 |
86 | pledged of $ goal 87 |
88 |
89 |
90 |
91 | days to go 92 |
93 |
94 |
95 | 96 |
97 |
98 |
99 | 100 | Back This Project 101 | $ minimum pledge 102 | 103 |
104 |
105 |
106 | 107 |
108 |
109 |

110 | This project will only be funded if at least $ is pledged by . 111 |

112 |
113 |
114 |
115 | -------------------------------------------------------------------------------- /woocommerce-gateway-stripe/gateway-stripe.php: -------------------------------------------------------------------------------- 1 | 68 |

69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | $credit_card ) : ?> 79 | 80 | 81 | 82 | 89 | 90 | 91 | 92 |
83 |
84 | 85 | 86 | 87 |
88 |
93 |
  • ' + response.error.message + '
  • ' ); 100 | $form.unblock(); 101 | 102 | } else { 103 | 104 | // token contains id, last4, and card type 105 | var token = response['id']; 106 | 107 | // insert the token into the form so it gets submitted to the server 108 | $form.append(""); 109 | $form.submit(); 110 | } 111 | } -------------------------------------------------------------------------------- /assets/css/wc-sponsorship.css: -------------------------------------------------------------------------------- 1 | body #wrapper #content .products .product .button.add_to_cart_button.product_type_sponsorship-project, 2 | body #wrapper #content .products .product .button.add_to_cart_button.product_type_sponsorship-project:visited { 3 | display: none; 4 | } 5 | 6 | .sp-progress { 7 | 8 | } 9 | 10 | .sp-progress-bar { 11 | height: 8px; 12 | border: 1px solid #aaaaaa; 13 | margin: 8px 4px; 14 | width: auto; 15 | border-radius: 4px; 16 | -moz-border-radius: 4px; 17 | -webkit-border-radius: 4px; 18 | } 19 | 20 | .sp-progress-bar-percent { 21 | height: 8px; 22 | background-color: #4AB915; 23 | } 24 | 25 | .sp-price { 26 | display: table; 27 | text-transform: uppercase; 28 | width: 100%; 29 | overflow: hidden; 30 | font-size: 10px; 31 | color: #555555; 32 | border: none; 33 | text-align: left; 34 | } 35 | 36 | .sp-price-col { 37 | line-height: 17px; 38 | display: table-cell; 39 | float: left; 40 | white-space: nowrap; 41 | vertical-align: baseline; 42 | text-align: left; 43 | width: 33%; 44 | } 45 | 46 | .sp-price-col strong { 47 | display: block; 48 | color: #666666; 49 | font-weight: bold; 50 | font-size: 11px; 51 | line-height: 11px; 52 | margin: 0; 53 | padding-top: 2px; 54 | } 55 | 56 | .sp-level { 57 | display: block; 58 | width: auto; 59 | border: 1px solid #ccc; 60 | border-radius: 3px; 61 | -moz-border-radius: 3px; 62 | -webkit-border-radius: 3px; 63 | cursor: pointer; 64 | margin-bottom: 8px; 65 | } 66 | 67 | .sp-level:hover, 68 | .sp-level:active { 69 | text-decoration: none; 70 | color: #555555; 71 | border: 1px solid #aaa; 72 | } 73 | 74 | .sp-level-title { 75 | padding: 4px; 76 | background-color: #e6e6e6; 77 | font-size: 16px; 78 | font-weight: 700; 79 | } 80 | 81 | .sp-level-amount { 82 | float: right; 83 | } 84 | 85 | .sp-level-description { 86 | padding: 4px; 87 | } 88 | 89 | #main-sidebar-container #sidebar.wc-sponsorship-hidden { 90 | display: none; 91 | } 92 | 93 | .sp-widget-levels { } 94 | .sp-widget-levels .sp-widget-level { 95 | display: block; 96 | width: auto; 97 | cursor: pointer; 98 | background-color: #eeeeee; 99 | border-top: 1px solid #d5d5d5; 100 | color: #666666; 101 | font-size: 12px; 102 | overflow: hidden; 103 | padding: 19px 15px 9px 20px; 104 | word-wrap: break-word; 105 | /*border: 1px solid #ccc; 106 | border-radius: 3px; 107 | -moz-border-radius: 3px; 108 | -webkit-border-radius: 3px; 109 | margin-bottom: 8px;*/ 110 | } 111 | 112 | .sp-widget-levels .sp-widget-level:hover, 113 | .sp-widget-levels .sp-widget-level:active { 114 | text-decoration: none; 115 | background-color: #e0e0e0; 116 | /*color: #555555; 117 | border: 1px solid #aaa;*/ 118 | } 119 | 120 | .sp-widget-levels .sp-widget-level-title { 121 | color: #333333; 122 | font-size: 16px; 123 | font-weight: bold; 124 | line-height: 23px; 125 | margin-bottom: 4px; 126 | padding: 3px 0; 127 | /*padding: 4px; 128 | background-color: #e6e6e6; 129 | font-size: 16px; 130 | font-weight: 700;*/ 131 | } 132 | 133 | .sp-widget-levels .sp-widget-level-amount { 134 | float: right; 135 | } 136 | 137 | .sp-widget-levels .sp-widget-level-description { 138 | margin-bottom: 10px; 139 | } 140 | 141 | .sp-widget-levels .sp-widget-level-description p { 142 | line-height: 1.5em; 143 | font-size: 14px; 144 | } 145 | 146 | .sp-widget-stats { 147 | background-color: #eeeeee; 148 | } 149 | .sp-project-stats { 150 | padding: 20px; 151 | } 152 | .sp-widget-stats h5 { 153 | color: #333333; 154 | font-size: 14px; 155 | font-weight: bold; 156 | margin-bottom: 5px; 157 | text-transform: lowercase; 158 | } 159 | .sp-project-stats .num { 160 | display: block; 161 | font-size: 48px; 162 | font-weight: bold; 163 | line-height: 45px; 164 | } 165 | .sp-project-status .text { } 166 | .sp-project-backers { } 167 | .sp-project-backers-label { } 168 | .sp-project-backers-value { } 169 | .sp-project-pledged { } 170 | .sp-project-pledged-value { } 171 | .sp-project-duration { } 172 | .sp-project-duration-value { } 173 | .sp-project-duration-label { } 174 | .sp-project-contribute { 175 | -moz-box-orient: vertical; 176 | display: inline-block; 177 | margin-top: -10px; 178 | padding: 0 0 0 20px; 179 | vertical-align: middle; 180 | } 181 | .sp-project-notice { } 182 | .sp-project-goal { } 183 | .sp-project-goal div { 184 | margin-top: 0; 185 | padding: 12px 20px 14px; 186 | } 187 | .sp-project-goal div p { 188 | color: #666666; 189 | font-size: 12px; 190 | margin-bottom: 0; 191 | line-height: 1.5em; 192 | } 193 | #sp-project-min-pledge-button { 194 | background-color: #87c442; 195 | box-orient: vertical; 196 | -moz-box-orient: vertical; 197 | -webkit-box-orient: vertical; 198 | border-radius: 5px; 199 | -moz-border-radius: 5px; 200 | -webkit-border-radius: 5px; 201 | display: inline-block; 202 | font-size: 18px; 203 | padding: 12px 25px; 204 | text-align: center; 205 | text-transform: none; 206 | vertical-align: middle; 207 | width: 190px; 208 | color: #ffffff; 209 | cursor: pointer; 210 | white-space: nowrap; 211 | text-decoration: none; 212 | } 213 | #sp-project-min-pledge-button:hover, 214 | #sp-project-min-pledge-button:active { 215 | background-color: #77b036; 216 | border-color: #6ba13c; 217 | color: #ffffff; 218 | text-decoration: none; 219 | } 220 | #sp-project-min-pledge-button small { 221 | color: #497323; 222 | display: block; 223 | font-size: 12px; 224 | font-weight: normal; 225 | line-height: 12px; 226 | margin: 5px 0; 227 | } -------------------------------------------------------------------------------- /woocommerce-gateway-stripe/classes/class-wc-gateway-stripe-sponsorship.php: -------------------------------------------------------------------------------- 1 | id, array( &$this, 'complete_sponsorship_payment' ), 10, 3 ); 22 | } 23 | 24 | /** 25 | * complete_sponsorship_payment function. 26 | * 27 | * @param $amount_to_charge float The amount to charge. 28 | * @param $order WC_Order The WC_Order object of the order which the subscription was purchased in. 29 | * @param $product_id int The ID of the subscription product for which this payment relates. 30 | * @access public 31 | * @return void 32 | */ 33 | function complete_sponsorship_payment( $amount_to_charge, $order, $product_id ) { 34 | $result = $this->process_sponsorship_payment( $order, $amount_to_charge ); 35 | 36 | if ( is_wp_error( $result ) ) { 37 | // record payment failed 38 | } else { 39 | // record payments succeeded 40 | } 41 | } 42 | 43 | /** 44 | * Process the payment 45 | */ 46 | function process_payment( $order_id ) { 47 | global $woocommerce; 48 | 49 | if ( class_exists( 'WC_Sponsorship_Order' ) && WC_Sponsorship_Order::order_contains_sponsorship( $order_id ) ) { 50 | 51 | $order = new WC_Order( $order_id ); 52 | 53 | $stripe_token = isset( $_POST['stripe_token'] ) ? woocommerce_clean( $_POST['stripe_token'] ) : ''; 54 | 55 | // Use Stripe CURL API for payment 56 | try { 57 | $post_data = array(); 58 | $customer_id = 0; 59 | 60 | // Check if paying via customer ID 61 | if ( isset( $_POST['stripe_customer_id'] ) && $_POST['stripe_customer_id'] !== 'new' && is_user_logged_in() ) { 62 | $customer_ids = get_user_meta( get_current_user_id(), '_stripe_customer_id', false ); 63 | 64 | if ( isset( $customer_ids[ $_POST['stripe_customer_id'] ]['customer_id'] ) ) 65 | $customer_id = $customer_ids[ $_POST['stripe_customer_id'] ]['customer_id']; 66 | else 67 | throw new Exception( __( 'Invalid card.', 'wc_stripe' ) ); 68 | } 69 | 70 | // Else, Check token 71 | elseif ( empty( $stripe_token ) ) 72 | throw new Exception( __( 'Please make sure your card details have been entered correctly and that your browser supports JavaScript.', 'wc_stripe' ) ); 73 | 74 | $customer_response = $this->add_customer_to_order( $order, $customer_id, $stripe_token );$customer_response = $this->add_customer_to_order( $order, $stripe_token ); 75 | 76 | if ( is_wp_error( $customer_response ) ) { 77 | throw new Exception( $customer_response->get_error_message() ); 78 | } else { 79 | // Mark as on-hold (we're awaiting the cheque) 80 | $order->update_status('on-hold', 'Awaiting the sponsorship project\'s goal to be met.'); 81 | 82 | // Empty awaiting payment session 83 | if ( defined( $_SESSION ) && array_key_exists( 'order_awaiting_payment', $_SESSION ) ) 84 | unset( $_SESSION['order_awaiting_payment'] ); 85 | 86 | // Remove cart 87 | $woocommerce->cart->empty_cart(); 88 | 89 | // Store token 90 | if ( $stripe_token ) 91 | update_post_meta( $order->id, '_stripe_token', $stripe_token ); 92 | 93 | // Return thank you page redirect 94 | return array( 95 | 'result' => 'success', 96 | 'redirect' => $this->get_return_url( $order ) 97 | ); 98 | } 99 | 100 | } catch( Exception $e ) { 101 | $woocommerce->add_error( __('Error:', 'wc_stripe') . ' "' . $e->getMessage() . '"' ); 102 | return; 103 | } 104 | 105 | } else { 106 | 107 | return parent::process_payment( $order_id ); 108 | 109 | } 110 | } 111 | 112 | /** 113 | * process_sponsorship_payment function. 114 | * 115 | * @access public 116 | * @param mixed $order 117 | * @param int $amount (default: 0) 118 | * @param string $stripe_token (default: '') 119 | * @return void 120 | */ 121 | function process_sponsorship_payment( $order = '', $amount = 0 ) { 122 | global $woocommerce; 123 | 124 | $order_items = $order->get_items(); 125 | $firstItem = reset( $order_items ); 126 | $product = get_product( $firstItem['product_id'] ); 127 | $sponsorship_name = sprintf( __( 'Sponsorship for "%s"', 'wc_stripe' ), $product->get_title() ) . ' ' . sprintf( __( '(Order %s)', 'wp_stripe' ), $order->get_order_number() ); 128 | 129 | if ( $amount * 100 < 50 ) 130 | return new WP_Error( 'stripe_error', __( 'Minimum amount is 0.50', 'wc_stripe' ) ); 131 | 132 | $stripe_customer = get_post_meta( $order->id, '_stripe_customer_id', true ); 133 | 134 | if ( ! $stripe_customer ) 135 | return new WP_Error( 'stripe_error', __( 'Customer not found', 'wc_stripe' ) ); 136 | 137 | // Charge the customer 138 | $response = $this->stripe_request( array( 139 | 'amount' => $amount * 100, // In cents, minimum amount = 50 140 | 'currency' => strtolower( get_woocommerce_currency() ), 141 | 'description' => $sponsorship_name, 142 | 'customer' => $stripe_customer 143 | ), 'charges' ); 144 | 145 | if ( is_wp_error( $response ) ) { 146 | return $response; 147 | } else { 148 | $order->update_status('completed', 'Sponsorship project\'s goal has been met.'); 149 | $order->add_order_note( sprintf( __('Stripe sponsorship payment completed (Charge ID: %s)', 'wc_stripe' ), $response->id ) ); 150 | 151 | return true; 152 | } 153 | 154 | } 155 | 156 | /** 157 | * add_customer_to_order function. 158 | * 159 | * @access public 160 | * @param mixed $order 161 | * @param string $customer_id (default: '') 162 | * @param string $stripe_token (default: '') 163 | * @return void 164 | */ 165 | function add_customer_to_order( $order, $customer_id = '', $stripe_token = '' ) { 166 | 167 | // If we have a customer id, use it for the order 168 | if ( $customer_id ) { 169 | 170 | update_post_meta( $order->id, '_stripe_customer_id', $customer_id ); 171 | 172 | } 173 | 174 | // If we have a token, we can create a customer with it 175 | elseif ( $stripe_token ) { 176 | $response = $this->stripe_request( array( 177 | 'email' => $order->billing_email, 178 | 'description' => 'Customer: ' . $order->shipping_first_name . ' ' . $order->shipping_last_name, 179 | 'card' => $stripe_token 180 | ), 'customers' ); 181 | 182 | if ( is_wp_error( $response ) ) { 183 | return $response; 184 | } else { 185 | $order->add_order_note( sprintf( __('Stripe customer added: ', 'wc_stripe' ), $response->id ) ); 186 | 187 | if ( is_user_logged_in() ) 188 | add_user_meta( get_current_user_id(), '_stripe_customer_id', array( 189 | 'customer_id' => $response->id, 190 | 'active_card' => $response->active_card->last4, 191 | 'exp_year' => $response->active_card->exp_year, 192 | 'exp_month' => $response->active_card->exp_month, 193 | ) ); 194 | 195 | update_post_meta( $order->id, '_stripe_customer_id', $response->id ); 196 | } 197 | 198 | } 199 | 200 | } 201 | } -------------------------------------------------------------------------------- /woocommerce-gateway-stripe/classes/class-wc-gateway-stripe-subscriptions.php: -------------------------------------------------------------------------------- 1 | id, array( &$this, 'scheduled_subscription_payment' ), 10, 3 ); 16 | 17 | add_filter( 'woocommerce_subscriptions_renewal_order_meta_query', array( &$this, 'remove_renewal_order_meta' ), 10, 4 ); 18 | } 19 | 20 | /** 21 | * Process the payment 22 | */ 23 | function process_payment( $order_id ) { 24 | global $woocommerce; 25 | 26 | if ( class_exists( 'WC_Subscriptions_Order' ) && WC_Subscriptions_Order::order_contains_subscription( $order_id ) ) { 27 | 28 | $order = new WC_Order( $order_id ); 29 | 30 | $stripe_token = isset( $_POST['stripe_token'] ) ? woocommerce_clean( $_POST['stripe_token'] ) : ''; 31 | 32 | // Use Stripe CURL API for payment 33 | try { 34 | 35 | $post_data = array(); 36 | $customer_id = 0; 37 | 38 | // Check if paying via customer ID 39 | if ( isset( $_POST['stripe_customer_id'] ) && $_POST['stripe_customer_id'] !== 'new' && is_user_logged_in() ) { 40 | $customer_ids = get_user_meta( get_current_user_id(), '_stripe_customer_id', false ); 41 | 42 | if ( isset( $customer_ids[ $_POST['stripe_customer_id'] ]['customer_id'] ) ) 43 | $customer_id = $customer_ids[ $_POST['stripe_customer_id'] ]['customer_id']; 44 | else 45 | throw new Exception( __( 'Invalid card.', 'wc_stripe' ) ); 46 | } 47 | 48 | // Else, Check token 49 | elseif ( empty( $stripe_token ) ) 50 | throw new Exception( __( 'Please make sure your card details have been entered correctly and that your browser supports JavaScript.', 'wc_stripe' ) ); 51 | 52 | if ( method_exists( 'WC_Subscriptions_Order', 'get_total_initial_payment' ) ) { 53 | $initial_payment = WC_Subscriptions_Order::get_total_initial_payment( $order ); 54 | } else { 55 | $initial_payment = WC_Subscriptions_Order::get_sign_up_fee( $order ) + WC_Subscriptions_Order::get_price_per_period( $order ); 56 | } 57 | 58 | $customer_response = $this->add_customer_to_order( $order, $customer_id, $stripe_token ); 59 | 60 | if ( $initial_payment > 0 ) 61 | $payment_response = $this->process_subscription_payment( $order, $initial_payment ); 62 | 63 | if ( is_wp_error( $customer_response ) ) { 64 | 65 | throw new Exception( $customer_response->get_error_message() ); 66 | 67 | } else if ( isset( $payment_response ) && is_wp_error( $payment_response ) ) { 68 | 69 | throw new Exception( $payment_response->get_error_message() ); 70 | 71 | } else { 72 | 73 | // Payment complete 74 | $order->payment_complete(); 75 | 76 | // Remove cart 77 | $woocommerce->cart->empty_cart(); 78 | 79 | // Activate subscriptions 80 | WC_Subscriptions_Manager::activate_subscriptions_for_order( $order ); 81 | 82 | // Store token 83 | if ( $stripe_token ) 84 | update_post_meta( $order->id, '_stripe_token', $stripe_token ); 85 | 86 | // Return thank you page redirect 87 | return array( 88 | 'result' => 'success', 89 | 'redirect' => $this->get_return_url( $order ) 90 | ); 91 | } 92 | 93 | } catch( Exception $e ) { 94 | $woocommerce->add_error( __('Error:', 'wc_stripe') . ' "' . $e->getMessage() . '"' ); 95 | return; 96 | } 97 | 98 | } else { 99 | 100 | return parent::process_payment( $order_id ); 101 | 102 | } 103 | } 104 | 105 | /** 106 | * scheduled_subscription_payment function. 107 | * 108 | * @param $amount_to_charge float The amount to charge. 109 | * @param $order WC_Order The WC_Order object of the order which the subscription was purchased in. 110 | * @param $product_id int The ID of the subscription product for which this payment relates. 111 | * @access public 112 | * @return void 113 | */ 114 | function scheduled_subscription_payment( $amount_to_charge, $order, $product_id ) { 115 | 116 | $result = $this->process_subscription_payment( $order, $amount_to_charge ); 117 | 118 | if ( is_wp_error( $result ) ) { 119 | 120 | WC_Subscriptions_Manager::process_subscription_payment_failure_on_order( $order, $product_id ); 121 | 122 | } else { 123 | 124 | WC_Subscriptions_Manager::process_subscription_payments_on_order( $order ); 125 | 126 | } 127 | 128 | } 129 | 130 | /** 131 | * process_subscription_payment function. 132 | * 133 | * @access public 134 | * @param mixed $order 135 | * @param int $amount (default: 0) 136 | * @param string $stripe_token (default: '') 137 | * @return void 138 | */ 139 | function process_subscription_payment( $order = '', $amount = 0 ) { 140 | global $woocommerce; 141 | 142 | $order_items = $order->get_items(); 143 | $product = $order->get_product_from_item( array_shift( $order_items ) ); 144 | $subscription_name = sprintf( __( 'Subscription for "%s"', 'wc_stripe' ), $product->get_title() ) . ' ' . sprintf( __( '(Order %s)', 'wp_stripe' ), $order->get_order_number() ); 145 | 146 | if ( $amount * 100 < 50 ) 147 | return new WP_Error( 'stripe_error', __( 'Minimum amount is 0.50', 'wc_stripe' ) ); 148 | 149 | $stripe_customer = get_post_meta( $order->id, '_stripe_customer_id', true ); 150 | 151 | if ( ! $stripe_customer ) 152 | return new WP_Error( 'stripe_error', __( 'Customer not found', 'wc_stripe' ) ); 153 | 154 | // Charge the customer 155 | $response = $this->stripe_request( array( 156 | 'amount' => $amount * 100, // In cents, minimum amount = 50 157 | 'currency' => strtolower( get_woocommerce_currency() ), 158 | 'description' => $subscription_name, 159 | 'customer' => $stripe_customer 160 | ), 'charges' ); 161 | 162 | if ( is_wp_error( $response ) ) { 163 | return $response; 164 | } else { 165 | $order->add_order_note( sprintf( __('Stripe subscription payment completed (Charge ID: %s)', 'wc_stripe' ), $response->id ) ); 166 | 167 | return true; 168 | } 169 | 170 | } 171 | 172 | /** 173 | * add_customer_to_order function. 174 | * 175 | * @access public 176 | * @param mixed $order 177 | * @param string $customer_id (default: '') 178 | * @param string $stripe_token (default: '') 179 | * @return void 180 | */ 181 | function add_customer_to_order( $order, $customer_id = '', $stripe_token = '' ) { 182 | 183 | // If we have a customer id, use it for the order 184 | if ( $customer_id ) { 185 | 186 | update_post_meta( $order->id, '_stripe_customer_id', $customer_id ); 187 | 188 | } 189 | 190 | // If we have a token, we can create a customer with it 191 | elseif ( $stripe_token ) { 192 | $response = $this->stripe_request( array( 193 | 'email' => $order->billing_email, 194 | 'description' => 'Customer: ' . $order->shipping_first_name . ' ' . $order->shipping_last_name, 195 | 'card' => $stripe_token 196 | ), 'customers' ); 197 | 198 | if ( is_wp_error( $response ) ) { 199 | return $response; 200 | } else { 201 | $order->add_order_note( sprintf( __('Stripe customer added: ', 'wc_stripe' ), $response->id ) ); 202 | 203 | if ( is_user_logged_in() ) 204 | add_user_meta( get_current_user_id(), '_stripe_customer_id', array( 205 | 'customer_id' => $response->id, 206 | 'active_card' => $response->active_card->last4, 207 | 'exp_year' => $response->active_card->exp_year, 208 | 'exp_month' => $response->active_card->exp_month, 209 | ) ); 210 | 211 | update_post_meta( $order->id, '_stripe_customer_id', $response->id ); 212 | } 213 | 214 | } 215 | 216 | } 217 | 218 | /** 219 | * Don't transfer Stripe customer/token meta when creating a parent renewal order. 220 | * 221 | * @access public 222 | * @param array $order_meta_query MySQL query for pulling the metadata 223 | * @param int $original_order_id Post ID of the order being used to purchased the subscription being renewed 224 | * @param int $renewal_order_id Post ID of the order created for renewing the subscription 225 | * @param string $new_order_role The role the renewal order is taking, one of 'parent' or 'child' 226 | * @return void 227 | */ 228 | function remove_renewal_order_meta( $order_meta_query, $original_order_id, $renewal_order_id, $new_order_role ) { 229 | 230 | if ( 'parent' == $new_order_role ) 231 | $order_meta_query .= " AND `meta_key` NOT LIKE '_stripe_customer_id' " 232 | . " AND `meta_key` NOT LIKE '_stripe_token' "; 233 | 234 | return $order_meta_query; 235 | } 236 | } -------------------------------------------------------------------------------- /woocommerce-sponsorship.php: -------------------------------------------------------------------------------- 1 | includes(); 35 | 36 | if ( is_admin() ) { 37 | // add admin styles and scripts 38 | add_action( 'woocommerce_admin_css', array( &$this, 'admin_styles' ) ); 39 | add_action( 'admin_enqueue_scripts', array( &$this, 'admin_scripts' ) ); 40 | add_action( 'admin_menu', array( &$this, 'menu' ) ); 41 | } else { 42 | // add front end styles and scripts 43 | add_action( 'wp_print_scripts', array( &$this, 'frontend_scripts' ) ); 44 | } 45 | 46 | add_filter( 'add_to_cart_redirect', array( &$this, 'add_product_redirect' ) ); 47 | add_filter( 'woocommerce_add_to_cart_validation', array( &$this, 'add_product_validation' ), 10, 3 ); 48 | 49 | // some sidebar stuff 50 | add_action( 'wp_head', create_function( "", 'ob_start();' ) ); 51 | add_action( 'get_sidebar', array( &$this, 'get_wc_sponsorship_sidebar' ) ); 52 | add_action( 'wp_footer', array( &$this, 'wc_sponsorship_sidebar_class_replace' ) ); 53 | register_sidebar( array( 'name' => 'Sponsorship Sidebar', 'id' => 'sponsorship_project_sidebar', 'description' => "Sidebar that overrides other sidebars when viewing a single product", ) ); 54 | 55 | // and a widget 56 | add_action( 'widgets_init', array( &$this, 'init_widgets' ) ); 57 | } 58 | 59 | /* 60 | * Plugin maintenance - install and uninstall 61 | */ 62 | 63 | function activation() { 64 | //wp_create_category('Sponsorship Project', 'product_cat'); 65 | } 66 | 67 | function deactivation() { 68 | 69 | } 70 | 71 | /* 72 | * Include required functions and classes 73 | */ 74 | 75 | function includes() { 76 | include_once( 'classes/class-wc-sponsorship-product.php' ); 77 | include_once( 'classes/class-wc-sponsorship-order.php' ); 78 | include_once( 'classes/class-wc-sponsorship-checkout.php' ); 79 | } 80 | 81 | /* 82 | * Admin - include necessary admin files, scripts, styles and handle any 83 | * admin related actions and filters 84 | */ 85 | 86 | function admin_styles() { 87 | wp_enqueue_style( 'woocommerce_sponsorship_admin_styles', $this->plugin_url() . '/assets/css/admin.css' ); 88 | } 89 | 90 | function admin_scripts() { 91 | //wp_register_script( 'wc-sponsorship-product-js', $this->plugin_url() . '/assets/js/wc-sponsorship-admin-product.js' ); 92 | //wp_enqueue_script( 'wc-sponsorship-product-js' ); 93 | } 94 | 95 | function menu() { } 96 | 97 | /* 98 | * Front end - include scripts, styles, and handle any front end related 99 | * handlers for actions or filters 100 | */ 101 | 102 | function frontend_scripts() { 103 | wp_enqueue_style( 'woocommerce_sponsorship_styles', $this->plugin_url() . '/assets/css/wc-sponsorship.css' ); 104 | } 105 | 106 | /* 107 | * Helper functions 108 | */ 109 | 110 | function plugin_url() { 111 | if ( $this->plugin_url ) return $this->plugin_url; 112 | return $this->plugin_url = plugins_url( basename( plugin_dir_path( __FILE__ ) ), basename( __FILE__ ) ); 113 | } 114 | 115 | function plugin_path() { 116 | if ( $this->plugin_path ) return $this->plugin_path; 117 | return $this->plugin_path = untrailingslashit( plugin_dir_path( __FILE__ ) ); 118 | } 119 | 120 | function is_sponsorship( $product ) { 121 | if ( !is_object( $product ) ) { 122 | $product = new WC_Product_Variable( $product ); 123 | } 124 | if ( $product->is_type('variable') || $product->is_type('simple') ) { 125 | $pm = get_post_meta( $product->id, '_sponsorship', true ); 126 | return is_array( $pm ); 127 | } 128 | return ( $product->is_type( 'sponsorship-project' ) ) ? true : false; 129 | } 130 | 131 | function is_sponsorship_contribution_level( $product ) { 132 | if ( !is_object( $product ) ) { 133 | $product = new WC_Product_Variable( $product ); 134 | } 135 | 136 | $prod_post = $product->post; 137 | if ( !$prod_post ) { 138 | $prod_post = get_post( $product->id ); 139 | } 140 | 141 | if ( $prod_post->post_parent ) { 142 | return WC_Sponsorship::is_sponsorship( $prod_post->post_parent ); 143 | } 144 | return false; 145 | } 146 | 147 | function cart_contains_sponsorship_contribution() { 148 | global $woocommerce; 149 | 150 | $contains_contribution = false; 151 | 152 | if ( !empty( $woocommerce->cart->cart_contents ) ) { 153 | foreach ( $woocommerce->cart->cart_contents as $cart_item ) { 154 | if ( WC_Sponsorship_Product::is_sponsorship_contribution_level( $cart_item[ 'product_id' ] ) ) { 155 | $contains_contribution = true; 156 | break; 157 | } 158 | } 159 | } 160 | 161 | return $contains_contribution; 162 | } 163 | 164 | function add_product_redirect( $url ) { 165 | global $woocommerce; 166 | 167 | if ( is_numeric( $_REQUEST[ 'add-to-cart' ] ) && WC_Sponsorship_Product::is_sponsorship_contribution_level( ( int ) $_REQUEST[ 'add-to-cart' ] ) ) { 168 | $woocommerce->clear_messages(); 169 | $url = $woocommerce->cart->get_checkout_url(); 170 | } 171 | 172 | return $url; 173 | } 174 | 175 | function add_product_validation( $valid, $product_id, $quantity ) { 176 | global $woocommerce; 177 | 178 | if ( WC_Sponsorship_Product::is_sponsorship_contribution_level( $product_id ) ) { 179 | $woocommerce->cart->empty_cart(); 180 | } elseif ( WC_Sponsorship::cart_contains_sponsorship_contribution() ) { 181 | WC_Sponsorship::remove_sponsorship_from_cart(); 182 | 183 | $woocommerce->add_error( 'A sponsorship contribution has been removed from your cart. Due to payment gateway restrictions, products can not be purchased at the same time.' ); 184 | $woocommerce->set_messages(); 185 | 186 | // Redirect to cart page to remove subscription & notify shopper 187 | add_filter( 'add_to_cart_fragments', array( &$this, 'redirect_ajax_add_to_cart' ) ); 188 | } 189 | 190 | return true; 191 | } 192 | 193 | function remove_sponsorship_from_cart() { 194 | global $woocommerce; 195 | 196 | foreach ( $woocommerce->cart->cart_contents as $cart_item_key => $cart_item ) if ( WC_Sponsorship_Product::is_sponsorship_contribution_level( $cart_item[ 'product_id' ] ) ) $woocommerce->cart->set_quantity( $cart_item_key, 0 ); 197 | } 198 | 199 | function get_wc_sponsorship_sidebar( $name ) { 200 | global $product; 201 | 202 | if ( is_single() && WC_Sponsorship_Product::is_sponsorship( $product ) && 'Sponsorship Sidebar' != $name ) { 203 | load_template( $this->plugin_path() . '/classes/class-wc-sponsorship-sidebar.php', true ); 204 | 205 | static $class = "wc-sponsorship-hidden"; 206 | $this->wc_sponsorship_sidebar_class_replace( $class ); 207 | } 208 | } 209 | 210 | function wc_sponsorship_sidebar_class_replace( $c = '' ) { 211 | static $class = ''; 212 | if ( !empty( $c ) ) { 213 | $class = $c; 214 | } else { 215 | echo str_replace( '