├── assets ├── css │ ├── hubaga.css │ └── index.php ├── images │ ├── index.php │ ├── screenshot-1.png │ ├── screenshot-2.png │ ├── screenshot-3.png │ └── screenshot-8.png ├── index.php └── js │ ├── hubaga.js │ ├── index.php │ └── instacheck.js ├── hubaga.php ├── includes ├── admin │ ├── admin.php │ ├── assets │ │ ├── css │ │ │ ├── admin.css │ │ │ └── index.php │ │ ├── images │ │ │ └── index.php │ │ ├── index.php │ │ └── js │ │ │ ├── admin.js │ │ │ ├── index.php │ │ │ ├── jquery.flot.categories.js │ │ │ ├── jquery.flot.js │ │ │ ├── jquery.flot.min.js │ │ │ ├── jquery.flot.resize.js │ │ │ ├── jquery.flot.time.js │ │ │ ├── vue.js │ │ │ └── vue.min.js │ ├── elements │ │ ├── editor.php │ │ ├── index.php │ │ ├── order_overview.php │ │ ├── reports_cards.php │ │ ├── reports_footer.php │ │ ├── reports_header.php │ │ ├── reports_header1.php │ │ └── tag.php │ ├── index.php │ ├── metaboxes.php │ ├── reports.php │ ├── settings.php │ └── views │ │ ├── coupon-details.php │ │ ├── coupon-template.php │ │ ├── extensions-template.php │ │ ├── index.php │ │ ├── order-details.php │ │ ├── order-template.php │ │ ├── product-details.php │ │ ├── product-template.php │ │ └── reports-template.php ├── ajax.php ├── checkout │ ├── abstract-payments-class.php │ ├── functions.php │ ├── gateways │ │ ├── index.php │ │ ├── paypal │ │ │ ├── paypal-gateway.php │ │ │ └── settings-paypal.php │ │ └── test-gateway.php │ ├── index.php │ └── payments-class.php ├── coupon-class.php ├── coupons.php ├── customer-class.php ├── customers.php ├── data │ ├── currencies.php │ ├── currency_symbols.php │ ├── email-template.php │ └── index.php ├── download.php ├── elementa │ ├── assets │ │ ├── css │ │ │ ├── datepicker.css │ │ │ ├── elementa.css │ │ │ └── selectize.bootstrap3.css │ │ └── js │ │ │ ├── datepicker.js │ │ │ ├── datepicker.min.js │ │ │ ├── elementa.js │ │ │ ├── selectize.js │ │ │ └── selectize.min.js │ ├── data │ │ └── countries.php │ ├── elementa.php │ ├── elements │ │ ├── alert.php │ │ ├── button.php │ │ ├── card.php │ │ ├── checkbox.php │ │ ├── color.php │ │ ├── date.php │ │ ├── email.php │ │ ├── import.php │ │ ├── list_group.php │ │ ├── multiselect.php │ │ ├── number.php │ │ ├── password.php │ │ ├── radio.php │ │ ├── range.php │ │ ├── raw.php │ │ ├── save.php │ │ ├── search.php │ │ ├── select.php │ │ ├── switch.php │ │ ├── text.php │ │ ├── textarea.php │ │ └── title.php │ ├── index.php │ ├── template.php │ └── template2.php ├── functions.php ├── index.php ├── install.php ├── notifications.php ├── order-class.php ├── orders.php ├── product-class.php ├── product-widget.php ├── products.php ├── shortcodes.php ├── system-info.php └── template.php ├── index.php ├── languages └── index.php ├── license.txt ├── readme.md ├── readme.txt └── uninstall.php /assets/css/index.php: -------------------------------------------------------------------------------- 1 | 500 && $( window ).width() > 350 10 | } 11 | 12 | // Prepare the variables needed to start the train 13 | var ajax_url = instacheck_params.ajaxurl, 14 | checkoutUrl = instacheck_params.checkout_url, 15 | accountUrl = instacheck_params.account_url, 16 | nonce = instacheck_params.pc_nonce, 17 | checkout = $( '.hubaga-instacheck-wrapper' ), 18 | loader = $( '.hubaga-loader-wrapper' ); 19 | 20 | // Init instacheck when a buy button is clicked 21 | $('.hubaga-buy') 22 | .on('click', 23 | function( e ) { 24 | 25 | //Ensure that instacheck is supported 26 | if( !is_instacheck() ){ 27 | return; 28 | } 29 | 30 | // Make sure that this is really a buy button 31 | if( $( this ).data( 'action' ) != 'hubaga_buy' ){ 32 | return; 33 | } 34 | 35 | // Great! Prevent the default event behaviour 36 | e.preventDefault(); 37 | 38 | // Post data 39 | var product = $( this ).data( 'product' ), 40 | _link = $( this ).attr( 'href' ); 41 | 42 | fetchCheckout( { 43 | nonce: nonce, 44 | action: 'hubaga_get_checkout', 45 | fetchedBy: 'instacheck', 46 | product: product 47 | } ).fail( 48 | //If there was a problem; redirect to the checkout page 49 | function() { 50 | window.location = _link; 51 | }); 52 | }); 53 | 54 | /* Helper function to fetch the checkouts */ 55 | var fetchCheckout = function( data ) { 56 | 57 | // Hide the checkout overlay and display the loader 58 | $( checkout ).hide(); 59 | $( loader ).show(); 60 | 61 | // Post the data then return a promise 62 | return $.post( 63 | ajax_url, 64 | data, 65 | function( html ) { 66 | 67 | //If this is JSON.... 68 | if( $.isPlainObject( html ) ) { 69 | if ( html.action == 'redirect' ) { 70 | window.location = html.url 71 | } 72 | } else { 73 | var innerCheckout = $( checkout ).find( '.hubaga-instacheck-overlay' ); 74 | $( innerCheckout ).html( html ); 75 | 76 | //Appends a close button 77 | appendCloseButton( innerCheckout, checkout ); 78 | 79 | //Updates event handlers 80 | updateCheckoutHandlers( innerCheckout ); 81 | } 82 | //Display the checkout 83 | $( loader ).hide(); 84 | $( checkout ).show(); 85 | }); 86 | } 87 | 88 | // Appends a button to el that closes victiom when clicked 89 | var appendCloseButton = function( el, victim ) { 90 | return $( '×' ) 91 | .appendTo( el ) 92 | .on( 'click.pc_close', 93 | function( e ) { 94 | e.preventDefault(); 95 | $( victim ).hide(); 96 | }); 97 | } 98 | 99 | //Updates checkout event handlers 100 | var updateCheckoutHandlers = function( el ){ 101 | 102 | var checkoutForm = $( el ).find( '.hubaga-checkout-form:not(.instacheck_disabled)' ); 103 | 104 | //Whenever the user clicks outside our checkout overlay 105 | $( document ) 106 | .on('mouseup.hubaga-instacheck', function(e){ 107 | if(!el.is(e.target) && el.has(e.target).length === 0 ) { 108 | $( checkout ).hide(); 109 | } 110 | }); 111 | 112 | //Handle form submissions 113 | $( checkoutForm ) 114 | .on( 'submit.hubaga-instacheck', 115 | function( e ){ 116 | e.preventDefault(); 117 | var data = $( checkoutForm ).serialize(); 118 | data = data + '&nonce=' + nonce; 119 | fetchCheckout( data ) 120 | .fail( 121 | function( data ) { 122 | window.location = checkoutUrl + '?' + $( checkoutForm ).serialize(); 123 | }); 124 | }); 125 | 126 | //Submit form when a gateway is clicked 127 | $( checkoutForm ) 128 | .find( '[name="gateway"]' ) 129 | .on( 'change.hubaga-instacheck', 130 | function( e ){ 131 | $( checkoutForm ).trigger( 'submit' ); 132 | }); 133 | 134 | // When a user clicks on the show coupon link... 135 | $( checkoutForm ). 136 | find('.hubaga-show-coupon') 137 | .on('click.hubaga-instacheck', 138 | function( e ) { 139 | e.preventDefault(); 140 | $ ( this ).closest( 'form' ).find( '.hubaga-coupon-grid' ).toggle(); 141 | }); 142 | 143 | // Input field events 144 | $( checkoutForm ). 145 | find('.hubaga-field') 146 | .on( 'focus', function(){ 147 | $(this).addClass( 'hubaga-is-focused' ) 148 | }) 149 | 150 | .on( 'blur', function(){ 151 | $(this).removeClass( 'hubaga-is-focused' ) 152 | }) 153 | 154 | .on( 'keyup', function(){ 155 | if ($(this).val().length === 0) { 156 | $(this).addClass('hubaga-is-empty'); 157 | } else { 158 | $(this).removeClass('hubaga-is-empty'); 159 | } 160 | }) 161 | 162 | 163 | //When a user applies a coupon 164 | $('.hubaga-coupon-btn') 165 | .on('click', 166 | function( e ) { 167 | 168 | e.preventDefault(); 169 | var that = this; 170 | var product= $( this ).closest( 'form' ).find( '[name="hubaga_buy"]' ).val(); 171 | var email = $( this ).closest( 'form' ).find( '[name="email"]' ).val(); 172 | var coupon = $( this ).closest( '.hubaga-coupon-grid' ).find( '.hubaga-coupon-input' ).val(); 173 | if( coupon === '' ) { 174 | $( this ).closest( '.hubaga-coupon-grid' ).find( '.hubaga-coupon-notices' ).text( instacheck_params.empty_coupon ); 175 | return; 176 | } 177 | 178 | $( that ).closest( 'form' ).fadeTo( 360, 0.5 ); 179 | 180 | $.post( 181 | ajax_url, 182 | { 183 | coupon: coupon, 184 | action: 'hubaga_apply_coupon', 185 | product: product, 186 | email: email, 187 | nonce: nonce 188 | }, 189 | function ( json ) { 190 | 191 | $( that ).closest( 'form' ).fadeTo( 360, 1 ); 192 | 193 | if ( json.result == 'success' ) { 194 | 195 | $( that ).closest( '.hubaga-coupon-grid' ).hide(); 196 | $( that ).closest( 'form' ).find( '.hubaga-order-total' ).html( json.price ); 197 | $( that ).closest( '.hubaga-coupon-grid' ).find( '.hubaga-coupon-notices' ).text( '' ); 198 | $( that ).closest( 'form' ).find( '.hubaga-coupon-notice' ).hide(); 199 | 200 | } else if( json.result == 'error' ){ 201 | 202 | $( that ).closest( '.hubaga-coupon-grid' ).find( '.hubaga-coupon-notices' ).text( json.error ); 203 | 204 | }else { 205 | 206 | $( that ).closest( '.hubaga-coupon-grid' ).find( '.hubaga-coupon-notices' ).text( instacheck_params.coupon_error ); 207 | 208 | } 209 | 210 | }).fail( function(){ 211 | $( that ).closest( 'form' ).fadeTo( 360, 1 ); 212 | $( that ).closest( '.hubaga-coupon-grid' ).find( '.hubaga-coupon-notices' ).text( instacheck_params.coupon_error ); 213 | }); 214 | 215 | }); 216 | } 217 | 218 | } )( jQuery ); 219 | -------------------------------------------------------------------------------- /includes/admin/assets/css/admin.css: -------------------------------------------------------------------------------- 1 | /* Hide coupon visibility settings on coupon pages */ 2 | .post-type-h_coupon .misc-pub-visibility{ 3 | display: none; 4 | } 5 | 6 | .hubaga-action-btn { 7 | font-size: 28px; 8 | padding: 0 0.8rem; 9 | padding-bottom: 4px; 10 | background-color: #ff4081; 11 | color: #fff; 12 | border: none; 13 | border-radius: 2px; 14 | display: inline-block; 15 | } 16 | 17 | @media only screen and (min-width: 601px){ 18 | .hubaga-filters { 19 | background: rgba(238, 235, 235, 0.06); 20 | padding-top: 1em; 21 | } 22 | } 23 | 24 | .report-card-wrapper{ 25 | margin-bottom: 1em; 26 | } 27 | .hubaga-report-card-aggregate{ 28 | padding: 1em; 29 | text-align: center; 30 | } 31 | 32 | .card-num { 33 | display: block; 34 | font-size: 25px; 35 | margin-bottom: 10px; 36 | } 37 | 38 | .hubaga-flotchart-placeholder{ 39 | width: 100%; 40 | height: 400px; 41 | } 42 | 43 | #hubaga_reports{ 44 | padding: 1em; 45 | } 46 | 47 | .hubaga-filter-btn{ 48 | width: 100%; 49 | } 50 | .btn-right{ 51 | float: right; 52 | } 53 | 54 | .hubaga-block{ 55 | display: block; 56 | } 57 | 58 | .hubaga-unstyled{ 59 | text-decoration: none; 60 | list-style-type: none; 61 | } 62 | 63 | .hubaga-price-more{ 64 | max-width: 320px; 65 | padding: 1em; 66 | margin-left: 0; 67 | margin-top: 2em; 68 | position: relative; 69 | } 70 | 71 | .hubaga-price-more::after { 72 | content: ''; 73 | display: block; 74 | position: absolute; 75 | top: -2.6em; 76 | width: 0; 77 | height: 0; 78 | border: 16px solid; 79 | left: 10%; 80 | border-color: transparent transparent rgba(0, 0, 0, 0.2) transparent; 81 | } 82 | 83 | .list-group.elementa-dropdown-content{ 84 | margin-top: 0; 85 | } 86 | 87 | .elementa .list-group-inner-item { 88 | border-bottom: 1px solid rgba(255, 255, 255, 0.16); 89 | padding-bottom: 5px; 90 | padding-top: 1em; 91 | } 92 | 93 | .stream-price, .hubaga-stream-price{ 94 | padding: 5px; 95 | color: #fff; 96 | } 97 | 98 | .hubaga-stream-price.green{background-color:#4CAF50!important} 99 | .hubaga-stream-price.orange{background-color:#ff9800!important} 100 | .hubaga-stream-price.black{background-color:#000!important} 101 | .hubaga-stream-price.red{background-color:#F44336!important} 102 | .hubaga-stream-price.teal{background-color:#009688!important} 103 | .hubaga-stream-price.light-blue{background-color:#03a9f4!important} 104 | 105 | .hubaga-price-muted { 106 | color: #888; 107 | font-weight: bold; 108 | border: 1px solid #aaa; 109 | padding: 5px; 110 | } 111 | 112 | .hubaga-muted { 113 | color: #888; 114 | font-size: 1.2em; 115 | margin-top: 0; 116 | font-weight: bold; 117 | } 118 | 119 | #hubaga_order_details .handlediv, 120 | #hubaga_order_details .hndle, 121 | .post-type-h_order #minor-publishing-actions, 122 | .post-type-h_order #visibility { 123 | display: none; 124 | } 125 | 126 | .hubaga-order-notes:after{ 127 | content:""; 128 | display:table; 129 | clear:both 130 | } 131 | 132 | .hubaga-note{ 133 | padding: 0.4em; 134 | border-radius: 5px; 135 | width: 80%; 136 | position: relative; 137 | } 138 | 139 | .hubaga-note:nth-child(even){ 140 | background: #009688; 141 | border: 1px solid #fff; 142 | color: #fff; 143 | float: right; 144 | } 145 | 146 | .hubaga-note:nth-child(odd){ 147 | background: #fff; 148 | border: 1px solid rgba(35, 40, 45, 0.23); 149 | float: left; 150 | } 151 | 152 | .hubaga-overlay-wrapper { 153 | position: fixed; 154 | top: 0; 155 | left: 0; 156 | width: 100%; 157 | height: 100%; 158 | z-index: 1000; 159 | background: rgba(0, 0, 0, 0.53); 160 | } 161 | 162 | .hubaga-loader { 163 | display: block; 164 | position: relative; 165 | left: 50%; 166 | top: 50%; 167 | width: 150px; 168 | height: 150px; 169 | margin: -75px 0 0 -75px; 170 | border-radius: 50%; 171 | border: 3px solid transparent; 172 | border-top-color: #3498db; 173 | -webkit-animation: hspin 2s linear infinite; 174 | animation: hspin 2s linear infinite; 175 | z-index: 1001; 176 | } 177 | 178 | .hubaga-loader:before { 179 | content: ""; 180 | position: absolute; 181 | top: 5px; 182 | left: 5px; 183 | right: 5px; 184 | bottom: 5px; 185 | border-radius: 50%; 186 | border: 3px solid transparent; 187 | border-top-color: #e74c3c; 188 | -webkit-animation: hspin 3s linear infinite; 189 | animation: hspin 3s linear infinite; 190 | } 191 | 192 | .hubaga-loader:after { 193 | content: ""; 194 | position: absolute; 195 | top: 15px; 196 | left: 15px; 197 | right: 15px; 198 | bottom: 15px; 199 | border-radius: 50%; 200 | border: 3px solid transparent; 201 | border-top-color: #f9c922; 202 | -webkit-animation: hspin 1.5s linear infinite; 203 | animation: hspin 1.5s linear infinite; 204 | } 205 | 206 | /*---------------------------------------- 207 | Animations 208 | ------------------------------------------*/ 209 | 210 | @-webkit-keyframes hspin { 211 | 0% { 212 | -webkit-transform: rotate(0deg); 213 | -ms-transform: rotate(0deg); 214 | transform: rotate(0deg); 215 | } 216 | 100% { 217 | -webkit-transform: rotate(360deg); 218 | -ms-transform: rotate(360deg); 219 | transform: rotate(360deg); 220 | } 221 | } 222 | 223 | @keyframes hspin { 224 | 0% { 225 | -webkit-transform: rotate(0deg); 226 | -ms-transform: rotate(0deg); 227 | transform: rotate(0deg); 228 | } 229 | 100% { 230 | -webkit-transform: rotate(360deg); 231 | -ms-transform: rotate(360deg); 232 | transform: rotate(360deg); 233 | } 234 | } 235 | 236 | .hubaga-extensions-template{ 237 | max-width: 620px; 238 | } 239 | 240 | .hubaga-hubaga-product-card { 241 | box-shadow: 0 5px 11px 0 rgba(0, 0, 0, 0.18), 0 4px 15px 0 rgba(0, 0, 0, 0.15); 242 | padding: 0; 243 | max-width: 100%; 244 | width: 300px; 245 | position: relative; 246 | min-height: 200px; 247 | margin: auto; 248 | margin-bottom: 1em; 249 | -webkit-box-sizing: border-box; 250 | -moz-box-sizing: border-box; 251 | box-sizing: border-box; 252 | } 253 | 254 | .hubaga-hubaga-product-card * { 255 | -webkit-box-sizing: border-box; 256 | -moz-box-sizing: border-box; 257 | box-sizing: border-box; 258 | } 259 | 260 | .hubaga-hubaga-product-card:after { 261 | content: ""; 262 | display: table; 263 | clear: both; 264 | } 265 | 266 | .hubaga-hubaga-product-card-header { 267 | min-height: 200px; 268 | box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.16), 0 2px 10px 0 rgba(0, 0, 0, 0.12); 269 | } 270 | 271 | .hubaga-hubaga-product-card-body { 272 | padding: 1em; 273 | } 274 | 275 | .hubaga-hubaga-card-price { 276 | position: absolute; 277 | top: 10px; 278 | left: 10px; 279 | border-radius: 50%; 280 | border: 2px solid #fff; 281 | width: 64px; 282 | height: 64px; 283 | padding-top: 1em; 284 | color: #ff5722; 285 | background: #fff; 286 | font-weight: bold; 287 | font-size: 15px; 288 | padding-left: 6px; 289 | } 290 | 291 | .hubaga-hubaga-product-card h2 { 292 | font-size: 1.62rem; 293 | margin: 1.78rem 0 1.424rem 0; 294 | font-weight: normal; 295 | line-height: 1.5; 296 | font-family: "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, sans-serif; 297 | } 298 | 299 | .hubaga-hubaga-product-card p{ 300 | font-size: 1rem; 301 | } 302 | 303 | @media only screen and (min-width: 620px) { 304 | 305 | .hubaga-hubaga-product-card { 306 | width: 100% !important; 307 | min-width: 100% !important; 308 | float: none; 309 | } 310 | 311 | .hubaga-hubaga-product-card-header { 312 | width: 30% !important; 313 | float: left !important; 314 | height: 100% !important; 315 | } 316 | 317 | .hubaga-hubaga-product-card-body { 318 | width: 70% !important; 319 | float: right !important; 320 | height: 100% !important; 321 | } 322 | 323 | .hubaga-hubaga-buy { 324 | position: absolute !important; 325 | bottom: 5px !important; 326 | right: 0 !important; 327 | width: 240px !important; 328 | } 329 | 330 | } 331 | 332 | #hubaga_product_editor{ 333 | max-width: 920px; 334 | } 335 | -------------------------------------------------------------------------------- /includes/admin/assets/css/index.php: -------------------------------------------------------------------------------- 1 | ', 9 | mounted: function () { 10 | $.plot( $( this.$el ) , this.datasets, this.options); 11 | }, 12 | 13 | watch: { 14 | datasets: function (datasets) { 15 | $.plot( $( this.$el ) , datasets, this.options); 16 | }, 17 | options: function (options) { 18 | $.plot( $( this.$el ) , this.datasets, options); 19 | }, 20 | currentCard: function (currentCard) { 21 | $.plot( $( this.$el ) , this.datasets, this.options); 22 | } 23 | } 24 | }); 25 | 26 | //Selectize component 27 | Vue.component('hubaga-reports-selectize', { 28 | props: ['options', 'value'], 29 | template: '', 30 | mounted: function () { 31 | var vm = this 32 | 33 | $(this.$el) 34 | .val(this.value) 35 | // init selectize 36 | .selectize({ 'options': this.options }) 37 | // emit event on change. 38 | .on('change', function () { 39 | vm.$emit('input', this.value) 40 | }) 41 | 42 | }, 43 | watch: { 44 | value: function (value) { 45 | // update value 46 | $(this.$el).val(value).trigger('change') 47 | }, 48 | options: function (options) { 49 | // update options 50 | $(this.$el).selectize({ 'options': this.options }) 51 | } 52 | }, 53 | destroyed: function () { 54 | $(this.$el).off().selectize('destroy') 55 | } 56 | }) 57 | 58 | //Custom click outside directive with caching 59 | Vue.directive( 'hubaga-click-outside', { 60 | bind: function( el, binding, vNode ){ 61 | function handler(e){ 62 | if(!vNode.context)return 63 | 64 | if(!$(el).is(e.target) && $(el).has(e.target).length === 0 ) { 65 | el.__hubagaClickOutside__.callback(e) 66 | } 67 | } 68 | 69 | el.__hubagaClickOutside__ = { 70 | handler: handler, 71 | callback: binding.value 72 | } 73 | 74 | $(document).on('mouseup', handler ); 75 | 76 | }, 77 | 78 | update: function( el, binding ){ 79 | el.__hubagaClickOutside__.callback = binding.value 80 | }, 81 | 82 | unbind: function( el, binding ){ 83 | $(document).off('mouseup', el.__hubagaClickOutside__.handler ) 84 | delete el.__hubagaClickOutside__ 85 | } 86 | }); 87 | 88 | //Reports app 89 | window.hubaga.reportsVue = function( data, el ){ 90 | return new Vue({ 91 | el: el, 92 | 93 | data: data, 94 | 95 | methods: { 96 | 97 | isFiltersShowing: function(){ 98 | return this.filters.showing === false 99 | }, 100 | 101 | toggleFiltersShowing: function(){ 102 | this.filtersShowing = !this.filtersShowing 103 | }, 104 | 105 | applyFilters: function(){ 106 | 107 | var vm = this; 108 | vm.loading = true; 109 | $.get( 110 | this.ajaxUrl, 111 | this.filters, 112 | function( data, status ) { 113 | vm.loading = false; 114 | vm.cards = data.cards; 115 | vm.filtersShowing = false; 116 | }).fail(function(){ 117 | vm.loading = false; 118 | vm.filtersShowing = false; 119 | }); 120 | }, 121 | 122 | hideStream: function( stream ) { 123 | this.currentStream = false 124 | }, 125 | 126 | showStream: function(key){ 127 | this.currentStream = key 128 | }, 129 | 130 | isCurrentCard: function( card ){ 131 | return this.currentCard == card.title 132 | }, 133 | 134 | changeCurrentCard: function( card ){ 135 | this.currentCard = card.title 136 | }, 137 | 138 | }, 139 | 140 | }); 141 | } 142 | 143 | } )( jQuery ); 144 | -------------------------------------------------------------------------------- /includes/admin/assets/js/index.php: -------------------------------------------------------------------------------- 1 | index) 102 | index = categories[v]; 103 | 104 | return index + 1; 105 | } 106 | 107 | function categoriesTickGenerator(axis) { 108 | var res = []; 109 | for (var label in axis.categories) { 110 | var v = axis.categories[label]; 111 | if (v >= axis.min && v <= axis.max) 112 | res.push([v, label]); 113 | } 114 | 115 | res.sort(function (a, b) { return a[0] - b[0]; }); 116 | 117 | return res; 118 | } 119 | 120 | function setupCategoriesForAxis(series, axis, datapoints) { 121 | if (series[axis].options.mode != "categories") 122 | return; 123 | 124 | if (!series[axis].categories) { 125 | // parse options 126 | var c = {}, o = series[axis].options.categories || {}; 127 | if ($.isArray(o)) { 128 | for (var i = 0; i < o.length; ++i) 129 | c[o[i]] = i; 130 | } 131 | else { 132 | for (var v in o) 133 | c[v] = o[v]; 134 | } 135 | 136 | series[axis].categories = c; 137 | } 138 | 139 | // fix ticks 140 | if (!series[axis].options.ticks) 141 | series[axis].options.ticks = categoriesTickGenerator; 142 | 143 | transformPointsOnAxis(datapoints, axis, series[axis].categories); 144 | } 145 | 146 | function transformPointsOnAxis(datapoints, axis, categories) { 147 | // go through the points, transforming them 148 | var points = datapoints.points, 149 | ps = datapoints.pointsize, 150 | format = datapoints.format, 151 | formatColumn = axis.charAt(0), 152 | index = getNextIndex(categories); 153 | 154 | for (var i = 0; i < points.length; i += ps) { 155 | if (points[i] == null) 156 | continue; 157 | 158 | for (var m = 0; m < ps; ++m) { 159 | var val = points[i + m]; 160 | 161 | if (val == null || !format[m][formatColumn]) 162 | continue; 163 | 164 | if (!(val in categories)) { 165 | categories[val] = index; 166 | ++index; 167 | } 168 | 169 | points[i + m] = categories[val]; 170 | } 171 | } 172 | } 173 | 174 | function processDatapoints(plot, series, datapoints) { 175 | setupCategoriesForAxis(series, "xaxis", datapoints); 176 | setupCategoriesForAxis(series, "yaxis", datapoints); 177 | } 178 | 179 | function init(plot) { 180 | plot.hooks.processRawData.push(processRawData); 181 | plot.hooks.processDatapoints.push(processDatapoints); 182 | } 183 | 184 | $.plot.plugins.push({ 185 | init: init, 186 | options: options, 187 | name: 'categories', 188 | version: '1.0' 189 | }); 190 | })(jQuery); 191 | -------------------------------------------------------------------------------- /includes/admin/assets/js/jquery.flot.resize.js: -------------------------------------------------------------------------------- 1 | /* Flot plugin for automatically redrawing plots as the placeholder resizes. 2 | 3 | Copyright (c) 2007-2014 IOLA and Ole Laursen. 4 | Licensed under the MIT license. 5 | 6 | It works by listening for changes on the placeholder div (through the jQuery 7 | resize event plugin) - if the size changes, it will redraw the plot. 8 | 9 | There are no options. If you need to disable the plugin for some plots, you 10 | can just fix the size of their placeholders. 11 | 12 | */ 13 | 14 | /* Inline dependency: 15 | * jQuery resize event - v1.1 - 3/14/2010 16 | * http://benalman.com/projects/jquery-resize-plugin/ 17 | * 18 | * Copyright (c) 2010 "Cowboy" Ben Alman 19 | * Dual licensed under the MIT and GPL licenses. 20 | * http://benalman.com/about/license/ 21 | */ 22 | (function($,e,t){"$:nomunge";var i=[],n=$.resize=$.extend($.resize,{}),a,r=false,s="setTimeout",u="resize",m=u+"-special-event",o="pendingDelay",l="activeDelay",f="throttleWindow";n[o]=200;n[l]=20;n[f]=true;$.event.special[u]={setup:function(){if(!n[f]&&this[s]){return false}var e=$(this);i.push(this);e.data(m,{w:e.width(),h:e.height()});if(i.length===1){a=t;h()}},teardown:function(){if(!n[f]&&this[s]){return false}var e=$(this);for(var t=i.length-1;t>=0;t--){if(i[t]==this){i.splice(t,1);break}}e.removeData(m);if(!i.length){if(r){cancelAnimationFrame(a)}else{clearTimeout(a)}a=null}},add:function(e){if(!n[f]&&this[s]){return false}var i;function a(e,n,a){var r=$(this),s=r.data(m)||{};s.w=n!==t?n:r.width();s.h=a!==t?a:r.height();i.apply(this,arguments)}if($.isFunction(e)){i=e;return a}else{i=e.handler;e.handler=a}}};function h(t){if(r===true){r=t||1}for(var s=i.length-1;s>=0;s--){var l=$(i[s]);if(l[0]==e||l.is(":visible")){var f=l.width(),c=l.height(),d=l.data(m);if(d&&(f!==d.w||c!==d.h)){l.trigger(u,[d.w=f,d.h=c]);r=t||true}}else{d=l.data(m);d.w=0;d.h=0}}if(a!==null){if(r&&(t==null||t-r<1e3)){a=e.requestAnimationFrame(h)}else{a=setTimeout(h,n[o]);r=false}}}if(!e.requestAnimationFrame){e.requestAnimationFrame=function(){return e.webkitRequestAnimationFrame||e.mozRequestAnimationFrame||e.oRequestAnimationFrame||e.msRequestAnimationFrame||function(t,i){return e.setTimeout(function(){t((new Date).getTime())},n[l])}}()}if(!e.cancelAnimationFrame){e.cancelAnimationFrame=function(){return e.webkitCancelRequestAnimationFrame||e.mozCancelRequestAnimationFrame||e.oCancelRequestAnimationFrame||e.msCancelRequestAnimationFrame||clearTimeout}()}})(jQuery,this); 23 | 24 | (function ($) { 25 | var options = { }; // no options 26 | 27 | function init(plot) { 28 | function onResize() { 29 | var placeholder = plot.getPlaceholder(); 30 | 31 | // somebody might have hidden us and we can't plot 32 | // when we don't have the dimensions 33 | if (placeholder.width() == 0 || placeholder.height() == 0) 34 | return; 35 | 36 | plot.resize(); 37 | plot.setupGrid(); 38 | plot.draw(); 39 | } 40 | 41 | function bindEvents(plot, eventHolder) { 42 | plot.getPlaceholder().resize(onResize); 43 | } 44 | 45 | function shutdown(plot, eventHolder) { 46 | plot.getPlaceholder().unbind("resize", onResize); 47 | } 48 | 49 | plot.hooks.bindEvents.push(bindEvents); 50 | plot.hooks.shutdown.push(shutdown); 51 | } 52 | 53 | $.plot.plugins.push({ 54 | init: init, 55 | options: options, 56 | name: 'resize', 57 | version: '1.0' 58 | }); 59 | })(jQuery); 60 | -------------------------------------------------------------------------------- /includes/admin/elements/editor.php: -------------------------------------------------------------------------------- 1 | 5, 13 | 'teeny' => true, 14 | ); 15 | 16 | wp_editor( $value, $id, $options ); 17 | 18 | if (! empty( $description ) ) { 19 | echo "

$description

"; 20 | } -------------------------------------------------------------------------------- /includes/admin/elements/index.php: -------------------------------------------------------------------------------- 1 | ID ); 11 | 12 | $data = apply_filters( 'hubaga_order_notes_editor_data', array( 13 | 'notes' => hubaga_get_order_notes( $order ), 14 | 'newNoteAuthor' => hubaga_get_customer_name( get_current_user_id() ), 15 | 'newNoteContent' => '', 16 | )); 17 | ?> 18 |
19 |

Notes

20 |
21 | 22 |
23 |
24 | 25 |
26 |
27 | 28 |
29 |
30 | 31 | 45 | 46 |
47 | -------------------------------------------------------------------------------- /includes/admin/elements/reports_cards.php: -------------------------------------------------------------------------------- 1 | 9 |
10 | 11 | 19 | 20 |
21 |
22 |

{{card.title}}

23 |
    24 |
  • 25 |
    {{aggregate}}
    26 |
  • 27 |
28 | 29 | 30 |
31 |
32 |
33 | -------------------------------------------------------------------------------- /includes/admin/elements/reports_footer.php: -------------------------------------------------------------------------------- 1 | 9 | 10 |
11 |

Revenue Stream

12 | 25 |
26 | 27 | 28 |
-------------------------------------------------------------------------------- /includes/admin/elements/reports_header.php: -------------------------------------------------------------------------------- 1 | 11 |
12 |
13 |
14 | 15 | 16 |
17 |
18 |
19 | 20 |
21 | 22 |
23 | 24 |
25 | 26 |
27 | 28 |
29 |
30 | -------------------------------------------------------------------------------- /includes/admin/elements/reports_header1.php: -------------------------------------------------------------------------------- 1 | 11 |
12 |
13 |
14 | 15 | 16 |
17 |
18 |
19 | 20 | 27 | 28 |
    29 |
  • 30 | 31 | {{category}} 40 | 41 |
      42 |
    • 43 | 44 |
    • 45 |
    46 |
  • 47 |
48 |

{{filters.dateFilter.label}}

49 |
50 | 51 |
52 | 53 |
54 | 55 |
56 | 57 |
58 |
-------------------------------------------------------------------------------- /includes/admin/elements/tag.php: -------------------------------------------------------------------------------- 1 | "; 16 | 17 | if (! empty( $description ) ) { 18 | echo "

$description

"; 19 | } 20 | 21 | echo " 22 | 30 | "; -------------------------------------------------------------------------------- /includes/admin/index.php: -------------------------------------------------------------------------------- 1 | array ( 20 | 'type' => 'select', 21 | 'data' => 'pages', 22 | 'data_args' => array( 'number' => '100' ), 23 | 'section' => 'General', 24 | 'placeholder' => esc_html__( 'Select Page', 'hubaga' ), 25 | 'title' => esc_html__( 'Account Page', 'hubaga' ), 26 | 'description' => esc_html__( 'Do not forget to include the [h-account] shortcode on this page.', 'hubaga' ), 27 | ), 28 | 'checkout_page_id' => array ( 29 | 'type' => 'select', 30 | 'data' => 'pages', 31 | 'data_args' => array( 'number' => '100' ), 32 | 'section' => 'General', 33 | 'placeholder' => esc_html__( 'Select Page', 'hubaga' ), 34 | 'title' => esc_html__( 'Checkout Page', 'hubaga' ), 35 | 'description' => esc_html__( 'Do not forget to include the [h-checkout] shortcode on this page.', 'hubaga' ), 36 | ), 37 | 'download_method' => array ( 38 | 'type' => 'select', 39 | 'options' => array( 40 | 'force' => esc_html__( 'Force Downloads', 'hubaga' ), 41 | 'redirect' => esc_html__( 'Redirect', 'hubaga' ), 42 | ), 43 | 'section' => 'General', 44 | 'placeholder' => esc_html__( 'Select Download Method', 'hubaga' ), 45 | 'title' => esc_html__( 'Download Method', 'hubaga' ), 46 | 'description' => esc_html__( 'Force Downloads is the best but might not work well for huge files.', 'hubaga' ), 47 | ), 48 | 'currency' => array ( 49 | 'type' => 'select', 50 | 'options' => $currencies, 51 | 'default' => 'USD', 52 | 'section' => 'General', 53 | 'placeholder' => esc_html__( 'Select Main Currency', 'hubaga' ), 54 | 'title' => esc_html__( 'Store Currency', 'hubaga' ), 55 | 'description' => esc_html__( 'This is the currency by which your customers will be charged.', 'hubaga' ), 56 | ), 57 | 'currency_position' => array ( 58 | 'type' => 'select', 59 | 'options' => array( 60 | 'left' => esc_html__( 'Left', 'hubaga' ), 61 | 'right' => esc_html__( 'Right', 'hubaga' ), 62 | ), 63 | 'default' => 'left', 64 | 'section' => 'General', 65 | 'placeholder' => esc_html__( 'Select Currency Location', 'hubaga' ), 66 | 'title' => esc_html__( 'Currency Position', 'hubaga' ), 67 | ), 68 | 'thousand_separator' => array ( 69 | 'type' => 'text', 70 | 'default' => ',', 71 | 'section' => 'General', 72 | 'title' => esc_html__( 'Thousand Separator', 'hubaga' ), 73 | 'custom_attributes' => array( 74 | 'style' => 'max-width: 100px;' 75 | ), 76 | ), 77 | 'decimal_separator' => array ( 78 | 'type' => 'text', 79 | 'default' => '.', 80 | 'section' => 'General', 81 | 'title' => esc_html__( 'Decimal Separator', 'hubaga' ), 82 | 'custom_attributes' => array( 83 | 'style' => 'max-width: 100px;' 84 | ), 85 | ), 86 | 'sandbox' => array ( 87 | 'type' => 'checkbox', 88 | 'default' => '0', 89 | 'section' => 'General', 90 | 'class' => 'filled-in', 91 | 'title' => esc_html__( 'Activate Test Mode', 'hubaga' ), 92 | 'description' => esc_html__( 'No actual transaction will happen. This is also called sandbox mode.', 'hubaga' ), 93 | 'custom_attributes' => array( 94 | 'style' => 'max-width: 100px;' 95 | ), 96 | ), 97 | 'enable_instacheck' => array ( 98 | 'type' => 'checkbox', 99 | 'default' => '1', 100 | 'section' => 'General', 101 | 'class' => 'filled-in', 102 | 'title' => esc_html__( 'Activate Instacheck', 'hubaga' ), 103 | 'description' => esc_html__( 'Instacheck allows customers on large screens to checkout without reloading pages.', 'hubaga' ), 104 | 'custom_attributes' => array( 105 | 'style' => 'max-width: 100px;' 106 | ), 107 | ), 108 | 'enable_coupons' => array ( 109 | 'type' => 'checkbox', 110 | 'default' => '1', 111 | 'section' => 'General', 112 | 'class' => 'filled-in', 113 | 'title' => esc_html__( 'Enable Coupons', 'hubaga' ), 114 | 'description' => esc_html__( 'Allow customers to use coupons during checkout.', 'hubaga' ), 115 | 'custom_attributes' => array( 116 | 'style' => 'max-width: 100px;' 117 | ), 118 | ), 119 | //Force the gateway section to follow general section 120 | 'gateway_section_title' => array ( 121 | 'type' => 'title', 122 | 'section' => 'Gateways', 123 | 'title' => esc_html__( 'Payment Gateways', 'hubaga' ), 124 | 'subtitle' => esc_html__( 'This section allows you to activate or deactivate the various payment gateways.', 'hubaga' ), 125 | ), 126 | 'notifications_title' => array( 127 | 'type' => 'title', 128 | 'title' => esc_html__( 'Notifications', 'hubaga' ), 129 | 'section' => 'Notifications', 130 | 'sub_section' => 'Emails', 131 | ), 132 | 'mailer_from_name' => array( 133 | 'type' => 'text', 134 | 'default' => wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ), 135 | 'title' => esc_html__( 'From Name', 'hubaga' ), 136 | 'description' => esc_html__( 'Fills the "from" field of outgoing emails', 'hubaga' ), 137 | 'section' => 'Notifications', 138 | 'sub_section' => 'Emails', 139 | ), 140 | 'mailer_from_email' => array( 141 | 'type' => 'text', 142 | 'default' => wp_specialchars_decode( get_option( 'admin_email' ), ENT_QUOTES ), 143 | 'title' => esc_html__( 'From Email', 'hubaga' ), 144 | 'description' => esc_html__( 'Fills the "reply to" field of outgoing emails', 'hubaga' ), 145 | 'section' => 'Notifications', 146 | 'sub_section' => 'Emails', 147 | ), 148 | 'mailer_header_bg' => array( 149 | 'type' => 'color', 150 | 'default' => '#ff5722', 151 | 'title' => esc_html__( 'Header Background', 'hubaga' ), 152 | 'section' => 'Notifications', 153 | 'sub_section' => 'Emails', 154 | ), 155 | 'mailer_header_color' => array( 156 | 'type' => 'color', 157 | 'default' => '#fff', 158 | 'title' => esc_html__( 'Header Color', 'hubaga' ), 159 | 'section' => 'Notifications', 160 | 'sub_section' => 'Emails', 161 | ), 162 | 'mailer_business_address' => array( 163 | 'type' => 'text', 164 | 'default' => 'Business Inc. 357 Westlands, Nairobi 00100', 165 | 'title' => esc_html__( 'Business Address', 'hubaga' ), 166 | 'description' => esc_html__( 'Helps escape spam filters.', 'hubaga' ), 167 | 'section' => 'Notifications', 168 | 'sub_section' => 'Emails', 169 | ), 170 | ); 171 | -------------------------------------------------------------------------------- /includes/admin/views/coupon-details.php: -------------------------------------------------------------------------------- 1 | array ( 14 | 'type' => 'text', 15 | 'title' => esc_html__( 'Coupon Code', 'hubaga' ), 16 | 'description' => esc_html__( 'The coupon code that customers enter during checkout. The shorter the better.', 'hubaga' ), 17 | 'placeholder' => 'SUMMERSALE', 18 | ), 19 | 20 | 'discount_type' => array ( 21 | 'type' => 'select', 22 | 'options' => hubaga_get_coupon_types(), 23 | 'title' => esc_html__( 'Coupon Type', 'hubaga' ), 24 | 'description' => esc_html__( 'The coupon type.', 'hubaga' ), 25 | ), 26 | 27 | 'amount' => array ( 28 | 'type' => 'text', 29 | 'title' => esc_html__( 'Amount', 'hubaga' ), 30 | 'description' => esc_html__( 'This is the amount that is discounted from the total order.', 'hubaga' ), 31 | ), 32 | 33 | 'date_expires' => array ( 34 | 'type' => 'date', 35 | 'title' => esc_html__( 'Expiry Date', 'hubaga' ), 36 | 'placeholder' => esc_html__( 'No expiry date', 'hubaga' ), 37 | 'description' => esc_html__( 'If you leave this blank then the coupon will never expire.', 'hubaga' ), 38 | ), 39 | 40 | 'usage_limit' => array ( 41 | 'type' => 'number', 42 | 'title' => esc_html__( 'Coupon Limit', 'hubaga' ), 43 | 'placeholder' => esc_html__( 'Unlimited', 'hubaga' ), 44 | 'description' => esc_html__( 'Set this to zero if you want the coupon to be used for an unlimited number of times.', 'hubaga' ), 45 | ), 46 | 47 | 'minimum_amount' => array ( 48 | 'type' => 'text', 49 | 'title' => esc_html__( 'Minimum Spend', 'hubaga' ), 50 | 'placeholder' => esc_html__( 'No Minimum Amount', 'hubaga' ), 51 | 'description' => esc_html__( 'The coupon will only be valid if the user spents at least the value you provide here.', 'hubaga' ), 52 | ), 53 | 54 | 'maximum_amount' => array ( 55 | 'type' => 'text', 56 | 'title' => esc_html__( 'Maximum Spend', 'hubaga' ), 57 | 'placeholder' => esc_html__( 'No Maximum Amount', 'hubaga' ), 58 | 'description' => esc_html__( 'Set this to 0 if you do not want to prevent users that spent more than the given amount from using this coupon.', 'hubaga' ), 59 | ), 60 | 61 | 'product_ids' => array ( 62 | 'type' => 'multiselect', 63 | 'data_args' => array( 'post_type' => hubaga_get_product_post_type() ), 64 | 'data' => "posts", 65 | 'title' => esc_html__( 'Products', 'hubaga' ), 66 | 'placeholder' => esc_html__( 'Applicable on all products', 'hubaga' ), 67 | 'description' => esc_html__( 'Leave this blank if you want it applicable on all products.', 'hubaga' ), 68 | ), 69 | 70 | 'excluded_product_ids' => array ( 71 | 'type' => 'multiselect', 72 | 'data_args' => array( 'post_type' => hubaga_get_product_post_type() ), 73 | 'data' => "posts", 74 | 'title' => esc_html__( 'Excluded Products', 'hubaga' ), 75 | 'placeholder' => esc_html__( 'Do not exclude any product', 'hubaga' ), 76 | 'description' => esc_html__( 'Leave this blank if you do not want to exclude any products.', 'hubaga' ), 77 | ), 78 | 79 | 'email_restrictions' => array ( 80 | 'type' => 'tag', 81 | 'title' => esc_html__( 'Emails', 'hubaga' ), 82 | 'placeholder' => esc_html__( 'Can be used by anyone', 'hubaga' ), 83 | 'description' => esc_html__( 'Leave this blank if you do not want to restrict the coupon to specific customer email addresses.', 'hubaga' ), 84 | ), 85 | 86 | ); 87 | -------------------------------------------------------------------------------- /includes/admin/views/coupon-template.php: -------------------------------------------------------------------------------- 1 | '; 15 | 16 | foreach ( $elements as $element ) { 17 | $this->render_element( $element ); 18 | } 19 | //Security check 20 | wp_nonce_field('hubaga_coupon_inner_custom_box','hubaga_coupon_inner_custom_box_nonce'); 21 | 22 | echo '
'; 23 | 24 | ?> 25 | 26 | -------------------------------------------------------------------------------- /includes/admin/views/extensions-template.php: -------------------------------------------------------------------------------- 1 | '; 17 | echo "

$view

"; 18 | 19 | foreach ( $elements as $element ) { 20 | $this->render_element( $element ); 21 | } 22 | 23 | echo '
'; 24 | -------------------------------------------------------------------------------- /includes/admin/views/index.php: -------------------------------------------------------------------------------- 1 | array ( 19 | 'type' => 'select', 20 | 'title' => esc_html__( 'Status', 'hubaga' ), 21 | 'options' => wp_list_pluck( hubaga_get_order_statuses(), 'label' ), 22 | ), 23 | 24 | 'payment_date' => array ( 25 | 'type' => 'text', 26 | 'title' => esc_html__( 'Payment Date', 'hubaga' ), 27 | ), 28 | 29 | 'product' => array ( 30 | 'type' => 'select', 31 | 'title' => esc_html__( 'Product', 'hubaga' ), 32 | 'placeholder' => __( 'Select Product', 'hubaga' ), 33 | 'data' => 'posts', 34 | 'data_args' => array( 35 | 'numberposts' => '100', 36 | 'post_type' => hubaga_get_product_post_type(), 37 | 'post_status' => 'publish', 38 | ), 39 | ), 40 | 41 | 'payment_method' => array ( 42 | 'type' => 'select', 43 | 'title' => esc_html__( 'Payment Method', 'hubaga' ), 44 | 'options' => $gateways, 45 | ), 46 | 47 | 'customer_id' => array ( 48 | 'type' => 'select', 49 | 'title' => esc_html__( 'Customer', 'hubaga' ), 50 | 'placeholder' => __( 'Select Customer', 'hubaga' ), 51 | 'data' => 'users', 52 | 'data_args' => array( 53 | 'count_total' => false, 54 | 'post_type' => hubaga_get_product_post_type(), 55 | 'fields' => array( 'ID', 'display_name' ), 56 | ), 57 | ), 58 | 59 | 'total' => array ( 60 | 'type' => 'text', 61 | 'title' => esc_html__( 'Order Total', 'hubaga' ), 62 | ), 63 | 64 | 'discount_total' => array ( 65 | 'type' => 'text', 66 | 'title' => esc_html__( 'Total Discount', 'hubaga' ), 67 | ), 68 | 69 | 'currency' => array ( 70 | 'type' => 'select', 71 | 'title' => esc_html__( 'Currency', 'hubaga' ), 72 | 'options' => hubaga_get_currencies(), 73 | ), 74 | ); -------------------------------------------------------------------------------- /includes/admin/views/order-template.php: -------------------------------------------------------------------------------- 1 | 18 |
19 |
20 | '; 21 | echo "

Order #$post->ID

"; 22 | 23 | foreach ( $elements as $element ) { 24 | $this->render_element( $element ); 25 | } 26 | //Security check 27 | wp_nonce_field('hubaga_order_inner_custom_box','hubaga_order_inner_custom_box_nonce'); 28 | 29 | echo'
30 |
'; 31 | hubaga()->Elementa('hubaga_order_details')->render_element( array( 'type' => 'order_overview', 'id' => 'order_overview' ) ); 32 | echo'
33 |
34 |
'; 35 | ?> 36 | 42 | -------------------------------------------------------------------------------- /includes/admin/views/product-details.php: -------------------------------------------------------------------------------- 1 | array ( 14 | 'type' => 'select', 15 | 'options' => hubaga_get_product_types(), 16 | 'title' => esc_html__( 'Product Type', 'hubaga' ), 17 | ), 18 | 19 | 'short_description' => array ( 20 | 'type' => 'editor', 21 | 'options' => hubaga_get_product_types(), 22 | 'title' => esc_html__( 'Short Description', 'hubaga' ), 23 | 'description' => esc_html__( 'A short description about the product. Shortcodes are allowed.', 'hubaga' ), 24 | ), 25 | 26 | 'price' => array ( 27 | 'type' => 'text', 28 | 'title' => esc_html__( 'Price', 'hubaga' ), 29 | 'description' => esc_html__( 'Do not include the currency symbol.', 'hubaga' ), 30 | ), 31 | 32 | 'download_name' => array ( 33 | 'type' => 'text', 34 | 'title' => esc_html__( 'Download Name', 'hubaga' ), 35 | 'placeholder' => 'download.zip', 36 | 'description' => esc_html__( 'This is the name by which the product will be saved.', 'hubaga' ), 37 | ), 38 | 39 | 'download_url' => array ( 40 | 'type' => 'text', 41 | 'title' => esc_html__( 'Download Url', 'hubaga' ), 42 | 'placeholder' => 'https://example.com/downloads/download.zip', 43 | 'description' => esc_html__( 'Link to the file. Your users won\'t see it.', 'hubaga' ), 44 | ), 45 | 46 | ); 47 | -------------------------------------------------------------------------------- /includes/admin/views/product-template.php: -------------------------------------------------------------------------------- 1 | ID ); 18 | 19 | echo '
'; 20 | 21 | foreach ( $elements as $element ) { 22 | $this->render_element( $element ); 23 | } 24 | //Security check 25 | wp_nonce_field('hubaga_product_inner_custom_box','hubaga_product_inner_custom_box_nonce'); 26 | 27 | echo '
'; 28 | ?> 29 | 35 | -------------------------------------------------------------------------------- /includes/admin/views/reports-template.php: -------------------------------------------------------------------------------- 1 | 18 |

$title

"; 19 | 20 | foreach ( $elements as $element ) { 21 | $this->render_element( $element ); 22 | } 23 | 24 | echo '
'; 25 | 26 | ?> 27 | 28 | 48 | 49 | template->get_checkout_html(); 24 | 25 | exit(); //Keep this! 26 | 27 | } 28 | 29 | add_action( 'wp_ajax_hubaga_apply_coupon', 'hubaga_ajax_apply_coupon' ); 30 | add_action( 'wp_ajax_nopriv_hubaga_apply_coupon', 'hubaga_ajax_apply_coupon' ); 31 | 32 | //Coupon requests 33 | function hubaga_ajax_apply_coupon( ){ 34 | 35 | //Check nonce 36 | $nonce = $_REQUEST['nonce']; 37 | 38 | if (! wp_verify_nonce( $nonce, 'hubaga_nonce' ) ) { 39 | wp_send_json( array( 40 | 'result' => 'error', 41 | 'error' => __( 'Unable to complete your request.', 'hubaga' ), 42 | ) ); 43 | exit(); 44 | } 45 | 46 | $data = wp_unslash( $_REQUEST ); 47 | 48 | //Validate the product 49 | if ( empty( $data['product'] ) OR !( hubaga_is_product( $data['product'] ) ) ) { 50 | wp_send_json( array( 51 | 'result' => 'error', 52 | 'error' => __( 'Error: Invalid product.', 'hubaga' ), 53 | ) ); 54 | exit(); 55 | } 56 | 57 | //Validate the coupon 58 | if ( empty( $data['coupon'] ) OR !hubaga_coupon_exists( false, $data['coupon'] ) ) { 59 | wp_send_json( array( 60 | 'result' => 'error', 61 | 'error' => __( 'Error: Invalid coupon.', 'hubaga' ), 62 | ) ); 63 | exit(); 64 | } 65 | 66 | $customer = 0; 67 | if (! empty( $data['email'] ) ) { 68 | $customer_data = get_user_by( 'email', $data['email'] ); 69 | if( $customer_data->ID ) { 70 | $customer = $customer_data->ID; 71 | } 72 | } 73 | 74 | $price = hubaga_get_product_price( $data['product'] ); 75 | if( ! $price ) { 76 | wp_send_json( array( 77 | 'result' => 'error', 78 | 'error' => __( 'Unable to apply this coupon.', 'hubaga' ), 79 | ) ); 80 | exit(); 81 | } 82 | 83 | $result = hubaga_apply_coupon( $data['coupon'], $price, $customer, $data['product'] ); 84 | 85 | if( ! is_array( $result ) ) { 86 | 87 | $error = __( 'Error applying this coupon.', 'hubaga' ); 88 | if( hubaga_has_errors() ) { 89 | $error = strip_tags( hubaga_get_errors_html() ); 90 | } 91 | wp_send_json( array( 92 | 'result' => 'error', 93 | 'error' => $error, 94 | ) ); 95 | exit(); 96 | } 97 | 98 | $price = " $price {$result['order_total']} "; 99 | wp_send_json( array( 100 | 'result' => 'success', 101 | 'price' => $price, 102 | ) ); 103 | exit(); 104 | 105 | } 106 | 107 | 108 | //Logged in users only 109 | add_action( 'wp_ajax_hubaga_handle_report_data', 'hubaga_handle_report_data' ); 110 | 111 | //Handles requests for reports 112 | function hubaga_handle_report_data() { 113 | 114 | $is_auth = wp_verify_nonce( $_REQUEST['nonce'], 'hubaga_reports_nonce' ); 115 | if ( !$is_auth OR !current_user_can( 'manage_options' ) ) { 116 | wp_die ( __( 'You are not allowed to view reports.', 'hubaga' ) ); 117 | } 118 | 119 | $reports = new H_Report(); 120 | wp_send_json( $reports->vue_data() ) ; 121 | die(); 122 | } 123 | -------------------------------------------------------------------------------- /includes/checkout/abstract-payments-class.php: -------------------------------------------------------------------------------- 1 | init_settings(); 53 | 54 | //Maybe handle the checkout 55 | if(! empty( $_REQUEST['action'] ) && $_REQUEST['action'] == 'hubaga_handle_checkout' ) { 56 | $this->process_checkout(); 57 | } 58 | 59 | //Sandbox settings 60 | if( hubaga_is_sandbox() ) { 61 | add_action( 'admin_notices' , array( $this, 'sandbox_notices' ) ); 62 | } 63 | } 64 | 65 | /** 66 | * Payment settings 67 | */ 68 | public function init_settings( ) { 69 | 70 | //Register the gateway settings 71 | $gateways = $this->get_gateways(); 72 | 73 | foreach( $gateways as $gateway ) { 74 | 75 | $gateway_obj = hubaga_get_gateway( $gateway ); 76 | $default = 0; 77 | if ( $gateway == 'paypal' ) 78 | $default = 1; //PayPal is usually active by default 79 | 80 | $_title = $gateway_obj->meta['title']; 81 | $title = sprintf( esc_html__( 'Enable %s', 'hubaga' ), $_title ); 82 | 83 | $description = ''; 84 | if ( isset( $gateway_obj->meta['description'] ) ) { 85 | $description = $gateway_obj->meta['description']; 86 | } 87 | 88 | hubaga_add_option( 89 | array( 90 | 'id' => "is_gateway_{$gateway}_active", 91 | 'type' => 'switch', 92 | 'default' => $default, 93 | 'class' => 'filled-in', 94 | 'title' => $title, 95 | 'description' => $description, 96 | 'section' => 'Gateways', 97 | ) 98 | ); 99 | 100 | if ( is_callable( array( $gateway_obj, 'init_settings' ) ) ) { 101 | $gateway_obj->init_settings(); 102 | } 103 | } 104 | 105 | } 106 | 107 | /** 108 | * Warn the user to disable sandbox when he is ready to start selling 109 | */ 110 | public function sandbox_notices(){ 111 | echo '
'; 112 | esc_html_e( 'You have activated sandbox mode. Do not forget to disable it when you are ready to start selling!', 'hubaga' ); 113 | 114 | echo '
'; 115 | } 116 | 117 | /** 118 | * Processes the checkout then redirects the user to the appropriate page. 119 | */ 120 | abstract public function process_checkout(); 121 | 122 | /** 123 | * Registers a new gateway 124 | * @see hubaga_register_core_gateways 125 | */ 126 | abstract public function add_gateway( $gateway, $object ); 127 | 128 | /** 129 | * Removes a registered gateway 130 | */ 131 | abstract public function remove_gateway( $gateway ); 132 | 133 | /** 134 | * Gets a registered gateway object 135 | */ 136 | abstract public function get_gateway( $gateway ); 137 | 138 | /** 139 | * Gets all registered gateway objects 140 | */ 141 | abstract public function get_gateways(); 142 | 143 | /** 144 | * Gets all active gateway objects 145 | */ 146 | abstract public function get_active_gateways(); 147 | 148 | /** 149 | * Checks if a given gateway is active or not 150 | */ 151 | abstract public function is_gateway_active( $gateway ); 152 | 153 | /** 154 | * Checks if an order is refundable 155 | * @see hubaga_get_order 156 | */ 157 | abstract public function is_refundable( $order ); 158 | 159 | /** 160 | * Refunds an order 161 | * @see hubaga_get_order 162 | */ 163 | abstract public function refund( $order ); 164 | 165 | } 166 | -------------------------------------------------------------------------------- /includes/checkout/functions.php: -------------------------------------------------------------------------------- 1 | payments ) && is_object( hubaga()->payments ) ) 22 | return hubaga()->payments; 23 | 24 | $processor = apply_filters( 'hubaga_payments_processor', false ); 25 | if (! is_object( $processor ) ) 26 | $processor = H_Payments::instance(); 27 | 28 | hubaga()->payments = $processor; 29 | return $processor; 30 | } 31 | 32 | /** 33 | * Adds a payment gateway 34 | * 35 | * @since Hubaga 1.0.0 36 | */ 37 | function hubaga_add_gateway( $gateway, $object ) { 38 | return hubaga_get_payment_processor()->add_gateway( $gateway, $object ); 39 | } 40 | 41 | /** 42 | * Retrieves a payment gateway 43 | * 44 | * @since Hubaga 1.0.0 45 | * 46 | * @return object an object of the payment gateway or false 47 | */ 48 | function hubaga_get_gateway( $gateway ) { 49 | $gateway = trim( $gateway ); 50 | $processor = hubaga_get_payment_processor(); 51 | return $processor->get_gateway( $gateway ); 52 | } 53 | 54 | /** 55 | * Retrieves a gateway title 56 | * 57 | * @since Hubaga 1.0.0 58 | * 59 | * @return string 60 | */ 61 | function hubaga_get_gateway_title( $id ) { 62 | $gateway = hubaga_get_gateway( $id ); 63 | if(! $gateway ) { 64 | return $id; 65 | } 66 | 67 | return $gateway->meta['title']; 68 | } 69 | 70 | /** 71 | * Retrieves all active payment gateways 72 | * 73 | * @since Hubaga 1.0.0 74 | * 75 | */ 76 | function hubaga_get_active_gateways() { 77 | $processor = hubaga_get_payment_processor(); 78 | return $processor->get_active_gateways(); 79 | } 80 | 81 | /** 82 | * Checks if a gateway is active 83 | * 84 | * @since Hubaga 1.0.0 85 | * 86 | * @return object an object of the payment gateway or false 87 | */ 88 | function hubaga_is_active_gateway( $gateway ) { 89 | $gateway = trim( $gateway ); 90 | $processor = hubaga_get_payment_processor(); 91 | return $processor->is_gateway_active( $gateway ); 92 | } 93 | 94 | /** 95 | * Registers core payment gateways 96 | * 97 | * @since Hubaga 1.0.0 98 | */ 99 | function hubaga_register_core_payment_gateways() { 100 | 101 | require_once hubaga_get_includes_path() . 'checkout/gateways/test-gateway.php'; 102 | require_once hubaga_get_includes_path() . 'checkout/gateways/paypal/paypal-gateway.php'; 103 | hubaga_add_gateway( 'test', new H_Test_Gateway() ); 104 | hubaga_add_gateway( 'paypal', new H_PayPal_Gateway() ); 105 | 106 | } 107 | add_action( 'hubaga_init', 'hubaga_register_core_payment_gateways', 11 ); 108 | 109 | 110 | /** 111 | * Validates checkout fields using the posted data 112 | * 113 | * @since Hubaga 1.0.0 114 | */ 115 | function hubaga_validate_checkout_fields() { 116 | $checkout_fields = hubaga_get_checkout_fields(); 117 | 118 | foreach( $checkout_fields as $field => $arguments ){ 119 | 120 | $field = esc_attr( $field ); 121 | $title = $arguments[ 'title' ]; 122 | 123 | if( isset( $arguments['required'] ) && !hubaga_is_array_key_valid( $_REQUEST, $field ) ) { 124 | hubaga_add_error( __( "$title is required", 'hubaga' ) ); 125 | continue; 126 | } 127 | 128 | if( isset( $arguments['validation'] ) && !hubaga_is_array_key_valid( $_REQUEST, $field, $arguments['validation'] ) ) { 129 | hubaga_add_error( __( "$title is invalid", 'hubaga' ) ); 130 | } 131 | 132 | } 133 | 134 | /** 135 | * Fires when validating checkout fields 136 | * 137 | * Use this hook to run your own checkout validations 138 | * 139 | * @since 1.0.0 140 | * 141 | */ 142 | do_action( 'hubaga_validating_checkout_fields' ); 143 | 144 | } 145 | add_action( 'hubaga_before_checkout_process', 'hubaga_validate_checkout_fields', 20 ); 146 | 147 | 148 | /** 149 | * Retrieves the checkout fields 150 | * 151 | * @since Hubaga 1.0.0 152 | */ 153 | function hubaga_get_checkout_fields() { 154 | 155 | //Setup the default email 156 | $default_email = ''; 157 | 158 | if ( is_user_logged_in() ) { 159 | $user = wp_get_current_user(); 160 | $default_email = $user->user_email; 161 | } 162 | 163 | if ( isset( $_REQUEST['email'] ) ) { 164 | $default_email = sanitize_email( $default_email ); 165 | } 166 | 167 | $label= __( 'Email', 'hubaga' ); 168 | $class= ''; 169 | if(! $default_email ){ 170 | $class= 'hubaga-is-empty'; 171 | } 172 | $html = " 173 | "; 177 | $fields = array( 178 | 'email' => array( 179 | 'validation' => 'is_email', 180 | 'title' => __( 'Email', 'hubaga' ), 181 | 'required' => true, 182 | 'html' => $html, 183 | ), 184 | ); 185 | return apply_filters( 'hubaga_checkout_fields', $fields ); 186 | 187 | } 188 | 189 | /** 190 | * Gets the url to the checkout page. 191 | * 192 | * @since 1.0.0 193 | * 194 | * @return string Url to checkout page 195 | */ 196 | function hubaga_get_checkout_url(){ 197 | 198 | $id = intval( hubaga_get_option( 'checkout_page_id' ) ); 199 | $permalink = 1 > $id ? get_home_url() : get_permalink( $id ); 200 | return apply_filters( 'hubaga_get_checkout_url', $permalink ); 201 | 202 | } 203 | 204 | /** 205 | * Checks whether or not this is a checkout page 206 | * 207 | * @since 1.0.0 208 | * 209 | * @return bool 210 | */ 211 | function hubaga_is_checkout_page(){ 212 | 213 | $id = intval( hubaga_get_option( 'checkout_page_id' ) ); 214 | if( !$id ){ 215 | return false; 216 | } 217 | return is_page( $id ); 218 | 219 | } 220 | 221 | /** 222 | * Returns or sets the custom checkout form 223 | * 224 | * @since 1.0.0 225 | * 226 | * @return string Url to checkout page 227 | */ 228 | function hubaga_checkout_form( $form = null ){ 229 | 230 | if( null !== $form ){ 231 | hubaga()->checkout_form = $form; 232 | } 233 | return hubaga()->checkout_form; 234 | 235 | } 236 | -------------------------------------------------------------------------------- /includes/checkout/gateways/index.php: -------------------------------------------------------------------------------- 1 | array( 12 | 'title' => __( 'Title', 'hubaga' ), 13 | 'type' => 'text', 14 | 'description' => __( 'The text to show on the checkout button.', 'hubaga' ), 15 | 'default' => __( 'Pay Via PayPal', 'hubaga' ), 16 | ), 17 | 'paypal_email' => array( 18 | 'title' => __( 'PayPal email', 'hubaga' ), 19 | 'type' => 'email', 20 | 'description' => __( 'The email address associated with your PayPal account.', 'hubaga' ), 21 | 'default' => get_option( 'admin_email' ), 22 | 'placeholder' => 'you@youremail.com', 23 | ), 24 | 'paypal_pdt_token' => array( 25 | 'title' => __( 'PDT Token', 'hubaga' ), 26 | 'type' => 'text', 27 | 'description' => sprintf( 28 | __( 'This is required before you can process transactions via PayPal. %s Get your token. %s', 'hubaga' ), 29 | '', 30 | ''), 31 | ), 32 | 'paypal_invoice_prefix' => array( 33 | 'title' => __( 'Invoice prefix', 'hubaga' ), 34 | 'type' => 'text', 35 | 'description' => __( 'Please enter a prefix for your invoice numbers. If you use your PayPal account for multiple stores ensure this prefix is unique as PayPal will not allow orders with the same invoice number.', 'hubaga' ), 36 | 'default' => 'H-', 37 | ), 38 | 'paypal_api_details' => array( 39 | 'title' => __( 'API credentials', 'hubaga' ), 40 | 'type' => 'title', 41 | 'description' => sprintf( __( 'You will have to enter your api credentials before you can receive payments via PayPal. Learn how to access your PayPal API Credentials.', 'hubaga' ), 'https://developer.paypal.com/webapps/developer/docs/classic/api/apiCredentials/#creating-an-api-signature' ), 42 | ), 43 | 'paypal_api_username' => array( 44 | 'title' => __( 'API username', 'hubaga' ), 45 | 'type' => 'text', 46 | 'default' => '', 47 | 'placeholder' => __( 'jb-us-seller_api1.paypal.com', 'hubaga' ), 48 | ), 49 | 'paypal_api_password' => array( 50 | 'title' => __( 'API password', 'hubaga' ), 51 | 'type' => 'password', 52 | 'default' => '', 53 | 'placeholder' => __( 'WX4WTU3S8MY44S7F', 'hubaga' ), 54 | ), 55 | 'paypal_api_signature' => array( 56 | 'title' => __( 'API signature', 'hubaga' ), 57 | 'type' => 'text', 58 | 'default' => '', 59 | 'placeholder' => __( 'AFcWxV21C7fd0v3bYYYRCpSSRl31A7yDhhsPUU2XhtMoZXsWHFxu-RWy', 'hubaga' ), 60 | ), 61 | ); 62 | -------------------------------------------------------------------------------- /includes/checkout/gateways/test-gateway.php: -------------------------------------------------------------------------------- 1 | meta['id'] = 'test'; 30 | 31 | //Gateway title 32 | $this->meta['title'] = 'Test Gateway'; 33 | 34 | //Gateway button text 35 | $this->meta['button_text'] = 'Test Gateway'; 36 | 37 | //Gateway description. Shown in administration areas 38 | $this->meta['description'] = 'Orders will be instantly marked as complete.'; 39 | 40 | //Gateway url. Link to this gateways homepage 41 | $this->meta['url'] = 'https://hubaga.com/hubaga/'; 42 | 43 | //Gateway checkout page description 44 | $this->meta['checkout_description'] = 'This gateway should ONLY be used when testing. Payments will instantly be marked as complete.'; 45 | 46 | //Gateway author 47 | $this->meta['author'] = 'Picocodes'; 48 | 49 | //Gateway author url 50 | $this->meta['author_url'] = 'https://hubaga.com/'; 51 | } 52 | 53 | /** 54 | * Process the payment and return the result. 55 | * @param object $order 56 | * @return array 57 | */ 58 | public function process_payment( $order ) { 59 | 60 | $order = hubaga_get_order( $order ); 61 | $order->payment_date = gmdate( 'D, d M Y H:i:s e' ); //GMT time 62 | $order->update_status( hubaga_get_completed_order_status() ); 63 | 64 | return array( 65 | 'action' => 'complete', 66 | ); 67 | 68 | } 69 | 70 | /** 71 | * Handles order refunds 72 | */ 73 | public function refund( $order, $amount = null, $reason = '' ) { 74 | $order = hubaga_get_order( $order ); 75 | return $order->update_status( hubaga_get_refunded_order_status() ); 76 | } 77 | 78 | } 79 | -------------------------------------------------------------------------------- /includes/checkout/index.php: -------------------------------------------------------------------------------- 1 | exists(); 41 | } 42 | 43 | /* 44 | * Creates / Updates a new coupon code 45 | * @param $id coupon id, array of data or H_Coupon object 46 | * @param $coupon_code string coupon code in case you want to search by code 47 | * @return bool 48 | */ 49 | function hubaga_save_coupon( $id = false, $coupon_code = false ) { 50 | $coupon = new H_Coupon( $id, $coupon_code ); 51 | return $coupon->save(); 52 | } 53 | 54 | /* 55 | * Calculates the amounts for a given coupon 56 | * 57 | * @param $coupon the coupon to apply 58 | * @param $order_total the current order total 59 | * @param $customer the customer using this coupon 60 | * @param $product the product that has been bought 61 | * 62 | * @return array. Returns an array with the new order_total and discount total 63 | */ 64 | function hubaga_apply_coupon( $coupon, $order_total, $customer, $product ) { 65 | 66 | $coupon = apply_filters( 'hubaga_coupon_code', $coupon ); 67 | $coupon = hubaga_get_coupon( false, $coupon ); 68 | $product = hubaga_get_product( $product ); 69 | $customer = hubaga_get_customer( $customer ); 70 | $order_total= floatval( $order_total ); 71 | $return = array( 72 | 'order_total' => $order_total, 73 | 'discount_total' => 0, 74 | ); 75 | 76 | //Is the coupon available for use? 77 | $can_use = true; 78 | if(! $coupon->exists() ) { 79 | $can_use = false; //coupon does not exist 80 | } 81 | 82 | if( !$coupon->is_active() ) { 83 | $can_use = false; //Not published 84 | } 85 | 86 | if( $coupon->has_exeeded_limit() ){ 87 | $can_use = false; //Exeeded limit 88 | } 89 | 90 | if( $coupon->is_expired() ){ 91 | $can_use = false; //Expired 92 | } 93 | 94 | if(! $coupon->is_valid_for_product( $product->ID ) ){ 95 | $can_use = false; //Not valid for this product 96 | } 97 | 98 | if(! $coupon->is_valid_for_email( hubaga_get_customer_email( $customer ) ) ){ 99 | $can_use = false; //Not valid for this user 100 | } 101 | 102 | if(! $coupon->is_valid_for_amount( $order_total ) ){ 103 | $can_use = false; //Not valid for this amount 104 | } 105 | 106 | if(! $can_use ) { 107 | hubaga_add_error( esc_html__( "Error. This coupon does not exist.", 'hubaga' ) ); 108 | return false; 109 | } 110 | 111 | $coupon_amount = floatval( $coupon->amount ); 112 | //Nothing to do here 113 | if( $coupon_amount < 1 ){ 114 | hubaga_add_error( esc_html__( "Error. You cannot use that coupon.", 'hubaga' ) ); 115 | return false; 116 | } 117 | 118 | //Get the order total and discount amount 119 | if( $coupon->is_type( 'percentage' ) ) { 120 | if( $coupon_amount > 100 ){ 121 | $coupon_amount = 100; 122 | } 123 | 124 | $return[ 'discount_total' ] = hubaga_price( ( $coupon_amount/100 ) * $order_total, false, false ); 125 | $return[ 'order_total' ] = hubaga_price( $order_total - $return[ 'discount_total' ], false, false ); 126 | 127 | } else { 128 | 129 | if( $coupon_amount > $order_total ){ 130 | $coupon_amount = $order_total; 131 | } 132 | 133 | $return[ 'discount_total' ] = hubaga_price( $order_total - $coupon_amount, false, false ); 134 | $return[ 'order_total' ] = hubaga_price( $order_total - $return[ 'discount_total' ], false, false ); 135 | 136 | } 137 | 138 | return apply_filters( 'hubaga_apply_coupon', $return, $coupon, $order_total, $customer, $product ); 139 | } 140 | 141 | /* 142 | * Applies a coupon to a given order 143 | * @param $order id, object or H_Order instance 144 | * @param $coupon id, object or H_Coupon instance 145 | * @return object. H_Order with the coupon applied OR WP_Error on error 146 | */ 147 | function hubaga_get_coupon_types() { 148 | return apply_filters( 'hubaga_coupon_types', 149 | array( 150 | 'fixed' => esc_html__( 'Fixed Amount', 'hubaga' ), 151 | 'percentage' => esc_html__( 'Percentage Discount', 'hubaga' ), 152 | )); 153 | } 154 | 155 | /** 156 | * A wrapper for wp_insert_post() that also includes the necessary meta values 157 | * for the forum to function properly. 158 | */ 159 | function hubaga_get_coupon_post_type_labels() { 160 | return apply_filters( 'hubaga_coupon_post_type_labels', 161 | array( 162 | 'name' => esc_html__( 'Coupons', 'hubaga' ), 163 | 'singular_name' => esc_html__( 'Coupon', 'hubaga' ), 164 | 'add_new' => esc_html__( 'Add coupon', 'hubaga' ), 165 | 'add_new_item' => esc_html__( 'Add new coupon', 'hubaga' ), 166 | 'edit' => esc_html__( 'Edit', 'hubaga' ), 167 | 'edit_item' => esc_html__( 'Edit coupon', 'hubaga' ), 168 | 'new_item' => esc_html__( 'New coupon', 'hubaga' ), 169 | 'view' => esc_html__( 'View coupon', 'hubaga' ), 170 | 'view_item' => esc_html__( 'View coupon', 'hubaga' ), 171 | 'search_items' => esc_html__( 'Search coupons', 'hubaga' ), 172 | 'not_found' => esc_html__( 'No coupons found', 'hubaga' ), 173 | 'not_found_in_trash' => esc_html__( 'No coupons found in trash', 'hubaga' ), 174 | 'parent' => esc_html__( 'Parent coupons', 'hubaga' ), 175 | 'menu_name' => esc_html_x( 'Coupons', 'Admin menu name', 'hubaga' ), 176 | 'filter_items_list' => esc_html__( 'Filter coupons', 'hubaga' ), 177 | 'items_list_navigation' => esc_html__( 'Coupons navigation', 'hubaga' ), 178 | 'items_list' => esc_html__( 'Coupons list', 'hubaga' ), 179 | ) ); 180 | } 181 | 182 | 183 | /** 184 | * Returns coupon post type details 185 | */ 186 | function hubaga_get_coupon_post_type_details(){ 187 | return apply_filters( 188 | 'hubaga_coupon_post_type_details', 189 | array( 190 | 'labels' => hubaga_get_coupon_post_type_labels(), 191 | 'description' => esc_html__( 'This is where store coupons are stored.', 'hubaga' ), 192 | 'public' => false, 193 | 'show_ui' => true, 194 | 'map_meta_cap' => true, 195 | 'publicly_queryable' => false, 196 | 'exclude_from_search' => true, 197 | 'show_in_menu' => hubaga_get_coupon_post_type_menu_name(), 198 | 'hierarchical' => false, 199 | 'show_in_nav_menus' => false, 200 | 'rewrite' => false, 201 | 'query_var' => false, 202 | 'supports' => false, 203 | 'has_archive' => false, 204 | )); 205 | } 206 | 207 | /** 208 | * Returns coupon post type 209 | */ 210 | function hubaga_get_coupon_post_type(){ 211 | return hubaga()->coupon_post_type; 212 | } 213 | 214 | /** 215 | * Returns coupon post type menu name 216 | */ 217 | function hubaga_get_coupon_post_type_menu_name(){ 218 | return apply_filters( 'hubaga_coupon_post_type_menu_name', hubaga_get_product_post_type_menu_name()); 219 | } -------------------------------------------------------------------------------- /includes/customer-class.php: -------------------------------------------------------------------------------- 1 | posts WHERE meta_key = '_order_platform' AND meta_value = %s ) 32 | $id = hubaga_wpdb_clean( $this->ID ); 33 | $where[ 'ID' ] = array( 34 | 'value' => "(SELECT post_id FROM $wpdb->postmeta WHERE meta_key = '_order_customer_id' AND meta_value = $id)" , 35 | 'operator' => 'in' , 36 | ); 37 | 38 | //post status 39 | $statuses = implode( ', ', array_map( 'hubaga_wpdb_clean', array_keys( hubaga_get_order_statuses() ) ) ); 40 | $where[ 'post_status' ] = array( 41 | 'value' => "($statuses)" , 42 | 'operator' => 'in' , 43 | ); 44 | 45 | //post type 46 | $where[ 'post_type' ] = array( 47 | 'value' => hubaga_wpdb_clean( hubaga_get_order_post_type() ) , 48 | 'operator' => '=' , 49 | ); 50 | 51 | 52 | $sql = "SELECT DISTINCT(ID) FROM $wpdb->posts"; 53 | $_where = ' 1 = 1'; 54 | $joined = false; 55 | 56 | foreach( $where as $field => $args ){ 57 | 58 | if( !is_array($args) ){ 59 | continue; 60 | } 61 | 62 | if( empty( $args['operator'] ) ){ 63 | $args['operator'] = '='; 64 | } 65 | $value = $args['value']; 66 | $operator = $args['operator']; 67 | 68 | if( in_array( $field, array( 'meta_key','meta_value' ) ) && !$joined ){ 69 | $sql .= " INNER JOIN $wpdb->postmeta ON ID = post_id"; 70 | } 71 | $_where .= " AND $field $operator $value"; 72 | } 73 | 74 | $sql .= " WHERE $_where ORDER BY post_date DESC"; 75 | 76 | return apply_filters( 'hubaga_customer_orders', $wpdb->get_col( $sql ), $this, $where ); 77 | 78 | } 79 | 80 | } 81 | -------------------------------------------------------------------------------- /includes/customers.php: -------------------------------------------------------------------------------- 1 | exists() ) 23 | return $customer; 24 | 25 | return false; 26 | } 27 | 28 | /** 29 | * Retrieves a given customer's display name 30 | * @since 1.0.0 31 | * @return string 32 | */ 33 | function hubaga_get_customer_name( $customer ){ 34 | $customer = hubaga_get_customer( $customer ); 35 | return apply_filters( 'hubaga_customer_name', $customer->display_name, $customer ); 36 | } 37 | add_filter( 'hubaga_customer_name', 'strip_tags' ); 38 | 39 | /** 40 | * Retrieves a given customer's email address 41 | * @since 1.0.0 42 | * @return string 43 | */ 44 | function hubaga_get_customer_email( $customer ){ 45 | $customer = hubaga_get_customer( $customer ); 46 | return apply_filters( 'hubaga_customer_email', $customer->user_email, $customer ); 47 | } 48 | add_filter( 'hubaga_customer_email', 'sanitize_email' ); 49 | 50 | /** 51 | * Retrieves a given customer's description 52 | * @since 1.0.0 53 | * @return string 54 | */ 55 | function hubaga_get_customer_description( $customer ){ 56 | $customer = hubaga_get_customer( $customer ); 57 | return apply_filters( 'hubaga_customer_description', $customer->user_description, $customer ); 58 | } 59 | add_filter( 'hubaga_customer_description', 'esc_html' ); 60 | 61 | /** 62 | * Retrieves a given customer's date of registration 63 | * @since 1.0.0 64 | * @return string 65 | */ 66 | function hubaga_get_customer_registered( $customer ){ 67 | $customer = hubaga_get_customer( $customer ); 68 | return apply_filters( 'hubaga_customer_registered', $customer->user_registered, $customer ); 69 | } 70 | 71 | /** 72 | * Retrieves a given customer's ID 73 | * @since 1.0.0 74 | * @return string 75 | */ 76 | function hubaga_get_customer_id( $customer ){ 77 | $customer = hubaga_get_customer( $customer ); 78 | return apply_filters( 'hubaga_customer_id', $customer->ID, $customer ); 79 | } 80 | add_filter( 'hubaga_customer_id', 'absint' ); 81 | 82 | /** 83 | * Returns a customer's orders 84 | * 85 | * @since Hubaga 1.0.0 86 | * 87 | * @return string 88 | */ 89 | 90 | function hubaga_get_customer_orders( $customer, $where = array() ){ 91 | 92 | $customer = hubaga_get_customer( $customer ); 93 | return $customer->get_orders_by( $where ); 94 | 95 | } 96 | 97 | /** 98 | * Create a new customer. 99 | * 100 | * @param string $email Customer email. 101 | * @return int (user ID) of created user or existing user or 0 on failure. 102 | */ 103 | function hubaga_process_checkout_customer( $email ){ 104 | 105 | // Check the email address. 106 | if ( empty( $email ) || ! is_email( $email ) ) { 107 | hubaga_add_error( esc_html( 'Invalid email address.', 'hubaga' ) ); 108 | return 0; 109 | } 110 | 111 | if ( email_exists( $email ) ) { 112 | return get_user_by( 'email', $email )->ID; 113 | } 114 | 115 | //The user does not exist; create one 116 | $username = hubaga_generate_username( $email ); 117 | $password = wp_generate_password(); 118 | 119 | /** 120 | * Filters a user data passed to wp_insert_user 121 | * 122 | * @since 1.0.0 123 | * 124 | * @param array the userdata being filtered. 125 | */ 126 | 127 | $new_customer_data = apply_filters( 'hubaga_new_customer_data', array( 128 | 'user_login' => $username, 129 | 'user_pass' => $password, 130 | 'user_email' => $email, 131 | 'role' => 'customer', 132 | ) ); 133 | 134 | $customer_id = wp_insert_user( $new_customer_data ); 135 | 136 | if ( is_wp_error( $customer_id ) ) { 137 | 138 | //99.999% of the time we will never enter here 139 | foreach( $customer_id->get_error_messages() as $error ){ 140 | hubaga_add_error( $error ); 141 | } 142 | return 0; 143 | 144 | } 145 | 146 | do_action( 'hubaga_customer_created', $customer_id, $new_customer_data ); 147 | 148 | return $customer_id; 149 | } 150 | 151 | 152 | /** 153 | * Generate a unique username from the provided email 154 | * @param email the email used to generate the username 155 | * @since 1.0.0 156 | */ 157 | function hubaga_generate_username( $email ){ 158 | $username = sanitize_user( current( explode( '@', $email ) ), true ); 159 | 160 | // Ensure username is unique. 161 | $append = 1; 162 | $o_username = $username; 163 | 164 | while ( username_exists( $username ) ) { 165 | $username = $o_username . $append; 166 | $append++; 167 | } 168 | 169 | return $username; 170 | } 171 | 172 | /** 173 | * Gets the url to the account page. 174 | * 175 | * @since 1.0.0 176 | * 177 | * @return string Url to account page 178 | */ 179 | function hubaga_get_account_url(){ 180 | 181 | $id = intval( hubaga_get_option( 'account_page_id' ) ); 182 | $permalink = 1 > $id ? get_home_url() : get_permalink( $id ); 183 | return apply_filters( 'hubaga_get_account_url', $permalink ); 184 | 185 | } 186 | add_filter( 'hubaga_get_account_url', 'esc_url' ); 187 | 188 | /** 189 | * Checks whether or not this is a checkout page 190 | * 191 | * @since 1.0.0 192 | * 193 | * @return bool 194 | */ 195 | function hubaga_is_account_page(){ 196 | 197 | $id = intval( hubaga_get_option( 'account_page_id' ) ); 198 | if( !$id ){ 199 | return false; 200 | } 201 | return is_page( $id ); 202 | 203 | } 204 | 205 | /** 206 | * Prevent any user who cannot 'edit_posts' (subscribers, customers etc) from seeing the admin bar. 207 | * 208 | * @access public 209 | * @param bool $show_admin_bar 210 | * @return bool 211 | */ 212 | function hubaga_disable_admin_bar( $show_admin_bar ){ 213 | return current_user_can( 'edit_posts' ); 214 | } 215 | add_filter( 'show_admin_bar', 'hubaga_disable_admin_bar' ); -------------------------------------------------------------------------------- /includes/data/currencies.php: -------------------------------------------------------------------------------- 1 | esc_html__( 'United Arab Emirates dirham', 'hubaga' ), 5 | 'AFN' => esc_html__( 'Afghan afghani', 'hubaga' ), 6 | 'ALL' => esc_html__( 'Albanian lek', 'hubaga' ), 7 | 'AMD' => esc_html__( 'Armenian dram', 'hubaga' ), 8 | 'ANG' => esc_html__( 'Netherlands Antillean guilder', 'hubaga' ), 9 | 'AOA' => esc_html__( 'Angolan kwanza', 'hubaga' ), 10 | 'ARS' => esc_html__( 'Argentine peso', 'hubaga' ), 11 | 'AUD' => esc_html__( 'Australian dollar', 'hubaga' ), 12 | 'AWG' => esc_html__( 'Aruban florin', 'hubaga' ), 13 | 'AZN' => esc_html__( 'Azerbaijani manat', 'hubaga' ), 14 | 'BAM' => esc_html__( 'Bosnia and Herzegovina convertible mark', 'hubaga' ), 15 | 'BBD' => esc_html__( 'Barbadian dollar', 'hubaga' ), 16 | 'BDT' => esc_html__( 'Bangladeshi taka', 'hubaga' ), 17 | 'BGN' => esc_html__( 'Bulgarian lev', 'hubaga' ), 18 | 'BHD' => esc_html__( 'Bahraini dinar', 'hubaga' ), 19 | 'BIF' => esc_html__( 'Burundian franc', 'hubaga' ), 20 | 'BMD' => esc_html__( 'Bermudian dollar', 'hubaga' ), 21 | 'BND' => esc_html__( 'Brunei dollar', 'hubaga' ), 22 | 'BOB' => esc_html__( 'Bolivian boliviano', 'hubaga' ), 23 | 'BRL' => esc_html__( 'Brazilian real', 'hubaga' ), 24 | 'BSD' => esc_html__( 'Bahamian dollar', 'hubaga' ), 25 | 'BTC' => esc_html__( 'Bitcoin', 'hubaga' ), 26 | 'BTN' => esc_html__( 'Bhutanese ngultrum', 'hubaga' ), 27 | 'BWP' => esc_html__( 'Botswana pula', 'hubaga' ), 28 | 'BYR' => esc_html__( 'Belarusian ruble', 'hubaga' ), 29 | 'BZD' => esc_html__( 'Belize dollar', 'hubaga' ), 30 | 'CAD' => esc_html__( 'Canadian dollar', 'hubaga' ), 31 | 'CDF' => esc_html__( 'Congolese franc', 'hubaga' ), 32 | 'CHF' => esc_html__( 'Swiss franc', 'hubaga' ), 33 | 'CLP' => esc_html__( 'Chilean peso', 'hubaga' ), 34 | 'CNY' => esc_html__( 'Chinese yuan', 'hubaga' ), 35 | 'COP' => esc_html__( 'Colombian peso', 'hubaga' ), 36 | 'CRC' => esc_html__( 'Costa Rican colón', 'hubaga' ), 37 | 'CUC' => esc_html__( 'Cuban convertible peso', 'hubaga' ), 38 | 'CUP' => esc_html__( 'Cuban peso', 'hubaga' ), 39 | 'CVE' => esc_html__( 'Cape Verdean escudo', 'hubaga' ), 40 | 'CZK' => esc_html__( 'Czech koruna', 'hubaga' ), 41 | 'DJF' => esc_html__( 'Djiboutian franc', 'hubaga' ), 42 | 'DKK' => esc_html__( 'Danish krone', 'hubaga' ), 43 | 'DOP' => esc_html__( 'Dominican peso', 'hubaga' ), 44 | 'DZD' => esc_html__( 'Algerian dinar', 'hubaga' ), 45 | 'EGP' => esc_html__( 'Egyptian pound', 'hubaga' ), 46 | 'ERN' => esc_html__( 'Eritrean nakfa', 'hubaga' ), 47 | 'ETB' => esc_html__( 'Ethiopian birr', 'hubaga' ), 48 | 'EUR' => esc_html__( 'Euro', 'hubaga' ), 49 | 'FJD' => esc_html__( 'Fijian dollar', 'hubaga' ), 50 | 'FKP' => esc_html__( 'Falkland Islands pound', 'hubaga' ), 51 | 'GBP' => esc_html__( 'Pound sterling', 'hubaga' ), 52 | 'GEL' => esc_html__( 'Georgian lari', 'hubaga' ), 53 | 'GGP' => esc_html__( 'Guernsey pound', 'hubaga' ), 54 | 'GHS' => esc_html__( 'Ghana cedi', 'hubaga' ), 55 | 'GIP' => esc_html__( 'Gibraltar pound', 'hubaga' ), 56 | 'GMD' => esc_html__( 'Gambian dalasi', 'hubaga' ), 57 | 'GNF' => esc_html__( 'Guinean franc', 'hubaga' ), 58 | 'GTQ' => esc_html__( 'Guatemalan quetzal', 'hubaga' ), 59 | 'GYD' => esc_html__( 'Guyanese dollar', 'hubaga' ), 60 | 'HKD' => esc_html__( 'Hong Kong dollar', 'hubaga' ), 61 | 'HNL' => esc_html__( 'Honduran lempira', 'hubaga' ), 62 | 'HRK' => esc_html__( 'Croatian kuna', 'hubaga' ), 63 | 'HTG' => esc_html__( 'Haitian gourde', 'hubaga' ), 64 | 'HUF' => esc_html__( 'Hungarian forint', 'hubaga' ), 65 | 'IDR' => esc_html__( 'Indonesian rupiah', 'hubaga' ), 66 | 'ILS' => esc_html__( 'Israeli new shekel', 'hubaga' ), 67 | 'IMP' => esc_html__( 'Manx pound', 'hubaga' ), 68 | 'INR' => esc_html__( 'Indian rupee', 'hubaga' ), 69 | 'IQD' => esc_html__( 'Iraqi dinar', 'hubaga' ), 70 | 'IRR' => esc_html__( 'Iranian rial', 'hubaga' ), 71 | 'IRT' => esc_html__( 'Iranian toman', 'hubaga' ), 72 | 'ISK' => esc_html__( 'Icelandic króna', 'hubaga' ), 73 | 'JEP' => esc_html__( 'Jersey pound', 'hubaga' ), 74 | 'JMD' => esc_html__( 'Jamaican dollar', 'hubaga' ), 75 | 'JOD' => esc_html__( 'Jordanian dinar', 'hubaga' ), 76 | 'JPY' => esc_html__( 'Japanese yen', 'hubaga' ), 77 | 'KES' => esc_html__( 'Kenyan shilling', 'hubaga' ), 78 | 'KGS' => esc_html__( 'Kyrgyzstani som', 'hubaga' ), 79 | 'KHR' => esc_html__( 'Cambodian riel', 'hubaga' ), 80 | 'KMF' => esc_html__( 'Comorian franc', 'hubaga' ), 81 | 'KPW' => esc_html__( 'North Korean won', 'hubaga' ), 82 | 'KRW' => esc_html__( 'South Korean won', 'hubaga' ), 83 | 'KWD' => esc_html__( 'Kuwaiti dinar', 'hubaga' ), 84 | 'KYD' => esc_html__( 'Cayman Islands dollar', 'hubaga' ), 85 | 'KZT' => esc_html__( 'Kazakhstani tenge', 'hubaga' ), 86 | 'LAK' => esc_html__( 'Lao kip', 'hubaga' ), 87 | 'LBP' => esc_html__( 'Lebanese pound', 'hubaga' ), 88 | 'LKR' => esc_html__( 'Sri Lankan rupee', 'hubaga' ), 89 | 'LRD' => esc_html__( 'Liberian dollar', 'hubaga' ), 90 | 'LSL' => esc_html__( 'Lesotho loti', 'hubaga' ), 91 | 'LYD' => esc_html__( 'Libyan dinar', 'hubaga' ), 92 | 'MAD' => esc_html__( 'Moroccan dirham', 'hubaga' ), 93 | 'MDL' => esc_html__( 'Moldovan leu', 'hubaga' ), 94 | 'MGA' => esc_html__( 'Malagasy ariary', 'hubaga' ), 95 | 'MKD' => esc_html__( 'Macedonian denar', 'hubaga' ), 96 | 'MMK' => esc_html__( 'Burmese kyat', 'hubaga' ), 97 | 'MNT' => esc_html__( 'Mongolian tögrög', 'hubaga' ), 98 | 'MOP' => esc_html__( 'Macanese pataca', 'hubaga' ), 99 | 'MRO' => esc_html__( 'Mauritanian ouguiya', 'hubaga' ), 100 | 'MUR' => esc_html__( 'Mauritian rupee', 'hubaga' ), 101 | 'MVR' => esc_html__( 'Maldivian rufiyaa', 'hubaga' ), 102 | 'MWK' => esc_html__( 'Malawian kwacha', 'hubaga' ), 103 | 'MXN' => esc_html__( 'Mexican peso', 'hubaga' ), 104 | 'MYR' => esc_html__( 'Malaysian ringgit', 'hubaga' ), 105 | 'MZN' => esc_html__( 'Mozambican metical', 'hubaga' ), 106 | 'NAD' => esc_html__( 'Namibian dollar', 'hubaga' ), 107 | 'NGN' => esc_html__( 'Nigerian naira', 'hubaga' ), 108 | 'NIO' => esc_html__( 'Nicaraguan córdoba', 'hubaga' ), 109 | 'NOK' => esc_html__( 'Norwegian krone', 'hubaga' ), 110 | 'NPR' => esc_html__( 'Nepalese rupee', 'hubaga' ), 111 | 'NZD' => esc_html__( 'New Zealand dollar', 'hubaga' ), 112 | 'OMR' => esc_html__( 'Omani rial', 'hubaga' ), 113 | 'PAB' => esc_html__( 'Panamanian balboa', 'hubaga' ), 114 | 'PEN' => esc_html__( 'Peruvian nuevo sol', 'hubaga' ), 115 | 'PGK' => esc_html__( 'Papua New Guinean kina', 'hubaga' ), 116 | 'PHP' => esc_html__( 'Philippine peso', 'hubaga' ), 117 | 'PKR' => esc_html__( 'Pakistani rupee', 'hubaga' ), 118 | 'PLN' => esc_html__( 'Polish złoty', 'hubaga' ), 119 | 'PRB' => esc_html__( 'Transnistrian ruble', 'hubaga' ), 120 | 'PYG' => esc_html__( 'Paraguayan guaraní', 'hubaga' ), 121 | 'QAR' => esc_html__( 'Qatari riyal', 'hubaga' ), 122 | 'RON' => esc_html__( 'Romanian leu', 'hubaga' ), 123 | 'RSD' => esc_html__( 'Serbian dinar', 'hubaga' ), 124 | 'RUB' => esc_html__( 'Russian ruble', 'hubaga' ), 125 | 'RWF' => esc_html__( 'Rwandan franc', 'hubaga' ), 126 | 'SAR' => esc_html__( 'Saudi riyal', 'hubaga' ), 127 | 'SBD' => esc_html__( 'Solomon Islands dollar', 'hubaga' ), 128 | 'SCR' => esc_html__( 'Seychellois rupee', 'hubaga' ), 129 | 'SDG' => esc_html__( 'Sudanese pound', 'hubaga' ), 130 | 'SEK' => esc_html__( 'Swedish krona', 'hubaga' ), 131 | 'SGD' => esc_html__( 'Singapore dollar', 'hubaga' ), 132 | 'SHP' => esc_html__( 'Saint Helena pound', 'hubaga' ), 133 | 'SLL' => esc_html__( 'Sierra Leonean leone', 'hubaga' ), 134 | 'SOS' => esc_html__( 'Somali shilling', 'hubaga' ), 135 | 'SRD' => esc_html__( 'Surinamese dollar', 'hubaga' ), 136 | 'SSP' => esc_html__( 'South Sudanese pound', 'hubaga' ), 137 | 'STD' => esc_html__( 'São Tomé and Príncipe dobra', 'hubaga' ), 138 | 'SYP' => esc_html__( 'Syrian pound', 'hubaga' ), 139 | 'SZL' => esc_html__( 'Swazi lilangeni', 'hubaga' ), 140 | 'THB' => esc_html__( 'Thai baht', 'hubaga' ), 141 | 'TJS' => esc_html__( 'Tajikistani somoni', 'hubaga' ), 142 | 'TMT' => esc_html__( 'Turkmenistan manat', 'hubaga' ), 143 | 'TND' => esc_html__( 'Tunisian dinar', 'hubaga' ), 144 | 'TOP' => esc_html__( 'Tongan paʻanga', 'hubaga' ), 145 | 'TRY' => esc_html__( 'Turkish lira', 'hubaga' ), 146 | 'TTD' => esc_html__( 'Trinidad and Tobago dollar', 'hubaga' ), 147 | 'TWD' => esc_html__( 'New Taiwan dollar', 'hubaga' ), 148 | 'TZS' => esc_html__( 'Tanzanian shilling', 'hubaga' ), 149 | 'UAH' => esc_html__( 'Ukrainian hryvnia', 'hubaga' ), 150 | 'UGX' => esc_html__( 'Ugandan shilling', 'hubaga' ), 151 | 'USD' => esc_html__( 'United States dollar', 'hubaga' ), 152 | 'UYU' => esc_html__( 'Uruguayan peso', 'hubaga' ), 153 | 'UZS' => esc_html__( 'Uzbekistani som', 'hubaga' ), 154 | 'VEF' => esc_html__( 'Venezuelan bolívar', 'hubaga' ), 155 | 'VND' => esc_html__( 'Vietnamese đồng', 'hubaga' ), 156 | 'VUV' => esc_html__( 'Vanuatu vatu', 'hubaga' ), 157 | 'WST' => esc_html__( 'Samoan tālā', 'hubaga' ), 158 | 'XAF' => esc_html__( 'Central African CFA franc', 'hubaga' ), 159 | 'XCD' => esc_html__( 'East Caribbean dollar', 'hubaga' ), 160 | 'XOF' => esc_html__( 'West African CFA franc', 'hubaga' ), 161 | 'XPF' => esc_html__( 'CFP franc', 'hubaga' ), 162 | 'YER' => esc_html__( 'Yemeni rial', 'hubaga' ), 163 | 'ZAR' => esc_html__( 'South African rand', 'hubaga' ), 164 | 'ZMW' => esc_html__( 'Zambian kwacha', 'hubaga' ), 165 | ); -------------------------------------------------------------------------------- /includes/data/currency_symbols.php: -------------------------------------------------------------------------------- 1 | 'د.إ', 5 | 'AFN' => '؋', 6 | 'ALL' => 'L', 7 | 'AMD' => 'AMD', 8 | 'ANG' => 'ƒ', 9 | 'AOA' => 'Kz', 10 | 'ARS' => '$', 11 | 'AUD' => '$', 12 | 'AWG' => 'ƒ', 13 | 'AZN' => 'AZN', 14 | 'BAM' => 'KM', 15 | 'BBD' => '$', 16 | 'BDT' => '৳ ', 17 | 'BGN' => 'лв.', 18 | 'BHD' => '.د.ب', 19 | 'BIF' => 'Fr', 20 | 'BMD' => '$', 21 | 'BND' => '$', 22 | 'BOB' => 'Bs.', 23 | 'BRL' => 'R$', 24 | 'BSD' => '$', 25 | 'BTC' => '฿', 26 | 'BTN' => 'Nu.', 27 | 'BWP' => 'P', 28 | 'BYR' => 'Br', 29 | 'BZD' => '$', 30 | 'CAD' => '$', 31 | 'CDF' => 'Fr', 32 | 'CHF' => 'CHF', 33 | 'CLP' => '$', 34 | 'CNY' => '¥', 35 | 'COP' => '$', 36 | 'CRC' => '₡', 37 | 'CUC' => '$', 38 | 'CUP' => '$', 39 | 'CVE' => '$', 40 | 'CZK' => 'Kč', 41 | 'DJF' => 'Fr', 42 | 'DKK' => 'DKK', 43 | 'DOP' => 'RD$', 44 | 'DZD' => 'د.ج', 45 | 'EGP' => 'EGP', 46 | 'ERN' => 'Nfk', 47 | 'ETB' => 'Br', 48 | 'EUR' => '€', 49 | 'FJD' => '$', 50 | 'FKP' => '£', 51 | 'GBP' => '£', 52 | 'GEL' => 'ლ', 53 | 'GGP' => '£', 54 | 'GHS' => '₵', 55 | 'GIP' => '£', 56 | 'GMD' => 'D', 57 | 'GNF' => 'Fr', 58 | 'GTQ' => 'Q', 59 | 'GYD' => '$', 60 | 'HKD' => '$', 61 | 'HNL' => 'L', 62 | 'HRK' => 'Kn', 63 | 'HTG' => 'G', 64 | 'HUF' => 'Ft', 65 | 'IDR' => 'Rp', 66 | 'ILS' => '₪', 67 | 'IMP' => '£', 68 | 'INR' => '₹', 69 | 'IQD' => 'ع.د', 70 | 'IRR' => '﷼', 71 | 'IRT' => 'تومان', 72 | 'ISK' => 'kr.', 73 | 'JEP' => '£', 74 | 'JMD' => '$', 75 | 'JOD' => 'د.ا', 76 | 'JPY' => '¥', 77 | 'KES' => 'KSh', 78 | 'KGS' => 'сом', 79 | 'KHR' => '៛', 80 | 'KMF' => 'Fr', 81 | 'KPW' => '₩', 82 | 'KRW' => '₩', 83 | 'KWD' => 'د.ك', 84 | 'KYD' => '$', 85 | 'KZT' => 'KZT', 86 | 'LAK' => '₭', 87 | 'LBP' => 'ل.ل', 88 | 'LKR' => 'රු', 89 | 'LRD' => '$', 90 | 'LSL' => 'L', 91 | 'LYD' => 'ل.د', 92 | 'MAD' => 'د.م.', 93 | 'MDL' => 'MDL', 94 | 'MGA' => 'Ar', 95 | 'MKD' => 'ден', 96 | 'MMK' => 'Ks', 97 | 'MNT' => '₮', 98 | 'MOP' => 'P', 99 | 'MRO' => 'UM', 100 | 'MUR' => '₨', 101 | 'MVR' => '.ރ', 102 | 'MWK' => 'MK', 103 | 'MXN' => '$', 104 | 'MYR' => 'RM', 105 | 'MZN' => 'MT', 106 | 'NAD' => '$', 107 | 'NGN' => '₦', 108 | 'NIO' => 'C$', 109 | 'NOK' => 'kr', 110 | 'NPR' => '₨', 111 | 'NZD' => '$', 112 | 'OMR' => 'ر.ع.', 113 | 'PAB' => 'B/.', 114 | 'PEN' => 'S/.', 115 | 'PGK' => 'K', 116 | 'PHP' => '₱', 117 | 'PKR' => '₨', 118 | 'PLN' => 'zł', 119 | 'PRB' => 'р.', 120 | 'PYG' => '₲', 121 | 'QAR' => 'ر.ق', 122 | 'RMB' => '¥', 123 | 'RON' => 'lei', 124 | 'RSD' => 'дин.', 125 | 'RUB' => '₽', 126 | 'RWF' => 'Fr', 127 | 'SAR' => 'ر.س', 128 | 'SBD' => '$', 129 | 'SCR' => '₨', 130 | 'SDG' => 'ج.س.', 131 | 'SEK' => 'kr', 132 | 'SGD' => '$', 133 | 'SHP' => '£', 134 | 'SLL' => 'Le', 135 | 'SOS' => 'Sh', 136 | 'SRD' => '$', 137 | 'SSP' => '£', 138 | 'STD' => 'Db', 139 | 'SYP' => 'ل.س', 140 | 'SZL' => 'L', 141 | 'THB' => '฿', 142 | 'TJS' => 'ЅМ', 143 | 'TMT' => 'm', 144 | 'TND' => 'د.ت', 145 | 'TOP' => 'T$', 146 | 'TRY' => '₺', 147 | 'TTD' => '$', 148 | 'TWD' => 'NT$', 149 | 'TZS' => 'Sh', 150 | 'UAH' => '₴', 151 | 'UGX' => 'UGX', 152 | 'USD' => '$', 153 | 'UYU' => '$', 154 | 'UZS' => 'UZS', 155 | 'VEF' => 'Bs F', 156 | 'VND' => '₫', 157 | 'VUV' => 'Vt', 158 | 'WST' => 'T', 159 | 'XAF' => 'Fr', 160 | 'XCD' => '$', 161 | 'XOF' => 'Fr', 162 | 'XPF' => 'Fr', 163 | 'YER' => '﷼', 164 | 'ZAR' => 'R', 165 | 'ZMW' => 'ZK', 166 | ); -------------------------------------------------------------------------------- /includes/data/email-template.php: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | <?php echo get_bloginfo( 'name', 'display' ); ?> 14 | 15 | 16 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 113 | 114 | 115 |
73 |
74 | 75 | 76 | 102 | 103 |
77 | 78 | 79 | 82 | 83 | 84 | 85 | 88 | 89 | 90 | 91 | 94 | 95 | 96 | 99 | 100 |
80 |

81 |
86 |

87 |
92 | 93 |
97 | 98 |
101 |
104 | 111 |
112 |
116 | 117 | 118 | 119 | -------------------------------------------------------------------------------- /includes/data/index.php: -------------------------------------------------------------------------------- 1 | method = 'redirect'; 94 | } 95 | 96 | //Setup the token; This allows the user to download a file without logging in 97 | if(!empty ( $_GET['token'] ) ){ 98 | $this->token = hubaga_clean( $_GET['token'] ); 99 | } 100 | 101 | //Setup up the order that is being downloaded 102 | if(!empty ( $_GET['order'] ) ){ 103 | $this->order = hubaga_clean( $_GET['order'] ); 104 | } 105 | 106 | //Setup up the file that is being downloaded 107 | if(!empty ( $_GET['download_key'] ) ){ 108 | $this->download_key = hubaga_clean( $_GET['download_key'] ); 109 | } 110 | 111 | if(! $this->validate_download() OR !$this->process_download() ){ 112 | status_header( WP_Http::FORBIDDEN ); 113 | wp_die( __( 'You are not allowed to download this file.', 'hubaga' ) ); 114 | } 115 | 116 | } 117 | 118 | /** 119 | * Validates a download 120 | * 121 | * @since Hubaga 1.0.0 122 | * @access protected 123 | * 124 | * @return bool 125 | */ 126 | protected function validate_download(){ 127 | 128 | //No order; Abort 129 | if(! $this->order ) return false; 130 | 131 | //No download key; Abort 132 | if(! $this->download_key ) return false; 133 | 134 | //Fetch the order 135 | $order = hubaga_get_order( $this->order ); 136 | 137 | //The order should exist and be marked complete 138 | if(! hubaga_is_order( $order ) ) return false; 139 | if(! hubaga_is_order_complete( $order ) ) return false; 140 | 141 | /** 142 | * The user must be logged in and own the order 143 | * An exception is when there is a token that 144 | * grants the user access to download the order. 145 | * 146 | * Tokens are usually generated when an order is created 147 | * and have a lifetime of 2 hours. 148 | * 149 | */ 150 | $can_user_download = ( get_current_user_id() == $order->customer_id ); 151 | 152 | if(! $can_user_download && $this->token ) { 153 | 154 | $order_token = get_transient( $this->order . '_download_token' ); 155 | if( $order_token && $order_token == $this->token ) { 156 | $can_user_download = true; 157 | } 158 | 159 | } 160 | 161 | if(! $can_user_download ) return false; 162 | 163 | /** 164 | * If we are here; this user can download files from this order 165 | * Just confirm that the download key exists 166 | * in the list of this orders downloads 167 | * 168 | */ 169 | 170 | $downloads = hubaga_get_order_downloads( $order ); 171 | if(! is_array( $downloads ) ) return false; 172 | if(! array_key_exists( $this->download_key, $downloads ) ) return false; 173 | if(! array_key_exists( 'url', $downloads[$this->download_key] ) ) return false; 174 | 175 | //We made it 176 | $this->url = $downloads[$this->download_key]['url']; 177 | if(!empty( $downloads[$this->download_key]['name'] ) ){ 178 | $this->name = sanitize_file_name( $downloads[$this->download_key]['name'] ); 179 | } 180 | $this->get_local_path(); 181 | 182 | return true; 183 | } 184 | 185 | 186 | /** 187 | * Converts a http path into a local path 188 | * 189 | * Wont work unless pretty permalinks are enabled 190 | * @since Hubaga 1.0.0 191 | */ 192 | protected function get_local_path(){ 193 | 194 | $upload_dir = wp_get_upload_dir(); 195 | $base_dir = $upload_dir['basedir']; 196 | $base_url = str_ireplace( 'https://' , 'http://', $upload_dir['baseurl'] ); 197 | $file_url = str_ireplace( 'https://' , 'http://', $this->url ); 198 | 199 | if( stripos( $file_url, $base_url ) == 0 ) { 200 | 201 | //This is a local file 202 | 203 | //Remove query vars 204 | list( $file_url ) = explode( '?', $file_url, 1 ); 205 | list( $file_url ) = explode( '#', $file_url, 1 ); 206 | 207 | //Simply replace the base url with the base dir 208 | $this->path = str_ireplace( $base_url, $base_dir, $file_url ); 209 | 210 | } 211 | } 212 | 213 | /** 214 | * Processes a download 215 | * 216 | * @since Hubaga 1.0.0 217 | * @access private 218 | * 219 | * @return bool 220 | */ 221 | protected function process_download() { 222 | 223 | $method = $this->method; //force 224 | if( hubaga_get_option( 'download_method' ) == 'redirect' ) { 225 | $method = 'redirect'; 226 | } 227 | 228 | //We dont want this url being cached 229 | nocache_headers(); 230 | 231 | //No bots either 232 | header("Robots: none"); 233 | 234 | //In case we are redirecting; abort early 235 | if( $method == 'redirect' && wp_redirect( $this->url, WP_Http::TEMPORARY_REDIRECT ) ) { 236 | exit(); 237 | } 238 | 239 | if(! $this->force_download() ) { 240 | //Force download failed. Try the redirect 241 | if( wp_redirect( $this->url, WP_Http::TEMPORARY_REDIRECT ) ) { 242 | exit(); 243 | } 244 | } 245 | 246 | return false; 247 | } 248 | 249 | /** 250 | * Forces a file to download 251 | * 252 | * @since Hubaga 1.0.0 253 | * @access private 254 | * 255 | * @return bool 256 | */ 257 | protected function force_download() { 258 | 259 | //We dont want buffered data being passed into our content 260 | wp_ob_end_flush_all(); 261 | 262 | //Use the local path in case it is available 263 | $path = $this->url; 264 | if( $this->path ) $path = $this->path; 265 | 266 | 267 | //Set the file size so that the browser can show the percentage downloaded 268 | if ( $size = @filesize( $path ) ) { 269 | header("Content-Length: $size"); 270 | } 271 | 272 | //The downloaded file will be saved using this name 273 | if ( $name = trim( $this->name ) ) { 274 | header("Content-Disposition: attachment;filename=$name"); 275 | } 276 | 277 | //Tell the browser what type of file it is getting 278 | $ext = wp_check_filetype( $path ); 279 | $type = $ext['type']; 280 | $ext = $ext['ext']; 281 | if(! $type ) 282 | $type = 'application/octet-stream'; 283 | 284 | header("Content-Type: $type"); 285 | 286 | /** 287 | * If this evaluates to true; we 288 | * can force download very large files without running 289 | * into any memory problems or max execution times 290 | * As long as the server can fetch the file in the confines 291 | * of the max excecution time; The speed of the customers 292 | * connection does not matter 293 | */ 294 | 295 | if( $this->path OR @ini_get( 'allow_url_fopen' ) == 1 ) { 296 | 297 | if(! @file_exists( $path ) ) return false; 298 | 299 | //Best case senario 300 | flush(); 301 | if( @readfile( $path ) ) exit(); 302 | 303 | // Default to fread; a bigger buffer size means 304 | // the user can download larger files before excution time 305 | // maxes out. It how increases risks of exceeding memory size 306 | 307 | $buffer_size = 2 * 1024 * 1024; //2MB 308 | if ( $handle = @fopen( $path, 'r' ) ) { 309 | while ( ! @feof( $handle ) ) { 310 | echo @fread( $handle, $buffer_size ); 311 | } 312 | 313 | @fclose( $handle ); 314 | exit(); 315 | } 316 | 317 | } 318 | 319 | //Bad News. This will fetch the whole file into memory 320 | //Before releasing it for donwload. Not a problem for small files < 20MB 321 | $res = wp_remote_get($url, $args = array()); 322 | $code= (int) wp_remote_retrieve_response_code( $res ); 323 | 324 | if( $code < 400 && $code > 199 ){ 325 | echo wp_remote_retrieve_body( $res ); 326 | exit(); 327 | }; 328 | 329 | return false; 330 | } 331 | 332 | } 333 | endif; 334 | -------------------------------------------------------------------------------- /includes/elementa/assets/css/datepicker.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Datepicker v0.4.0 3 | * https://github.com/fengyuanchen/datepicker 4 | * 5 | * Copyright (c) 2014-2016 Fengyuan Chen 6 | * Released under the MIT license 7 | * 8 | * Date: 2016-10-15T04:28:09.384Z 9 | */ 10 | .datepicker-container { 11 | font-size: 12px; 12 | line-height: 30px; 13 | position: fixed; 14 | z-index: -1; 15 | top: 0; 16 | left: 0; 17 | width: 210px; 18 | -webkit-user-select: none; 19 | -moz-user-select: none; 20 | -ms-user-select: none; 21 | user-select: none; 22 | background-color: #fff !important; 23 | direction: ltr !important; 24 | -ms-touch-action: none; 25 | touch-action: none; 26 | -webkit-tap-highlight-color: transparent; 27 | -webkit-touch-callout: none; 28 | padding: 4px; 29 | font-weight: bold; 30 | border-radius: 5px; 31 | vertical-align: baseline; 32 | zoom: 1; 33 | *display: inline; 34 | *vertical-align: auto; 35 | -webkit-box-shadow: 0 8px 17px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19); 36 | box-shadow: 0 8px 17px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19); 37 | } 38 | 39 | .datepicker-container:before, 40 | .datepicker-container:after { 41 | position: absolute; 42 | height: 0; 43 | content: ' '; 44 | border: 5px solid transparent; 45 | } 46 | 47 | .datepicker-dropdown { 48 | position: absolute; 49 | z-index: 1; 50 | -webkit-box-sizing: content-box; 51 | -moz-box-sizing: content-box; 52 | box-sizing: content-box; 53 | border: 1px solid #ccc; 54 | } 55 | 56 | .datepicker-inline { 57 | position: static; 58 | } 59 | 60 | .datepicker-top-left, 61 | .datepicker-top-right { 62 | border-top-color: #87929c; 63 | } 64 | 65 | .datepicker-top-left:before, 66 | .datepicker-top-left:after, 67 | .datepicker-top-right:before, 68 | .datepicker-top-right:after { 69 | top: -5px; 70 | left: 10px; 71 | border-top: 0; 72 | } 73 | 74 | .datepicker-top-left:before, 75 | .datepicker-top-right:before { 76 | border-bottom-color: #87929c; 77 | } 78 | 79 | .datepicker-top-left:after, 80 | .datepicker-top-right:after { 81 | top: -4px; 82 | border-bottom-color: #fff; 83 | } 84 | 85 | .datepicker-bottom-left, 86 | .datepicker-bottom-right { 87 | border-bottom-color: #87929c; 88 | } 89 | 90 | .datepicker-bottom-left:before, 91 | .datepicker-bottom-left:after, 92 | .datepicker-bottom-right:before, 93 | .datepicker-bottom-right:after { 94 | bottom: -5px; 95 | left: 10px; 96 | border-bottom: 0; 97 | } 98 | 99 | .datepicker-bottom-left:before, 100 | .datepicker-bottom-right:before { 101 | border-top-color: #39f; 102 | } 103 | 104 | .datepicker-bottom-left:after, 105 | .datepicker-bottom-right:after { 106 | bottom: -4px; 107 | border-top-color: #fff; 108 | } 109 | 110 | .datepicker-top-right:before, 111 | .datepicker-top-right:after, 112 | .datepicker-bottom-right:before, 113 | .datepicker-bottom-right:after { 114 | right: 10px; 115 | left: auto; 116 | } 117 | 118 | .datepicker-panel > ul:before, 119 | .datepicker-panel > ul:after { 120 | display: table; 121 | content: ' '; 122 | } 123 | 124 | .datepicker-panel > ul:after { 125 | clear: both; 126 | } 127 | 128 | .datepicker-panel > ul { 129 | width: 102%; 130 | margin: 0; 131 | padding: 0; 132 | } 133 | 134 | .datepicker-panel > ul > li { 135 | float: left; 136 | width: 30px; 137 | height: 30px; 138 | margin: 0; 139 | padding: 0; 140 | list-style: none; 141 | cursor: pointer; 142 | text-align: center; 143 | 144 | /*background-color: #fff;*/ 145 | } 146 | 147 | .datepicker-panel > ul > li:hover { 148 | background-color: #0275D8; 149 | color: #fff; 150 | } 151 | 152 | .datepicker-panel > ul > li.muted { 153 | color: #aca8aB; 154 | } 155 | 156 | .datepicker-panel > ul > li.picked, 157 | .datepicker-panel > ul > li.picked:hover { 158 | color: #f3f8f8; 159 | background-color: #0275D8; 160 | } 161 | 162 | .datepicker-panel > ul > li.disabled, 163 | .datepicker-panel > ul > li.disabled:hover { 164 | cursor: default; 165 | color: #a3a0a0 !important; 166 | } 167 | 168 | .datepicker-panel > ul > li[data-view='years prev'], 169 | .datepicker-panel > ul > li[data-view='year prev'], 170 | .datepicker-panel > ul > li[data-view='month prev'], 171 | .datepicker-panel > ul > li[data-view='years next'], 172 | .datepicker-panel > ul > li[data-view='year next'], 173 | .datepicker-panel > ul > li[data-view='month next'], 174 | .datepicker-panel > ul > li[data-view='next'] { 175 | font-size: 18px; 176 | } 177 | 178 | .datepicker-panel > ul > li[data-view='years current'], 179 | .datepicker-panel > ul > li[data-view='year current'], 180 | .datepicker-panel > ul > li[data-view='month current'] { 181 | width: 150px; 182 | } 183 | 184 | .datepicker-panel > ul[data-view='years'] > li, 185 | .datepicker-panel > ul[data-view='months'] > li { 186 | line-height: 52.5px; 187 | 188 | width: 52.5px; 189 | height: 52.5px; 190 | } 191 | 192 | .datepicker-panel > ul[data-view='week'] > li, 193 | .datepicker-panel > ul[data-view='week'] > li:hover { 194 | cursor: default; 195 | } 196 | 197 | .datepicker-hide { 198 | display: none; 199 | } 200 | -------------------------------------------------------------------------------- /includes/elementa/assets/js/elementa.js: -------------------------------------------------------------------------------- 1 | 2 | //Allow for external interactions 3 | window.Elementa_Instances = window.Elementa_Instances || {}; 4 | 5 | ( function( $ ) { 6 | 7 | /** 8 | * An Elementa instance 9 | */ 10 | function Elementa ( args ) { 11 | Elementa_Instances[ args.id ] = this; 12 | 13 | this.id = args.id 14 | this.i18 = args.translations 15 | this.$el = $( '#'+ this.id ); 16 | this.check_save = false; 17 | this.args = args 18 | 19 | //Datepickers 20 | if ( typeof ( $.fn.datepicker ) != "undefined" ) { 21 | $.fn.wp_elements_datepicker = $.fn.datepicker.noConflict(); 22 | this.$el.find('.wpe-date-control').wp_elements_datepicker(); 23 | } 24 | 25 | //Colorpickers 26 | if ( typeof ( $.fn.wpColorPicker ) != "undefined" ) { 27 | this.$el.find('.elementa-color').wpColorPicker({ 28 | change: function( event, ui ) { 29 | $( this ).closest( '.elementa-color-wrapper' ).find( '.elementa-color-preview' ).css({ backgroundColor: ui.color.toString() }); 30 | }, 31 | clear: function() { 32 | $( this ).closest( '.elementa-color-wrapper' ).find( '.elementa-color-preview' ).css({ backgroundColor: '' }); 33 | } 34 | }) 35 | } 36 | 37 | //Select boxes 38 | if ( typeof ( $.fn.selectize ) != "undefined" ) { 39 | this.$el.find('select').selectize(); 40 | } 41 | 42 | //Alert boxes 43 | this.$el.find('.alert-close').on('click', function( e ){ 44 | e.preventDefault(); 45 | $( this ).closest('.alert').remove(); 46 | }) 47 | 48 | //Toggle export / import buttons 49 | this.$el.find('.wpe-export-btn').on('click', function( e ){ 50 | e.preventDefault(); 51 | $( this ).siblings( '.wpe-import' ).addClass('d-none'); 52 | $( this ).siblings( '.wpe-export' ).removeClass('d-none'); 53 | }) 54 | 55 | this.$el.find('.wpe-import-btn').on('click', function( e ){ 56 | e.preventDefault(); 57 | $( this ).siblings( '.wpe-import' ).removeClass('d-none'); 58 | $( this ).siblings( '.wpe-export' ).addClass('d-none'); 59 | }) 60 | 61 | //Handle data imports whenever data is imported 62 | var self = this; 63 | this.$el.find('.wpe-finish-import-btn').on('click', function( e ){ 64 | e.preventDefault(); 65 | var importdata = $( this ).siblings( 'textarea' ).val(); 66 | var feedaback_el = $( this ).siblings( '.alert-warning' ).empty().hide(); 67 | 68 | if( importdata.length == 0 ){ 69 | self.log_feedaback( feedaback_el, self.i18.emptyData, 'danger' ); 70 | return; 71 | } 72 | 73 | try { 74 | var _importdata = $.parseJSON( importdata ); 75 | self.log_feedaback( feedaback_el, self.i18.importing, 'info' ); 76 | 77 | if ( _.isEmpty( _importdata )) { 78 | //Was valid json but still empty 79 | self.log_feedaback(feedaback_el, self.i18.emptyJson, 'warning'); 80 | return; 81 | } 82 | 83 | self.log_feedaback(feedaback_el, self.i18.finalising, 'info'); 84 | var _x = $( '' ).val( importdata ); 85 | $( this ).closest('form').append(_x).submit(); 86 | }catch ( error ) { 87 | //Invalid JSON 88 | self.log_feedaback(feedaback_el, self.i18.badFormat, 'danger'); 89 | return; 90 | } 91 | 92 | }); 93 | 94 | //Conditionally display sections 95 | if( args.has_sections ) this.do_sections() 96 | 97 | this.$el.find('.elementa-sub_section-changer').on('click', function( e ){ 98 | e.preventDefault(); 99 | self.args.active_section = $( this ).data('section'); 100 | self.args.active_sub_section = $( this ).data('subSection'); 101 | 102 | self.hide_inactive_sub_sections(); 103 | }) 104 | } 105 | 106 | Elementa.prototype.log_feedaback = function ( el, data, type ) { 107 | return el 108 | .removeClass( 'alert-danger alert-warning alert-info' ) 109 | .addClass('alert-' + type ) 110 | .html( data ) 111 | .show(); 112 | } 113 | 114 | Elementa.prototype.prompt_exit = function () { 115 | // If we haven't been passed the event get the window.event 116 | e = e || window.event; 117 | 118 | // For IE6-8 and Firefox prior to version 4 119 | if ( e ) { 120 | e.returnValue = this.i18.exit_prompt; 121 | } 122 | 123 | window.onbeforeunload = null; 124 | 125 | // For Chrome, Safari, IE8+ and Opera 12+ 126 | return this.i18.exit_prompt; 127 | } 128 | 129 | Elementa.prototype.do_sections = function () { 130 | var self = this 131 | this.args.active_sub_section 132 | this.hide_inactive_sub_sections( this.args.active_section, this.args.active_section ); 133 | 134 | this.$el. 135 | find('.elementa_sub_section_wrapper.elementa_section_' + this.args.active_section ) 136 | .removeClass('d-none'); 137 | 138 | $('.elementa-section-wrapper').on('click', function( e ){ 139 | e.preventDefault(); 140 | 141 | //Abort if the current section was clicked 142 | if( self.args.active_section === $( this ).data('section') ) return; 143 | 144 | //Add the active class to the clicked nav element 145 | $('.elementa-section-wrapper').removeClass('nav-tab-active'); 146 | $( this ).addClass('nav-tab-active'); 147 | 148 | //Save the current section data 149 | self.args.active_section = $( this ).data('section'); 150 | self.args.active_sub_section = $( this ).data('defaultSection'); 151 | 152 | self.hide_inactive_sub_sections(); 153 | 154 | //Hide section links 155 | self.$el.find('.elementa_sub_section_wrapper').addClass('d-none'); 156 | self.$el. 157 | find('.elementa_sub_section_wrapper.elementa_section_' + self.args.active_section ) 158 | .removeClass('d-none'); 159 | }); 160 | 161 | } 162 | 163 | Elementa.prototype.hide_inactive_sub_sections = function () { 164 | var section = this.args.active_section 165 | var sub_section = this.args.active_sub_section 166 | 167 | this.$el.find('[class*="elementa-sub_section-element-"]').addClass('d-none'); 168 | this.$el.find('.elementa-sub_section-element-' + section + '-' + sub_section ).removeClass('d-none'); 169 | } 170 | 171 | $.Elementa = Elementa 172 | } )( jQuery ); 173 | -------------------------------------------------------------------------------- /includes/elementa/elements/alert.php: -------------------------------------------------------------------------------- 1 | "; 38 | 39 | if(! $not_dismissible ) { 40 | 41 | echo ''; 43 | 44 | } 45 | echo "{$args['text']} "; -------------------------------------------------------------------------------- /includes/elementa/elements/button.php: -------------------------------------------------------------------------------- 1 | $value"; 25 | 26 | if (! empty( $description ) ) 27 | echo "

$description

"; 28 | -------------------------------------------------------------------------------- /includes/elementa/elements/card.php: -------------------------------------------------------------------------------- 1 | "; 18 | 19 | //Loop through the cards and display them 20 | foreach( $args['cards'] as $card => $details ) { 21 | 22 | $class = 'col s12 '; 23 | $inner_class = ' '; 24 | if( isset( $details['card_class'] ) ) { 25 | $class .= $details['card_class']; 26 | } 27 | 28 | if( isset( $details['card_inner_class'] ) ) { 29 | $inner_class .= $details['card_inner_class']; 30 | } 31 | 32 | echo "
"; 33 | if( isset( $details['card_image'] ) ) { 34 | $image = esc_url( $details['card_image'] ); 35 | echo "
"; 36 | } 37 | 38 | if( isset( $details['card_content'] ) OR isset( $details['card_title'] )) { 39 | 40 | echo '
'; 41 | if ( isset( $details['card_title'] ) ) 42 | echo "

{$details['card_title']}

"; 43 | 44 | if ( isset( $details['card_content'] ) ) 45 | echo $details['card_content']; 46 | 47 | echo '
'; 48 | 49 | } 50 | 51 | 52 | if( isset( $details['card_action'] ) ) { 53 | echo "
{$details['card_action']}
"; 54 | } 55 | 56 | echo '
'; 57 | 58 | } 59 | 60 | echo ""; 61 | if( isset( $args['card_wrapper_end'] ) ) { 62 | echo $args['card_wrapper_end']; 63 | } 64 | -------------------------------------------------------------------------------- /includes/elementa/elements/checkbox.php: -------------------------------------------------------------------------------- 1 | "; 23 | -------------------------------------------------------------------------------- /includes/elementa/elements/color.php: -------------------------------------------------------------------------------- 1 |
"; 18 | 19 | echo ""; 20 | 21 | if (! empty( $description ) ) { 22 | echo "

$description

"; 23 | } 24 | echo ""; // elementa-color-wrapper -------------------------------------------------------------------------------- /includes/elementa/elements/date.php: -------------------------------------------------------------------------------- 1 | "; 17 | 18 | if (! empty( $description ) ) { 19 | echo "

$description

"; 20 | } 21 | -------------------------------------------------------------------------------- /includes/elementa/elements/email.php: -------------------------------------------------------------------------------- 1 | "; 18 | 19 | if (! empty( $description ) ) { 20 | echo "

$description

"; 21 | } 22 | -------------------------------------------------------------------------------- /includes/elementa/elements/import.php: -------------------------------------------------------------------------------- 1 | get_options() ) ); 9 | ?> 10 | 11 |
12 | Export 13 | Import 14 | 15 |
16 | 17 | 18 | 19 | 20 |
21 | 22 |
23 | 24 | 25 |
26 |
-------------------------------------------------------------------------------- /includes/elementa/elements/list_group.php: -------------------------------------------------------------------------------- 1 | 17 | -------------------------------------------------------------------------------- /includes/elementa/elements/multiselect.php: -------------------------------------------------------------------------------- 1 | "; 17 | 18 | //Loop over options and print them 19 | if ( is_array( $options ) ) { 20 | 21 | foreach ( $options as $key => $val ) { 22 | 23 | $value = esc_attr( $key ); 24 | $current = $args['_value']; 25 | 26 | echo ""; 40 | } 41 | 42 | } 43 | echo ""; 44 | 45 | 46 | if (! empty( $description ) ) { 47 | echo "

$description

"; 48 | } -------------------------------------------------------------------------------- /includes/elementa/elements/number.php: -------------------------------------------------------------------------------- 1 | "; 18 | 19 | if (! empty( $description ) ) { 20 | echo "

$description

"; 21 | } 22 | -------------------------------------------------------------------------------- /includes/elementa/elements/password.php: -------------------------------------------------------------------------------- 1 | "; 18 | 19 | if (! empty( $description ) ) { 20 | echo "

$description

"; 21 | } 22 | -------------------------------------------------------------------------------- /includes/elementa/elements/radio.php: -------------------------------------------------------------------------------- 1 | $label ) { 15 | echo "

"; 20 | } 21 | 22 | if (! empty( $descprition ) ) { 23 | echo "

$descprition

"; 24 | } 25 | -------------------------------------------------------------------------------- /includes/elementa/elements/range.php: -------------------------------------------------------------------------------- 1 | "; 33 | 34 | // The description 35 | if (! empty( $description ) ) { 36 | echo "

$description

"; 37 | } 38 | -------------------------------------------------------------------------------- /includes/elementa/elements/raw.php: -------------------------------------------------------------------------------- 1 | "; 15 | echo ""; 16 | 17 | if (! empty( $description ) ) 18 | echo "

$description

"; 19 | -------------------------------------------------------------------------------- /includes/elementa/elements/search.php: -------------------------------------------------------------------------------- 1 | "; 18 | 19 | if (! empty( $description ) ) { 20 | echo "

$description

"; 21 | } 22 | -------------------------------------------------------------------------------- /includes/elementa/elements/select.php: -------------------------------------------------------------------------------- 1 | "; 18 | 19 | //Loop over options and print them 20 | if ( is_array( $options ) ) { 21 | 22 | foreach ( $options as $key => $val ) { 23 | 24 | $value = esc_attr( $key ); 25 | $current = $args['_value']; 26 | 27 | echo ""; 41 | } 42 | 43 | } 44 | echo ""; 45 | 46 | 47 | if (! empty( $description ) ) { 48 | echo "

$description

"; 49 | } -------------------------------------------------------------------------------- /includes/elementa/elements/switch.php: -------------------------------------------------------------------------------- 1 | "; 20 | -------------------------------------------------------------------------------- /includes/elementa/elements/text.php: -------------------------------------------------------------------------------- 1 | "; 18 | 19 | if (! empty( $description ) ) { 20 | echo "

$description

"; 21 | } 22 | -------------------------------------------------------------------------------- /includes/elementa/elements/textarea.php: -------------------------------------------------------------------------------- 1 | $value"; 19 | 20 | if (! empty( $description ) ) { 21 | echo "

$description

"; 22 | } 23 | -------------------------------------------------------------------------------- /includes/elementa/elements/title.php: -------------------------------------------------------------------------------- 1 | "; 18 | 19 | if ( isset( $args['title'] ) ) { 20 | echo '

' . $args['title'] . '

'; 21 | } 22 | 23 | if ( isset( $args['subtitle'] ) ) { 24 | echo $args['subtitle']; 25 | } 26 | 27 | if (! empty( $args['description'] ) ) { 28 | echo "
{$args['description']}"; 29 | } 30 | 31 | echo '
'; 32 | -------------------------------------------------------------------------------- /includes/elementa/index.php: -------------------------------------------------------------------------------- 1 | 17 |
18 |

Hubaga

19 | 42 | $sub_sections ) { 46 | 47 | if( !is_array( $sub_sections ) ) continue; 48 | if( count( $sub_sections ) < 2 ) continue; 49 | 50 | $section = sanitize_html_class($section); 51 | echo ""; 60 | } 61 | 62 | ?> 63 |
64 | render_element( $element ); 68 | } 69 | 70 | //Keep the following lines if you would like elementa to save options for you 71 | wp_nonce_field( 'elementa' ); 72 | echo ""; 73 | ?> 74 |
75 | 76 |
77 | 82 | element_pluck('section') ); 31 | $sub_sections = array_unique ( $this->element_pluck('subsection') ); 32 | ; 33 | if ( count( $sections ) > 0 ) : 34 | ?> 35 |
36 |
37 |
38 |
39 | $_section"; 56 | 57 | } 58 | 59 | ?> 60 |
61 |
62 |
63 | render_element( $element ); 66 | } 67 | //Keep this line in your templates else options wont be saved 68 | wp_nonce_field( 'wp-elements' ); 69 | ?> 70 |
71 |
72 |
73 | 95 | 96 | 99 | 100 |
101 |
102 |
103 | render_element( $element ); 106 | } 107 | 108 | //Keep this line in your templates else options wont be saved 109 | wp_nonce_field( 'wp-elements' ); 110 | ?> 111 |
112 |
113 |
114 | create_pages(); 27 | $this->create_options(); 28 | $this->create_roles(); 29 | 30 | } 31 | 32 | /** 33 | * Create pages that the plugin relies on, storing page IDs in variables. 34 | */ 35 | public function create_pages() { 36 | 37 | $pages = apply_filters( 'hubaga_create_pages', array( 38 | 'checkout' => array( 39 | 'name' => _x( 'checkout', 'Page slug', 'hubaga' ), 40 | 'title' => _x( 'Checkout', 'Page title', 'hubaga' ), 41 | 'content' => '[h-checkout]', 42 | ), 43 | 'account' => array( 44 | 'name' => _x( 'account', 'Page slug', 'hubaga' ), 45 | 'title' => _x( 'Account Details', 'Page title', 'hubaga' ), 46 | 'content' => '[h-account]', 47 | ), 48 | ) ); 49 | $return = array(); 50 | 51 | foreach ( $pages as $key => $page ) { 52 | $page_id = wp_insert_post( array( 53 | 'post_status' => 'publish', 54 | 'post_type' => 'page', 55 | 'post_author' => 1, 56 | 'post_name' => $page['name'], 57 | 'post_title' => $page['title'], 58 | 'post_content' => $page['content'], 59 | 'comment_status' => 'closed', 60 | ) ); 61 | $return[$key] = $page_id; 62 | } 63 | 64 | set_transient( 'hubaga_core_pages', $return ); 65 | } 66 | 67 | /** 68 | * Default options. 69 | * 70 | * Sets up the default options used on the settings page. 71 | */ 72 | private static function create_options() { 73 | 74 | $pages = get_transient( 'hubaga_core_pages' ); 75 | $to_save = array(); 76 | 77 | // Include settings so that we can run through defaults 78 | $settings = require plugin_dir_path( __FILE__ ) . 'admin/settings.php'; 79 | foreach( $settings as $id=>$args ){ 80 | if(isset($args['default'])){ 81 | $to_save[$id] = $args['default']; 82 | } 83 | } 84 | 85 | //Paypal settings 86 | $paypal = require plugin_dir_path( __FILE__ ) . 'checkout/gateways/paypal/settings-paypal.php'; 87 | foreach( $paypal as $id=>$args ){ 88 | if(isset($args['default'])){ 89 | $to_save[$id] = $args['default']; 90 | } 91 | } 92 | $to_save['is_gateway_paypal_active'] = 1; 93 | 94 | //Set shop pages 95 | foreach (get_transient( 'hubaga_core_pages' ) as $page => $id) { 96 | $to_save["{$page}_page_id"] = $id; 97 | } 98 | add_option( 'hubaga', $to_save ); 99 | } 100 | 101 | 102 | /** 103 | * Create roles and capabilities. 104 | */ 105 | public static function create_roles() { 106 | // Customer role 107 | add_role( 'customer', 'Customer', array( 'read' => true ) ); 108 | } 109 | 110 | } 111 | -------------------------------------------------------------------------------- /includes/notifications.php: -------------------------------------------------------------------------------- 1 | blogname = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ); 59 | $this->admin_email = wp_specialchars_decode( get_option( 'admin_email' ), ENT_QUOTES ); 60 | $this->setup_actions(); 61 | 62 | /** 63 | * Fires after Hubaga Notifications handler initializes 64 | * 65 | * @since 1.0.0 66 | * 67 | */ 68 | do_action( 'hubaga_notifications_init' ); 69 | } 70 | 71 | /** 72 | * Setup the hooks. Overwrite this hooks in your themes for custom looks 73 | * 74 | * @since Hubaga 1.0.0 75 | * @access private 76 | * 77 | * @uses add_action() To add various actions 78 | */ 79 | private function setup_actions() { 80 | 81 | //Order created 82 | add_action( 'hubaga_order_created', array( $this, 'order_created' ), 10, 3 ); 83 | 84 | //Order refunded 85 | add_action( 'hubaga_order_refunded', array( $this, 'order_refunded' ), 10, 3 ); 86 | 87 | //Order cancelled 88 | add_action( 'hubaga_order_cancelled', array( $this, 'order_cancelled' ), 10, 3 ); 89 | 90 | //Order failed 91 | add_action( 'hubaga_order_failed', array( $this, 'order_failed' ), 10, 3 ); 92 | 93 | //Order completed 94 | add_action( 'hubaga_order_completed', array( $this, 'order_completed' ), 10, 3 ); 95 | 96 | //Customer created 97 | add_action( 'hubaga_customer_created', array( $this, 'send_new_customer_email' ), 10, 2 ); 98 | 99 | } 100 | 101 | /** 102 | * Delivers emails 103 | * 104 | * @since Hubaga 1.0.0 105 | * 106 | */ 107 | public function send_emails( $subject, $body, $emails ) { 108 | foreach( array_unique($emails) as $email ) { 109 | $this->send_mail( $email, $subject, $body ); 110 | } 111 | } 112 | 113 | /** 114 | * Sends an email 115 | * 116 | * @since Hubaga 1.0.0 117 | * 118 | */ 119 | public function send_mail( $to, $subject, $body ) { 120 | 121 | //Set email variables 122 | $email_header_bg = hubaga_get_option('mailer_header_bg'); 123 | $email_header_color = hubaga_get_option('mailer_header_color'); 124 | $business_address = hubaga_get_option('mailer_business_address'); 125 | $email_header_title = $this->blogname; 126 | if(isset($body['title'])){ 127 | $email_header_subtitle = $body['title']; 128 | } 129 | $email_content = $body['content']; 130 | 131 | ob_start(); 132 | require hubaga_get_includes_path( 'data/email-template.php' ); 133 | $message = ob_get_clean(); 134 | 135 | add_filter( 'wp_mail_content_type', array( $this, 'mail_content_type' ) ); 136 | add_filter( 'wp_mail_from', array( $this, 'mail_from' ) ); 137 | add_filter( 'wp_mail_from_name', array( $this, 'mail_from_name' ) ); 138 | 139 | $return = wp_mail( $to, $subject, $message ); 140 | 141 | remove_filter( 'wp_mail_content_type', array( $this, 'mail_content_type' ) ); 142 | remove_filter( 'wp_mail_from', array( $this, 'mail_from' ) ); 143 | remove_filter( 'wp_mail_from_name', array( $this, 'mail_from_name' ) ); 144 | 145 | return $return; 146 | } 147 | 148 | /** 149 | * Returns the email content type 150 | * 151 | * @since Hubaga 1.0.0 152 | * 153 | */ 154 | public function mail_content_type() { 155 | return 'text/html'; 156 | } 157 | 158 | /** 159 | * Returns the email from 160 | * 161 | * @since Hubaga 1.0.0 162 | * 163 | */ 164 | public function mail_from( $_email ) { 165 | 166 | $email = sanitize_email( hubaga_get_option( 'mailer_from_email' ) ); 167 | if( is_email( $email ) ){ 168 | return $email; 169 | } 170 | return $_email; 171 | 172 | } 173 | 174 | /** 175 | * Returns the email from name 176 | * 177 | * @since Hubaga 1.0.0 178 | * 179 | */ 180 | public function mail_from_name( $_from ) { 181 | 182 | $from = hubaga_get_option( 'mailer_from_name' ); 183 | if( $from ){ 184 | return $from; 185 | } 186 | return $_from; 187 | 188 | } 189 | 190 | /** 191 | * Sends an email to admin and customer when an order is complete 192 | * 193 | * @since Hubaga 1.0.0 194 | * 195 | */ 196 | public function order_completed( $order ) { 197 | 198 | $emails = array( 199 | hubaga_get_order_customer_email( $order ), 200 | $this->admin_email 201 | ); 202 | 203 | $subject = sprintf( esc_html__( "(%s) - Your order is complete", 'hubaga' ), $this->blogname ); 204 | $title = esc_html( sprintf( 205 | __( "Hi %s. Your recent order (#%s) is complete.", 'hubaga' ), 206 | hubaga_get_order_customer_name( $order ), 207 | $order->ID 208 | ) ); 209 | 210 | $body = array( 211 | 'title' => $title, 212 | 'content'=> $this->order_details( $order ) , 213 | ); 214 | 215 | $this->send_emails( $subject, $body, $emails ); 216 | } 217 | 218 | /** 219 | * Sends an email when an order fails 220 | * 221 | * @since Hubaga 1.0.0 222 | * 223 | */ 224 | public function order_failed( $order ) { 225 | 226 | $emails = array( 227 | hubaga_get_order_customer_email( $order ), 228 | $this->admin_email 229 | ); 230 | 231 | $subject = sprintf( esc_html__( "(%s) - Your order has failed processing", 'hubaga' ), $this->blogname ); 232 | $title = esc_html( sprintf( 233 | __( "Hi %s. Your recent order (#%s) has been marked as failed.", 'hubaga' ), 234 | hubaga_get_order_customer_name( $order ), 235 | $order->ID 236 | ) ); 237 | 238 | $body = array( 239 | 'title' => $title, 240 | 'content'=> $this->order_details( $order ) , 241 | ); 242 | 243 | $this->send_emails( $subject, $body, $emails ); 244 | } 245 | 246 | /** 247 | * Sends an email when an order is refunded 248 | * 249 | * @since Hubaga 1.0.0 250 | * 251 | */ 252 | public function order_refunded( $order ) { 253 | 254 | $emails = array( 255 | hubaga_get_order_customer_email( $order ), 256 | $this->admin_email 257 | ); 258 | 259 | $subject = sprintf( esc_html__( "(%s) - Your order has been refunded", 'hubaga' ), $this->blogname ); 260 | $title = esc_html( sprintf( 261 | __( "Hi %s. Your order (#%s) has been refunded.", 'hubaga' ), 262 | hubaga_get_order_customer_name( $order ), 263 | $order->ID 264 | ) ); 265 | 266 | $body = array( 267 | 'title' => $title, 268 | 'content'=> $this->order_details( $order ) , 269 | ); 270 | 271 | $this->send_emails( $subject, $body, $emails ); 272 | } 273 | 274 | /** 275 | * Sends an email when an order is cancelled 276 | * 277 | * @since Hubaga 1.0.0 278 | * 279 | */ 280 | public function order_cancelled( $order ) { 281 | 282 | $emails = array( 283 | hubaga_get_order_customer_email( $order ), 284 | $this->admin_email 285 | ); 286 | 287 | $subject = sprintf( esc_html__( "(%s) - Order cancelled", 'hubaga' ), $this->blogname ); 288 | $title = esc_html( sprintf( 289 | __( "Hi %s. Your order (#%s) was cancelled.", 'hubaga' ), 290 | hubaga_get_order_customer_name( $order ), 291 | $order->ID 292 | ) ); 293 | 294 | $body = array( 295 | 'title' => $title, 296 | 'content'=> $this->order_details( $order ) , 297 | ); 298 | 299 | $this->send_emails( $subject, $body, $emails ); 300 | } 301 | 302 | /** 303 | * Sends an email when an order is created 304 | * 305 | * @since Hubaga 1.0.0 306 | * 307 | */ 308 | public function order_created( $order ) { 309 | 310 | $emails = array( 311 | hubaga_get_order_customer_email( $order ), 312 | $this->admin_email 313 | ); 314 | 315 | $subject = sprintf( esc_html__( "(%s) - New order", 'hubaga' ), $this->blogname ); 316 | $title = esc_html( sprintf( 317 | __( "Hi %s. Here are details about your recent order.", 'hubaga' ), 318 | hubaga_get_order_customer_name( $order ), 319 | $order->ID 320 | ) ); 321 | 322 | $body = array( 323 | 'title' => $title, 324 | 'content'=> $this->order_details( $order ) , 325 | ); 326 | 327 | $this->send_emails( $subject, $body, $emails ); 328 | } 329 | 330 | 331 | /** 332 | * Sends an to new customers 333 | * 334 | * @since Hubaga 1.0.0 335 | * 336 | */ 337 | public function send_new_customer_email( $customer_id, $customer_data ) { 338 | 339 | $emails = array( $customer_data['user_email'] ); 340 | $subject = sprintf( esc_html__( "(%s) - Account created", 'hubaga' ), $this->blogname ); 341 | $title = esc_html( sprintf( 342 | __( "Hi %s. Your account at %s has been created.", 'hubaga' ), 343 | $customer_data['user_login'], 344 | $this->blogname 345 | ) ); 346 | 347 | $body = array( 348 | 'title' => $title, 349 | 'content'=> esc_html( sprintf( 350 | __( "Your username is %s and your password is %s. You can login here: %s ", 'hubaga' ), 351 | $customer_data['user_login'], 352 | $customer_data['user_pass'], 353 | hubaga_get_account_url() 354 | ) ) , 355 | ); 356 | 357 | $this->send_emails( $subject, $body, $emails ); 358 | 359 | } 360 | 361 | /** 362 | * Generates order details HTML 363 | */ 364 | function order_details( $order ){ 365 | //total, subtotal, discount, product, gateway, email, download 366 | $order_details = hubaga_get_order_details( $order, false ); 367 | if( hubaga_is_order_complete( $order ) ){ 368 | $order_details['More'] = esc_html( sprintf( 369 | __( "%sView more details and download your files. %s", 'hubaga' ), 370 | ''; 376 | 377 | foreach( $order_details as $left => $right ){ 378 | $return .= ' 379 | 380 | ' . $left . ' 381 | ' . $right . ' 382 | 383 | '; 384 | } 385 | return $return . ''; 386 | 387 | } 388 | 389 | } 390 | 391 | endif; // class_exists check 392 | -------------------------------------------------------------------------------- /includes/product-class.php: -------------------------------------------------------------------------------- 1 | init( $product->data ); 37 | return; 38 | } elseif ( is_array( $product ) ) { 39 | $this->init( $product ); 40 | return; 41 | } 42 | 43 | //Try fetching the product by its post id 44 | if ( ! empty( $product ) && is_numeric( $product ) ) { 45 | $product = absint( $product ); 46 | 47 | if ( $data = self::get_data_by( 'id', $product ) ) { 48 | $this->init( $data ); 49 | return; 50 | } 51 | } 52 | 53 | 54 | //If we are here then the product does not exist 55 | $this->init( array() ); 56 | } 57 | 58 | /** 59 | * Sets up object properties 60 | * 61 | * @param array $data contains product details 62 | */ 63 | public function init( $data ) { 64 | 65 | $data = $this->sanitize_product_data( $data ); 66 | $this->data = $data; 67 | $this->ID = $data['ID']; 68 | 69 | } 70 | 71 | /** 72 | * Fetch a product from the db/cache 73 | * 74 | * @global wpdb $wpdb WordPress database abstraction object. 75 | * 76 | * @param string $field The field to query against: At the moment only ID is allowed 77 | * @param string|int $value The field value 78 | * @return array|false array of product details on success. False otherwise. 79 | */ 80 | public function get_data_by( $field, $value ) { 81 | global $wpdb; 82 | 83 | // 'ID' is an alias of 'id'. 84 | if ( 'ID' === $field ) { 85 | $field = 'id'; 86 | } 87 | 88 | if ( 'id' == $field ) { 89 | // Make sure the value is numeric to avoid casting objects, for example, 90 | // to int 1. 91 | if ( ! is_numeric( $value ) ) 92 | return false; 93 | $value = intval( $value ); 94 | if ( $value < 1 ) 95 | return false; 96 | } else { 97 | return false; 98 | } 99 | 100 | if ( !$value ) 101 | return false; 102 | 103 | 104 | if ( $product = wp_cache_get( $value, 'h_products' ) ) 105 | return $product; 106 | 107 | $post_type = hubaga_get_product_post_type(); 108 | $_product = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->posts} WHERE ID = %d LIMIT 1", $value ) ); 109 | if ( !$_product || $_product->post_type != $post_type ) 110 | return false; 111 | 112 | //So the product exists; great 113 | $product = array(); 114 | $product['ID'] = $_product->ID; 115 | $product['post_date'] = $_product->post_date; 116 | $product['post_modified'] = $_product->post_modified; 117 | $product['post_status'] = $_product->post_status; 118 | $product['post_title'] = $_product->post_title; 119 | $product['price'] = get_post_meta( $_product->ID, '_product_price', true ); 120 | $product['sell_count'] = get_post_meta( $_product->ID, '_product_sell_count', true ); 121 | $product['short_description'] = get_post_meta( $_product->ID, '_product_short_description', true ); 122 | $product['type'] = get_post_meta( $_product->ID, '_product_type', true ); 123 | $product['download_url'] = get_post_meta( $_product->ID, '_product_download_url', true ); 124 | $product['download_name'] = get_post_meta( $_product->ID, '_product_download_name', true ); 125 | 126 | //Update the cache with out data 127 | wp_cache_add( $product['ID'], $product, 'h_products' ); 128 | 129 | return $this->sanitize_product_data( $product ); 130 | } 131 | 132 | /** 133 | * Sanitizes product data 134 | * 135 | * @since 1.0.0 136 | * @access public 137 | * 138 | * @return array the sanitized data 139 | */ 140 | public function sanitize_product_data( $data ) { 141 | 142 | $return = array( 143 | 'ID' => null, 144 | 'post_date' => null, 145 | 'post_modified' => null, 146 | 'post_status' => 'draft', 147 | 'post_title' => null, 148 | 'price' => 0, 149 | 'download_name' => 'download.zip', 150 | 'download_url' => null, 151 | 'short_description' => null, 152 | 'type' => 'normal', 153 | 'sell_count' => 0, 154 | ); 155 | 156 | $product_types = hubaga_get_product_types(); 157 | 158 | //Arrays only please 159 | if (! is_array( $data ) ) 160 | return $return; 161 | 162 | if ( hubaga_is_array_key_valid( $data, 'ID', 'is_numeric' ) ) 163 | $return['ID'] = absint( $data['ID'] ); 164 | 165 | if ( hubaga_is_array_key_valid( $data, 'post_date', 'is_string' )) 166 | $return['post_date'] = $data['post_date']; 167 | 168 | if ( hubaga_is_array_key_valid( $data, 'post_modified', 'is_string' )) 169 | $return['post_modified'] = $data['post_modified']; 170 | 171 | if ( hubaga_is_array_key_valid( $data, 'post_status', 'is_string' )) 172 | $return['post_status'] = $data['post_status']; 173 | 174 | if ( hubaga_is_array_key_valid( $data, 'post_title' , 'is_string' )) 175 | $return['post_title'] = $data['post_title']; 176 | 177 | if ( hubaga_is_array_key_valid( $data, 'price' , 'is_numeric' )) 178 | $return['price'] = floatval( $data['price'] ); 179 | 180 | if ( hubaga_is_array_key_valid( $data, 'download_url', 'is_string' )) 181 | $return['download_url'] = $data['download_url'] ; 182 | 183 | if ( hubaga_is_array_key_valid( $data, 'download_name', 'is_string' )) 184 | $return['download_name'] = $data['download_name'] ; 185 | 186 | if ( hubaga_is_array_key_valid( $data, 'short_description', 'is_string' )) 187 | $return['short_description'] = $data['short_description'] ; 188 | 189 | if ( hubaga_is_array_key_valid( $data, 'type', 'is_string' ) && array_key_exists( $data['type'], $product_types)) 190 | $return['type'] = $data['type']; 191 | 192 | if ( hubaga_is_array_key_valid( $data, 'sell_count', 'is_numeric' )) 193 | $return['sell_count'] = absint( $data['sell_count'] ); 194 | 195 | return $return; 196 | } 197 | 198 | /** 199 | * Magic method for checking the existence of a certain custom field. 200 | * 201 | * @since 1.0.0 202 | * @access public 203 | * 204 | * @return bool Whether the given product field is set. 205 | */ 206 | public function __isset( $key ) { 207 | 208 | if ( $key == 'id' ) { 209 | $key = 'ID'; 210 | } 211 | return isset( $this->data[$key] ) && $this->data[$key] != null; 212 | 213 | } 214 | 215 | /** 216 | * Magic method for accessing custom fields. 217 | * 218 | * @since 1.0.0 219 | * @access public 220 | * 221 | * @param string $key Product meta key to retrieve. 222 | * @return mixed Value of the given product meta key (if set). If `$key` is 'id', the product ID. 223 | */ 224 | public function __get( $key ) { 225 | 226 | if ( $key == 'id' ) { 227 | $key = 'ID'; 228 | } 229 | 230 | if( $key == 'price' ) { 231 | $value = hubaga_format_price( $this->data['price'] ); 232 | } else { 233 | $value = $this->data[$key]; 234 | } 235 | 236 | return apply_filters( "hubaga_product_{$key}", $value, $this ); 237 | } 238 | 239 | /** 240 | * Magic method for setting custom product fields. 241 | * 242 | * This method does not update custom fields in the database. It only stores 243 | * the value on the H_Product instance. 244 | * 245 | * @since 1.0.0 246 | * @access public 247 | * 248 | */ 249 | public function __set( $key, $value ) { 250 | 251 | if ( 'id' == strtolower( $key ) ) { 252 | 253 | $this->ID = $value; 254 | $this->data['ID'] = $value; 255 | return; 256 | 257 | } 258 | 259 | $this->data[$key] = $value; 260 | 261 | } 262 | 263 | /** 264 | * Saves the current product to the database 265 | * 266 | * 267 | * @since 1.0.0 268 | * @access public 269 | * 270 | */ 271 | public function save() { 272 | 273 | $data = $this->sanitize_product_data( $this->data ); 274 | 275 | if(! $data[ 'ID' ] ) 276 | return false; 277 | 278 | $id = $data[ 'ID' ]; 279 | unset( $data['ID'] ); 280 | unset( $data['post_date'] ); 281 | unset( $data['post_modified'] ); 282 | unset( $data['post_status'] ); 283 | 284 | foreach ( $data as $key => $value ){ 285 | $key = trim($key); 286 | $key = "_product_$key"; 287 | update_post_meta( $id, $key, $value ); 288 | } 289 | 290 | //Update the cache with our new data 291 | wp_cache_delete( $id, 'h_products' ); 292 | wp_cache_add($id, $this->data, 'h_products' ); 293 | 294 | return true; 295 | } 296 | 297 | ////////### Conditionals #####/////// 298 | 299 | /** 300 | * Determine whether the product exists in the database. 301 | * 302 | * @since 1.0.0 303 | * @access public 304 | * 305 | * @return bool True if product exists in the database, false if not. 306 | */ 307 | public function exists() { 308 | return null != $this->ID; 309 | } 310 | 311 | /** 312 | * Determines whether this product has been published 313 | * 314 | * @since 1.0.0 315 | * @access public 316 | * 317 | * @return bool True if product exists in the database, false if not. 318 | */ 319 | public function is_published() { 320 | return $this->post_status == 'publish'; 321 | } 322 | 323 | /** 324 | * Checks whether an product is free or not 325 | * 326 | * @return bool 327 | */ 328 | public function is_free() { 329 | $is_free = !( $this->price > 0 ); 330 | return apply_filters( "hubaga_is_product_free", $is_free, $this ); 331 | } 332 | 333 | /** 334 | * Checks whether or not a given product can be bought 335 | * 336 | * @return bool 337 | */ 338 | public function can_buy() { 339 | $can_buy = ( $this->is_product() && $this->is_published() ); 340 | return apply_filters( "hubaga_can_buy_product", $can_buy, $this ); 341 | } 342 | 343 | /** 344 | * Checks whether this is a real product and is saved to the database 345 | * 346 | * @return bool 347 | */ 348 | public function is_product() { 349 | $is_product = ( $this->exists() && get_post_type( $this->ID ) == hubaga_get_product_post_type() ); 350 | return apply_filters( "hubaga_is_product", $is_product, $this ); 351 | } 352 | 353 | /** 354 | * Returns the product view shortcode 355 | * 356 | * @return string 357 | */ 358 | public function product_shortcode() { 359 | return '[h-product ID="' . $this->ID .'"]'; 360 | } 361 | 362 | /** 363 | * Returns the buy button shortcode 364 | * 365 | * @return string 366 | */ 367 | public function buy_shortcode() { 368 | return '[h-buy-button ID="' . $this->ID .'"] BUY [/h-buy-button]'; 369 | } 370 | 371 | /** 372 | * Increases a products sell count 373 | * 374 | * @return bool 375 | */ 376 | public function update_sell_count( $by = 1 ){ 377 | $sell_count = $this->sell_count + $by; 378 | $this->sell_count =$sell_count; 379 | return $this->save(); 380 | } 381 | 382 | /** 383 | * Fetches all product data 384 | * 385 | * @return array an array of order data 386 | */ 387 | public function get_all_data(){ 388 | return $this->data; 389 | } 390 | } 391 | -------------------------------------------------------------------------------- /includes/product-widget.php: -------------------------------------------------------------------------------- 1 | 'hubaga_widget_product', 18 | 'description' => esc_html__( 'Display a product in the sidebar.', 'hubaga' ), 19 | 'customize_selective_refresh' => true, 20 | ) ); 21 | 22 | $this->products = hubaga_elementa()->get_data( 'posts', array( 23 | 'numberposts' => '-1', 24 | 'post_type' => hubaga_get_product_post_type(), 25 | 'post_status' => 'publish', 26 | )); 27 | } 28 | 29 | /** 30 | * Output the HTML for this widget. 31 | * 32 | * @access public 33 | * 34 | * @param array $args An array of standard parameters for widgets in this theme. 35 | * @param array $instance An array of settings for this widget instance. 36 | */ 37 | public function widget( $args, $instance ) { 38 | 39 | $_args = array( 40 | 'id' => isset( $instance['product_id'] ) && array_key_exists($instance['product_id'], $this->products ) ? $instance['product_id'] : 0, 41 | 'class' => '', 42 | ); 43 | 44 | echo $args['before_widget']; 45 | 46 | if ( !empty($instance['title']) ) 47 | echo $args['before_title'] . $instance['title'] . $args['after_title']; 48 | 49 | echo hubaga()->template->get_view_product_html( $_args ); 50 | 51 | echo $args['after_widget']; 52 | 53 | } 54 | 55 | /** 56 | * Handles updating settings for the current widget instance 57 | * 58 | * @since 3.0.0 59 | * @access public 60 | * 61 | * @param array $new_instance New settings for this instance as input by the user via 62 | * WP_Widget::form(). 63 | * @param array $old_instance Old settings for this instance. 64 | * @return array Updated settings to save. 65 | */ 66 | public function update( $new_instance, $old_instance ) { 67 | $instance = array(); 68 | if ( ! empty( $new_instance['title'] ) ) { 69 | $instance['title'] = sanitize_text_field( $new_instance['title'] ); 70 | } 71 | if ( ! empty( $new_instance['product_id'] ) ) { 72 | $instance['product_id'] = (int) $new_instance['product_id']; 73 | } 74 | return $instance; 75 | } 76 | 77 | /** 78 | * Display the form for this widget on the Widgets page of the Admin area. 79 | * 80 | * 81 | * @param array $instance 82 | */ 83 | function form( $instance ) { 84 | $product_id = empty( $instance['product_id'] ) ? '' : esc_attr( $instance['product_id'] ); 85 | $title = empty( $instance['title'] ) ? '' : esc_html( $instance['title'] ); 86 | ?> 87 | 88 |

89 | 90 | 91 |

92 | 93 |

94 | 95 | 103 |

104 | save(); 34 | } 35 | 36 | /** 37 | * Returns a products ID 38 | * 39 | * @since Hubaga 1.0.0 40 | * 41 | * @returns a string containing the product id 42 | */ 43 | function hubaga_get_product_id( $product ) { 44 | return hubaga_get_product( $product )->ID; 45 | } 46 | add_filter( 'hubaga_product_ID', 'absint' ); 47 | 48 | 49 | /** 50 | * Returns a products title 51 | * 52 | * @since Hubaga 1.0.0 53 | * 54 | * @returns a string containing the product title 55 | */ 56 | function hubaga_get_product_title( $product ) { 57 | return hubaga_get_product( $product )->post_title; 58 | } 59 | add_filter( 'hubaga_product_title', 'sanitize_text_field' ); 60 | 61 | 62 | /** 63 | * Returns a products short description 64 | * 65 | * @since Hubaga 1.0.0 66 | * 67 | * @returns a string containing the product description 68 | */ 69 | function hubaga_get_product_description( $product ) { 70 | return hubaga_get_product( $product )->short_description; 71 | } 72 | add_filter( 'hubaga_product_short_description', 'wptexturize' ); 73 | add_filter( 'hubaga_product_short_description', 'convert_smilies' ); 74 | add_filter( 'hubaga_product_short_description', 'convert_chars' ); 75 | add_filter( 'hubaga_product_short_description', 'wpautop' ); 76 | add_filter( 'hubaga_product_short_description', 'shortcode_unautop' ); 77 | add_filter( 'hubaga_product_short_description', 'prepend_attachment' ); 78 | add_filter( 'hubaga_product_short_description', 'do_shortcode', 11 ); // AFTER wpautop() 79 | 80 | /** 81 | * Returns the number of times a product has been sold 82 | * 83 | * @since Hubaga 1.0.0 84 | * 85 | * @returns a string containing the product sell count 86 | */ 87 | function hubaga_get_product_sell_count( $product ) { 88 | return hubaga_get_product( $product )->sell_count; 89 | } 90 | add_filter( 'hubaga_product_sell_count', 'absint' ); 91 | 92 | 93 | /** 94 | * Returns a product type 95 | * 96 | * @since Hubaga 1.0.0 97 | * 98 | * @returns a string containing the product type 99 | */ 100 | function hubaga_get_product_type( $product ) { 101 | return hubaga_get_product( $product )->type; 102 | } 103 | add_filter( 'hubaga_product_type', 'sanitize_title' ); 104 | 105 | /** 106 | * Returns the downloads attached to a product 107 | * 108 | * @since Hubaga 1.0.0 109 | * 110 | * @returns an array containing the downloads. 111 | */ 112 | function hubaga_get_product_downloads( $product ) { 113 | $product = hubaga_get_product( $product ); 114 | $downloads= array(); 115 | if( $product->download_url ){ 116 | $downloads[] = array( 117 | 'name' => $product->download_name, 118 | 'url' => $product->download_url, 119 | ); 120 | } 121 | return apply_filters( 'hubaga_product_downloads', $downloads, $product); 122 | } 123 | 124 | /** 125 | * Returns a product status 126 | * 127 | * @since Hubaga 1.0.0 128 | * 129 | * @returns a string containing the product status 130 | */ 131 | function hubaga_get_product_status( $product ) { 132 | return hubaga_get_product( $product )->post_status; 133 | } 134 | 135 | 136 | /** 137 | * Returns a product price with the symbol 138 | * 139 | * @since Hubaga 1.0.0 140 | * 141 | * @returns a string containing the product price 142 | */ 143 | function hubaga_get_product_price( $product ) { 144 | return hubaga_get_product( $product )->price; 145 | } 146 | 147 | /** 148 | * Returns a formatted product price with the symbol 149 | * 150 | * @since Hubaga 1.0.0 151 | * 152 | * @returns a string containing the product price 153 | */ 154 | function hubaga_get_formatted_product_price( $product ) { 155 | $price = hubaga_price( hubaga_get_product_price( $product ) ); 156 | return apply_filters( 'hubaga_formatted_product_price', $price, $product ); 157 | } 158 | 159 | /** 160 | * Checks if the provided product exists in the db 161 | * @since 1.0 162 | * @param mixed $product ID, details or object 163 | * @return bool 164 | */ 165 | function hubaga_is_product( $product ) { 166 | return hubaga_get_product( $product )->is_product(); 167 | } 168 | 169 | /** 170 | * Checks if the provided product can be bought 171 | * @since 1.0 172 | * @param mixed $product ID, details or object 173 | * @return bool 174 | */ 175 | function hubaga_can_buy_product( $product ) { 176 | return hubaga_get_product( $product )->can_buy(); 177 | } 178 | 179 | /** 180 | * Checks if the provided product is free 181 | * @since 1.0 182 | * @param mixed $product ID, details or object 183 | * @return bool 184 | */ 185 | function hubaga_is_product_free( $product ) { 186 | return hubaga_get_product( $product )->is_free(); 187 | } 188 | 189 | /** 190 | * Updates a products sell count 191 | * @since 1.0 192 | * @param mixed $product ID, details or object 193 | * @return bool 194 | */ 195 | function hubaga_update_product_sell_count( $product, $by = 1 ) { 196 | return hubaga_get_product( $product )->update_sell_count( $by ); 197 | } 198 | 199 | /** 200 | * Retrieves a list of product types 201 | * 202 | * @since 1.0 203 | * @return array 204 | */ 205 | function hubaga_get_product_types() { 206 | return apply_filters( 'hubaga_get_product_types', array( 207 | 'normal' => _x( 'Normal Product', 'A normal product that accepts a single payment', 'hubaga' ), 208 | ) ); 209 | } 210 | 211 | /** 212 | * Retrieves a list of product labels 213 | * 214 | * @since 1.0 215 | * @return array 216 | */ 217 | function hubaga_get_product_post_type_labels() { 218 | return apply_filters( 219 | 'hubaga_product_post_type_labels', 220 | array( 221 | 'name' => __( 'Products', 'hubaga' ), 222 | 'singular_name' => __( 'Product', 'hubaga' ), 223 | 'menu_name' => _x( 'Hubaga', 'Admin menu name', 'hubaga' ), 224 | 'add_new' => __( 'Add product', 'hubaga' ), 225 | 'add_new_item' => __( 'Add new product', 'hubaga' ), 226 | 'edit' => __( 'Edit', 'hubaga' ), 227 | 'edit_item' => __( 'Edit product', 'hubaga' ), 228 | 'new_item' => __( 'New product', 'hubaga' ), 229 | 'view' => __( 'View product', 'hubaga' ), 230 | 'view_item' => __( 'View product', 'hubaga' ), 231 | 'search_items' => __( 'Search products', 'hubaga' ), 232 | 'not_found' => __( 'No products found', 'hubaga' ), 233 | 'not_found_in_trash' => __( 'No products found in trash', 'hubaga' ), 234 | 'parent' => __( 'Parent product', 'hubaga' ), 235 | 'featured_image' => __( 'Product image', 'hubaga' ), 236 | 'set_featured_image' => __( 'Set product image', 'hubaga' ), 237 | 'remove_featured_image' => __( 'Remove product image', 'hubaga' ), 238 | 'use_featured_image' => __( 'Use as product image', 'hubaga' ), 239 | 'insert_into_item' => __( 'Insert into product', 'hubaga' ), 240 | 'uploaded_to_this_item' => __( 'Uploaded to this product', 'hubaga' ), 241 | 'filter_items_list' => __( 'Filter products', 'hubaga' ), 242 | 'items_list_navigation' => __( 'Products navigation', 'hubaga' ), 243 | 'items_list' => __( 'Products list', 'hubaga' ), 244 | ) ); 245 | } 246 | 247 | 248 | 249 | /** 250 | * Returns product post type details 251 | */ 252 | function hubaga_get_product_post_type_details(){ 253 | return apply_filters( 254 | 'hubaga_product_post_type_details', 255 | array( 256 | 'labels' => hubaga_get_product_post_type_labels(), 257 | 'description' => __( 'This is where you can add new digital products to your website.', 'hubaga' ), 258 | 'public' => false, 259 | 'show_ui' => true, 260 | 'map_meta_cap' => true, 261 | 'publicly_queryable' => false, 262 | 'exclude_from_search' => true, 263 | 'hierarchical' => false, // Hierarchical causes memory issues - WP loads all records! 264 | 'query_var' => true, 265 | 'supports' => array( 'title' ), 266 | 'has_archive' => false, 267 | 'show_in_nav_menus' => false, 268 | 'show_in_rest' => true, 269 | 'menu_icon' => 'dashicons-products' 270 | )); 271 | } 272 | 273 | /** 274 | * Returns product post type 275 | */ 276 | function hubaga_get_product_post_type(){ 277 | return hubaga()->product_post_type; 278 | } 279 | 280 | /** 281 | * Returns product post type menu name 282 | */ 283 | function hubaga_get_product_post_type_menu_name(){ 284 | return apply_filters( 'hubaga_product_post_type_menu_name', 'edit.php?post_type=' . hubaga_get_product_post_type()); 285 | } 286 | 287 | /** 288 | * Trigger a product purchase hook 289 | */ 290 | function hubaga_trigger_product_purchased_hook( $order ){ 291 | do_action( 'hubaga_product_purchased', hubaga_get_product( $order->product ), $order ); 292 | } 293 | add_action( 'hubaga_order_complete', 'hubaga_trigger_product_purchased_hook' ); 294 | -------------------------------------------------------------------------------- /includes/shortcodes.php: -------------------------------------------------------------------------------- 1 | add_shortcodes(); 33 | $this->template = hubaga()->template; 34 | } 35 | 36 | /** 37 | * Registers shortocodes 38 | * 39 | * @since Hubaga 1.0.0 40 | * @access private 41 | * 42 | * @uses apply_filters() 43 | */ 44 | private function add_shortcodes() { 45 | 46 | // Available shortcodes 47 | $shortcodes = apply_filters( 'hubaga_shortcodes', array( 48 | 'h-product' => array( $this, 'display_product' ), 49 | 'h-checkout' => array( $this, 'display_checkout' ), 50 | 'h-account' => array( $this, 'display_account' ), 51 | 'h-buy-button' => array( $this, 'display_buy_button' ), 52 | ) ); 53 | 54 | foreach ( $shortcodes as $code => $cb ) { 55 | add_shortcode( $code, $cb ); 56 | } 57 | } 58 | 59 | /** 60 | * Displays a single product 61 | * 62 | * @since Hubaga 1.0.0 63 | * 64 | * @param array $attr 65 | * @return string 66 | */ 67 | public function display_product( $atts ) { 68 | 69 | $options = shortcode_atts( array( 70 | 'id' => 0, 71 | 'class' => '', 72 | ), $atts ); 73 | 74 | return $this->template->get_view_product_html( $options ); 75 | } 76 | 77 | /** 78 | * Displays a the checkout page 79 | * 80 | * @since Hubaga 1.0.0 81 | * 82 | * @return string 83 | */ 84 | public function display_checkout() { 85 | return $this->template->get_checkout_html(); 86 | } 87 | 88 | /** 89 | * Displays a the account page 90 | * 91 | * @since Hubaga 1.0.0 92 | * 93 | * @return string 94 | */ 95 | public function display_account() { 96 | return $this->template->get_account_html(); 97 | } 98 | 99 | /** 100 | * Displays a list of products 101 | * 102 | * @since Hubaga 1.0.0 103 | * 104 | * @return string 105 | */ 106 | public function display_buy_button( $atts, $content ) { 107 | 108 | if(! $content ) { 109 | $content = 'BUY'; 110 | } 111 | 112 | $options = shortcode_atts( array( 113 | 'id' => 0, 114 | 'class' => '', 115 | 'content' => $content, 116 | ), $atts ); 117 | 118 | return $this->template->get_buy_button( $options ); 119 | } 120 | 121 | } 122 | endif; -------------------------------------------------------------------------------- /includes/system-info.php: -------------------------------------------------------------------------------- 1 | info = $this->get_info(); 31 | } 32 | 33 | /** 34 | * Returns an array of system information 35 | * in the form 36 | * 37 | * array( 'category' => array( ) ) 38 | * 39 | * @since Hubaga 1.0.0 40 | * 41 | */ 42 | public function get_info() { 43 | 44 | $plugins = hubaga_get_all_plugins(); 45 | 46 | //These have intentionally been untranslated 47 | return apply_filters( 'hubaga_system_info', array( 48 | 'Site Info' => $this->get_site_info(), 49 | 'WordPress Configuration' => $this->get_wordpress_config(), 50 | 'Server Info' => $this->get_server_info(), 51 | 'Active Plugins' => $plugins['active_plugins'], 52 | 'Inactive Plugins' => $plugins['inactive_plugins'], 53 | ) ); 54 | } 55 | 56 | /** 57 | * Returns the system information as a text string for use in textarea elements 58 | * 59 | * @since Hubaga 1.0.0 60 | * 61 | */ 62 | public function get_info_as_text() { 63 | $info = $this->info; 64 | $text = "### Begin System Info ###\n\n"; 65 | 66 | foreach( $info as $cat => $info ){ 67 | 68 | if( is_array( $info ) ) { 69 | 70 | $text .= "\n\n ----------- $cat -------------- \n\n"; 71 | 72 | foreach( $info as $label => $value ){ 73 | 74 | if ( is_array( $value ) ) { 75 | $value = print_r( $value, true ); 76 | } 77 | 78 | $text .= "\t $label : $value \n\n"; 79 | } 80 | 81 | } else { 82 | $text .= "$cat : $info \n\n"; 83 | } 84 | } 85 | 86 | $text .= "\n ### End System Info ###"; 87 | return apply_filters( 'hubaga_system_info_text', $text ); 88 | } 89 | 90 | 91 | /** 92 | * Returns the system information as a json string for use with apis or download 93 | * 94 | * @since Hubaga 1.0.0 95 | * 96 | */ 97 | public function get_info_as_json() { 98 | $info = wp_json_encode( $this->info ); 99 | return apply_filters( 'hubaga_system_info_json', $info ); 100 | } 101 | 102 | /** 103 | * Returns information about the current WordPress site configuration 104 | * 105 | * 106 | * @since Hubaga 1.0.0 107 | * 108 | */ 109 | public function get_site_info() { 110 | 111 | return apply_filters( 'hubaga_site_system_info', array( 112 | 'Site URL' => site_url(), 113 | 'Home URL' => home_url(), 114 | 'Multisite' => ( is_multisite() ? 'Yes' : 'No' ), 115 | ) ); 116 | } 117 | 118 | /** 119 | * Returns information about the current WordPress site configuration 120 | * 121 | * 122 | * @since Hubaga 1.0.0 123 | * 124 | */ 125 | public function get_wordpress_config() { 126 | 127 | global $wpdb; 128 | $theme_data = wp_get_theme(); 129 | $theme = $theme_data->Name . ' ' . $theme_data->Version . ' (' . $theme_data->uri . ')'; 130 | 131 | return apply_filters( 'hubaga_wordpress_config_system_info', array( 132 | 'Version' => get_bloginfo( 'version' ), 133 | 'Language' => get_locale(), 134 | 'Permalink Structure' => ( get_option( 'permalink_structure' ) ? get_option( 'permalink_structure' ) : 'Default' ), 135 | 'Active Theme' => $theme, 136 | 'Table Prefix' => $wpdb->prefix, 137 | 'WP_DEBUG' => ( defined( 'WP_DEBUG' ) ? WP_DEBUG ? 'Enabled' : 'Disabled' : 'Not set' ), 138 | 'Memory Limit' => WP_MEMORY_LIMIT, 139 | 'Registered Post Stati' => implode( ', ', get_post_stati() ), 140 | ) ); 141 | } 142 | 143 | /** 144 | * Returns information about the server 145 | * 146 | * 147 | * @since Hubaga 1.0.0 148 | * 149 | */ 150 | public function get_server_info() { 151 | 152 | global $wpdb; 153 | $server_data = array(); 154 | 155 | if ( function_exists( 'ini_get' ) ) { 156 | 157 | $server_data['Post Max Size'] = size_format( ini_get( 'post_max_size' ) ); 158 | $server_data['Safe Mode'] = ini_get( 'safe_mode' ) ? 'Enabled' : 'Disabled'; 159 | $server_data['Memory Limit'] = ini_get( 'memory_limit' ); 160 | $server_data['Upload Max Size'] = ini_get( 'upload_max_filesize' ); 161 | $server_data['Time Limit'] = ini_get( 'max_execution_time' ); 162 | $server_data['Max Input Vars'] = ini_get( 'max_input_vars' ); 163 | 164 | } 165 | 166 | return apply_filters( 'hubaga_server_system_info', array_merge( array( 167 | 'PHP Version' => PHP_VERSION, 168 | 'MySQL Version' => $wpdb->db_version(), 169 | 'Server' => ( empty( $_SERVER['SERVER_SOFTWARE'] ) ? 'Unknown' : $_SERVER['SERVER_SOFTWARE'] ), 170 | 'cURL' => ( function_exists( 'curl_init' ) ? 'Supported' : 'Not Supported' ), 171 | 'fsockopen' => ( function_exists( 'fsockopen' ) ? 'Supported' : 'Not Supported' ), 172 | 'SOAP Client' => ( class_exists( 'SoapClient' ) ? 'Installed' : 'Not Installed' ), 173 | 'Suhosin' => ( extension_loaded( 'suhosin' ) ? 'Installed' : 'Not Installed' ), 174 | ), $server_data ) ); 175 | } 176 | 177 | } 178 | endif; // class_exists check 179 | -------------------------------------------------------------------------------- /index.php: -------------------------------------------------------------------------------- 1 | New > Upload then upload the the source code that you just downloaded. 38 | 39 | Before you can sell your products; you will have to set up PayPal. This can be done by clicking on Hubaga in your WordPress dashboard then selecting settings. 40 | 41 | 42 | ## Found a Bug? 43 | 44 | You can let us know by [opening a new issue](https://github.com/picocodes/hubaga/issues). 45 | 46 | ## Contributing 47 | 48 | Make sure to communicate the changes to your code via an issue or email before [sending a pull request](https://help.github.com/articles/creating-a-pull-request/). 49 | 50 | ## Versioning 51 | 52 | We use [SemVer](http://semver.org/) for versioning. For the versions available, see the [tags on this repository](https://github.com/picocodes/hubaga/tags). 53 | 54 | 55 | ## License 56 | 57 | This project is licensed under the GPL3 License - see the [license.txt](license.txt) file for details 58 | 59 | -------------------------------------------------------------------------------- /readme.txt: -------------------------------------------------------------------------------- 1 | === Hubaga Sell Digital Downloads === 2 | Contributors: hubaga 3 | Tags: ecommerce, e-commerce, store, sell downloads, sell, shop, cart, checkout, downloads, paypal, digital downloads 4 | Donate link: https://hubaga.com 5 | Requires at least: 4.1 6 | Tested up to: 4.9 7 | Requires PHP: 5.2.4 8 | Stable tag: 1.0.3 9 | License: GPLv3 10 | License URI: https://www.gnu.org/licenses/gpl-3.0.html 11 | 12 | Use this light-weight eCommerce plugin to sell your software and other digital products. 13 | 14 | == Description == 15 | Hubaga was built to make it easy to sell digital products without using bloated plugins. 16 | 17 | It uses a single-field checkout to keep the checkout process short. In addition; you can enable instacheck and load the checkout form via ajax further speeding up the checkout process. 18 | 19 | Hubaga maximizes conversions by applying several checkout optimisation techniques such as short checkout processes and strategic application of trust seals. 20 | 21 | == Installation == 22 | = Minimum Requirements = 23 | 24 | * PHP version 5.2.4 or greater (PHP 7 or greater is recommended) 25 | * fsockopen or cURL enabled to confirm payments 26 | * WordPress 4.1+ 27 | 28 | = Automatic installation = 29 | 30 | Automatic installation is the easiest option as WordPress handles the file transfers itself and you don’t need to leave your web browser. To do an automatic install of Hubaga, log in to your WordPress dashboard, navigate to the Plugins menu and click Add New. 31 | 32 | In the search field type “Hubaga” and click Search Plugins. Once you’ve found our eCommerce plugin, you can install it by simply clicking “Install Now”. 33 | 34 | = Manual installation = 35 | 36 | The manual installation method involves downloading our eCommerce plugin and uploading it to your webserver via your favourite FTP application. The WordPress codex contains [instructions on how to do this here](https://codex.wordpress.org/Managing_Plugins#Manual_Plugin_Installation). 37 | 38 | 39 | == Frequently Asked Questions == 40 | = Where can I get support? = 41 | 42 | If you get stuck, you can ask for help in the [Hubaga Plugin Forum](https://wordpress.org/support/plugin/woocommerce). 43 | 44 | Our premium customers can contact us at [our helpdesk](https://hubaga.freshdesk.com/). 45 | 46 | = Will Hubaga work with my theme? = 47 | Yes. 48 | 49 | = Where can I report bugs or contribute to the project? = 50 | 51 | Bugs can be reported on the [Hubaga GitHub repository](https://github.com/hubaga/hubaga/issues). 52 | 53 | 54 | == Screenshots == 55 | 1. Sample Product Card 56 | 2. Reports page 57 | 3. Instacheck -------------------------------------------------------------------------------- /uninstall.php: -------------------------------------------------------------------------------- 1 |