├── icon-256x256.png ├── banner-800x150.png ├── snippets ├── ppc_pvc.zip ├── ppc_wp_slimstat.zip ├── ppc_shortcode_stripper.zip └── ppcp_pb_exclude_days.php.zip ├── style ├── images │ ├── pro.png │ ├── black.png │ ├── info.png │ ├── minus.png │ ├── plus.png │ ├── star.png │ ├── write.png │ ├── dollar.png │ ├── feedback.png │ ├── paypal.png │ ├── warning.png │ ├── ajax-loader.gif │ └── screenshots │ │ ├── stats.png │ │ ├── pro_stats.png │ │ ├── misc_settings.png │ │ └── counting_settings.png ├── ui-lightness │ ├── jquery.ui.base.css │ ├── images │ │ ├── ui-icons_222222_256x240.png │ │ ├── ui-icons_228ef1_256x240.png │ │ ├── ui-icons_ef8c08_256x240.png │ │ ├── ui-icons_ffd27a_256x240.png │ │ ├── ui-icons_ffffff_256x240.png │ │ ├── ui-bg_flat_10_000000_40x100.png │ │ ├── ui-bg_glass_65_ffffff_1x400.png │ │ ├── ui-bg_glass_100_f6f6f6_1x400.png │ │ ├── ui-bg_glass_100_fdf5ce_1x400.png │ │ ├── ui-bg_gloss-wave_35_f6a828_500x100.png │ │ ├── ui-bg_diagonals-thick_18_b81900_40x40.png │ │ ├── ui-bg_diagonals-thick_20_666666_40x40.png │ │ ├── ui-bg_highlight-soft_100_eeeeee_1x100.png │ │ └── ui-bg_highlight-soft_75_ffe45c_1x100.png │ ├── jquery.ui.all.css │ ├── jquery.ui.core.css │ ├── jquery.ui.datepicker.css │ └── jquery.ui.theme.css ├── ppc_welcome_style.css ├── ppc_addons_style.css ├── ppc_header_style.css ├── ppc_options_style_old.css ├── ppc_options_style.css ├── ppc_stats_style.css └── tipTip.css ├── lang ├── post-pay-counter-ar_AE.mo ├── post-pay-counter-cs_CZ.mo ├── post-pay-counter-de_DE.mo ├── post-pay-counter-es_ES.mo ├── post-pay-counter-fr_FR.mo ├── post-pay-counter-it_IT.mo ├── post-pay-counter-nl_NL.mo ├── post-pay-counter-pl_PL.mo ├── post-pay-counter-pt_BR.mo ├── post-pay-counter-pt_PT.mo ├── post-pay-counter-ru_RU.mo └── post-pay-counter-tr_TR.mo ├── uninstall.php ├── classes ├── ppc_permissions_class.php ├── ppc_notifications_class.php ├── ppc_visits_trackers.php ├── ppc_error_class.php ├── ppc_system_info_class.php ├── ppc_cache_class.php ├── ppc_license_class.php ├── ppc_autoupdate_class.php ├── ppc_addons_class.php ├── ppc_update_class.php ├── ppc_options_fields_class.php ├── ppc_install_functions_class.php ├── ppc_ajax_functions_class.php ├── ppc_welcome_class.php ├── ppc_counting_types_class.php └── ppc_general_functions_class.php ├── .gitignore ├── js ├── ppc_stats_effects.js ├── jquery.tiptip.min.js ├── ppc_options_effects.js └── ppc_options_ajax_stuff.js └── wp-cli.php /icon-256x256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheCrowned/Post-Pay-Counter/HEAD/icon-256x256.png -------------------------------------------------------------------------------- /banner-800x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheCrowned/Post-Pay-Counter/HEAD/banner-800x150.png -------------------------------------------------------------------------------- /snippets/ppc_pvc.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheCrowned/Post-Pay-Counter/HEAD/snippets/ppc_pvc.zip -------------------------------------------------------------------------------- /style/images/pro.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheCrowned/Post-Pay-Counter/HEAD/style/images/pro.png -------------------------------------------------------------------------------- /style/images/black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheCrowned/Post-Pay-Counter/HEAD/style/images/black.png -------------------------------------------------------------------------------- /style/images/info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheCrowned/Post-Pay-Counter/HEAD/style/images/info.png -------------------------------------------------------------------------------- /style/images/minus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheCrowned/Post-Pay-Counter/HEAD/style/images/minus.png -------------------------------------------------------------------------------- /style/images/plus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheCrowned/Post-Pay-Counter/HEAD/style/images/plus.png -------------------------------------------------------------------------------- /style/images/star.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheCrowned/Post-Pay-Counter/HEAD/style/images/star.png -------------------------------------------------------------------------------- /style/images/write.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheCrowned/Post-Pay-Counter/HEAD/style/images/write.png -------------------------------------------------------------------------------- /style/images/dollar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheCrowned/Post-Pay-Counter/HEAD/style/images/dollar.png -------------------------------------------------------------------------------- /style/images/feedback.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheCrowned/Post-Pay-Counter/HEAD/style/images/feedback.png -------------------------------------------------------------------------------- /style/images/paypal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheCrowned/Post-Pay-Counter/HEAD/style/images/paypal.png -------------------------------------------------------------------------------- /style/images/warning.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheCrowned/Post-Pay-Counter/HEAD/style/images/warning.png -------------------------------------------------------------------------------- /style/ui-lightness/jquery.ui.base.css: -------------------------------------------------------------------------------- 1 | @import url("jquery.ui.core.css"); 2 | @import url("jquery.ui.datepicker.css"); -------------------------------------------------------------------------------- /lang/post-pay-counter-ar_AE.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheCrowned/Post-Pay-Counter/HEAD/lang/post-pay-counter-ar_AE.mo -------------------------------------------------------------------------------- /lang/post-pay-counter-cs_CZ.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheCrowned/Post-Pay-Counter/HEAD/lang/post-pay-counter-cs_CZ.mo -------------------------------------------------------------------------------- /lang/post-pay-counter-de_DE.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheCrowned/Post-Pay-Counter/HEAD/lang/post-pay-counter-de_DE.mo -------------------------------------------------------------------------------- /lang/post-pay-counter-es_ES.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheCrowned/Post-Pay-Counter/HEAD/lang/post-pay-counter-es_ES.mo -------------------------------------------------------------------------------- /lang/post-pay-counter-fr_FR.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheCrowned/Post-Pay-Counter/HEAD/lang/post-pay-counter-fr_FR.mo -------------------------------------------------------------------------------- /lang/post-pay-counter-it_IT.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheCrowned/Post-Pay-Counter/HEAD/lang/post-pay-counter-it_IT.mo -------------------------------------------------------------------------------- /lang/post-pay-counter-nl_NL.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheCrowned/Post-Pay-Counter/HEAD/lang/post-pay-counter-nl_NL.mo -------------------------------------------------------------------------------- /lang/post-pay-counter-pl_PL.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheCrowned/Post-Pay-Counter/HEAD/lang/post-pay-counter-pl_PL.mo -------------------------------------------------------------------------------- /lang/post-pay-counter-pt_BR.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheCrowned/Post-Pay-Counter/HEAD/lang/post-pay-counter-pt_BR.mo -------------------------------------------------------------------------------- /lang/post-pay-counter-pt_PT.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheCrowned/Post-Pay-Counter/HEAD/lang/post-pay-counter-pt_PT.mo -------------------------------------------------------------------------------- /lang/post-pay-counter-ru_RU.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheCrowned/Post-Pay-Counter/HEAD/lang/post-pay-counter-ru_RU.mo -------------------------------------------------------------------------------- /lang/post-pay-counter-tr_TR.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheCrowned/Post-Pay-Counter/HEAD/lang/post-pay-counter-tr_TR.mo -------------------------------------------------------------------------------- /snippets/ppc_wp_slimstat.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheCrowned/Post-Pay-Counter/HEAD/snippets/ppc_wp_slimstat.zip -------------------------------------------------------------------------------- /style/images/ajax-loader.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheCrowned/Post-Pay-Counter/HEAD/style/images/ajax-loader.gif -------------------------------------------------------------------------------- /snippets/ppc_shortcode_stripper.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheCrowned/Post-Pay-Counter/HEAD/snippets/ppc_shortcode_stripper.zip -------------------------------------------------------------------------------- /style/images/screenshots/stats.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheCrowned/Post-Pay-Counter/HEAD/style/images/screenshots/stats.png -------------------------------------------------------------------------------- /snippets/ppcp_pb_exclude_days.php.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheCrowned/Post-Pay-Counter/HEAD/snippets/ppcp_pb_exclude_days.php.zip -------------------------------------------------------------------------------- /style/images/screenshots/pro_stats.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheCrowned/Post-Pay-Counter/HEAD/style/images/screenshots/pro_stats.png -------------------------------------------------------------------------------- /style/images/screenshots/misc_settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheCrowned/Post-Pay-Counter/HEAD/style/images/screenshots/misc_settings.png -------------------------------------------------------------------------------- /style/ppc_welcome_style.css: -------------------------------------------------------------------------------- 1 | .ppc-welcome-screenshots { 2 | float: right; 3 | margin-left: 10px !important; 4 | width: 400px !important; 5 | } 6 | -------------------------------------------------------------------------------- /style/images/screenshots/counting_settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheCrowned/Post-Pay-Counter/HEAD/style/images/screenshots/counting_settings.png -------------------------------------------------------------------------------- /style/ui-lightness/images/ui-icons_222222_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheCrowned/Post-Pay-Counter/HEAD/style/ui-lightness/images/ui-icons_222222_256x240.png -------------------------------------------------------------------------------- /style/ui-lightness/images/ui-icons_228ef1_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheCrowned/Post-Pay-Counter/HEAD/style/ui-lightness/images/ui-icons_228ef1_256x240.png -------------------------------------------------------------------------------- /style/ui-lightness/images/ui-icons_ef8c08_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheCrowned/Post-Pay-Counter/HEAD/style/ui-lightness/images/ui-icons_ef8c08_256x240.png -------------------------------------------------------------------------------- /style/ui-lightness/images/ui-icons_ffd27a_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheCrowned/Post-Pay-Counter/HEAD/style/ui-lightness/images/ui-icons_ffd27a_256x240.png -------------------------------------------------------------------------------- /style/ui-lightness/images/ui-icons_ffffff_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheCrowned/Post-Pay-Counter/HEAD/style/ui-lightness/images/ui-icons_ffffff_256x240.png -------------------------------------------------------------------------------- /style/ui-lightness/images/ui-bg_flat_10_000000_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheCrowned/Post-Pay-Counter/HEAD/style/ui-lightness/images/ui-bg_flat_10_000000_40x100.png -------------------------------------------------------------------------------- /style/ui-lightness/images/ui-bg_glass_65_ffffff_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheCrowned/Post-Pay-Counter/HEAD/style/ui-lightness/images/ui-bg_glass_65_ffffff_1x400.png -------------------------------------------------------------------------------- /style/ui-lightness/images/ui-bg_glass_100_f6f6f6_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheCrowned/Post-Pay-Counter/HEAD/style/ui-lightness/images/ui-bg_glass_100_f6f6f6_1x400.png -------------------------------------------------------------------------------- /style/ui-lightness/images/ui-bg_glass_100_fdf5ce_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheCrowned/Post-Pay-Counter/HEAD/style/ui-lightness/images/ui-bg_glass_100_fdf5ce_1x400.png -------------------------------------------------------------------------------- /style/ui-lightness/images/ui-bg_gloss-wave_35_f6a828_500x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheCrowned/Post-Pay-Counter/HEAD/style/ui-lightness/images/ui-bg_gloss-wave_35_f6a828_500x100.png -------------------------------------------------------------------------------- /style/ui-lightness/images/ui-bg_diagonals-thick_18_b81900_40x40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheCrowned/Post-Pay-Counter/HEAD/style/ui-lightness/images/ui-bg_diagonals-thick_18_b81900_40x40.png -------------------------------------------------------------------------------- /style/ui-lightness/images/ui-bg_diagonals-thick_20_666666_40x40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheCrowned/Post-Pay-Counter/HEAD/style/ui-lightness/images/ui-bg_diagonals-thick_20_666666_40x40.png -------------------------------------------------------------------------------- /style/ui-lightness/images/ui-bg_highlight-soft_100_eeeeee_1x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheCrowned/Post-Pay-Counter/HEAD/style/ui-lightness/images/ui-bg_highlight-soft_100_eeeeee_1x100.png -------------------------------------------------------------------------------- /style/ui-lightness/images/ui-bg_highlight-soft_75_ffe45c_1x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheCrowned/Post-Pay-Counter/HEAD/style/ui-lightness/images/ui-bg_highlight-soft_75_ffe45c_1x100.png -------------------------------------------------------------------------------- /style/ui-lightness/jquery.ui.all.css: -------------------------------------------------------------------------------- 1 | /* 2 | * jQuery UI CSS Framework 1.8.15 3 | * 4 | * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) 5 | * Dual licensed under the MIT or GPL Version 2 licenses. 6 | * http://jquery.org/license 7 | * 8 | * http://docs.jquery.com/UI/Theming 9 | */ 10 | @import "jquery.ui.base.css"; 11 | @import "jquery.ui.theme.css"; 12 | -------------------------------------------------------------------------------- /style/ppc_addons_style.css: -------------------------------------------------------------------------------- 1 | #ppc_addons h2 { 2 | margin: 0 0 15px; 3 | } 4 | #ppc_addons .ppc_addon { 5 | float: left; 6 | margin: 0 15px 15px 0; 7 | background: #f0f0f0; 8 | border: 1px solid #ccc; 9 | width: 320px; 10 | padding: 8px; 11 | height: 315px; 12 | position: relative; 13 | } 14 | #ppc_addons .ppc_addon h3 { 15 | margin: 0 0 8px; 16 | font-size: 13px; 17 | } 18 | #ppc_addons .ppc_addon img { 19 | width: 320px; 20 | height: 200px; 21 | object-fit: contain; 22 | } 23 | #ppc_addons .ppc_addon .button-secondary { 24 | position: absolute; 25 | bottom: 8px; 26 | } 27 | -------------------------------------------------------------------------------- /style/ppc_header_style.css: -------------------------------------------------------------------------------- 1 | #ppc_logo { 2 | float: right; 3 | width: 11%; 4 | margin-top: 23px; 5 | margin-right: -10%; 6 | margin-bottom: 3px; 7 | text-align: center; 8 | } 9 | #ppc_logo img { 10 | width: 160px; 11 | } 12 | #ppc_logo_caption { 13 | text-transform: uppercase; 14 | font-size: smaller; 15 | margin-top: -5px; 16 | text-align: center; 17 | } 18 | #ppc_logo_caption a, #ppc_logo_caption a:link, #ppc_logo_caption a:visited { 19 | color: inherit; 20 | } 21 | #ppc_header { 22 | float: left; 23 | 24 | margin-bottom: 5px; 25 | } 26 | #ppc_header_links { 27 | float: right; 28 | color: #777; 29 | margin-top: 5px; 30 | } 31 | #ppc_header_text { 32 | float: left; 33 | } -------------------------------------------------------------------------------- /style/ppc_options_style_old.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Deprecated styles. Use ppc- prefixed classes. 3 | */ 4 | 5 | .section { 6 | border-left-width: 1px; 7 | border-left-style: dashed; 8 | border-left-color: gray; 9 | padding-left: 10px; 10 | margin-bottom: 2.2em; 11 | } 12 | .section .title { 13 | font-weight: bold; 14 | text-align: left; 15 | margin-bottom: -5px; 16 | margin-top: 20px; 17 | } 18 | .section .content { 19 | margin-left: 1.5em; 20 | } 21 | .section .field_value { 22 | margin-left: 1.5em; 23 | } 24 | .section input[type="text"] { 25 | float: right; 26 | } 27 | .section td { 28 | width: 50%; 29 | } 30 | .save_settings { 31 | float: right; 32 | width: 30%; 33 | } 34 | .save_settings input { 35 | float: right; 36 | } 37 | .ajax_loader { 38 | display: none; 39 | float: left; 40 | margin-right: 5px; 41 | } 42 | -------------------------------------------------------------------------------- /uninstall.php: -------------------------------------------------------------------------------- 1 | get_col( 'SELECT blog_id FROM '.$wpdb->blogs ); 40 | foreach( $blog_ids as $blog_id ) { 41 | switch_to_blog( $blog_id ); 42 | ppc_uninstall_procedure(); 43 | } 44 | 45 | restore_current_blog(); 46 | return; 47 | } 48 | 49 | ppc_uninstall_procedure(); 50 | -------------------------------------------------------------------------------- /classes/ppc_permissions_class.php: -------------------------------------------------------------------------------- 1 | ID; 28 | 29 | $settings = PPC_general_functions::get_settings( $user ); 30 | 31 | //Admins override permissions, unless they have that permission turned off 32 | if( $settings['admins_override_permissions'] AND current_user_can( $ppc_global_settings['cap_manage_options'] ) ) { 33 | $user_only_settings = PPC_general_functions::get_settings( $user, false, false ); 34 | if ( ! ( $user_only_settings['userid'] != 'general' AND isset( $user_only_settings[$permission] ) AND ! $user_only_settings[$permission] ) ) // if user does not have this specific permission turned off 35 | return true; 36 | } 37 | 38 | return (bool) $settings[$permission]; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /style/ui-lightness/jquery.ui.core.css: -------------------------------------------------------------------------------- 1 | /* 2 | * jQuery UI CSS Framework 1.8.15 3 | * 4 | * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) 5 | * Dual licensed under the MIT or GPL Version 2 licenses. 6 | * http://jquery.org/license 7 | * 8 | * http://docs.jquery.com/UI/Theming/API 9 | */ 10 | 11 | /* Layout helpers 12 | ----------------------------------*/ 13 | .ui-helper-hidden { display: none; } 14 | .ui-helper-hidden-accessible { position: absolute !important; clip: rect(1px 1px 1px 1px); clip: rect(1px,1px,1px,1px); } 15 | .ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; } 16 | .ui-helper-clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; } 17 | .ui-helper-clearfix { display: inline-block; } 18 | /* required comment for clearfix to work in Opera \*/ 19 | * html .ui-helper-clearfix { height:1%; } 20 | .ui-helper-clearfix { display:block; } 21 | /* end clearfix */ 22 | .ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); } 23 | 24 | 25 | /* Interaction Cues 26 | ----------------------------------*/ 27 | .ui-state-disabled { cursor: default !important; } 28 | 29 | 30 | /* Icons 31 | ----------------------------------*/ 32 | 33 | /* states and images */ 34 | .ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; } 35 | 36 | 37 | /* Misc visuals 38 | ----------------------------------*/ 39 | 40 | /* Overlays */ 41 | .ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; } 42 | -------------------------------------------------------------------------------- /style/ppc_options_style.css: -------------------------------------------------------------------------------- 1 | #side-info-column { 2 | width: 49%; 3 | } 4 | .inner-sidebar #side-sortables { 5 | width: 100%; 6 | } 7 | .has-right-sidebar #post-body-content { 8 | width: 49%; 9 | margin-right: 390px; 10 | } 11 | .has-right-sidebar #post-body { 12 | margin-right: -50%; 13 | } 14 | #post-body #normal-sortables { 15 | width: 100%; 16 | } 17 | .ppc_section { 18 | border-left-width: 1px; 19 | border-left-style: dashed; 20 | border-left-color: gray; 21 | padding-left: 10px; 22 | margin-bottom: 2.2em; 23 | } 24 | .ppc_section .ppc_title { 25 | font-weight: bold; 26 | text-align: left; 27 | margin-bottom: -5px; 28 | margin-top: 20px; 29 | } 30 | .ppc_section .ppc_content { 31 | margin-left: 1.5em; 32 | } 33 | .ppc_section .ppc_field_value { 34 | margin-left: 1.5em; 35 | } 36 | .ppc_section input[type="text"] { 37 | float: right; 38 | background-color: #eee; 39 | margin-right: 2em; 40 | } 41 | .ppc_section select { 42 | float: right; 43 | background-color: #eee; 44 | margin-right: 0.5em; 45 | } 46 | .ppc_section td { 47 | width: 50%; 48 | } 49 | .ppc_tooltip { 50 | float: right; 51 | width: 20px; 52 | text-align: right; 53 | } 54 | .ppc_save_settings { 55 | float: right; 56 | width: 30%; 57 | } 58 | .ppc_save_settings input { 59 | float: right; 60 | } 61 | .ppc_align_right { 62 | float: right; 63 | } 64 | .ppc_ajax_loader { 65 | display: none; 66 | float: left; 67 | margin-right: 5px; 68 | } 69 | .ppc_save_success { 70 | display: none; 71 | float: left; 72 | width: 70%; 73 | padding: 5px; 74 | background: #BCED91; 75 | border-style: solid; 76 | border-width: 1px; 77 | border-color: #567E3A; 78 | } 79 | .ppc_save_error { 80 | display: none; 81 | float: left; 82 | width: 70%; 83 | padding: 5px; 84 | background: #FF6060; 85 | border-style: solid; 86 | border-width: 1px; 87 | border-color: #C12B45; 88 | } 89 | #ppc_personalize_users { 90 | max-height: 12em; 91 | overflow: auto; 92 | display: none; 93 | } 94 | .ppc_copy_license_key { 95 | font-size: x-small; 96 | color: grey; 97 | } 98 | -------------------------------------------------------------------------------- /style/ppc_stats_style.css: -------------------------------------------------------------------------------- 1 | #ppc_logo { 2 | margin-right: 0px; 3 | margin-top: -5px; 4 | width: 11%; 5 | padding-left: 30px; 6 | } 7 | #ppc_logo img { 8 | width: 100px; 9 | } 10 | 11 | .ppc_error { 12 | display: none; 13 | color: red; 14 | font-weight: bold; 15 | float: left; 16 | width: 70%; 17 | } 18 | .ppc_success { 19 | display: none; 20 | color: green; 21 | font-weight: bold; 22 | float: left; 23 | width: 70%; 24 | } 25 | .ppc_ajax_loader { 26 | display: none; 27 | } 28 | .ppc_table_divider { 29 | margin-top: 15px; 30 | height: 1px; 31 | clear: both; 32 | } 33 | .ppc_hr_divider { 34 | border-color: #ccc; 35 | border-style: solid; 36 | border-width: 1px 0 0; 37 | clear: both; 38 | margin: 5px 0 20px; 39 | height: 0; 40 | } 41 | 42 | @media screen and (max-width: 500px) { 43 | abbr[title].ppc_payment_column { 44 | position: relative; 45 | text-decoration: underline dotted; 46 | } 47 | abbr[title].ppc_payment_column:hover::after, 48 | abbr[title].ppc_payment_column:focus::after { 49 | content: attr(title); 50 | 51 | /* position tooltip like the native one */ 52 | /*position: absolute; 53 | left: 0; 54 | bottom: -30px; 55 | width: auto; 56 | white-space: nowrap;*/ 57 | 58 | /* style tooltip */ 59 | bottom: -30px; 60 | background-color: #1e1e1e; 61 | color: #fff; 62 | border-radius: 3px; 63 | box-shadow: 1px 1px 5px 0 rgba(0,0,0,0.4); 64 | font-size: 14px; 65 | padding: 3px 5px; 66 | } 67 | } 68 | 69 | .ppc_payment_column { 70 | border-bottom: 1px dotted; 71 | color: #000000; 72 | }*/ 73 | .ppc_count_column { 74 | border-bottom: 1px dotted; 75 | } 76 | #ppc_stats_header { 77 | height: 50px; 78 | } 79 | #ppc_stats_header_datepicker { 80 | float: left; 81 | text-align: left; 82 | } 83 | #ppc_stats_header_datepicker h3 { 84 | margin: 10px 0px 5px; 85 | } 86 | #ppc_stats_header_features { 87 | float: right; 88 | text-align: right; 89 | width: 20%; 90 | min-width: 30em; 91 | } 92 | #ppc_stats_header_features a { 93 | font-size: smaller; 94 | } 95 | #ppc_stats_header_links { 96 | float: right; 97 | height: 100%; 98 | border-left: 1px solid; 99 | border-color: #ccc; 100 | margin-left: 5%; 101 | padding-left: 5%; 102 | } 103 | -------------------------------------------------------------------------------- /style/tipTip.css: -------------------------------------------------------------------------------- 1 | /* TipTip CSS - Version 1.2 */ 2 | 3 | #tiptip_holder { 4 | display: none; 5 | position: absolute; 6 | top: 0; 7 | left: 0; 8 | z-index: 99999; 9 | } 10 | 11 | #tiptip_holder.tip_top { 12 | padding-bottom: 5px; 13 | } 14 | 15 | #tiptip_holder.tip_bottom { 16 | padding-top: 5px; 17 | } 18 | 19 | #tiptip_holder.tip_right { 20 | padding-left: 5px; 21 | } 22 | 23 | #tiptip_holder.tip_left { 24 | padding-right: 5px; 25 | } 26 | 27 | #tiptip_content { 28 | font-size: 12px; 29 | color: #fff; 30 | text-shadow: 0 0 2px #000; 31 | line-height: 130%; 32 | padding: 4px 8px; 33 | border: 1px solid rgba(255,255,255,0.25); 34 | background-color: rgb(25,25,25); 35 | background-color: rgba(25,25,25,0.92); 36 | background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, from(transparent), to(#000)); 37 | border-radius: 3px; 38 | -webkit-border-radius: 3px; 39 | -moz-border-radius: 3px; 40 | box-shadow: 0 0 3px #555; 41 | -webkit-box-shadow: 0 0 3px #555; 42 | -moz-box-shadow: 0 0 3px #555; 43 | } 44 | 45 | #tiptip_arrow, #tiptip_arrow_inner { 46 | position: absolute; 47 | border-color: transparent; 48 | border-style: solid; 49 | border-width: 6px; 50 | height: 0; 51 | width: 0; 52 | } 53 | 54 | #tiptip_holder.tip_top #tiptip_arrow { 55 | border-top-color: #fff; 56 | border-top-color: rgba(255,255,255,0.35); 57 | } 58 | 59 | #tiptip_holder.tip_bottom #tiptip_arrow { 60 | border-bottom-color: #fff; 61 | border-bottom-color: rgba(255,255,255,0.35); 62 | } 63 | 64 | #tiptip_holder.tip_right #tiptip_arrow { 65 | border-right-color: #fff; 66 | border-right-color: rgba(255,255,255,0.35); 67 | } 68 | 69 | #tiptip_holder.tip_left #tiptip_arrow { 70 | border-left-color: #fff; 71 | border-left-color: rgba(255,255,255,0.35); 72 | } 73 | 74 | #tiptip_holder.tip_top #tiptip_arrow_inner { 75 | margin-top: -7px; 76 | margin-left: -6px; 77 | border-top-color: rgb(25,25,25); 78 | border-top-color: rgba(25,25,25,0.92); 79 | } 80 | 81 | #tiptip_holder.tip_bottom #tiptip_arrow_inner { 82 | margin-top: -5px; 83 | margin-left: -6px; 84 | border-bottom-color: rgb(25,25,25); 85 | border-bottom-color: rgba(25,25,25,0.92); 86 | } 87 | 88 | #tiptip_holder.tip_right #tiptip_arrow_inner { 89 | margin-top: -6px; 90 | margin-left: -5px; 91 | border-right-color: rgb(25,25,25); 92 | border-right-color: rgba(25,25,25,0.92); 93 | } 94 | 95 | #tiptip_holder.tip_left #tiptip_arrow_inner { 96 | margin-top: -6px; 97 | margin-left: -7px; 98 | border-left-color: rgb(25,25,25); 99 | border-left-color: rgba(25,25,25,0.92); 100 | } 101 | 102 | /* Webkit Hacks */ 103 | @media screen and (-webkit-min-device-pixel-ratio:0) { 104 | #tiptip_content { 105 | padding: 4px 8px 5px 8px; 106 | background-color: rgba(45,45,45,0.88); 107 | } 108 | #tiptip_holder.tip_bottom #tiptip_arrow_inner { 109 | border-bottom-color: rgba(45,45,45,0.88); 110 | } 111 | #tiptip_holder.tip_top #tiptip_arrow_inner { 112 | border-top-color: rgba(20,20,20,0.92); 113 | } 114 | } -------------------------------------------------------------------------------- /classes/ppc_notifications_class.php: -------------------------------------------------------------------------------- 1 | current_notification = $notification; 20 | } 21 | 22 | /** 23 | * Adds a simple WordPress pointer to plugin's menu 24 | * 25 | * @access public 26 | * @since 2.46 27 | */ 28 | 29 | function display_notification() { 30 | ?> 31 | 32 |
33 |

current_notification['text']; ?>

34 |
35 | 36 | 58 | 59 | 4 ) ); 77 | 78 | if ( ! is_wp_error( $feed ) ) { 79 | if ( isset( $feed['body'] ) && strlen( $feed['body'] ) > 0 ) 80 | $notifications = maybe_unserialize( wp_remote_retrieve_body( $feed ) ); 81 | } else { 82 | $notifications = $feed; 83 | //new PPC_Error( "ppc_notifications_get_remote_error", $feed->get_error_message(), $feed->get_error_code() ); //log error 84 | } 85 | 86 | set_transient( 'ppc_notifications_list', $notifications, 3600*15 ); //log even if error to avoid making too many requests 87 | } 88 | 89 | } 90 | 91 | return apply_filters( 'ppc_notifications_get_list', $notifications ); 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | cache/ 2 | 3 | ################# 4 | ## Eclipse 5 | ################# 6 | 7 | *.pydevproject 8 | .project 9 | .metadata 10 | bin/ 11 | tmp/ 12 | *.tmp 13 | *.bak 14 | *.swp 15 | *~.nib 16 | local.properties 17 | .classpath 18 | .settings/ 19 | .loadpath 20 | .svn/ 21 | branches/ 22 | 23 | # External tool builders 24 | .externalToolBuilders/ 25 | 26 | # Locally stored "Eclipse launch configurations" 27 | *.launch 28 | 29 | # CDT-specific 30 | .cproject 31 | 32 | # PDT-specific 33 | .buildpath 34 | 35 | 36 | ################# 37 | ## Visual Studio 38 | ################# 39 | 40 | ## Ignore Visual Studio temporary files, build results, and 41 | ## files generated by popular Visual Studio add-ons. 42 | 43 | # User-specific files 44 | *.suo 45 | *.user 46 | *.sln.docstates 47 | 48 | # Build results 49 | 50 | [Dd]ebug/ 51 | [Rr]elease/ 52 | x64/ 53 | build/ 54 | [Bb]in/ 55 | [Oo]bj/ 56 | 57 | # MSTest test Results 58 | [Tt]est[Rr]esult*/ 59 | [Bb]uild[Ll]og.* 60 | 61 | *_i.c 62 | *_p.c 63 | *.ilk 64 | *.meta 65 | *.obj 66 | *.pch 67 | *.pdb 68 | *.pgc 69 | *.pgd 70 | *.rsp 71 | *.sbr 72 | *.tlb 73 | *.tli 74 | *.tlh 75 | *.tmp 76 | *.tmp_proj 77 | *.log 78 | *.vspscc 79 | *.vssscc 80 | .builds 81 | *.pidb 82 | *.log 83 | *.scc 84 | 85 | # Visual C++ cache files 86 | ipch/ 87 | *.aps 88 | *.ncb 89 | *.opensdf 90 | *.sdf 91 | *.cachefile 92 | 93 | # Visual Studio profiler 94 | *.psess 95 | *.vsp 96 | *.vspx 97 | 98 | # Guidance Automation Toolkit 99 | *.gpState 100 | 101 | # ReSharper is a .NET coding add-in 102 | _ReSharper*/ 103 | *.[Rr]e[Ss]harper 104 | 105 | # TeamCity is a build add-in 106 | _TeamCity* 107 | 108 | # DotCover is a Code Coverage Tool 109 | *.dotCover 110 | 111 | # NCrunch 112 | *.ncrunch* 113 | .*crunch*.local.xml 114 | 115 | # Installshield output folder 116 | [Ee]xpress/ 117 | 118 | # DocProject is a documentation generator add-in 119 | DocProject/buildhelp/ 120 | DocProject/Help/*.HxT 121 | DocProject/Help/*.HxC 122 | DocProject/Help/*.hhc 123 | DocProject/Help/*.hhk 124 | DocProject/Help/*.hhp 125 | DocProject/Help/Html2 126 | DocProject/Help/html 127 | 128 | # Click-Once directory 129 | publish/ 130 | 131 | # Publish Web Output 132 | *.Publish.xml 133 | *.pubxml 134 | 135 | # NuGet Packages Directory 136 | ## TODO: If you have NuGet Package Restore enabled, uncomment the next line 137 | #packages/ 138 | 139 | # Windows Azure Build Output 140 | csx 141 | *.build.csdef 142 | 143 | # Windows Store app package directory 144 | AppPackages/ 145 | 146 | # Others 147 | sql/ 148 | *.Cache 149 | ClientBin/ 150 | [Ss]tyle[Cc]op.* 151 | ~$* 152 | *~ 153 | *.dbmdl 154 | *.[Pp]ublish.xml 155 | *.pfx 156 | *.publishsettings 157 | 158 | # RIA/Silverlight projects 159 | Generated_Code/ 160 | 161 | # Backup & report files from converting an old project file to a newer 162 | # Visual Studio version. Backup files are not needed, because we have git ;-) 163 | _UpgradeReport_Files/ 164 | Backup*/ 165 | UpgradeLog*.XML 166 | UpgradeLog*.htm 167 | 168 | # SQL Server files 169 | App_Data/*.mdf 170 | App_Data/*.ldf 171 | 172 | ############# 173 | ## Windows detritus 174 | ############# 175 | 176 | # Windows image file caches 177 | Thumbs.db 178 | ehthumbs.db 179 | 180 | # Folder config file 181 | Desktop.ini 182 | 183 | # Recycle Bin used on file shares 184 | $RECYCLE.BIN/ 185 | 186 | # Mac crap 187 | .DS_Store 188 | 189 | 190 | ############# 191 | ## Python 192 | ############# 193 | 194 | *.py[co] 195 | 196 | # Packages 197 | *.egg 198 | *.egg-info 199 | dist/ 200 | build/ 201 | eggs/ 202 | parts/ 203 | var/ 204 | sdist/ 205 | develop-eggs/ 206 | .installed.cfg 207 | 208 | # Installer logs 209 | pip-log.txt 210 | 211 | # Unit test / coverage reports 212 | .coverage 213 | .tox 214 | 215 | #Translations 216 | #*.mo 217 | 218 | #Mr Developer 219 | .mr.developer.cfg 220 | banner-772x250.png 221 | -------------------------------------------------------------------------------- /js/ppc_stats_effects.js: -------------------------------------------------------------------------------- 1 | jQuery(document).ready(function($) { 2 | $('#post_pay_counter_time_start').datepicker({ 3 | dateFormat : 'yy-mm-dd', 4 | minDate : ppc_stats_effects_vars.datepicker_mindate, 5 | maxDate: ppc_stats_effects_vars.datepicker_maxdate, 6 | changeMonth : true, 7 | changeYear : true, 8 | showButtonPanel: true, 9 | showOtherMonths: true, 10 | selectOtherMonths: true, 11 | showAnim: "slideDown", 12 | onSelect: function(dateText, inst) { 13 | $('#post_pay_counter_time_end').datepicker('option', 'minDate', new Date(inst.selectedYear, inst.selectedMonth, inst.selectedDay)); 14 | } 15 | }); 16 | $('#post_pay_counter_time_end').datepicker({ 17 | dateFormat : 'yy-mm-dd', 18 | minDate : ppc_stats_effects_vars.datepicker_mindate, 19 | maxDate: ppc_stats_effects_vars.datepicker_maxdate, 20 | changeMonth : true, 21 | changeYear : true, 22 | showButtonPanel: true, 23 | showOtherMonths: true, 24 | selectOtherMonths: true, 25 | showAnim: "slideDown", 26 | onSelect: function(dateText, inst) { 27 | $('#post_pay_counter_time_start').datepicker('option', 'maxDate', new Date(inst.selectedYear, inst.selectedMonth, inst.selectedDay)); 28 | } 29 | }); 30 | 31 | //Handles date picker fields display 32 | $('#ppc-time-range').change(function() { 33 | var selected = $(this).val(); 34 | 35 | if(selected == 'custom') { 36 | $('#ppc-time-range-custom').css('display', 'block'); 37 | } else { 38 | $('#ppc-time-range-custom').css('display', 'none'); 39 | } 40 | 41 | //Tweaks the datepicker fields dates when a choice is made from select menu 42 | if(selected == 'this_month') { 43 | $('#post_pay_counter_time_start').val(ppc_stats_effects_vars.time_start_this_month); 44 | $('#post_pay_counter_time_end').val(ppc_stats_effects_vars.time_end_this_month); 45 | } 46 | if(selected == 'last_month') { 47 | $('#post_pay_counter_time_start').val(ppc_stats_effects_vars.time_start_last_month); 48 | $('#post_pay_counter_time_end').val(ppc_stats_effects_vars.time_end_last_month); 49 | } 50 | if(selected == 'this_week') { 51 | $('#post_pay_counter_time_start').val(ppc_stats_effects_vars.time_start_this_week); 52 | $('#post_pay_counter_time_end').val(ppc_stats_effects_vars.time_end_this_week); 53 | } 54 | if(selected == 'this_year') { 55 | $('#post_pay_counter_time_start').val(ppc_stats_effects_vars.time_start_this_year); 56 | $('#post_pay_counter_time_end').val(ppc_stats_effects_vars.time_end_this_year); 57 | } 58 | if(selected == 'all_time') { 59 | $('#post_pay_counter_time_start').val(ppc_stats_effects_vars.datepicker_mindate); 60 | $('#post_pay_counter_time_end').val(ppc_stats_effects_vars.datepicker_maxdate); 61 | } 62 | 63 | }); 64 | 65 | //Makes sure datepicker fields are displayed if custom is the default choice 66 | $('#ppc-time-range').trigger('change'); 67 | 68 | $('#ppc_stats_role').on('change', function(e) { 69 | e.preventDefault(); 70 | 71 | //$('#ppcp_ga_status_ajax_loader').css('display', 'inline'); 72 | $('#ppc_stats_role').attr('disabled', 'disabled'); 73 | 74 | var data = { 75 | action: "ppc_stats_get_users_by_role", 76 | user_role: $('#ppc_stats_role').val(), 77 | _ajax_nonce: ppc_stats_effects_vars.nonce_ppc_stats_get_users_by_role 78 | }; 79 | 80 | $.post(ajaxurl, data, function(response) { 81 | //$('#ppcp_ga_status_ajax_loader').css('display', 'none'); 82 | $('#ppc_stats_role').removeAttr('disabled'); 83 | 84 | if(! response.success) { 85 | alert(response); 86 | } else { 87 | $('#ppc_stats_user').html(response.data.html); 88 | } 89 | }); 90 | }); 91 | }); 92 | -------------------------------------------------------------------------------- /classes/ppc_visits_trackers.php: -------------------------------------------------------------------------------- 1 | array( 24 | 'post-views-counter' => array( 25 | 'name' => 'Post Views Counter', 26 | 'callback' => 'ppc_get_post_views_counter_views', 27 | ), 28 | 'slimstat-analytics' => array( 29 | 'name' => 'Slimstat Analytics', 30 | 'callback' => 'ppc_wp_get_slimstat_views', 31 | ), 32 | 'wp-postviews' => array( 33 | 'name' => 'WP-PostViews', 34 | 'callback' => 'ppc_get_wp_postviews_views', 35 | ), 36 | 'active-analytics' => array( 37 | 'name' => 'Active Analytics', 38 | 'callback' => 'ppc_get_active_analytics_views', 39 | ), 40 | 'wordpress-popular-posts' => array( 41 | 'name' => 'WordPress Popular Posts', 42 | 'callback' => 'ppc_get_wordpress_popular_posts_views', 43 | ), 44 | 'top-10' => array( 45 | 'name' => 'Top 10', 46 | 'callback' => 'ppc_get_top_10_posts_views', 47 | ), 48 | ), 49 | ) ); 50 | } 51 | 52 | function ppc_wp_get_slimstat_views( $post ) { 53 | global $ppc_wp_slimstat_include_status; 54 | if( ! ( $ppc_wp_slimstat_include_status AND ppc_is_plugin_active( 'wp-slimstat/wp-slimstat.php' ) ) ) 55 | return ppc_default_visits_callback( $post ); 56 | $filters = 'content_id equals ' . $post->ID; 57 | wp_slimstat_db::init( $filters ); 58 | $post_views = wp_slimstat_db::count_records( 'id', '', false ); 59 | return $post_views; 60 | } 61 | 62 | function ppc_get_wp_postviews_views( $post ) { 63 | if( ! ppc_is_plugin_active( 'wp-postviews/wp-postviews.php' ) ) 64 | return ppc_default_visits_callback( $post ); 65 | $post_views = (int) get_post_meta( $post->ID, 'views', true ); 66 | //if( ! $post_views ) 67 | // $post_views = 0; 68 | return $post_views; 69 | } 70 | 71 | function ppc_get_post_views_counter_views( $post ) { 72 | if( ! ppc_is_plugin_active( 'post-views-counter/post-views-counter.php' ) ) 73 | return ppc_default_visits_callback( $post ); 74 | $post_views = pvc_get_post_views( $post->ID ); 75 | return $post_views; 76 | } 77 | 78 | function ppc_get_wordpress_popular_posts_views( $post ) { 79 | if( ! ppc_is_plugin_active( 'wordpress-popular-posts/wordpress-popular-posts.php' ) ) 80 | return ppc_default_visits_callback( $post ); 81 | $post_views = wpp_get_views( $post->ID, 'all', false ); 82 | return $post_views; 83 | } 84 | 85 | function ppc_get_active_analytics_views( $post ) { 86 | if( ! ppc_is_plugin_active( 'active-analytics/active-analytics.php' ) ) 87 | return ppc_default_visits_callback( $post ); 88 | $postmeta_name = get_option( 'wpaa_pageviews_key' ); 89 | $post_views = (int) get_post_meta( $post->ID, $postmeta_name, true ); 90 | return $post_views; 91 | } 92 | 93 | function ppc_get_top_10_posts_views( $post ) { 94 | if( ! ppc_is_plugin_active( 'top-10/top-10.php' ) ) 95 | return ppc_default_visits_callback( $post ); 96 | $post_views = (int) get_tptn_post_count_only( $post->ID ); 97 | return $post_views; 98 | } 99 | 100 | function ppc_default_visits_callback( $post ) { 101 | return -1; 102 | } 103 | -------------------------------------------------------------------------------- /style/ui-lightness/jquery.ui.datepicker.css: -------------------------------------------------------------------------------- 1 | /* 2 | * jQuery UI Datepicker 1.8.15 3 | * 4 | * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) 5 | * Dual licensed under the MIT or GPL Version 2 licenses. 6 | * http://jquery.org/license 7 | * 8 | * http://docs.jquery.com/UI/Datepicker#theming 9 | */ 10 | .ui-datepicker { width: 17em; padding: .2em .2em 0; display: none; } 11 | .ui-datepicker .ui-datepicker-header { position:relative; padding:.2em 0; } 12 | .ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 2px; width: 1.8em; height: 1.8em; } 13 | .ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { top: 1px; } 14 | .ui-datepicker .ui-datepicker-prev { left:2px; } 15 | .ui-datepicker .ui-datepicker-next { right:2px; } 16 | .ui-datepicker .ui-datepicker-prev-hover { left:1px; } 17 | .ui-datepicker .ui-datepicker-next-hover { right:1px; } 18 | .ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px; } 19 | .ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; } 20 | .ui-datepicker .ui-datepicker-title select { font-size:1em; margin:1px 0; } 21 | .ui-datepicker select.ui-datepicker-month-year {width: 100%;} 22 | .ui-datepicker select.ui-datepicker-month, 23 | .ui-datepicker select.ui-datepicker-year { width: 49%;} 24 | .ui-datepicker table {width: 100%; font-size: .9em; border-collapse: collapse; margin:0 0 .4em; } 25 | .ui-datepicker th { padding: .7em .3em; text-align: center; font-weight: bold; border: 0; } 26 | .ui-datepicker td { border: 0; padding: 1px; } 27 | .ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em; text-align: right; text-decoration: none; } 28 | .ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: .7em 0 0 0; padding:0 .2em; border-left: 0; border-right: 0; border-bottom: 0; } 29 | .ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width:auto; overflow:visible; } 30 | .ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { float:left; } 31 | 32 | /* with multiple calendars */ 33 | .ui-datepicker.ui-datepicker-multi { width:auto; } 34 | .ui-datepicker-multi .ui-datepicker-group { float:left; } 35 | .ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; } 36 | .ui-datepicker-multi-2 .ui-datepicker-group { width:50%; } 37 | .ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; } 38 | .ui-datepicker-multi-4 .ui-datepicker-group { width:25%; } 39 | .ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; } 40 | .ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; } 41 | .ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; } 42 | .ui-datepicker-row-break { clear:both; width:100%; font-size:0em; } 43 | 44 | /* RTL support */ 45 | .ui-datepicker-rtl { direction: rtl; } 46 | .ui-datepicker-rtl .ui-datepicker-prev { right: 2px; left: auto; } 47 | .ui-datepicker-rtl .ui-datepicker-next { left: 2px; right: auto; } 48 | .ui-datepicker-rtl .ui-datepicker-prev:hover { right: 1px; left: auto; } 49 | .ui-datepicker-rtl .ui-datepicker-next:hover { left: 1px; right: auto; } 50 | .ui-datepicker-rtl .ui-datepicker-buttonpane { clear:right; } 51 | .ui-datepicker-rtl .ui-datepicker-buttonpane button { float: left; } 52 | .ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current { float:right; } 53 | .ui-datepicker-rtl .ui-datepicker-group { float:right; } 54 | .ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header { border-right-width:0; border-left-width:1px; } 55 | .ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width:0; border-left-width:1px; } 56 | 57 | /* IE6 IFRAME FIX (taken from datepicker 1.5.3 */ 58 | .ui-datepicker-cover { 59 | display: none; /*sorry for IE5*/ 60 | display/**/: block; /*sorry for IE5*/ 61 | position: absolute; /*must have*/ 62 | z-index: -1; /*must have*/ 63 | filter: mask(); /*must have*/ 64 | top: -4px; /*must have*/ 65 | left: -4px; /*must have*/ 66 | width: 200px; /*must have*/ 67 | height: 200px; /*must have*/ 68 | } -------------------------------------------------------------------------------- /classes/ppc_error_class.php: -------------------------------------------------------------------------------- 1 | $code, 36 | 'message' => $message, 37 | 'data' => $data, 38 | 'time' => current_time( 'timestamp' ) 39 | ); 40 | 41 | //If debug or logging enabled, make up detailed error (only shown if requested) 42 | if( PPC_DEBUG_SHOW OR ( PPC_DEBUG_LOG AND $log ) ) 43 | $error_details['debug_message'] = 'An error was thrown with code "'.$code.'", message "'.$message.'" and debug data "'.var_export( $data, true ).'".'; 44 | 45 | if( PPC_DEBUG_SHOW ) 46 | $error_details['output'] = $error_details['debug_message']; 47 | else 48 | $error_details['output'] = $error_details['message']; 49 | 50 | //If logging enabled, push error with others 51 | if( PPC_DEBUG_LOG AND $log ) { 52 | $errors = @file_get_contents( $ppc_global_settings['file_errors'] ); 53 | 54 | if( $errors !== false ) 55 | $errors = unserialize( $errors ); 56 | else 57 | $errors = array(); 58 | 59 | $errors[] = $error_details; 60 | 61 | //Get rid of old errors - only run once a day, ensure this through an option 62 | $daily_delete = get_option( $ppc_global_settings['option_error_deletion'], true ); 63 | if( $daily_delete != false AND $daily_delete < current_time( 'timestamp' ) - 86400 ) { 64 | foreach( $errors as $key => $single ) { 65 | if( $single['time'] < ( current_time( 'timestamp' ) - PPC_ERROR_PURGE_TIME*24*60*60 ) ) 66 | unset( $errors[$key] ); 67 | } 68 | 69 | //See the record is not bigger than ~10MB 70 | if( strlen( serialize( $errors ) ) > 10000 ) 71 | $errors = array( $error_details ); //only save latest error 72 | 73 | update_option( $ppc_global_settings['option_error_deletion'], current_time( 'timestamp' ) ); 74 | } 75 | 76 | if( file_put_contents( $ppc_global_settings['file_errors'], serialize( $errors ) ) ) 77 | $this->wp_error = new WP_Error( 'ppc_update_error_update', 'Could not update errors option.', 'post-pay-counter' ); 78 | } 79 | 80 | $this->wp_error = new WP_Error( $error_details['code'], $error_details['output'], $data ); 81 | } 82 | 83 | /** 84 | * Returns the error stored in the class var. 85 | * 86 | * @since 2.21 87 | * @access public 88 | * 89 | * @return object WP_Error with current error details 90 | */ 91 | function return_error() { 92 | return $this->wp_error; 93 | } 94 | 95 | /** 96 | * Retrieves an error from the error log, if found. 97 | * Several searching criteria available. 98 | * 99 | * @since 2.604 100 | * @access public 101 | * 102 | * @param $args array 103 | * @return array|bool the error details, or bool false if not found 104 | */ 105 | static function get_error( $args ) { 106 | global $ppc_global_settings; 107 | 108 | if( isset( $args['error_code'] ) AND ! empty( $args['error_code'] ) ) { 109 | $errors = file_get_contents( $ppc_global_settings['file_errors'] ); 110 | 111 | if( $errors !== false ) 112 | $errors = unserialize( $errors ); 113 | else 114 | return false; 115 | 116 | $key = array_search( $args['error_code'], array_column( $errors, 'code' ) ); 117 | 118 | if( is_int( $key ) ) 119 | return $errors[$key]; 120 | } 121 | 122 | return false; 123 | 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /wp-cli.php: -------------------------------------------------------------------------------- 1 | ] 11 | * : Time range start date in YYYY-MM-DD format. 12 | * 13 | * [--time-end=] 14 | * : Time range end date in YYYY-MM-DD format. 15 | * 16 | * [--author=] 17 | * : Author ID if you want to generate specific author stats. 18 | * 19 | * [--as-user=] 20 | * : User ID to generate stats as (for personalized settings purposes). If --author is provided, it is also used as default user. Otherwise, it defaults to 1 (usually an admin). 21 | * 22 | * [--cache-full] 23 | * : Cache full stats snapshot. Cached stats are stored in cache/ folder, and *not removed automatically*. 24 | * 25 | * ## EXAMPLES 26 | * 27 | * $ wp ppc stats --time-start=1 --cache-full 28 | * Generates general stats for all users from the very beginning of time and cache them. 29 | */ 30 | function ppc_cli_stats( $args, $assoc_args ) { 31 | global $ppc_global_settings; 32 | $perm = new PPC_permissions(); 33 | 34 | if( isset( $assoc_args['cache-full'] ) ) { 35 | global $CLI_PPC_CACHE; 36 | $CLI_PPC_CACHE = true; // read by cache retrieval to ignore existing cache when building anew 37 | } 38 | 39 | $begin = time(); 40 | 41 | WP_CLI::line( "Now loading stats..." ); 42 | 43 | $general_settings = PPC_general_functions::get_settings( 'general' ); 44 | $cache_slug = 'ppc_stats'; 45 | 46 | //Initiliaze counting types 47 | $ppc_global_settings['counting_types_object'] = new PPC_counting_types(); 48 | $ppc_global_settings['counting_types_object']->register_built_in_counting_types(); 49 | 50 | PPC_general_functions::get_default_stats_time_range( $general_settings ); 51 | 52 | //Try to parse dates - fallback to default ones if fail 53 | if( isset( $assoc_args['time-start'] ) ) 54 | $assoc_args['time-start'] = @strtotime( $assoc_args['time-start'] ); 55 | else 56 | $assoc_args['time-start'] = $ppc_global_settings['stats_tstart']; 57 | 58 | if( isset( $assoc_args['time-end'] ) ) 59 | $assoc_args['time-end'] = @strtotime( $assoc_args['time-end'].' 23:59:59' ); 60 | else 61 | $assoc_args['time-end'] = $ppc_global_settings['stats_tend']; 62 | 63 | $cache_slug .= '-tstart_'.$assoc_args['time-start'].'-tend_'.$assoc_args['time-end']; 64 | 65 | WP_CLI::line( 'Time range: '.date('Y-m-d', $assoc_args['time-start']).' - '.date( 'Y-m-d', $assoc_args['time-end'] ) ); 66 | 67 | if( ! isset( $assoc_args['author'] ) ) { 68 | $assoc_args['author'] = null; 69 | } else { 70 | WP_CLI::line( 'For author: '.get_userdata( $assoc_args['author'] )->display_name.' (ID: '.$assoc_args['author'].')' ); 71 | $cache_slug .= '-author_'.$assoc_args['author']; 72 | $assoc_args['author'] = array( (int) $assoc_args['author'] ); 73 | } 74 | 75 | //Set current user. Needed for personalized settings & the like 76 | // Only set `as-user` in slug if user has less permissive permissions than admin. 77 | if( ! isset( $assoc_args['as-user'] ) ) { 78 | $assoc_args['as-user'] = 1; 79 | } 80 | wp_set_current_user( (int) $assoc_args['as-user'] ); 81 | WP_CLI::line( 'As user: '.get_userdata( $assoc_args['as-user'] )->display_name.' (ID: '.$assoc_args['as-user'].')' ); 82 | if( ! $perm->can_see_countings_special_settings() OR ! $perm->can_see_others_general_stats() ) { 83 | $cache_slug .= '-as-user_'.$assoc_args['as-user']; 84 | } 85 | 86 | WP_CLI::line( "\nThis may take a while... \n" ); 87 | $stats = PPC_generate_stats::produce_stats( (int) $assoc_args['time-start'], (int) $assoc_args['time-end'], $assoc_args['author'] ); 88 | 89 | if( ! is_wp_error( $stats ) ) { 90 | if( isset( $assoc_args['cache-full'] ) ) { 91 | if( ! is_dir( $ppc_global_settings['dir_path'].'cache' ) ) 92 | mkdir( $ppc_global_settings['dir_path'].'cache' ); 93 | 94 | $cache_data = array( 95 | 'stats' => $stats, 96 | 'time' => current_time( 'timestamp' ), 97 | 'args' => $assoc_args 98 | ); 99 | $cache_outcome = (bool) file_put_contents( $ppc_global_settings['dir_path'].'cache/'.$cache_slug, serialize( $cache_data ) ); 100 | $cache_size = round( strlen( serialize( $stats ) ) / 1024 / 1024, 2 ); 101 | WP_CLI::line( "Cached stats with slug $cache_slug, size $cache_size MB, outcome $cache_outcome" ); 102 | } else { 103 | var_dump( $stats ); 104 | } 105 | 106 | $duration = time() - $begin; 107 | 108 | @WP_CLI::success( "Stats generated in $duration seconds. \nVisit them at: ".admin_url( $ppc_global_settings['stats_menu_link']."&tstart=".$assoc_args['time-start']."&tend=".$assoc_args['time-end']."&author=".$assoc_args['author'][0] ) ); 109 | } else { 110 | WP_CLI::line( "Error: ".$stats->get_error_message() ); 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /js/jquery.tiptip.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | * TipTip 3 | * Copyright 2010 Drew Wilson 4 | * www.drewwilson.com 5 | * code.drewwilson.com/entry/tiptip-jquery-plugin 6 | * 7 | * Version 1.3 - Updated: Mar. 23, 2010 8 | * 9 | * This Plug-In will create a custom tooltip to replace the default 10 | * browser tooltip. It is extremely lightweight and very smart in 11 | * that it detects the edges of the browser window and will make sure 12 | * the tooltip stays within the current window size. As a result the 13 | * tooltip will adjust itself to be displayed above, below, to the left 14 | * or to the right depending on what is necessary to stay within the 15 | * browser window. It is completely customizable as well via CSS. 16 | * 17 | * This TipTip jQuery plug-in is dual licensed under the MIT and GPL licenses: 18 | * http://www.opensource.org/licenses/mit-license.php 19 | * http://www.gnu.org/licenses/gpl.html 20 | */ 21 | (function($){$.fn.tipTip=function(options){var defaults={activation:"hover",keepAlive:false,maxWidth:"200px",edgeOffset:3,defaultPosition:"bottom",delay:400,fadeIn:200,fadeOut:200,attribute:"title",content:false,enter:function(){},exit:function(){}};var opts=$.extend(defaults,options);if($("#tiptip_holder").length<=0){var tiptip_holder=$('
');var tiptip_content=$('
');var tiptip_arrow=$('
');$("body").append(tiptip_holder.html(tiptip_content).prepend(tiptip_arrow.html('
')))}else{var tiptip_holder=$("#tiptip_holder");var tiptip_content=$("#tiptip_content");var tiptip_arrow=$("#tiptip_arrow")}return this.each(function(){var org_elem=$(this);if(opts.content){var org_title=opts.content}else{var org_title=org_elem.attr(opts.attribute)}if(org_title!=""){if(!opts.content){org_elem.removeAttr(opts.attribute)}var timeout=false;if(opts.activation=="hover"){org_elem.hover(function(){active_tiptip()},function(){if(!opts.keepAlive){deactive_tiptip()}});if(opts.keepAlive){tiptip_holder.hover(function(){},function(){deactive_tiptip()})}}else if(opts.activation=="focus"){org_elem.focus(function(){active_tiptip()}).blur(function(){deactive_tiptip()})}else if(opts.activation=="click"){org_elem.click(function(){active_tiptip();return false}).hover(function(){},function(){if(!opts.keepAlive){deactive_tiptip()}});if(opts.keepAlive){tiptip_holder.hover(function(){},function(){deactive_tiptip()})}}function active_tiptip(){opts.enter.call(this);tiptip_content.html(org_title);tiptip_holder.hide().removeAttr("class").css("margin","0");tiptip_arrow.removeAttr("style");var top=parseInt(org_elem.offset()['top']);var left=parseInt(org_elem.offset()['left']);var org_width=parseInt(org_elem.outerWidth());var org_height=parseInt(org_elem.outerHeight());var tip_w=tiptip_holder.outerWidth();var tip_h=tiptip_holder.outerHeight();var w_compare=Math.round((org_width-tip_w)/2);var h_compare=Math.round((org_height-tip_h)/2);var marg_left=Math.round(left+w_compare);var marg_top=Math.round(top+org_height+opts.edgeOffset);var t_class="";var arrow_top="";var arrow_left=Math.round(tip_w-12)/2;if(opts.defaultPosition=="bottom"){t_class="_bottom"}else if(opts.defaultPosition=="top"){t_class="_top"}else if(opts.defaultPosition=="left"){t_class="_left"}else if(opts.defaultPosition=="right"){t_class="_right"}var right_compare=(w_compare+left)parseInt($(window).width());if((right_compare&&w_compare<0)||(t_class=="_right"&&!left_compare)||(t_class=="_left"&&left<(tip_w+opts.edgeOffset+5))){t_class="_right";arrow_top=Math.round(tip_h-13)/2;arrow_left=-12;marg_left=Math.round(left+org_width+opts.edgeOffset);marg_top=Math.round(top+h_compare)}else if((left_compare&&w_compare<0)||(t_class=="_left"&&!right_compare)){t_class="_left";arrow_top=Math.round(tip_h-13)/2;arrow_left=Math.round(tip_w);marg_left=Math.round(left-(tip_w+opts.edgeOffset+5));marg_top=Math.round(top+h_compare)}var top_compare=(top+org_height+opts.edgeOffset+tip_h+8)>parseInt($(window).height()+$(window).scrollTop());var bottom_compare=((top+org_height)-(opts.edgeOffset+tip_h+8))<0;if(top_compare||(t_class=="_bottom"&&top_compare)||(t_class=="_top"&&!bottom_compare)){if(t_class=="_top"||t_class=="_bottom"){t_class="_top"}else{t_class=t_class+"_top"}arrow_top=tip_h;marg_top=Math.round(top-(tip_h+5+opts.edgeOffset))}else if(bottom_compare|(t_class=="_top"&&bottom_compare)||(t_class=="_bottom"&&!top_compare)){if(t_class=="_top"||t_class=="_bottom"){t_class="_bottom"}else{t_class=t_class+"_bottom"}arrow_top=-12;marg_top=Math.round(top+org_height+opts.edgeOffset)}if(t_class=="_right_top"||t_class=="_left_top"){marg_top=marg_top+5}else if(t_class=="_right_bottom"||t_class=="_left_bottom"){marg_top=marg_top-5}if(t_class=="_left_top"||t_class=="_left_bottom"){marg_left=marg_left+5}tiptip_arrow.css({"margin-left":arrow_left+"px","margin-top":arrow_top+"px"});tiptip_holder.css({"margin-left":marg_left+"px","margin-top":marg_top+"px"}).attr("class","tip"+t_class);if(timeout){clearTimeout(timeout)}timeout=setTimeout(function(){tiptip_holder.stop(true,true).fadeIn(opts.fadeIn)},opts.delay)}function deactive_tiptip(){opts.exit.call(this);if(timeout){clearTimeout(timeout)}tiptip_holder.fadeOut(opts.fadeOut)}}})}})(jQuery); -------------------------------------------------------------------------------- /classes/ppc_system_info_class.php: -------------------------------------------------------------------------------- 1 | 32 | 33 |
34 |

Post Pay Counter -

35 |
36 | 120 |

121 | 122 |

123 |
124 |
125 | 126 | ').appendTo(jQuery("#counting_"+counting_type+"_system_zonal_content").find("#"+counting_type+"_0_zone_threshold").parent().parent().parent()); 60 | }); 61 | 62 | jQuery("#counting_"+counting_type+"_less_zones").click(function(e) { 63 | e.preventDefault(); 64 | 65 | if(zones_count == 1){ 66 | alert(ppc_options_effects_vars.localized_too_few_zones); 67 | return false; 68 | } 69 | 70 | jQuery("#"+counting_type+"_"+zones_count+"_zone_threshold").parent().parent().remove(); 71 | zones_count--; 72 | }); 73 | } 74 | 75 | jQuery(document).ready(function($) { 76 | //Counting types 77 | post_pay_counter_checkbox_auto_toggle("#basic_payment", "#ppc_basic_payment_content"); 78 | post_pay_counter_checkbox_auto_toggle("#counting_words", "#ppc_counting_words_content"); 79 | post_pay_counter_checkbox_auto_toggle("#counting_visits", "#ppc_counting_visits_content"); 80 | post_pay_counter_checkbox_auto_toggle("#counting_images", "#ppc_counting_images_content"); 81 | post_pay_counter_checkbox_auto_toggle("#counting_comments", "#ppc_counting_comments_content"); 82 | 83 | //Visits counting methods 84 | post_pay_counter_radio_auto_toggle("#counting_visits_ppc_supported_tracker", "#counting_visits_ppc_supported_tracker_content", "#counting_visits_callback", "#counting_visits_callback_content"); 85 | 86 | //Payments systems 87 | post_pay_counter_radio_auto_toggle("#counting_words_system_zonal", "#counting_words_system_zonal_content", "#counting_words_system_incremental", "#counting_words_system_incremental_content"); 88 | post_pay_counter_radio_auto_toggle("#counting_visits_system_zonal", "#counting_visits_system_zonal_content", "#counting_visits_system_incremental", "#counting_visits_system_incremental_content"); 89 | post_pay_counter_radio_auto_toggle("#counting_images_system_zonal", "#counting_images_system_zonal_content", "#counting_images_system_incremental", "#counting_images_system_incremental_content"); 90 | post_pay_counter_radio_auto_toggle("#counting_comments_system_zonal", "#counting_comments_system_zonal_content", "#counting_comments_system_incremental", "#counting_comments_system_incremental_content"); 91 | 92 | //Initializes tooltips 93 | $(".ppc_tooltip_container").tipTip({ 94 | activation: "click", 95 | keepAlive: "true", 96 | maxWidth: "300px" 97 | }); 98 | 99 | //Prevents counting_payment_only_when_total_threshold from being checked if not threshold is set 100 | $("#counting_payment_only_when_total_threshold").change(function() { 101 | if(this.checked == true) { 102 | if($("#counting_payment_total_threshold").val() == 0) { 103 | $(this).removeAttr("checked"); 104 | alert(ppc_options_effects_vars.localized_need_threshold); 105 | } 106 | } 107 | }); 108 | 109 | //Handles adding/removing of zones 110 | //WORDS 111 | var words_zones_count = (ppc_options_effects_vars.counting_words_current_zones_count-1); 112 | ppc_zones_manager('words', words_zones_count); 113 | 114 | //VISITS 115 | var visits_zones_count = (ppc_options_effects_vars.counting_visits_current_zones_count-1); 116 | ppc_zones_manager('visits', visits_zones_count); 117 | 118 | //IMAGES 119 | var images_zones_count = (ppc_options_effects_vars.counting_images_current_zones_count-1); 120 | ppc_zones_manager('images', images_zones_count); 121 | 122 | //COMMENTS 123 | var comments_zones_count = (ppc_options_effects_vars.counting_comments_current_zones_count-1); 124 | ppc_zones_manager('comments', comments_zones_count); 125 | }); 126 | -------------------------------------------------------------------------------- /classes/ppc_cache_class.php: -------------------------------------------------------------------------------- 1 | array( 'ID' ) ) ); 36 | 37 | foreach( $wp_all_users as $user ) { 38 | self::clear_settings( $user->ID ); 39 | } 40 | } 41 | } 42 | 43 | /** 44 | * Retrieves post stats, if caching is enabled. 45 | * 46 | * @since 2.720 47 | * @param $post_id int 48 | * @return mixed cache content or false 49 | */ 50 | static function get_post_stats( $post_id ) { 51 | $cache_salt = PPC_cache_functions::get_stats_incrementor(); 52 | return wp_cache_get( 'ppc_stats_post_ID-'.$post_id.'-'.$cache_salt, 'ppc_stats' ); 53 | } 54 | 55 | /** 56 | * Stores post stats, if caching is enabled. 57 | * 58 | * @since 2.720 59 | * @param $post_id int 60 | * @return mixed cache content or false 61 | */ 62 | static function set_post_stats( $post_id, $data ) { 63 | $cache_salt = PPC_cache_functions::get_stats_incrementor(); 64 | wp_cache_set( 'ppc_stats_post_ID-'.$post_id.'-'.$cache_salt, $data, 'ppc_stats', 86400 ); 65 | } 66 | 67 | /** 68 | * Clear stats cache for given post. 69 | * 70 | * @since 2.720 71 | * @param $post_id int 72 | * @return void 73 | */ 74 | static function clear_post_stats( $post_id ) { 75 | wp_cache_delete( 'ppc_stats_post_ID-'.$post_id.'-'.self::get_stats_incrementor(), 'ppc_stats' ); 76 | } 77 | 78 | /** 79 | * Clear all stats cache. 80 | * 81 | * @since 2.720 82 | * @return void 83 | */ 84 | static function clear_stats() { 85 | self::get_stats_incrementor( true ); 86 | } 87 | 88 | /** 89 | * Add actions for clearing post stats cache when needed for old versions of addons. 90 | * 91 | * @since 2.720 92 | * @return void 93 | */ 94 | static function clear_post_stats_old_addons() { 95 | global $ppcp_global_settings; 96 | if( isset( $ppcp_global_settings['current_version'] ) AND version_compare( $ppcp_global_settings['current_version'], '1.7.2' ) ) { 97 | add_action( 'ppcp_updated_post_payment_history', array( 'PPC_cache_functions', 'clear_post_stats' ), 10, 1 ); 98 | } 99 | 100 | global $ppcp_fb_global_settings; 101 | if( isset( $ppcp_fb_global_settings['current_version'] ) AND version_compare( $ppcp_fb_global_settings['current_version'], '1.4.1' ) ) { 102 | add_action( 'ppcp_fb_updated_post_data', array( 'PPC_cache_functions', 'clear_post_stats' ), 10, 1 ); 103 | } 104 | } 105 | 106 | /** 107 | * Gets (and updates) incrementor for invalidating stats cache group. 108 | * 109 | * See https://www.tollmanz.com/invalidation-schemes/ for info on how it works. 110 | * 111 | * @since 2.720 112 | * @param $refresh bool whether to refresh the incrementor 113 | * @return string incrementor current value 114 | */ 115 | static function get_stats_incrementor( $refresh = false ) { 116 | if( self::$incrementor_value AND ! $refresh ) 117 | return self::$incrementor_value; 118 | 119 | global $ppc_global_settings; 120 | $incrementor_key = $ppc_global_settings['option_stats_cache_incrementor']; 121 | $incrementor_value = get_option( $incrementor_key ); 122 | 123 | if( $incrementor_value === false OR $refresh === true ) { 124 | $incrementor_value = time(); 125 | update_option( $incrementor_key, $incrementor_value ); 126 | } 127 | 128 | self::$incrementor_value = $incrementor_value; 129 | return $incrementor_value; 130 | } 131 | 132 | /** 133 | * Get full cache snapshot if available. 134 | * 135 | * @since 2.755 136 | * @param $slug string cache slug (also file name) 137 | * @return $cached_data array unserialized cache file content (whole of it!) 138 | */ 139 | static function get_full_stats( $slug ) { 140 | global $ppc_global_settings; 141 | 142 | $path = $ppc_global_settings['dir_path'].'cache/'.$slug; 143 | 144 | if( is_file( $path ) AND filesize( $path ) != 0 ) { 145 | $open = fopen( $path, "r" ); 146 | 147 | $file_content = fread( $open, filesize( $path ) ); 148 | if( $file_content !== false ) { 149 | $cached_data = unserialize( $file_content ); 150 | PPC_counting_stuff::$settings = PPC_general_functions::get_settings( 'general' ); //put some settings there (hack!), since we never go through data2cash() 151 | return $cached_data; 152 | } 153 | } 154 | } 155 | 156 | /** 157 | * Retrieve cached stats snapshot, if available. 158 | * 159 | * Cache snapshots can only be generated through WP-CLI command `wp ppc stats --cache-full`. 160 | * 161 | * @since 2.770 162 | * @param $time_start int 163 | * @param $time_end int 164 | * @param $author array|NULL 165 | * @return stats_array|false 166 | */ 167 | static function get_stats_snapshot( $time_start, $time_end, $author ) { 168 | // Disable cache snapshot with GET arg `no-cache`, or by hooking to this filter, or when creating snapshots through WP-CLI 169 | global $CLI_PPC_CACHE; 170 | if( isset( $CLI_PPC_CACHE ) OR apply_filters( 'ppc_cache_snapshots_default_noload', isset( $_GET['no-cache'] ) ) ) 171 | return false; 172 | 173 | global $ppc_global_settings, $current_user; 174 | $perm = new PPC_permissions(); 175 | 176 | // Build snapshot slug, used as cache filename 177 | $cache_slug = 'ppc_stats-tstart_'.$time_start.'-tend_'.$time_end; 178 | if( ! $perm->can_see_countings_special_settings() ) 179 | $cache_slug .= '-as-user_'.$current_user->ID; 180 | if( is_array( $author ) ) 181 | $cache_slug .= '-author_'.$author[0]; 182 | 183 | // Load cached snapshot from file 184 | $path = $ppc_global_settings['dir_path'].'cache/'.$cache_slug; 185 | if( is_file( $path ) AND filesize( $path ) != 0 ) { 186 | $open = fopen( $path, "r" ); 187 | $file_content = fread( $open, filesize( $path ) ); 188 | if( $file_content !== false ) { 189 | $cached_data = unserialize( $file_content ); 190 | PPC_counting_stuff::$settings = PPC_general_functions::get_settings( 'general' ); // put some settings there (hack!), since we never go through data2cash() 191 | set_transient( 'ppc_full_stats_snapshot_time', $cached_data['time'], 5 ); // for stats page header to know data is from cache, hacky 192 | return $cached_data; 193 | } 194 | } 195 | 196 | return false; 197 | } 198 | } 199 | -------------------------------------------------------------------------------- /classes/ppc_license_class.php: -------------------------------------------------------------------------------- 1 | $check_local_status_function 54 | ) ); 55 | return $error->return_error(); 56 | } 57 | 58 | $this->local_status = $local_status; 59 | $this->remote_URL = $remote_URL; 60 | $this->addon_version = $addon_version; 61 | $this->activation_key_name = $activation_key_name; 62 | } 63 | 64 | /** 65 | * Calls home for license stuff. 66 | * 67 | * @access public 68 | * @since 2.511 69 | * @param $parameters array http request parameters 70 | * @return array request result details 71 | */ 72 | function license_request( $parameters ) { 73 | global $ppc_global_settings; 74 | 75 | //Send website url, language, current plugin version along 76 | $parameters['website'] = site_url(); 77 | $parameters['language'] = get_bloginfo( 'language' ); 78 | $parameters['PPC_version'] = $ppc_global_settings['current_version']; 79 | $parameters['addon_version'] = $this->addon_version; 80 | 81 | $parameters = apply_filters( 'ppcp_license_request_parameters', $parameters ); 82 | 83 | $headers['Accept'] = 'text/html'; 84 | 85 | $request = wp_remote_post( $this->remote_URL, array( 86 | 'timeout' => 10, 87 | 'body' => $parameters, 88 | 'headers' => $headers 89 | ) ); 90 | 91 | if( is_wp_error( $request ) ) { 92 | $error = new PPC_Error( 'ppcp_license_request_connection_error', sprintf( __( 'Error', 'ppcp').': '.$request->get_error_message().'.' ), array( 93 | 'request_url' => $this->remote_URL, 94 | 'parameters' => $parameters 95 | ) ); 96 | return $error->return_error(); 97 | 98 | } else if( $request['response']['code'] != 200 ) { 99 | $error = new PPC_Error( 'ppcp_license_request_reponse_error', __( 'Error', 'ppcp').': '.$request['response']['code'].' - '.$request['response']['message'], array( 100 | 'request_url' => $this->remote_URL, 101 | 'parameters' => $parameters 102 | ) ); 103 | return $error->return_error(); 104 | 105 | } else if( ! isset( $request['headers']['ppcp_activation_status'] ) ) { 106 | $error = new PPC_Error( 'ppcp_license_request_remote_error', __( 'Error: something went wrong on the remote server. This should be reported.', 'ppcp' ), array( 107 | 'request_url' => $this->remote_URL, 108 | 'parameters' => $parameters 109 | ) ); 110 | return $error->return_error(); 111 | 112 | } else if( $request['headers']['ppcp_activation_status'] == 'false' ) { 113 | $error = new PPC_Error( 'ppcp_license_request_activation_error', $request['headers']['ppcp_activation_error'], array( 114 | 'request_url' => $this->remote_URL, 115 | 'parameters' => $parameters 116 | ) ); 117 | return $error->return_error(); 118 | } 119 | 120 | return $request; 121 | } 122 | 123 | /** 124 | * Cares about license activation 125 | * 126 | * @access public 127 | * @since 2.511 128 | * 129 | * @param $license key string license key 130 | */ 131 | function activate( $license_key ) { 132 | if( $this->local_status ) { 133 | $error = new PPC_Error( 'ppcp_already_pro', __( 'You already have an active license for this addon.', 'ppc' ), array( 134 | 'remote_url' => $this->remote_URL 135 | ) ); 136 | return $error->return_error(); 137 | } 138 | 139 | $request = $this->license_request( array( 140 | 'license_key' => $license_key 141 | ) ); 142 | 143 | if( is_wp_error( $request ) ) return $request; 144 | 145 | //Try to add option first, and then to update it if doesn't work 146 | if( ! update_option( $this->activation_key_name, maybe_unserialize( $request['headers']['ppcp_activation_details'] ) ) ) { 147 | $error = new PPC_Error( 'ppcp_license_activation_error', __( 'Error: could not store license details.', 'ppc' ), array( 148 | 'meta_name' => $this->activation_key_name, 149 | 'meta_value' => get_option( $this->activation_key_name ), 150 | 'license_key' => $license_key, 151 | 'activation_key' => maybe_unserialize( $request['headers']['ppcp_activation_details'] ) 152 | ) ); 153 | return $error->return_error(); 154 | } 155 | } 156 | 157 | /** 158 | * Deactivates current license key for this website. 159 | * 160 | * @access public 161 | * @since 2.511 162 | */ 163 | function deactivate() { 164 | if( ! $this->local_status ) { 165 | $error = new PPC_Error( 'ppcp_not_pro', __( 'You do not have an active license for this addon.', 'ppc' ), array( 166 | 'remote_url' => $this->remote_URL 167 | ) ); 168 | return $error->return_error(); 169 | } 170 | 171 | $request = $this->license_request( array( 172 | 'license_deactivate' => true, 173 | 'activation_key' => get_option( $this->activation_key_name ) 174 | ) ); 175 | 176 | if( is_wp_error( $request ) ) return $request; 177 | 178 | delete_option( $this->activation_key_name ); 179 | } 180 | 181 | /** 182 | * Checks whether stored activation key is valid. 183 | * 184 | * Scheduled event. 185 | * 186 | * @access public 187 | * @since 2.511 188 | */ 189 | function check_activation() { 190 | if( ! $this->local_status ) { 191 | $error = new PPC_Error( 'ppcp_not_pro', __( 'You do not have an active license for this addon.', 'ppc' ), array( 192 | 'remote_url' => $this->remote_URL 193 | ) ); 194 | return $error->return_error(); 195 | } 196 | 197 | $request = $this->license_request( array( 198 | 'activation_key' => get_option( $this->activation_key_name ) 199 | ) ); 200 | 201 | if( is_wp_error( $request ) AND $request->get_error_code() == 'ppcp_license_request_activation_error' ) 202 | delete_option( $this->activation_key_name ); 203 | else 204 | update_option( $this->activation_key_name, maybe_unserialize( $request['headers']['ppcp_activation_details'] ) ); 205 | } 206 | } 207 | -------------------------------------------------------------------------------- /classes/ppc_autoupdate_class.php: -------------------------------------------------------------------------------- 1 | last_checked ) OR ! isset( $transient->checked ) ) return; 56 | 57 | $checked_plugins = $transient->checked; 58 | //if( $transient->last_checked > ( time() - 3600*6 ) AND isset( $checked_plugins[$plugin_slug] ) ) 59 | //return; 60 | 61 | // Set the class public variables 62 | $this->current_version = $current_version; 63 | $this->update_path = $update_path; 64 | $this->plugin_slug = $plugin_slug; 65 | $this->activation_key_name = $activation_key_name; 66 | $this->activation_key = get_option( $activation_key_name ); 67 | $this->activation_key = $this->activation_key['activation_key']; 68 | 69 | list($t1, $t2) = explode('/', $plugin_slug); 70 | $this->slug = str_replace('.php', '', $t2); 71 | 72 | // define the alternative API for updating checking 73 | add_filter('pre_set_site_transient_update_plugins', array(&$this, 'check_update')); 74 | 75 | // Define the alternative response for information checking 76 | add_filter('plugins_api', array(&$this, 'check_info'), 10, 3); 77 | 78 | //Enqueue on WP cron event 79 | add_action( 'wp_update_plugins', array( &$this, 'check_update' ) ); 80 | 81 | //Maybe display notice in plugin page if addon license is expired 82 | add_action( 'in_plugin_update_message-' . plugin_basename( $this->plugin_slug ), array( $this, 'plugin_row_license_missing' ), 10, 2 ); 83 | } 84 | 85 | /** 86 | * Add our self-hosted autoupdate plugin to the filter transient 87 | * 88 | * @param $transient 89 | * @return object $ transient 90 | */ 91 | public function check_update($transient = array()) { 92 | global $ppc_global_settings; 93 | 94 | if (empty($transient)) 95 | $transient = get_site_transient( 'update_plugins' ); 96 | 97 | // Get the remote version 98 | $remote_version = $this->getRemote_version(); 99 | 100 | // If a newer version is available, add the update 101 | if (version_compare($this->current_version, $remote_version, '<')) { 102 | 103 | //Get information and download url 104 | $information = $this->getRemote_information(); 105 | 106 | if( ! is_object( $information ) ) return; 107 | 108 | $icon_url = 'https://postpaycounter.com/ppc/icon-256x256.png'; 109 | if( isset( $information->icon_url ) AND $information->icon_url != '' ) 110 | $icon_url = $information->icon_url; 111 | 112 | $obj = new stdClass(); 113 | $obj->slug = $this->slug; 114 | $obj->new_version = $remote_version; 115 | $obj->url = $this->update_path; 116 | $obj->package = $information->download_link; 117 | $obj->requires_php = $information->requires; 118 | $obj->tested = $information->tested; 119 | $obj->plugin = $this->plugin_slug; 120 | $obj->icons = array( '1x' => $icon_url ); 121 | $transient->response[$this->plugin_slug] = $obj; 122 | $transient->checked[$this->plugin_slug] = $obj->new_version; 123 | } 124 | 125 | return $transient; 126 | } 127 | 128 | /** 129 | * Add our self-hosted description to the filter 130 | * 131 | * @param boolean $false 132 | * @param array $action 133 | * @param object $arg 134 | * @return bool|object 135 | */ 136 | public function check_info($false, $action, $arg) { 137 | if (isset($arg->slug) AND $arg->slug === $this->slug) { 138 | $information = $this->getRemote_information(); 139 | return $information; 140 | } 141 | 142 | /** 143 | * Return variable $false instead of explicitly returning boolean FALSE 144 | * wordpress passes FALSE here by default 145 | */ 146 | return $false; 147 | } 148 | 149 | /** 150 | * Return the remote version 151 | * @return string $remote_version 152 | */ 153 | public function getRemote_version() { 154 | global $ppc_global_settings; 155 | 156 | $request = wp_remote_post( $this->update_path, apply_filters( 'ppcp_autoupdate_get_remote_version_args', array( 157 | 'timeout' => 10, 158 | 'body' => array( 159 | 'action' => 'version', 160 | 'activation_key' => $this->activation_key, 161 | 'website' => site_url(), 162 | 'language' => get_bloginfo( 'language' ), 163 | 'PPC_version' => $ppc_global_settings['current_version'], 164 | 'addon_version' => $this->current_version 165 | ) 166 | ) ) ); 167 | 168 | if ( ! is_wp_error($request) || wp_remote_retrieve_response_code( $request ) === 200 ) { 169 | return $request['body']; 170 | } else { 171 | new PPC_Error( 'ppcp_get_remote_version_error', 'Could not get latest version from update server.', array( 172 | 'response_code' => wp_remote_retrieve_response_code($request), 173 | 'request' => $request 174 | ), false ); 175 | } 176 | } 177 | 178 | /** 179 | * Get information about the remote version 180 | * @return bool|object 181 | */ 182 | public function getRemote_information() { 183 | global $ppc_global_settings; 184 | 185 | $request = wp_remote_post( $this->update_path, apply_filters( 'ppcp_autoupdate_get_remote_information_args', array( 186 | 'timeout' => 10, 187 | 'body' => array( 188 | 'action' => 'info', 189 | 'website' => site_url(), 190 | 'activation_key' => $this->activation_key, 191 | 'language' => get_bloginfo( 'language' ), 192 | 'PPC_version' => $ppc_global_settings['current_version'], 193 | 'addon_version' => $this->current_version 194 | ) 195 | ) ) ); 196 | 197 | if ( ! is_wp_error( $request ) || wp_remote_retrieve_response_code( $request ) === 200 ) { 198 | return maybe_unserialize( $request['body'] ); 199 | } else { 200 | new PPC_Error( 'ppcp_get_remote_information_error', 'Could not get latest version information from update server.', array( 201 | 'response_code' => wp_remote_retrieve_response_code($request), 202 | 'request' => $request 203 | ) ); 204 | } 205 | } 206 | 207 | /** 208 | * Displays message inline on plugin row that the license key is expired 209 | * 210 | * @access public 211 | * @since 2.602 212 | * @return void 213 | * @from EDD 214 | */ 215 | public function plugin_row_license_missing( $plugin_data, $version_info ) { 216 | $license = get_option( $this->activation_key_name ); 217 | if( ( is_array( $license ) AND $license['expiration_time'] < current_time( 'timestamp' ) ) ) 218 | echo '
'.__( 'Your license has expired, so you may no longer update to newer versions nor receive support. Renew your license!' ).''; 219 | } 220 | } -------------------------------------------------------------------------------- /classes/ppc_addons_class.php: -------------------------------------------------------------------------------- 1 | array( 35 | 'Addons Premium Bundle' => array( 36 | 'description' => 'Our best addons at discounted price. All the payment tracking features to save time and pay authors easily!', 37 | 'image' => 'https://postpaycounter.com/ppcp/features/images/addons-premium-bundle.png', 38 | 'link' => 'https://postpaycounter.com/addons-premium-bundle', 39 | 'campaign' => 'ppc_premium_bundle' 40 | ), 41 | 'Post Pay Counter PRO' => array( 42 | 'description' => 'Keep track of past payments, integrate with PayPal, Analytics and Adsense, and much more!', 43 | 'image' => 'https://postpaycounter.com/ppcp/features/images/ppcp.png', 44 | 'link' => 'https://postpaycounter.com/post-pay-counter-pro', 45 | 'campaign' => 'ppcp' 46 | ), 47 | 'Facebook' => array( 48 | 'description' => 'Pay writers basing on the number of Facebook shares, likes and comments their articles receive.', 49 | 'image' => 'https://postpaycounter.com/ppcp_fb/features/images/stats.png', 50 | 'link' => 'https://postpaycounter.com/facebook-pay-per-social-interactions-shares-likes-and-comments', 51 | 'campaign' => 'ppcp_fb' 52 | ), 53 | 'BuddyPress' => array( 54 | 'description' => 'Displays stats, payment history and PayPal email field in BuddyPress Member page.', 55 | 'image' => 'https://postpaycounter.com/ppc_buddypress/features/images/buddypress-stats_crop.png', 56 | 'link' => 'https://postpaycounter.com/buddypress', 57 | 'campaign' => 'ppc_buddypress' 58 | ), 59 | 'Payment Request' => array( 60 | 'description' => 'Allows authors to request payment when they reach a certain threshold.', 61 | 'image' => 'https://postpaycounter.com/ppcp_rp/features/images/payment-request.png', 62 | 'link' => 'https://postpaycounter.com/request-payment-require-authors-reach-threshold-request-paid/', 63 | 'campaign' => 'ppc_rp' 64 | ), 65 | 'Referral Visits' => array( 66 | 'description' => 'Pay authors for the visitors they bring to your site.', 67 | 'image' => 'https://postpaycounter.com/wp-content/uploads/2018/02/ppc-referral-2.png', 68 | 'link' => 'https://postpaycounter.com/referral-visits-pay-users-visitors-bring-site/', 69 | 'campaign' => 'ppc_ref_vis' 70 | ), 71 | 'Author Payment Bonus' => array( 72 | 'description' => 'Award a bonus to writers before paying: personally tweak the payroll, giving authors a little reward.', 73 | 'image' => 'https://postpaycounter.com/ppc_apb/features/images/payment_confirm_crop.png', 74 | 'link' => 'https://postpaycounter.com/author-payment-bonus-manually-change-the-total-payout-to-authors/', 75 | 'campaign' => 'ppc_apb' 76 | ), 77 | 'Publisher bonus' => array( 78 | 'description' => 'Set up an author rewarding system in which users (proof-readers) earn bonus by publishing posts.', 79 | 'image' => 'https://postpaycounter.com/ppcp_pb/features/images/metabox.png', 80 | 'link' => 'https://postpaycounter.com/publisher-bonus-editor-rewarding-system', 81 | 'campaign' => 'ppcp_pb' 82 | ), 83 | 'User Roles Custom Settings' => array( 84 | 'description' => 'Allows to set custom settings for each user role that apply to all users belonging to it.', 85 | 'image' => 'https://postpaycounter.com/ppc_urcs/features/images/personalize_settings_box.jpg', 86 | 'link' => 'https://postpaycounter.com/user-roles-custom-settings', 87 | 'campaign' => 'ppc_urcs' 88 | ), 89 | 'Custom Email Notifications' => array( 90 | 'description' => 'Allows to customize payment email notifications sent by the PRO version when users are paid.', 91 | 'image' => 'https://postpaycounter.com/ppc_cen/features/images/custom-email-notifications.png', 92 | 'link' => 'https://postpaycounter.com/custom-email-notifications/', 93 | 'campaign' => 'ppc_cen' 94 | ), 95 | 'Category Custom Settings' => array( 96 | 'description' => 'Allows to set custom settings for each category that apply to all posts belonging to it.', 97 | 'image' => 'https://postpaycounter.com/ppc_ccs/features/images/category-custom-settings.png', 98 | 'link' => 'https://postpaycounter.com/category-custom-settings', 99 | 'campaign' => 'ppc_ccs' 100 | ), 101 | 'Pay Per Character' => array( 102 | 'description' => 'Allows to pay writers depending on how many characters their posts are made of.', 103 | 'image' => 'https://postpaycounter.com/ppc_ppc/features/images/stats.png', 104 | 'link' => 'https://postpaycounter.com/pay-per-character', 105 | 'campaign' => 'ppc_ppc' 106 | ), 107 | 'Author Basic Payment' => array( 108 | 'description' => 'Allows to award authors a fixed fee for each payment.', 109 | 'image' => 'https://postpaycounter.com/ppc_abp/features/images/stats.png', 110 | 'link' => 'https://postpaycounter.com/author-basic-payment', 111 | 'campaign' => 'ppc_abp' 112 | ), 113 | 'Stop Words' => array( 114 | 'description' => 'Allows to specify a list of stop words that should not be counted when computing posts word count.', 115 | 'image' => 'https://postpaycounter.com/ppcp_sw/features/images/stopwords.png', 116 | 'link' => 'https://postpaycounter.com/stop-words-exclude-certain-words', 117 | 'campaign' => 'ppcp_sw' 118 | ), 119 | 'Shortcode Stripper' => array( 120 | 'description' => 'Allows to exclude text enclosed by shortcodes from words payment.', 121 | 'image' => 'https://postpaycounter.com/ppc/addons/shortcode.jpg', 122 | 'link' => 'https://postpaycounter.com/shortcode-stripper-exclude-shortcodes-from-words-payment/', 123 | 'campaign' => 'ppc_shortcode_stripper' 124 | ) 125 | ), 126 | 'time' => current_time( 'timestamp' ) + 3600*48 127 | ); 128 | 129 | foreach( $addons['data'] as $title => &$info ) 130 | $info['link'] .= '?utm_source=users_site&utm_medium=addons_list&utm_campaign='.$info['campaign']; //referral 131 | 132 | if( ! get_option( 'ppc_addons_list' ) ) 133 | add_option( 'ppc_addons_list', $addons, '', 'no' ); 134 | else 135 | update_option( 'ppc_addons_list', $addons ); 136 | } 137 | 138 | /** 139 | * Add-ons Page 140 | * 141 | * Renders the add-ons page content. 142 | * 143 | * @ccess public 144 | * @since 2.40 145 | */ 146 | static function addons_page() { 147 | ?> 148 |
149 |

150 | 151 |  —  152 |

153 |

154 | 155 |
156 | 10 ) ); 172 | 173 | if ( ! is_wp_error( $feed ) ) { 174 | if ( isset( $feed['body'] ) && strlen( $feed['body'] ) > 0 ) { 175 | $cache = array(); 176 | $cache['data'] = wp_remote_retrieve_body( $feed ); 177 | $cache['time'] = current_time() + 3600*48; 178 | 179 | update_option( 'ppc_addons_list', $cache ); 180 | } 181 | } else { 182 | if( ! isset( $cache['data'] ) OR ! is_array( $cache['data'] ) ) 183 | $cache['data'] = '

' . __( 'There was an error retrieving the extensions list from the server. Please try again later.', 'post-pay-counter' ) . '

'; 184 | } 185 | }*/ 186 | 187 | //We stopped pulling addons list from remote server since version 2.518 188 | if( is_string( $cache['data'] ) ) { 189 | return $cache['data']; 190 | } else if( is_array( $cache['data'] ) ) { 191 | $return = ''; 192 | 193 | foreach( $cache['data'] as $title => $info ) { 194 | $return .= '
195 |

'.$title.'

196 | 197 |

'.$info['description'].'

198 | Get this Add On 199 |
'; 200 | } 201 | 202 | return $return; 203 | } 204 | 205 | } 206 | } 207 | -------------------------------------------------------------------------------- /js/ppc_options_ajax_stuff.js: -------------------------------------------------------------------------------- 1 | jQuery(document).ready(function($) { 2 | 3 | /* */ 4 | $('#ppc_save_counting_settings').on("click", function(e) { 5 | e.preventDefault(); 6 | $('#ppc_counting_settings_ajax_loader').css('display', 'inline'); 7 | $('#ppc_counting_settings_error').css('display', 'none'); 8 | $('#ppc_counting_settings_success').css('display', 'none'); 9 | 10 | var data = { 11 | action: "ppc_save_counting_settings", 12 | _ajax_nonce: ppc_options_ajax_stuff_vars.nonce_ppc_save_counting_settings, 13 | form_data: $('#ppc_counting_settings_form').serialize() 14 | }; 15 | 16 | $.post(ajaxurl, data, function(response) { 17 | $('#ppc_counting_settings_ajax_loader').css('display', 'none'); 18 | 19 | if(response.indexOf('ok') < 0) { 20 | $('#ppc_counting_settings_error').html(response); 21 | $('#ppc_counting_settings_error').css('display', 'inline'); 22 | } else { 23 | $('#ppc_counting_settings_success').css('display', 'inline'); 24 | } 25 | }); 26 | }); 27 | /* */ 28 | 29 | /* */ 30 | $('#ppc_save_misc_settings').on("click", function(e) { 31 | e.preventDefault(); 32 | $('#ppc_misc_settings_ajax_loader').css('display', 'inline'); 33 | $('#ppc_misc_settings_error').css('display', 'none'); 34 | $('#ppc_misc_settings_success').css('display', 'none'); 35 | 36 | var data = { 37 | action: "ppc_save_misc_settings", 38 | _ajax_nonce: ppc_options_ajax_stuff_vars.nonce_ppc_save_misc_settings, 39 | form_data: $('#ppc_misc_settings_form').serialize() 40 | }; 41 | 42 | $.post(ajaxurl, data, function(response) { 43 | $('#ppc_misc_settings_ajax_loader').css('display', 'none'); 44 | 45 | if(response.indexOf('ok') < 0) { 46 | $('#ppc_misc_settings_error').html(response); 47 | $('#ppc_misc_settings_error').css('display', 'inline'); 48 | } else { 49 | $('#ppc_misc_settings_success').css('display', 'inline'); 50 | } 51 | }); 52 | }); 53 | /* */ 54 | 55 | /* */ 56 | $('#ppc_save_permissions').on("click", function(e) { 57 | e.preventDefault(); 58 | $('#ppc_permissions_ajax_loader').css('display', 'inline'); 59 | $('#ppc_permissions_error').css('display', 'none'); 60 | $('#ppc_permissions_success').css('display', 'none'); 61 | 62 | var data = { 63 | action: "ppc_save_permissions", 64 | _ajax_nonce: ppc_options_ajax_stuff_vars.nonce_ppc_save_permissions, 65 | form_data: $('#ppc_permissions_form').serialize() 66 | }; 67 | 68 | $.post(ajaxurl, data, function(response) { 69 | $('#ppc_permissions_ajax_loader').css('display', 'none'); 70 | 71 | if(response.indexOf('ok') < 0) { 72 | $('#ppc_permissions_error').html(response); 73 | $('#ppc_permissions_error').css('display', 'inline'); 74 | } else { 75 | $('#ppc_permissions_success').css('display', 'inline'); 76 | } 77 | }); 78 | }); 79 | /* */ 80 | 81 | /* */ 82 | $('.ppc_personalize_roles').on('click', function(e) { 83 | e.preventDefault(); 84 | $('#ppc_personalize_settings_ajax_loader').css('display', 'inline'); 85 | $('#ppc_personalize_user_roles').css('opacity', '0.6'); 86 | $("#ppc_personalize_users").css('display', 'none'); 87 | $("#ppc_users").html(""); 88 | 89 | var data = { 90 | action: "ppc_personalize_fetch_users_by_roles", 91 | user_role: $(this).attr("id"), 92 | _ajax_nonce: ppc_options_ajax_stuff_vars.nonce_ppc_personalize_fetch_users_by_roles 93 | }; 94 | 95 | $.post(ajaxurl, data, function(response) { 96 | if(response.indexOf('ok') < 0) { 97 | alert(response); 98 | } else { 99 | response = response.substr(2); 100 | $('#ppc_personalize_settings_ajax_loader').css('display', 'none'); 101 | $("#ppc_personalize_users").css('display', 'block'); 102 | $('#ppc_personalize_user_roles').css('opacity', '1'); 103 | $("#ppc_users").html(response); 104 | } 105 | }); 106 | }); 107 | /* */ 108 | 109 | /* */ 110 | $('#vaporize_user_settings').on('click', function(e) { 111 | e.preventDefault(); 112 | 113 | var data = { 114 | action: "ppc_vaporize_user_settings", 115 | user_id: $(this).attr("accesskey"), 116 | _ajax_nonce: ppc_options_ajax_stuff_vars.nonce_ppc_vaporize_user_settings 117 | }; 118 | 119 | $.post(ajaxurl, data, function(response) { 120 | if(response.indexOf('ok') < 0) { 121 | alert(response); 122 | } else { 123 | alert(ppc_options_ajax_stuff_vars.localized_vaporize_user_success); 124 | window.location.replace(ppc_options_ajax_stuff_vars.ppc_options_url); 125 | } 126 | }); 127 | }); 128 | /* */ 129 | 130 | /* */ 131 | $('#ppc_import_settings').on('click', function(e) { 132 | e.preventDefault(); 133 | $('#ppc_import_settings_ajax_loader').css('display', 'inline'); 134 | $('#ppc_import_settings_error').css('display', 'none'); 135 | $('#ppc_import_settings_success').css('display', 'none'); 136 | 137 | var data = { 138 | action: "ppc_import_settings", 139 | import_settings_content: $("#ppc_import_settings_content").val(), 140 | userid: $("#ppc_import_settings_userid").val(), 141 | _ajax_nonce: ppc_options_ajax_stuff_vars.nonce_ppc_import_settings 142 | }; 143 | 144 | $.post(ajaxurl, data, function(response) { 145 | $('#ppc_import_settings_ajax_loader').css('display', 'none'); 146 | 147 | if(! response.success) { 148 | $('#ppc_import_settings_error').html(response.data.message); 149 | $('#ppc_import_settings_error').css('display', 'inline'); 150 | } else { 151 | $('#ppc_import_settings_success').css('display', 'inline'); 152 | } 153 | }); 154 | }); 155 | /* */ 156 | 157 | /* */ 158 | $('#ppc_clear_error_log').on('click', function(e) { 159 | e.preventDefault(); 160 | $('#ppc_error_log_ajax_loader').css('display', 'inline'); 161 | $('#ppc_error_log_error').css('display', 'none'); 162 | $('#ppc_error_log_success').css('display', 'none'); 163 | 164 | var data = { 165 | action: "ppc_clear_error_log", 166 | _ajax_nonce: ppc_options_ajax_stuff_vars.nonce_ppc_clear_error_log 167 | }; 168 | 169 | $.post(ajaxurl, data, function(response) { 170 | $('#ppc_error_log_ajax_loader').css('display', 'none'); 171 | 172 | if(response.indexOf('ok') < 0) { 173 | $('#ppc_error_log_error').html(response); 174 | $('#ppc_error_log_error').css('display', 'inline'); 175 | } else { 176 | $('#ppc_error_log_success').css('display', 'inline'); 177 | } 178 | }); 179 | }); 180 | /* */ 181 | 182 | /* */ 183 | $('.ppc_license_deactivate').on('click', function(e) { 184 | e.preventDefault(); 185 | 186 | var agree = confirm(ppc_options_ajax_stuff_vars.localized_license_deactivate_warning); 187 | if(!agree) { return false; } 188 | 189 | var clicked = $(this); 190 | 191 | $('#ppc_license_ajax_loader').css('display', 'inline'); 192 | clicked.attr('disabled', 'disabled'); 193 | $('#ppc_license_error').css('display', 'none'); 194 | 195 | var data = { 196 | action: "ppc_license_deactivate", 197 | plugin_slug: clicked.attr('accesskey'), 198 | _ajax_nonce: ppc_options_ajax_stuff_vars.nonce_ppc_license_key_deactivate 199 | }; 200 | 201 | $.post(ajaxurl, data, function(response) { 202 | $('#ppc_license_ajax_loader').css('display', 'none'); 203 | 204 | if(response.indexOf('ok') < 0) { 205 | clicked.removeAttr('disabled'); 206 | $('#ppc_license_error').css('display', 'inline'); 207 | $('#ppc_license_error').html(response); 208 | } else { 209 | clicked.closest('tr').fadeOut(); 210 | } 211 | }); 212 | }); 213 | 214 | $('#ppc_license_key').bind('input', function() { 215 | if($('#ppc_license_key').val() != '') { 216 | $('#ppc_license_key_submit').removeAttr('disabled'); 217 | } else { 218 | $('#ppc_license_key_submit').attr('disabled', 'disabled'); 219 | } 220 | }); 221 | 222 | $('#ppc_license_key_submit').on('click', function(e) { 223 | e.preventDefault(); 224 | $('#ppc_license_ajax_loader').css('display', 'inline'); 225 | $('#ppc_license_error').css('display', 'none'); 226 | $('#ppc_license_key').attr('disabled', 'disabled'); 227 | $('#ppc_license_key_submit').attr('disabled', 'disabled'); 228 | 229 | var data = { 230 | action: "ppc_license_activate", 231 | _ajax_nonce: ppc_options_ajax_stuff_vars.nonce_ppc_license_key_activate, 232 | license_key: $('#ppc_license_key').val() 233 | }; 234 | 235 | $.post(ajaxurl, data, function(response) { 236 | $('#ppc_license_ajax_loader').css('display', 'none'); 237 | 238 | if(response.indexOf('ok') < 0) { 239 | $('#ppc_license_key_submit').removeAttr('disabled'); 240 | $('#ppc_license_key').removeAttr('disabled'); 241 | $('#ppc_license_error').css('display', 'inline'); 242 | $('#ppc_license_error').html(response); 243 | } else { 244 | $('#ppc_license_success').css('display', 'inline'); 245 | } 246 | }); 247 | }); 248 | /* */ 249 | 250 | }); 251 | -------------------------------------------------------------------------------- /classes/ppc_update_class.php: -------------------------------------------------------------------------------- 1 | get_col( "SELECT blog_id FROM ".$wpdb->blogs ); 24 | 25 | foreach( $blog_ids as $blog_id ) { 26 | switch_to_blog( $blog_id ); 27 | self::update_exec(); 28 | } 29 | 30 | restore_current_blog(); 31 | return; 32 | } 33 | 34 | self::update_exec(); 35 | } 36 | 37 | /** 38 | * Runs update procedure. 39 | * Changed @ 2.3.1 40 | * 41 | * Also updates current version option and pages permissions. 42 | * 43 | * @access public 44 | * @since 2.0.5 45 | */ 46 | static function update_exec() { 47 | global $ppc_global_settings; 48 | 49 | $general_settings = PPC_general_functions::get_settings( 'general' ); 50 | $general_settings_old = $general_settings; 51 | 52 | //Fixed: installation added personalized user settings in place of general ones (v 2.1.1) 53 | if( $general_settings['userid'] != 'general' ) { 54 | delete_option( $ppc_global_settings['option_name'] ); 55 | unset( $ppc_global_settings['general_settings'] ); 56 | PPC_install_functions::ppc_install_procedure(); 57 | } 58 | 59 | /** 60 | * Settings updates 61 | */ 62 | $new_settings = array( 63 | 'display_overall_stats' => 1, 64 | 'counting_visits_callback_value' => '', 65 | 'admins_override_permissions' => 0, 66 | 'basic_payment_display_status' => 'tooltip', 67 | 'counting_words_display_status' => 'count', 68 | 'counting_words_include_excerpt' => 0, 69 | 'counting_words_legacy' => 1, 70 | 'counting_visits_display_status' => 'count', 71 | 'counting_images_display_status' => 'count', 72 | 'counting_comments_display_status' => 'count', 73 | 'stats_display_edit_post_link' => 0, 74 | 'counting_words_parse_spaces' => 0, 75 | 'enable_stats_payments_tooltips' => 1, 76 | 'default_stats_time_range_last_month' => 0, 77 | 'default_stats_time_range_this_year' => 0, 78 | 'default_stats_time_range_all_time' => 0, 79 | 'default_stats_time_range_start_day' => 0, 80 | 'default_stats_time_range_start_day_value' => '1605-11-05', 81 | 'enable_post_stats_caching' => 1, 82 | 'payment_display_round_digits' => 2, 83 | 'save_stats_order' => 1, 84 | 'hide_column_total_payment' => 0, 85 | 'counting_words_global_threshold' => 0, 86 | 'counting_visits_global_threshold' => 0, 87 | 'counting_comments_global_threshold' => 0, 88 | 'counting_images_global_threshold' => 0, 89 | 'counting_words_exclude_pre' => 0, 90 | 'counting_words_exclude_captions' => 0, 91 | 'counting_words_apply_shortcodes' => 0, 92 | 'counting_visits_display_percentage' => 100, 93 | 'stats_show_all_users' => 0, 94 | ); 95 | 96 | foreach( $new_settings as $setting => $value ) { 97 | if( ! isset( $general_settings[$setting] ) ) 98 | $general_settings[$setting] = $value; 99 | } 100 | 101 | //Count private posts 102 | if( ! isset( $general_settings['counting_allowed_post_statuses']['private'] ) ) 103 | $general_settings['counting_allowed_post_statuses']['private'] = 0; 104 | 105 | //Images & comments problems with counting systems - general and personalized settings update (v 2.1.2) 106 | if( isset( $general_settings['counting_images_value'] ) OR isset( $general_settings['counting_comments_value'] ) ) { 107 | $general_settings['counting_images_system_incremental_value'] = $general_settings['counting_images_value']; 108 | $general_settings['counting_comments_system_incremental_value'] = $general_settings['counting_comments_value']; 109 | unset( $general_settings['counting_images_value'], $general_settings['counting_comments_value'] ); 110 | } 111 | 112 | //Migrate visits trackers 113 | if( ! isset( $general_settings['counting_visits_tracker'] ) ) { 114 | if( $general_settings['counting_visits_callback'] == 'ppc_wp_slimstat_views' ) { 115 | $general_settings['counting_visits_tracker'] = 'slimstat-analytics'; 116 | $general_settings['counting_visits_ppc_supported_tracker'] = 1; 117 | $general_settings['counting_visits_callback'] = 0; 118 | } 119 | if( $general_settings['counting_visits_callback'] == 'ppc_pvc_views' ) { 120 | $general_settings['counting_visits_tracker'] = 'post-views-counter'; 121 | $general_settings['counting_visits_ppc_supported_tracker'] = 1; 122 | $general_settings['counting_visits_callback'] = 0; 123 | } 124 | if( $general_settings['counting_visits_postmeta'] == 'views' ) { 125 | $general_settings['counting_visits_tracker'] = 'wp-postviews'; 126 | $general_settings['counting_visits_ppc_supported_tracker'] = 1; 127 | $general_settings['counting_visits_postmeta'] = 0; 128 | } 129 | if( isset( $general_settings['counting_visits_google_analytics'] ) AND $general_settings['counting_visits_google_analytics'] ) { 130 | $general_settings['counting_visits_tracker'] = 'google-universal-analytics'; 131 | $general_settings['counting_visits_ppc_supported_tracker'] = 1; 132 | $general_settings['counting_visits_callback'] = 0; 133 | } 134 | if( isset( $general_settings['counting_visits_matomo'] ) AND $general_settings['counting_visits_matomo'] ) { 135 | $general_settings['counting_visits_tracker'] = 'matomo-analytics'; 136 | $general_settings['counting_visits_ppc_supported_tracker'] = 1; 137 | $general_settings['counting_visits_callback'] = 0; 138 | } 139 | if( isset( $general_settings['counting_visits_plausible'] ) AND $general_settings['counting_visits_plausible'] ) { 140 | $general_settings['counting_visits_tracker'] = 'plausible-analytics'; 141 | $general_settings['counting_visits_ppc_supported_tracker'] = 1; 142 | $general_settings['counting_visits_callback'] = 0; 143 | } 144 | } 145 | 146 | if( $general_settings != $general_settings_old ) { 147 | if( ! update_option( $ppc_global_settings['option_name'], $general_settings ) ) { 148 | $error = new PPC_Error( 'ppcp_update_settings_error', __( 'Error: could not update settings.', 'post-pay-counter' ), array( 149 | 'count_before' => count( $general_settings_old ), 150 | 'count_after' => count( $general_settings ), 151 | 'settings' => $general_settings, 152 | 'settings_start' => $general_settings_old 153 | ) ); 154 | return $error->return_error(); 155 | } 156 | } 157 | 158 | //User settings updates 159 | $args = array( 160 | 'meta_key' => $ppc_global_settings['option_name'], 161 | 'fields' => 'ids' 162 | ); 163 | $personalized_users = get_users( $args ); 164 | foreach( $personalized_users as $user ) { 165 | $user_settings = PPC_general_functions::get_settings( $user ); 166 | $user_settings_old = $user_settings; 167 | 168 | //Count private posts 169 | if( ! isset( $user_settings['counting_allowed_post_statuses']['private'] ) ) 170 | $user_settings['counting_allowed_post_statuses']['private'] = 0; 171 | 172 | //Images & comments problems with counting systems - general and personalized settings update (v 2.1.2) 173 | if( isset( $user_settings['counting_images_value'] ) OR isset( $user_settings['counting_comments_value'] ) ) { 174 | $user_settings['counting_images_system_incremental_value'] = $user_settings['counting_images_value']; 175 | $user_settings['counting_comments_system_incremental_value'] = $user_settings['counting_comments_value']; 176 | unset( $user_settings['counting_images_value'], $user_settings['counting_comments_value'] ); 177 | } 178 | 179 | if( $user_settings != $user_settings_old ) { 180 | if( ! update_user_option( $user, $ppc_global_settings['option_name'], $user_settings ) ) { 181 | $error = new PPC_Error( 'ppc_update_user_settings_error', __( 'Error: could not update user\'s settings.', 'post-pay-counter' ), array( 182 | 'settings' => $user_settings, 183 | 'settings_start' => $user_settings_old 184 | ) ); 185 | $error->return_error(); 186 | } 187 | } 188 | } 189 | 190 | //License cron check 191 | if( ! wp_next_scheduled( 'ppcp_cron_check_activation' ) ) 192 | wp_schedule_event( time(), 'weekly2', 'ppcp_cron_check_activation' ); 193 | 194 | PPC_general_functions::manage_cap_allowed_user_roles_plugin_pages( $general_settings['can_see_options_user_roles'], $general_settings['can_see_stats_user_roles'] ); 195 | 196 | //Insert default addons list 197 | PPC_addons::add_addons_list(); 198 | 199 | //Delete old errors wp_option, moved to a file 200 | $old_errors = get_option( $ppc_global_settings['option_errors'] ); 201 | if( $old_errors !== false AND ! empty( $old_errors ) ) 202 | file_put_contents( $ppc_global_settings['file_errors'], serialize( $old_errors ) ); 203 | 204 | delete_option( $ppc_global_settings['option_errors'] ); 205 | 206 | update_option( 'ppc_current_version', $ppc_global_settings['newest_version'] ); 207 | 208 | //PRO gets deactivated as soon as PPC is deactivated - if it was active before, reactivate if now 209 | if( get_option( 'ppcp_active' ) == 1 ) 210 | activate_plugin( 'post-pay-counter-pro/post-pay-counter-pro.php' ); 211 | 212 | if( get_option( 'ppcp_pb_active' ) == 1 ) 213 | activate_plugin( 'ppcp-publisher-bonus/ppcp-publisher-bonus.php' ); 214 | 215 | if( get_option( 'ppcp_fb_active' ) == 1 ) 216 | activate_plugin( 'ppcp-facebook/ppcp-facebook.php' ); 217 | 218 | if( get_option( 'ppcp_sw_active' ) == 1 ) 219 | activate_plugin( 'ppcp-stopwords/ppcp-stopwords.php' ); 220 | 221 | if( get_option( 'ppc_urcs_active' ) == 1 ) 222 | activate_plugin( 'ppc-user-roles-custom-settings/ppc-user-roles-custom-settings.php' ); 223 | 224 | //Clear settings cache 225 | PPC_cache_functions::clear_settings( 'general' ); 226 | PPC_cache_functions::clear_stats(); 227 | } 228 | } 229 | -------------------------------------------------------------------------------- /classes/ppc_options_fields_class.php: -------------------------------------------------------------------------------- 1 | '; 25 | } 26 | 27 | /** 28 | * Generates a maybe checked checkbox field 29 | * 30 | * @access public 31 | * @since 2.0 32 | * @param $setting int current setting value (either 0 or 1) 33 | * @param $name string field name 34 | * @param $id string field id 35 | * @param $disabled bool whether field should be disabled 36 | * @return string the html of the checkbox field 37 | */ 38 | 39 | static function generate_checkbox_field( $setting, $name, $value, $id, $disabled ) { 40 | return ''; 41 | } 42 | 43 | /** 44 | * Generates payment systems fields: zonal (2 to 10 zones) and incremental 45 | * 46 | * @access public 47 | * @since 2.0 48 | * @param $counting_type string what counting are we talking about (words, visits, images, comments) 49 | * @param $settings array current settings 50 | * @return string the html of the payment systems fields 51 | */ 52 | 53 | static function echo_payment_systems( $counting_type, $counting_type_localized, $settings ) { 54 | global $ppc_global_settings; 55 | 56 | $html = '
'; 57 | $html .= PPC_HTML_functions::echo_p_field( __( 'Use the zonal system' , 'post-pay-counter'), $settings['counting_'.$counting_type.'_system_zonal'], 'radio', 'counting_'.$counting_type.'_system', sprintf( __( 'With this system you can define up to how many zones of retribution you would like, so that from X %1$s to Y %1$s the same pay will be applied (eg. from 200 %1$s to 300 %1$s pay 2.00). It does not matter how many %1$s a post has, but only in what zone it fits in.' , 'post-pay-counter'), $counting_type_localized ), 'counting_'.$counting_type.'_system_zonal', 'counting_'.$counting_type.'_system_zonal' ); 58 | $html .= '
'; 59 | $html .= ''; 60 | $html .= ''; 61 | $html .= ''; 62 | $html .= ''; 63 | $html .= ''; 64 | $html .= ''; 65 | $html .= ''; 66 | $html .= ''; 67 | 68 | $n = 0; 69 | $zones_count = count( $settings['counting_'.$counting_type.'_system_zonal_value'] ); 70 | while( $n < $zones_count ) { 71 | $html .= ''; 72 | $html .= ''; 73 | $html .= ''; 74 | $html .= ''; 75 | ++$n; 76 | } 77 | 78 | $html .= ''; 79 | $html .= '
'.ucfirst( $counting_type_localized ).''.__( 'Payment' , 'post-pay-counter').'
'; 80 | $html .= '
'; 81 | $html .= ''; 82 | $html .= ''; 83 | $html .= '
'; 84 | $html .= '
'; 85 | 86 | $html .= PPC_HTML_functions::echo_p_field( __( 'Use the incremental payment system' , 'post-pay-counter'), $settings['counting_'.$counting_type.'_system_incremental'], 'radio', 'counting_'.$counting_type.'_system', sprintf( __( 'With this system, every %1$s has a value: more %1$s => higher pay. Just think that the %1$s number will be multiplied for the incremental payment value, so that is a post has 300 %1$s and you set the incremental payment value to 0.01, the writer will be credited with 3.' , 'post-pay-counter'), $counting_type_localized ), 'counting_'.$counting_type.'_system_incremental', 'counting_'.$counting_type.'_system_incremental' ); 87 | $html .= '
'; 88 | $html .= PPC_HTML_functions::echo_text_field( 'counting_'.$counting_type.'_system_incremental_value', $settings['counting_'.$counting_type.'_system_incremental_value'], __( 'Incremental payment value' , 'post-pay-counter'), 2 ); 89 | $html .= '
'; 90 | $html .= '
'; 91 | 92 | return $html; 93 | } 94 | 95 | /** 96 | * Generates counting type display options select menu, 97 | * 98 | * @access public 99 | * @since 2.514 100 | * @param $counting_type string what counting are we talking about (words, visits, images, comments, ...) 101 | * @param $current_value string current setting for given counting type 102 | * @return string the html of the select menu 103 | */ 104 | 105 | static function echo_counting_type_display_dropdown( $counting_type, $current_value ) { 106 | global $ppc_global_settings; 107 | 108 | $html = '

'; 109 | $html .= ''; 110 | $html .= ''; 111 | $html .= ''; 112 | $html .= __( 'Payment display status', 'post-pay-counter' ); 113 | $html .= ''; 120 | 121 | return $html; 122 | } 123 | 124 | /** 125 | * Checks whether the given value is set or not. Sets $checkbox to NULL so we'll later know what vars are still to be dealt with 126 | * 127 | * @access public 128 | * @since 2.0 129 | * @param $checkbox int checkbox value 130 | * @return bool checkbox status 131 | */ 132 | 133 | static function get_checkbox_value( &$checkbox ) { 134 | if( ! isset( $checkbox ) ) 135 | return 0; 136 | else 137 | return 1; 138 | 139 | $checkbox = NULL; 140 | } 141 | 142 | /** 143 | * Gets a radio-set value. All three possibilities are set to zero in an array. Switch through the $radio and check which one was selected. The selected option has its value turned to 1 in the return array, while others are still 0. Set $radio to NULL so we'll later know what vars are still to be dealt with. 144 | * 145 | * @access public 146 | * @since 2.0 147 | * @param $radio string the value of the checked radio 148 | * @param $opt_1 string the value of the first option 149 | * @param $opt_2 string the value of the second option 150 | * @param $opt_3 string optional the value of the third option 151 | * @param $options_array array optional allows to handle N options 152 | * @return array the 2/3 possibilities along with their set values 153 | */ 154 | 155 | static function get_radio_value( &$radio, $opt_1, $opt_2, $opt_3 = FALSE, $options_array = FALSE ) { 156 | 157 | //New method: handles more than 3 options 158 | if( $options_array !== false ) { 159 | $return = array(); 160 | 161 | foreach( $options_array as $single ) { 162 | if( $radio == $single ) 163 | $return[$single] = 1; 164 | else 165 | $return[$single] = 0; 166 | } 167 | 168 | //$radio = null; // commented cause visits method are split among free and pro 169 | return $return; 170 | } 171 | 172 | //OLD STUFF for backwards compatibility 173 | $return = array( 174 | $opt_1 => 0, 175 | $opt_2 => 0, 176 | ); 177 | 178 | if( $opt_3 ) 179 | $return[$opt_3] = 0; 180 | 181 | switch( $radio ) { 182 | case $opt_1: 183 | $return[$opt_1] = 1; 184 | break; 185 | 186 | case $opt_2: 187 | $return[$opt_2] = 1; 188 | break; 189 | 190 | case $opt_3: 191 | $return[$opt_3] = 1; 192 | break; 193 | } 194 | 195 | //$radio = null; // commented cause visits method are split among free and pro 196 | return $return; 197 | } 198 | } 199 | -------------------------------------------------------------------------------- /classes/ppc_install_functions_class.php: -------------------------------------------------------------------------------- 1 | get_col( "SELECT blog_id FROM ".$wpdb->blogs ); 26 | 27 | foreach( $blog_ids as $blog_id ) { 28 | switch_to_blog( $blog_id ); 29 | self::ppc_install_procedure(); 30 | } 31 | 32 | restore_current_blog(); 33 | return; 34 | } 35 | 36 | //Single blog activation 37 | self::ppc_install_procedure(); 38 | 39 | //Send to Welcome page 40 | //set_transient( $ppc_global_settings['transient_activation_redirect'], 'do it!', 3600 ); 41 | wp_safe_redirect( admin_url( add_query_arg( array( 'page' => 'ppc-about' ), 'admin.php' ) ) ); 42 | } 43 | 44 | /** 45 | * If plugin was activated with a network-wide activation, activate and install it on new blogs when they are created 46 | * 47 | * @access public 48 | * @since 2.0 49 | * @param $blog_id int the id of the newly created blog 50 | * @param $user_id int the id of the newly created blog's admin 51 | * @param $domain string the domain of the newly created blog's admin 52 | * @param $path string the path of the newly created blog's admin 53 | * @param $site_id int the site id (usually = 1) 54 | * @param $meta array initial site options 55 | */ 56 | static function ppc_new_blog_install( $blog_id, $user_id, $domain, $path, $site_id, $meta ) { 57 | global $ppc_global_settings; 58 | 59 | if( is_plugin_active_for_network( basename( dirname( dirname( __FILE__ ) ).'/post-pay-counter.php' ) ) ) { 60 | switch_to_blog( $blog_id ); 61 | self::ppc_install_procedure(); 62 | restore_current_blog(); 63 | 64 | //Send to Welcome page 65 | //set_transient( $ppc_global_settings['transient_activation_redirect'], 'do it!', 3600 ); 66 | wp_safe_redirect( admin_url( add_query_arg( array( 'page' => 'ppc-about' ), 'admin.php' ) ) ); 67 | } 68 | } 69 | 70 | /** 71 | * Adds default settings, current version to the database and assigns default capabilities. 72 | * 73 | * @access public 74 | * @since 2.0 75 | */ 76 | static function ppc_install_procedure() { 77 | global $ppc_global_settings, $current_user; 78 | 79 | if( ! is_object( $current_user ) ) 80 | get_currentuserinfo(); 81 | 82 | $default_settings = array( 83 | 'general' => array( 84 | 'userid' => 'general', 85 | 'basic_payment' => 1, 86 | 'basic_payment_value' => 1.5, 87 | 'basic_payment_display_status' => 'tooltip', 88 | 'counting_words' => 1, 89 | 'counting_words_system_zonal' => 0, 90 | 'counting_words_system_zonal_value' => array( 91 | 0 => array( 92 | 'threshold' => 100, 93 | 'payment' => 1 94 | ), 95 | 1 => array( 96 | 'threshold' => 200, 97 | 'payment' => 2 98 | ) 99 | ), 100 | 'counting_words_system_incremental' => 1, 101 | 'counting_words_system_incremental_value' => 0.01, 102 | 'counting_words_threshold_max' => 0, 103 | 'counting_words_display_status' => 'count', 104 | 'counting_words_legacy' => 0, 105 | 'counting_words_parse_spaces' => 0, 106 | 'counting_words_include_excerpt' => 0, 107 | 'counting_words_exclude_pre' => 0, 108 | 'counting_words_exclude_captions' => 0, 109 | 'counting_words_apply_shortcodes' => 0, 110 | 'counting_words_global_threshold' => 0, 111 | 'counting_visits' => 0, 112 | 'counting_visits_callback' => 0, 113 | 'counting_visits_callback_value' => '', 114 | 'counting_visits_ppc_supported_tracker' => 1, 115 | 'counting_visits_tracker' => '', 116 | 'counting_visits_system_zonal' => 0, 117 | 'counting_visits_system_zonal_value' => array( 118 | 0 => array( 119 | 'threshold' => 100, 120 | 'payment' => 1 121 | ), 122 | 1 => array( 123 | 'threshold' => 200, 124 | 'payment' => 2 125 | ) 126 | ), 127 | 'counting_visits_system_incremental' => 1, 128 | 'counting_visits_system_incremental_value' => 0.01, 129 | 'counting_visits_threshold_max' => 0, 130 | 'counting_visits_global_threshold' => 0, 131 | 'counting_visits_display_percentage' => 100, 132 | 'counting_visits_display_status' => 'count', 133 | 'counting_images' => 1, 134 | 'counting_images_system_zonal' => 0, 135 | 'counting_images_system_zonal_value' => array( 136 | 0 => array( 137 | 'threshold' => 100, 138 | 'payment' => 1 139 | ), 140 | 1 => array( 141 | 'threshold' => 200, 142 | 'payment' => 2 143 | ) 144 | ), 145 | 'counting_images_system_incremental' => 1, 146 | 'counting_images_system_incremental_value' => 0.2, 147 | 'counting_images_threshold_min' => 2, 148 | 'counting_images_threshold_max' => 10, 149 | 'counting_images_include_featured' => 1, 150 | 'counting_images_include_galleries' => 1, 151 | 'counting_images_global_threshold' => 0, 152 | 'counting_images_display_status' => 'count', 153 | 'counting_comments' => 1, 154 | 'counting_comments_system_zonal' => 0, 155 | 'counting_comments_system_zonal_value' => array( 156 | 0 => array( 157 | 'threshold' => 100, 158 | 'payment' => 1 159 | ), 160 | 1 => array( 161 | 'threshold' => 200, 162 | 'payment' => 2 163 | ) 164 | ), 165 | 'counting_comments_system_incremental' => 1, 166 | 'counting_comments_system_incremental_value' => 0.2, 167 | 'counting_comments_threshold_min' => 2, 168 | 'counting_comments_threshold_max' => 10, 169 | 'counting_comments_global_threshold' => 0, 170 | 'counting_comments_display_status' => 'count', 171 | 'counting_payment_total_threshold' => 0, 172 | 'counting_payment_only_when_total_threshold' => 0, 173 | 'counting_allowed_post_statuses' => array( 174 | 'publish' => 1, 175 | 'future' => 1, 176 | 'pending' => 0, 177 | 'private' => 0 178 | ), 179 | 'counting_exclude_quotations' => 1, 180 | 'can_see_others_general_stats' => 1, 181 | 'can_see_others_detailed_stats' => 1, 182 | 'can_see_countings_special_settings' => 1, 183 | 'enable_post_stats_caching' => 1, 184 | 'display_overall_stats' => 1, 185 | 'can_see_options_user_roles' => array( 186 | 'administrator' => 'administrator' 187 | ), 188 | 'can_see_stats_user_roles' => array( 189 | 'administrator' => 'administrator', 190 | 'editor' => 'editor', 191 | 'author' => 'author', 192 | 'contributor' => 'contributor' 193 | ), 194 | 'counting_allowed_user_roles' => array( 195 | 'administrator' => 'administrator', 196 | 'editor' => 'editor', 197 | 'author' => 'author', 198 | 'contributor' => 'contributor' 199 | ), 200 | 'counting_allowed_post_types' => array( 201 | 'post', 202 | 'page' 203 | ), 204 | 'default_stats_time_range_month' => 1, 205 | 'default_stats_time_range_last_month' => 0, 206 | 'default_stats_time_range_this_year' => 0, 207 | 'default_stats_time_range_week' => 0, 208 | 'default_stats_time_range_all_time' => 0, 209 | 'default_stats_time_range_custom' => 0, 210 | 'default_stats_time_range_custom_value' => 100, 211 | 'default_stats_time_range_start_day' => 0, 212 | 'default_stats_time_range_start_day_value' => '1605-11-05', 213 | 'admins_override_permissions' => 1, 214 | 'stats_display_edit_post_link' => 0, 215 | 'enable_stats_payments_tooltips' => 1, 216 | 'payment_display_round_digits' => 2, 217 | 'save_stats_order' => 1, 218 | 'hide_column_total_payment' => 0, 219 | 'stats_show_all_users' => 0, 220 | ) 221 | ); 222 | 223 | //Only add default settings if not there already 224 | $general_settings = PPC_general_functions::get_settings( 'general' ); 225 | if( ! is_array( $general_settings ) ) { 226 | 227 | //Add option if not available, update it otherwise 228 | if( get_option( $ppc_global_settings['option_name'] ) === false ) { 229 | if( ! add_option( $ppc_global_settings['option_name'], $default_settings['general'], '', 'no' ) ) { 230 | $error = new PPC_Error( 'ppc_add_option_general_error', __( 'Could not add general settings option.', 'post-pay-counter' ), array( 231 | 'option_name' => $ppc_global_settings['option_name'], 232 | 'old_settings' => $general_settings, 233 | 'default_settings' => $default_settings['general'] 234 | ) ); 235 | trigger_error( $wp_error->get_error_message(), E_USER_ERROR ); 236 | } 237 | } else { 238 | if( ! update_option( $ppc_global_settings['option_name'], $default_settings['general'] ) ) { 239 | $error = new PPC_Error( 'ppc_update_option_general_error', __( 'Could not update general settings option.', 'post-pay-counter' ), array( 240 | 'option_name' => $ppc_global_settings['option_name'], 241 | 'old_settings' => $general_settings, 242 | 'default_settings' => $default_settings['general'] 243 | ) ); 244 | trigger_error( $wp_error->get_error_message(), E_USER_ERROR ); 245 | } 246 | } 247 | } 248 | 249 | //Add error log option 250 | if( ! get_option( $ppc_global_settings['option_errors'] ) ) 251 | add_option( $ppc_global_settings['option_errors'], $errors, '', 'no' ); 252 | 253 | //Add dismissed notification option 254 | $dismissed = array( 255 | "ppcp_publisher_bonus_available", 256 | "ppcp_facebook_available", 257 | "ppcp_stopwords_available" 258 | ); 259 | if( ! get_option( "ppc_dismissed_notifications" ) ) 260 | add_option( "ppc_dismissed_notifications", $dismissed, '', 'no' ); 261 | 262 | //Set default permissions for acessing plugin pages 263 | PPC_general_functions::manage_cap_allowed_user_roles_plugin_pages( $default_settings['general']['can_see_options_user_roles'], $default_settings['general']['can_see_stats_user_roles'] ); 264 | 265 | //Insert default addons list 266 | PPC_addons::add_addons_list(); 267 | 268 | update_option( 'ppc_current_version', $ppc_global_settings['newest_version'] ); 269 | } 270 | } 271 | -------------------------------------------------------------------------------- /classes/ppc_ajax_functions_class.php: -------------------------------------------------------------------------------- 1 | get_error_message() ); 44 | 45 | die( 'ok' ); 46 | } 47 | 48 | /** 49 | * Handles the AJAX request for the misc settings saving. 50 | * 51 | * @access public 52 | * @since 2.0 53 | * @param $nonce string the WP nonce 54 | */ 55 | 56 | static function save_misc_settings() { 57 | self::ppc_check_ajax_referer( 'ppc_save_misc_settings' ); 58 | 59 | parse_str( $_REQUEST['form_data'], $settings ); 60 | 61 | $save_settings = PPC_save_options::save_misc_settings( $settings ); 62 | if( is_wp_error( $save_settings ) ) die( $save_settings->get_error_message() ); 63 | 64 | die( 'ok' ); 65 | } 66 | 67 | /** 68 | * Handles the AJAX request for the permissions saving. 69 | * 70 | * @access public 71 | * @since 2.0 72 | * @param $nonce string the WP nonce 73 | */ 74 | 75 | static function save_permissions() { 76 | self::ppc_check_ajax_referer( 'ppc_save_permissions' ); 77 | 78 | parse_str( $_REQUEST['form_data'], $settings ); 79 | 80 | $save_settings = PPC_save_options::save_permissions( $settings ); 81 | if( is_wp_error( $save_settings ) ) die( $save_settings->get_error_message() ); 82 | 83 | die( 'ok' ); 84 | } 85 | 86 | /** 87 | * Fetches users to be personalized basing on the requested user role. 88 | * 89 | * @access public 90 | * @since 2.0 91 | */ 92 | static function personalize_fetch_users_by_roles() { 93 | global $ppc_global_settings; 94 | self::ppc_check_ajax_referer( 'ppc_personalize_fetch_users_by_roles' ); 95 | 96 | echo 'ok'; 97 | $user_role = trim( $_REQUEST['user_role'] ); 98 | 99 | $args = array( 100 | 'orderby' => 'display_name', 101 | 'order' => 'ASC', 102 | 'role' => $user_role, 103 | 'count_total' => true, 104 | 'fields' => array( 105 | 'ID', 106 | 'display_name' 107 | ) 108 | ); 109 | 110 | /** 111 | * Filters user fetching (by role) for Personalize settings box. 112 | * 113 | * This fetches the users list that is shown in the Options Personalize settings box when a user role is clicked. 114 | * 115 | * @since 2.0 116 | * @param array $args WP_User_query args 117 | */ 118 | 119 | $args = apply_filters( 'ppc_personalize_fetch_users_args', $args ); 120 | 121 | $users_to_show = new WP_User_Query( $args ); 122 | 123 | if( $users_to_show->get_total() == 0 ) { 124 | _e( 'No users found.' , 'post-pay-counter'); 125 | 126 | } else { 127 | $n = 0; 128 | $html = ''; 129 | echo ''; 130 | 131 | foreach( $users_to_show->results as $single ) { 132 | if( $n % 3 == 0 ) 133 | $html .= ''; 134 | 135 | $html .= ''; 136 | 137 | if( $n % 3 == 2 ) 138 | $html .= ''; 139 | 140 | /** 141 | * Filters user display in Personalize settings box. 142 | * 143 | * This fires for every user that is displayed for the selected role. 144 | * 145 | * @since 2.0 146 | * @param string $html html code for the user list up to the current one 147 | * @param object $single WP_User current user data 148 | */ 149 | 150 | echo apply_filters( 'ppc_html_personalize_list_print_user', $html, $single ); 151 | 152 | $html = ''; 153 | $n++; 154 | } 155 | 156 | echo '
'.$single->display_name.'
'; 157 | } 158 | 159 | /** 160 | * Allows to display html after the list of users from a user-role in the personalize settings box. 161 | * 162 | * @since 2.518 163 | * @param string $user_role user role selected 164 | */ 165 | 166 | do_action( 'ppc_personalize_users_role_list_end', $user_role ); 167 | 168 | exit; 169 | } 170 | 171 | /** 172 | * Fetches users to be personalized basing on the requested user role. 173 | * 174 | * @access public 175 | * @since 2.710 176 | */ 177 | static function stats_get_users_by_role() { 178 | global $ppc_global_settings; 179 | self::ppc_check_ajax_referer( 'ppc_stats_get_users_by_role' ); 180 | 181 | $user_role = trim( $_REQUEST['user_role'] ); 182 | 183 | $args = array( 184 | 'orderby' => 'display_name', 185 | 'order' => 'ASC', 186 | 'role' => $user_role, 187 | 'count_total' => true, 188 | 'fields' => array( 189 | 'ID', 190 | 'display_name' 191 | ) 192 | ); 193 | 194 | /** 195 | * Filters user fetching (by role) for stats select. 196 | * 197 | * This fetches the users list that is shown in the Stats User dropdown when a user role is selected. 198 | * 199 | * @since 2.710 200 | * @param array $args WP_User_query args 201 | */ 202 | 203 | $args = apply_filters( 'ppc_stats_get_users_args', $args ); 204 | 205 | $users_to_show = new WP_User_Query( $args ); 206 | $html = ''; 207 | 208 | if( $users_to_show->get_total() != 0 ) { 209 | 210 | foreach( $users_to_show->results as $single ) 211 | $html .= ''; 212 | 213 | } 214 | 215 | wp_send_json_success( array( 216 | 'html' => $html 217 | ) ); 218 | } 219 | 220 | /** 221 | * If a valid user is given, their special settings are deleted. 222 | * 223 | * @access public 224 | * @since 2.0 225 | */ 226 | static function vaporize_user_settings() { 227 | global $ppc_global_settings; 228 | self::ppc_check_ajax_referer( 'ppc_vaporize_user_settings' ); 229 | 230 | $user_id = (int) $_REQUEST['user_id']; 231 | if( is_int( $user_id ) ) { 232 | delete_user_option( $user_id, $ppc_global_settings['option_name'] ); 233 | 234 | PPC_general_functions::clear_settings_cache( $user_id ); 235 | 236 | /** 237 | * Fires after a user's personalized settings have been deleted. 238 | * 239 | * @since 2.0 240 | * @param int $user_id user id whose settings have been deleted. 241 | */ 242 | do_action( 'ppc_deleted_user_settings', $user_id ); 243 | 244 | die( 'ok' ); 245 | } 246 | } 247 | 248 | /** 249 | * Imports a valid serialized and base64_encoded array of PPC settings. 250 | * 251 | * @access public 252 | * @since 2.1.3 253 | */ 254 | static function import_settings() { 255 | global $ppc_global_settings; 256 | self::ppc_check_ajax_referer( 'ppc_import_settings' ); 257 | 258 | $to_import = json_decode( base64_decode( $_REQUEST['import_settings_content'] ), true ); 259 | if( $to_import != NULL AND is_array( $to_import ) AND isset( $to_import['userid'] ) ) { 260 | $to_import['userid'] = $_REQUEST['userid']; 261 | $update = PPC_save_options::update_settings( $to_import['userid'], $to_import ); 262 | if( is_wp_error( $update ) ) 263 | wp_send_json_error( array( 264 | 'message' => $update->get_error_message() 265 | ) ); 266 | else 267 | wp_send_json_success(); 268 | } else { 269 | wp_send_json_error( array( 270 | 'message' => __( 'What are you importing, cows?', 'post-pay-counter' ) 271 | ) ); 272 | } 273 | } 274 | 275 | /** 276 | * Clears error log. 277 | * 278 | * Empties error log wp_option, if it exists (doesn't delete not to lose autload=no). 279 | * 280 | * @access public 281 | * @since 2.22 282 | */ 283 | static function clear_error_log() { 284 | global $ppc_global_settings; 285 | self::ppc_check_ajax_referer( 'ppc_clear_error_log' ); 286 | 287 | if( ! file_put_contents( $ppc_global_settings['file_errors'], serialize( array() ) ) ) 288 | die( __( 'Error: could not clear error log.', 'post-pay-counter' ) ); 289 | 290 | die( 'ok' ); 291 | } 292 | 293 | /** 294 | * Dismisses a notification. 295 | * 296 | * Adds notification ID to wp_option list of dismissed ones. 297 | * 298 | * @access public 299 | * @since 2.46 300 | */ 301 | 302 | static function dismiss_notification() { 303 | global $ppc_global_settings; 304 | self::ppc_check_ajax_referer( 'ppc_dismiss_notification' ); 305 | 306 | if( ! $dismissed = get_option( 'ppc_dismissed_notifications' ) ) 307 | $dismissed = array(); 308 | 309 | $dismissed[$_REQUEST['id']] = $_REQUEST['id']; 310 | update_option( 'ppc_dismissed_notifications', $dismissed ); 311 | 312 | die( 'ok' ); 313 | } 314 | 315 | /** 316 | * Cares about AJAX license activation 317 | * 318 | * @access public 319 | * @since 2.511 320 | */ 321 | 322 | static function license_activate() { 323 | PPC_ajax_functions::ppc_check_ajax_referer( 'ppc_license_key_activate' ); 324 | 325 | $license = ''; 326 | $license = apply_filters( 'ppcp_license_activate_object', $license, $_REQUEST['license_key'] ); 327 | 328 | if( ! ( is_a( $license, 'PPC_license' ) OR is_a( $license, 'PPCP_license' ) ) ) 329 | die( __( 'Make sure the license you are trying to activate is related to an addon that is both installed and active.', 'post-pay-counter' ).' '.__( 'You may be activating an old PRO version: in this case, try to use the other License status box you can find in the Options page. You may have to scroll the page to find it.', 'post-pay-counter' ).'
Error: License object is not a PPCP_license instance.' ); 330 | 331 | $license_activate = $license->activate( $_REQUEST['license_key'] ); 332 | if( is_wp_error( $license_activate ) ) die( $license_activate->get_error_message() ); 333 | 334 | die( 'ok' ); 335 | } 336 | 337 | /** 338 | * Cares about AJAX license deactivation 339 | * 340 | * @access public 341 | * @since 2.511 342 | */ 343 | 344 | static function license_deactivate() { 345 | PPC_ajax_functions::ppc_check_ajax_referer( 'ppc_license_key_deactivate' ); 346 | 347 | $license = ''; 348 | $license = apply_filters( 'ppcp_license_deactivate_object', $license, $_REQUEST['plugin_slug'] ); 349 | 350 | if( ! ( is_a( $license, 'PPC_license' ) OR is_a( $license, 'PPCP_license' ) ) ) 351 | die( 'License object is not a PPCP_license instance.' ); 352 | 353 | $license_deactivate = $license->deactivate(); 354 | if( is_wp_error( $license_deactivate ) ) die( $license_deactivate->get_error_message() ); 355 | 356 | die( 'ok' ); 357 | } 358 | } 359 | -------------------------------------------------------------------------------- /classes/ppc_welcome_class.php: -------------------------------------------------------------------------------- 1 | 74 | 75 |

83 | 95 | 96 |
97 | 98 |

99 |
100 | 101 | 102 | 103 |
104 |

105 | 106 |
107 | 108 | 109 |

110 |

111 | 112 |

113 |

100 words are worth $1.00) or a zonal one (e.g. between 100 and 200 words pay $1.20 => 190 words are worth $1.20) with as many zones you want.', 'post-pay-counter' );?>

114 | 115 |

116 |

117 |
118 |
119 | 120 |
121 |

122 | 123 |
124 | 125 | 126 |

127 |

128 | 129 |

130 |

131 | 132 |

133 |

134 | 135 |

136 |

137 |
138 |
139 | 140 |
141 |

142 | 143 |
144 | 145 | 146 |

147 |

148 | 149 |

150 |

151 | 152 |

153 |

154 |
155 |
156 | 157 | 158 | 159 |
160 | 161 |
162 |
163 | 175 | 176 |
177 |

178 |
179 | 180 | 181 | 182 |
183 |

184 | 185 |
186 | 187 |
188 |
189 | 190 |
191 | 192 |
193 |
194 | 206 | 207 |
208 |

209 | 210 |
211 | 212 | 213 |

214 |

>%2$s' ), '', '' );?>

215 | 216 |

217 |

>%2$s' ), '', '' );?>

218 | 219 |

220 |

', '' );?>

221 |
222 |
223 | 224 | ' . __( 'No valid changelog was found.', 'post-pay-counter' ) . '

'; 242 | } else { 243 | $readme = file_get_contents( $file ); 244 | $readme = nl2br( esc_html( $readme ) ); 245 | 246 | $parts = explode( '== Changelog ==', $readme ); 247 | $readme = end( $parts ); 248 | 249 | $readme = preg_replace( '/`(.*?)`/', '\\1', $readme ); 250 | $readme = preg_replace( '/[\040]\*\*(.*?)\*\*/', ' \\1', $readme ); 251 | $readme = preg_replace( '/[\040]\*(.*?)\*/', ' \\1', $readme ); 252 | $readme = preg_replace( '/= (.*?) =/', '

\\1

', $readme ); 253 | $readme = preg_replace( '/\[(.*?)\]\((.*?)\)/', '\\1', $readme ); 254 | } 255 | 256 | return $readme; 257 | } 258 | 259 | /** 260 | * Sends user to the Welcome page on activation and to Changelog page on update. 261 | * 262 | * @access public 263 | * @since 2.34 264 | */ 265 | public static function welcome() { 266 | global $ppc_global_settings; 267 | 268 | if( get_transient( $ppc_global_settings['transient_activation_redirect'] ) OR get_transient( $ppc_global_settings['transient_update_redirect'] ) ) { 269 | 270 | //Delete redirect transients 271 | delete_transient( $ppc_global_settings['transient_activation_redirect'] ); 272 | delete_transient( $ppc_global_settings['transient_update_redirect'] ); 273 | 274 | //Return if activating from network, or bulk 275 | if( is_network_admin() || isset( $_GET['activate-multi'] ) ) 276 | return; 277 | 278 | wp_safe_redirect( admin_url( add_query_arg( array( 'page' => 'ppc-about' ), 'admin.php' ) ) ); 279 | } 280 | } 281 | } 282 | -------------------------------------------------------------------------------- /classes/ppc_counting_types_class.php: -------------------------------------------------------------------------------- 1 | array(), 38 | 'author' => array() 39 | ); 40 | } 41 | 42 | /** 43 | * Registers a counting type. 44 | * 45 | * Words, visits, comments, images are examples of built-in counting types. 46 | * 47 | * @access public 48 | * @since 2.40 49 | * @param $parameters array containing 50 | * id - unique identifier 51 | * label - to be displayed label 52 | * apply_to - whether post or author counting type (or both) 53 | * settings_status_index - (optional) the name of the settings index of the plugin settings to check the counting-enabled-status against. 54 | * If not given, counting type will be disabled by default. 55 | * count_callback - (optional) method to count "how many of the counting_type there are (eg. how many words, visits...)". 56 | * Needs to return an array in the form array( 'to_count' => int, 'real' => int ). 57 | * Can (should) be a class method, in which case an array is needed (eg array( 'classname', 'static_method' ) or array( $object, 'method' ) ). 58 | * Will receive the $post WP_Post_Object as parameter if apply_to = post, will receive author stats and author id if apply_to = author. 59 | * If no count_callback is given, a dummy method will assign 1 as value of the count. 60 | * display - (optional) what you want to be displayed in the stats, possible values are 'count', 'payment', 'both', 'tooltip', 'none'. Default to 'both'. 61 | * display_status_index - (optional) the name of the settings index of the plugin settings containing a display value. This is used to provide different display values to different users. If not given, the above 'display' will be used. 62 | * payment_callback - method to compute payment of the counted "how many". Will receive the counting output array as parameter as well as the post ID or author ID. 63 | * other_params - (optional) can contain whatever you want. Maybe you want to add custom checks to a counting type: then you can use this to register it with custom args and then hook to actions in the method and use this parameter. 64 | * # not_to_pay (bool) exclude counting from payments. 65 | * # payment_only (bool) whether payment criteria is not based on any 'count' method, but rather a standalone payment. 66 | */ 67 | function register_counting_type( $parameters ) { 68 | //Check everything needed has been given 69 | if( ! isset( $parameters['id'] ) OR ! isset( $parameters['label'] ) OR ! isset( $parameters['apply_to'] ) OR ! isset( $parameters['payment_callback'] ) ) { 70 | trigger_error( 'ID, label, apply_to (post|author), payment_callback parameters must be provided when registering a counting type.', E_USER_WARNING ); 71 | return; 72 | } 73 | 74 | $counting_type_arr = array( 75 | 'id' => $parameters['id'], 76 | 'label' => $parameters['label'], 77 | 'payment_callback' => $parameters['payment_callback'], 78 | 'apply_to' => $parameters['apply_to'], 79 | 'other_params' => array() 80 | ); 81 | 82 | if( isset( $parameters['payment_only'] ) ) 83 | $counting_type_arr['payment_only'] = $parameters['payment_only']; 84 | 85 | if( isset( $parameters['settings_status_index'] ) ) 86 | $counting_type_arr['settings_status_index'] = $parameters['settings_status_index']; 87 | 88 | //If no display choice is made, assign 'both' 89 | if( ! isset( $parameters['display'] ) ) 90 | $counting_type_arr['display'] = 'both'; 91 | else 92 | $counting_type_arr['display'] = $parameters['display']; 93 | 94 | if( isset( $parameters['display_status_index'] ) AND ! empty( $parameters['display_status_index'] ) ) { 95 | $counting_type_arr['display_status_index'] = $parameters['display_status_index']; 96 | 97 | $general_settings = PPC_general_functions::get_settings( 'general' ); 98 | if( isset( $general_settings[$parameters['display_status_index']] ) ) //Adjust display arg depending on settings 99 | $counting_type_arr['display'] = $general_settings[$parameters['display_status_index']]; 100 | } 101 | 102 | if( isset( $parameters['count_callback'] ) ) 103 | $counting_type_arr['count_callback'] = $parameters['count_callback']; 104 | 105 | if( isset( $parameters['other_params'] ) ) 106 | $counting_type_arr['other_params'] = $parameters['other_params']; 107 | 108 | do_action( 'ppc_registering_counting_type', $counting_type_arr ); 109 | 110 | //Counting types are stored in the global var 111 | if( $parameters['apply_to'] == 'both' ) { 112 | self::$counting_types['post'][$parameters['id']] = apply_filters( 'ppc_define_counting_type', $counting_type_arr ); 113 | self::$counting_types['author'][$parameters['id']] = apply_filters( 'ppc_define_counting_type', $counting_type_arr ); 114 | } else { 115 | self::$counting_types[$parameters['apply_to']][$parameters['id']] = apply_filters( 'ppc_define_counting_type', $counting_type_arr ); 116 | } 117 | } 118 | 119 | /** 120 | * Gets currently active counting types for given user and context (post or author). 121 | * Active counting types for users are stored in a class var and retrieved if available when needed. 122 | * Generates a list, whereas get_user_counting_types takes the list and completes each counting type with its details. 123 | * 124 | * @access public 125 | * @since 2.40 126 | * @param $what string whether post or author 127 | * @param $userid int|string (optional) whose counting types? 128 | * @return array counting types 129 | */ 130 | 131 | function get_active_counting_types( $what, $userid = 'general', $settings = false ) { 132 | // $userid = apply_filters( 'ppc_get_active_counting_types_settings_userid', $userid, $what ); 133 | 134 | //Try to retrieve them from "cache" 135 | $cache = false; //wp_cache_get( 'ppc_user_active_counting_types_list_'.$what.'_'.$userid ); 136 | //WARNING - Cannot cache this stuff, as it also depends on who VIEWS the stats - there's a true parameter in the $settings call below! 137 | 138 | //If no cache available, need to build the data first 139 | if( $cache === false ) { 140 | if( $settings === false ) 141 | $settings = PPC_general_functions::get_settings( $userid, TRUE ); 142 | 143 | //See which ones are active 144 | $active_user_counting_types = array(); 145 | 146 | foreach( self::$counting_types[$what] as $id => $single ) { 147 | $counting_status = 0; 148 | if( isset( $single['settings_status_index'] ) AND isset( $settings[$single['settings_status_index']] ) AND $settings[$single['settings_status_index']] ) 149 | $counting_status = 1; 150 | 151 | //If you haven't given 'settings_status_index', this is your chance - the filter - to enable the counting type depending on custom checks! 152 | $counting_status = apply_filters( 'ppc_get_counting_type_status', $counting_status, $id, $userid ); 153 | 154 | if( $counting_status == 1 ) 155 | $active_user_counting_types[] = $id; 156 | } 157 | 158 | self::$active_counting_types[$userid][$what] = $active_user_counting_types; //needed for get_user_counting_types 159 | //wp_cache_set( 'ppc_user_active_counting_types_list_'.$what.'_'.$userid, $active_user_counting_types ); //Cache 160 | } 161 | 162 | return $this->get_user_counting_types( $what, $userid ); 163 | } 164 | 165 | /** 166 | * Gets user counting types. 167 | * Checks which counting types are active for the given user and returns the array with all the details of them. 168 | * It basically interbreeds general counting types with a list of the user-active ones. 169 | * Takes the list generated by get_active_counting_types and completes each counting type with its details. 170 | * 171 | * @access public 172 | * @since 2.40 173 | * @param $what 174 | * @param $userid int userid 175 | * @return array user counting types 176 | */ 177 | 178 | function get_user_counting_types( $what, $userid ) { 179 | //Try to retrieve them from cache 180 | $cache = false; //wp_cache_get( 'ppc_user_active_counting_types_details_'.$what.'_'.$userid ); 181 | //WARNING - Cannot cache this stuff, as it also depends on who VIEWS the stats 182 | if( $cache !== false ) 183 | return $cache; 184 | 185 | $user_settings = PPC_general_functions::get_settings( $userid ); 186 | 187 | $active_user_counting_types = array(); 188 | foreach( self::$active_counting_types[$userid][$what] as $single ) { //counting types 189 | $current_counting_type = self::$counting_types[$what][$single]; 190 | 191 | //Change 'display' param depending on user settings, if any 192 | if( isset( $current_counting_type['display_status_index'] ) AND isset( $user_settings[$current_counting_type['display_status_index']] ) AND $user_settings[$current_counting_type['display_status_index']] ) 193 | $current_counting_type['display'] = $user_settings[$current_counting_type['display_status_index']]; 194 | 195 | $active_user_counting_types[$single] = $current_counting_type; 196 | } 197 | 198 | //wp_cache_set( 'ppc_user_active_counting_types_details_'.$what.'_'.$userid, $active_user_counting_types ); //Cache 199 | 200 | return apply_filters( 'ppc_active_user_counting_types', $active_user_counting_types, $userid, $what ); 201 | } 202 | 203 | /** 204 | * Gets all registered counting types. 205 | * 206 | * @access public 207 | * @since 2.40 208 | * @param $what string whether post or author 209 | * @return array counting types 210 | */ 211 | 212 | function get_all_counting_types( $what ) { 213 | return self::$counting_types[$what]; 214 | } 215 | 216 | /** 217 | * Registers plugin built-in counting types. 218 | * 219 | * @access public 220 | * @since 2.40 221 | */ 222 | 223 | function register_built_in_counting_types() { 224 | $built_in_counting_types = array(); 225 | 226 | $built_in_counting_types[] = array( 227 | 'id' => 'basic', 228 | 'label' => __( 'Basic', 'post-pay-counter' ), 229 | 'apply_to' => 'post', 230 | 'settings_status_index' => 'basic_payment', 231 | 'display' => 'tooltip', 232 | 'display_status_index' => 'basic_payment_display_status', 233 | 'count_callback' => array( 'PPC_counting_stuff', 'dummy_counter' ), 234 | 'payment_callback' => array( 'PPC_counting_stuff', 'basic_payment' ) 235 | ); 236 | 237 | $built_in_counting_types[] = array( 238 | 'id' => 'words', 239 | 'label' => __( 'Words', 'post-pay-counter' ), 240 | 'apply_to' => 'post', 241 | 'settings_status_index' => 'counting_words', 242 | 'display' => 'count', 243 | 'display_status_index' => 'counting_words_display_status', 244 | 'count_callback' => array( 'PPC_counting_stuff', 'count_post_words' ), 245 | 'payment_callback' => array( 'PPC_counting_stuff', 'words_payment' ) 246 | ); 247 | 248 | 249 | $built_in_counting_types[] = array( 250 | 'id' => 'visits', 251 | 'label' => __( 'Visits', 'post-pay-counter' ), 252 | 'apply_to' => 'post', 253 | 'settings_status_index' => 'counting_visits', 254 | 'display' => 'count', 255 | 'display_status_index' => 'counting_visits_display_status', 256 | 'count_callback' => array( 'PPC_counting_stuff', 'count_post_visits' ), 257 | 'payment_callback' => array( 'PPC_counting_stuff', 'visits_payment' ) 258 | ); 259 | 260 | $built_in_counting_types[] = array( 261 | 'id' => 'images', 262 | 'label' => __( 'Images', 'post-pay-counter' ), 263 | 'apply_to' => 'post', 264 | 'settings_status_index' => 'counting_images', 265 | 'display' => 'count', 266 | 'display_status_index' => 'counting_images_display_status', 267 | 'count_callback' => array( 'PPC_counting_stuff', 'count_post_images' ), 268 | 'payment_callback' => array( 'PPC_counting_stuff', 'images_payment' ) 269 | ); 270 | 271 | $built_in_counting_types[] = array( 272 | 'id' => 'comments', 273 | 'label' => __( 'Comments', 'post-pay-counter' ), 274 | 'apply_to' => 'post', 275 | 'settings_status_index' => 'counting_comments', 276 | 'display' => 'count', 277 | 'display_status_index' => 'counting_comments_display_status', 278 | 'count_callback' => array( 'PPC_counting_stuff', 'count_post_comments' ), 279 | 'payment_callback' => array( 'PPC_counting_stuff', 'comments_payment' ) 280 | ); 281 | 282 | foreach( $built_in_counting_types as $single ) 283 | $this->register_counting_type( $single ); 284 | 285 | do_action( 'ppc_registered_built_in_counting_types' ); 286 | } 287 | } 288 | -------------------------------------------------------------------------------- /style/ui-lightness/jquery.ui.theme.css: -------------------------------------------------------------------------------- 1 | 2 | 3 | /* 4 | * jQuery UI CSS Framework 1.8.15 5 | * 6 | * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) 7 | * Dual licensed under the MIT or GPL Version 2 licenses. 8 | * http://jquery.org/license 9 | * 10 | * http://docs.jquery.com/UI/Theming/API 11 | * 12 | * To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Trebuchet%20MS,%20Tahoma,%20Verdana,%20Arial,%20sans-serif&fwDefault=bold&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=f6a828&bgTextureHeader=12_gloss_wave.png&bgImgOpacityHeader=35&borderColorHeader=e78f08&fcHeader=ffffff&iconColorHeader=ffffff&bgColorContent=eeeeee&bgTextureContent=03_highlight_soft.png&bgImgOpacityContent=100&borderColorContent=dddddd&fcContent=333333&iconColorContent=222222&bgColorDefault=f6f6f6&bgTextureDefault=02_glass.png&bgImgOpacityDefault=100&borderColorDefault=cccccc&fcDefault=1c94c4&iconColorDefault=ef8c08&bgColorHover=fdf5ce&bgTextureHover=02_glass.png&bgImgOpacityHover=100&borderColorHover=fbcb09&fcHover=c77405&iconColorHover=ef8c08&bgColorActive=ffffff&bgTextureActive=02_glass.png&bgImgOpacityActive=65&borderColorActive=fbd850&fcActive=eb8f00&iconColorActive=ef8c08&bgColorHighlight=ffe45c&bgTextureHighlight=03_highlight_soft.png&bgImgOpacityHighlight=75&borderColorHighlight=fed22f&fcHighlight=363636&iconColorHighlight=228ef1&bgColorError=b81900&bgTextureError=08_diagonals_thick.png&bgImgOpacityError=18&borderColorError=cd0a0a&fcError=ffffff&iconColorError=ffd27a&bgColorOverlay=666666&bgTextureOverlay=08_diagonals_thick.png&bgImgOpacityOverlay=20&opacityOverlay=50&bgColorShadow=000000&bgTextureShadow=01_flat.png&bgImgOpacityShadow=10&opacityShadow=20&thicknessShadow=5px&offsetTopShadow=-5px&offsetLeftShadow=-5px&cornerRadiusShadow=5px 13 | */ 14 | 15 | 16 | /* Component containers 17 | ----------------------------------*/ 18 | .ui-widget { font-family: Trebuchet MS, Tahoma, Verdana, Arial, sans-serif; font-size: 1.1em; } 19 | .ui-widget .ui-widget { font-size: 1em; } 20 | .ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Trebuchet MS, Tahoma, Verdana, Arial, sans-serif; font-size: 1em; } 21 | .ui-widget-content { border: 1px solid #dddddd; background: #eeeeee url(images/ui-bg_highlight-soft_100_eeeeee_1x100.png) 50% top repeat-x; color: #333333; } 22 | .ui-widget-content a { color: #333333; } 23 | .ui-widget-header { border: 1px solid #e78f08; background: #f6a828 url(images/ui-bg_gloss-wave_35_f6a828_500x100.png) 50% 50% repeat-x; color: #ffffff; font-weight: bold; } 24 | .ui-widget-header a { color: #ffffff; } 25 | 26 | /* Interaction states 27 | ----------------------------------*/ 28 | .ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #cccccc; background: #f6f6f6 url(images/ui-bg_glass_100_f6f6f6_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #1c94c4; } 29 | .ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #1c94c4; text-decoration: none; } 30 | .ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: 1px solid #fbcb09; background: #fdf5ce url(images/ui-bg_glass_100_fdf5ce_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #c77405; } 31 | .ui-state-hover a, .ui-state-hover a:hover { color: #c77405; text-decoration: none; } 32 | .ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #fbd850; background: #ffffff url(images/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #eb8f00; } 33 | .ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #eb8f00; text-decoration: none; } 34 | .ui-widget :active { outline: none; } 35 | 36 | /* Interaction Cues 37 | ----------------------------------*/ 38 | .ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight {border: 1px solid #fed22f; background: #ffe45c url(images/ui-bg_highlight-soft_75_ffe45c_1x100.png) 50% top repeat-x; color: #363636; } 39 | .ui-state-highlight a, .ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a { color: #363636; } 40 | .ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error {border: 1px solid #cd0a0a; background: #b81900 url(images/ui-bg_diagonals-thick_18_b81900_40x40.png) 50% 50% repeat; color: #ffffff; } 41 | .ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #ffffff; } 42 | .ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #ffffff; } 43 | .ui-priority-primary, .ui-widget-content .ui-priority-primary, .ui-widget-header .ui-priority-primary { font-weight: bold; } 44 | .ui-priority-secondary, .ui-widget-content .ui-priority-secondary, .ui-widget-header .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; } 45 | .ui-state-disabled, .ui-widget-content .ui-state-disabled, .ui-widget-header .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; } 46 | 47 | /* Icons 48 | ----------------------------------*/ 49 | 50 | /* states and images */ 51 | .ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_222222_256x240.png); } 52 | .ui-widget-content .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); } 53 | .ui-widget-header .ui-icon {background-image: url(images/ui-icons_ffffff_256x240.png); } 54 | .ui-state-default .ui-icon { background-image: url(images/ui-icons_ef8c08_256x240.png); } 55 | .ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_ef8c08_256x240.png); } 56 | .ui-state-active .ui-icon {background-image: url(images/ui-icons_ef8c08_256x240.png); } 57 | .ui-state-highlight .ui-icon {background-image: url(images/ui-icons_228ef1_256x240.png); } 58 | .ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_ffd27a_256x240.png); } 59 | 60 | /* positioning */ 61 | .ui-icon-carat-1-n { background-position: 0 0; } 62 | .ui-icon-carat-1-ne { background-position: -16px 0; } 63 | .ui-icon-carat-1-e { background-position: -32px 0; } 64 | .ui-icon-carat-1-se { background-position: -48px 0; } 65 | .ui-icon-carat-1-s { background-position: -64px 0; } 66 | .ui-icon-carat-1-sw { background-position: -80px 0; } 67 | .ui-icon-carat-1-w { background-position: -96px 0; } 68 | .ui-icon-carat-1-nw { background-position: -112px 0; } 69 | .ui-icon-carat-2-n-s { background-position: -128px 0; } 70 | .ui-icon-carat-2-e-w { background-position: -144px 0; } 71 | .ui-icon-triangle-1-n { background-position: 0 -16px; } 72 | .ui-icon-triangle-1-ne { background-position: -16px -16px; } 73 | .ui-icon-triangle-1-e { background-position: -32px -16px; } 74 | .ui-icon-triangle-1-se { background-position: -48px -16px; } 75 | .ui-icon-triangle-1-s { background-position: -64px -16px; } 76 | .ui-icon-triangle-1-sw { background-position: -80px -16px; } 77 | .ui-icon-triangle-1-w { background-position: -96px -16px; } 78 | .ui-icon-triangle-1-nw { background-position: -112px -16px; } 79 | .ui-icon-triangle-2-n-s { background-position: -128px -16px; } 80 | .ui-icon-triangle-2-e-w { background-position: -144px -16px; } 81 | .ui-icon-arrow-1-n { background-position: 0 -32px; } 82 | .ui-icon-arrow-1-ne { background-position: -16px -32px; } 83 | .ui-icon-arrow-1-e { background-position: -32px -32px; } 84 | .ui-icon-arrow-1-se { background-position: -48px -32px; } 85 | .ui-icon-arrow-1-s { background-position: -64px -32px; } 86 | .ui-icon-arrow-1-sw { background-position: -80px -32px; } 87 | .ui-icon-arrow-1-w { background-position: -96px -32px; } 88 | .ui-icon-arrow-1-nw { background-position: -112px -32px; } 89 | .ui-icon-arrow-2-n-s { background-position: -128px -32px; } 90 | .ui-icon-arrow-2-ne-sw { background-position: -144px -32px; } 91 | .ui-icon-arrow-2-e-w { background-position: -160px -32px; } 92 | .ui-icon-arrow-2-se-nw { background-position: -176px -32px; } 93 | .ui-icon-arrowstop-1-n { background-position: -192px -32px; } 94 | .ui-icon-arrowstop-1-e { background-position: -208px -32px; } 95 | .ui-icon-arrowstop-1-s { background-position: -224px -32px; } 96 | .ui-icon-arrowstop-1-w { background-position: -240px -32px; } 97 | .ui-icon-arrowthick-1-n { background-position: 0 -48px; } 98 | .ui-icon-arrowthick-1-ne { background-position: -16px -48px; } 99 | .ui-icon-arrowthick-1-e { background-position: -32px -48px; } 100 | .ui-icon-arrowthick-1-se { background-position: -48px -48px; } 101 | .ui-icon-arrowthick-1-s { background-position: -64px -48px; } 102 | .ui-icon-arrowthick-1-sw { background-position: -80px -48px; } 103 | .ui-icon-arrowthick-1-w { background-position: -96px -48px; } 104 | .ui-icon-arrowthick-1-nw { background-position: -112px -48px; } 105 | .ui-icon-arrowthick-2-n-s { background-position: -128px -48px; } 106 | .ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; } 107 | .ui-icon-arrowthick-2-e-w { background-position: -160px -48px; } 108 | .ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; } 109 | .ui-icon-arrowthickstop-1-n { background-position: -192px -48px; } 110 | .ui-icon-arrowthickstop-1-e { background-position: -208px -48px; } 111 | .ui-icon-arrowthickstop-1-s { background-position: -224px -48px; } 112 | .ui-icon-arrowthickstop-1-w { background-position: -240px -48px; } 113 | .ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; } 114 | .ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; } 115 | .ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; } 116 | .ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; } 117 | .ui-icon-arrowreturn-1-w { background-position: -64px -64px; } 118 | .ui-icon-arrowreturn-1-n { background-position: -80px -64px; } 119 | .ui-icon-arrowreturn-1-e { background-position: -96px -64px; } 120 | .ui-icon-arrowreturn-1-s { background-position: -112px -64px; } 121 | .ui-icon-arrowrefresh-1-w { background-position: -128px -64px; } 122 | .ui-icon-arrowrefresh-1-n { background-position: -144px -64px; } 123 | .ui-icon-arrowrefresh-1-e { background-position: -160px -64px; } 124 | .ui-icon-arrowrefresh-1-s { background-position: -176px -64px; } 125 | .ui-icon-arrow-4 { background-position: 0 -80px; } 126 | .ui-icon-arrow-4-diag { background-position: -16px -80px; } 127 | .ui-icon-extlink { background-position: -32px -80px; } 128 | .ui-icon-newwin { background-position: -48px -80px; } 129 | .ui-icon-refresh { background-position: -64px -80px; } 130 | .ui-icon-shuffle { background-position: -80px -80px; } 131 | .ui-icon-transfer-e-w { background-position: -96px -80px; } 132 | .ui-icon-transferthick-e-w { background-position: -112px -80px; } 133 | .ui-icon-folder-collapsed { background-position: 0 -96px; } 134 | .ui-icon-folder-open { background-position: -16px -96px; } 135 | .ui-icon-document { background-position: -32px -96px; } 136 | .ui-icon-document-b { background-position: -48px -96px; } 137 | .ui-icon-note { background-position: -64px -96px; } 138 | .ui-icon-mail-closed { background-position: -80px -96px; } 139 | .ui-icon-mail-open { background-position: -96px -96px; } 140 | .ui-icon-suitcase { background-position: -112px -96px; } 141 | .ui-icon-comment { background-position: -128px -96px; } 142 | .ui-icon-person { background-position: -144px -96px; } 143 | .ui-icon-print { background-position: -160px -96px; } 144 | .ui-icon-trash { background-position: -176px -96px; } 145 | .ui-icon-locked { background-position: -192px -96px; } 146 | .ui-icon-unlocked { background-position: -208px -96px; } 147 | .ui-icon-bookmark { background-position: -224px -96px; } 148 | .ui-icon-tag { background-position: -240px -96px; } 149 | .ui-icon-home { background-position: 0 -112px; } 150 | .ui-icon-flag { background-position: -16px -112px; } 151 | .ui-icon-calendar { background-position: -32px -112px; } 152 | .ui-icon-cart { background-position: -48px -112px; } 153 | .ui-icon-pencil { background-position: -64px -112px; } 154 | .ui-icon-clock { background-position: -80px -112px; } 155 | .ui-icon-disk { background-position: -96px -112px; } 156 | .ui-icon-calculator { background-position: -112px -112px; } 157 | .ui-icon-zoomin { background-position: -128px -112px; } 158 | .ui-icon-zoomout { background-position: -144px -112px; } 159 | .ui-icon-search { background-position: -160px -112px; } 160 | .ui-icon-wrench { background-position: -176px -112px; } 161 | .ui-icon-gear { background-position: -192px -112px; } 162 | .ui-icon-heart { background-position: -208px -112px; } 163 | .ui-icon-star { background-position: -224px -112px; } 164 | .ui-icon-link { background-position: -240px -112px; } 165 | .ui-icon-cancel { background-position: 0 -128px; } 166 | .ui-icon-plus { background-position: -16px -128px; } 167 | .ui-icon-plusthick { background-position: -32px -128px; } 168 | .ui-icon-minus { background-position: -48px -128px; } 169 | .ui-icon-minusthick { background-position: -64px -128px; } 170 | .ui-icon-close { background-position: -80px -128px; } 171 | .ui-icon-closethick { background-position: -96px -128px; } 172 | .ui-icon-key { background-position: -112px -128px; } 173 | .ui-icon-lightbulb { background-position: -128px -128px; } 174 | .ui-icon-scissors { background-position: -144px -128px; } 175 | .ui-icon-clipboard { background-position: -160px -128px; } 176 | .ui-icon-copy { background-position: -176px -128px; } 177 | .ui-icon-contact { background-position: -192px -128px; } 178 | .ui-icon-image { background-position: -208px -128px; } 179 | .ui-icon-video { background-position: -224px -128px; } 180 | .ui-icon-script { background-position: -240px -128px; } 181 | .ui-icon-alert { background-position: 0 -144px; } 182 | .ui-icon-info { background-position: -16px -144px; } 183 | .ui-icon-notice { background-position: -32px -144px; } 184 | .ui-icon-help { background-position: -48px -144px; } 185 | .ui-icon-check { background-position: -64px -144px; } 186 | .ui-icon-bullet { background-position: -80px -144px; } 187 | .ui-icon-radio-off { background-position: -96px -144px; } 188 | .ui-icon-radio-on { background-position: -112px -144px; } 189 | .ui-icon-pin-w { background-position: -128px -144px; } 190 | .ui-icon-pin-s { background-position: -144px -144px; } 191 | .ui-icon-play { background-position: 0 -160px; } 192 | .ui-icon-pause { background-position: -16px -160px; } 193 | .ui-icon-seek-next { background-position: -32px -160px; } 194 | .ui-icon-seek-prev { background-position: -48px -160px; } 195 | .ui-icon-seek-end { background-position: -64px -160px; } 196 | .ui-icon-seek-start { background-position: -80px -160px; } 197 | /* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */ 198 | .ui-icon-seek-first { background-position: -80px -160px; } 199 | .ui-icon-stop { background-position: -96px -160px; } 200 | .ui-icon-eject { background-position: -112px -160px; } 201 | .ui-icon-volume-off { background-position: -128px -160px; } 202 | .ui-icon-volume-on { background-position: -144px -160px; } 203 | .ui-icon-power { background-position: 0 -176px; } 204 | .ui-icon-signal-diag { background-position: -16px -176px; } 205 | .ui-icon-signal { background-position: -32px -176px; } 206 | .ui-icon-battery-0 { background-position: -48px -176px; } 207 | .ui-icon-battery-1 { background-position: -64px -176px; } 208 | .ui-icon-battery-2 { background-position: -80px -176px; } 209 | .ui-icon-battery-3 { background-position: -96px -176px; } 210 | .ui-icon-circle-plus { background-position: 0 -192px; } 211 | .ui-icon-circle-minus { background-position: -16px -192px; } 212 | .ui-icon-circle-close { background-position: -32px -192px; } 213 | .ui-icon-circle-triangle-e { background-position: -48px -192px; } 214 | .ui-icon-circle-triangle-s { background-position: -64px -192px; } 215 | .ui-icon-circle-triangle-w { background-position: -80px -192px; } 216 | .ui-icon-circle-triangle-n { background-position: -96px -192px; } 217 | .ui-icon-circle-arrow-e { background-position: -112px -192px; } 218 | .ui-icon-circle-arrow-s { background-position: -128px -192px; } 219 | .ui-icon-circle-arrow-w { background-position: -144px -192px; } 220 | .ui-icon-circle-arrow-n { background-position: -160px -192px; } 221 | .ui-icon-circle-zoomin { background-position: -176px -192px; } 222 | .ui-icon-circle-zoomout { background-position: -192px -192px; } 223 | .ui-icon-circle-check { background-position: -208px -192px; } 224 | .ui-icon-circlesmall-plus { background-position: 0 -208px; } 225 | .ui-icon-circlesmall-minus { background-position: -16px -208px; } 226 | .ui-icon-circlesmall-close { background-position: -32px -208px; } 227 | .ui-icon-squaresmall-plus { background-position: -48px -208px; } 228 | .ui-icon-squaresmall-minus { background-position: -64px -208px; } 229 | .ui-icon-squaresmall-close { background-position: -80px -208px; } 230 | .ui-icon-grip-dotted-vertical { background-position: 0 -224px; } 231 | .ui-icon-grip-dotted-horizontal { background-position: -16px -224px; } 232 | .ui-icon-grip-solid-vertical { background-position: -32px -224px; } 233 | .ui-icon-grip-solid-horizontal { background-position: -48px -224px; } 234 | .ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; } 235 | .ui-icon-grip-diagonal-se { background-position: -80px -224px; } 236 | 237 | 238 | /* Misc visuals 239 | ----------------------------------*/ 240 | 241 | /* Corner radius */ 242 | .ui-corner-all, .ui-corner-top, .ui-corner-left, .ui-corner-tl { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; -khtml-border-top-left-radius: 4px; border-top-left-radius: 4px; } 243 | .ui-corner-all, .ui-corner-top, .ui-corner-right, .ui-corner-tr { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; -khtml-border-top-right-radius: 4px; border-top-right-radius: 4px; } 244 | .ui-corner-all, .ui-corner-bottom, .ui-corner-left, .ui-corner-bl { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; -khtml-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; } 245 | .ui-corner-all, .ui-corner-bottom, .ui-corner-right, .ui-corner-br { -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; -khtml-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; } 246 | 247 | /* Overlays */ 248 | .ui-widget-overlay { background: #666666 url(images/ui-bg_diagonals-thick_20_666666_40x40.png) 50% 50% repeat; opacity: .50;filter:Alpha(Opacity=50); } 249 | .ui-widget-shadow { margin: -5px 0 0 -5px; padding: 5px; background: #000000 url(images/ui-bg_flat_10_000000_40x100.png) 50% 50% repeat-x; opacity: .20;filter:Alpha(Opacity=20); -moz-border-radius: 5px; -khtml-border-radius: 5px; -webkit-border-radius: 5px; border-radius: 5px; } -------------------------------------------------------------------------------- /classes/ppc_general_functions_class.php: -------------------------------------------------------------------------------- 1 | ID != 0 AND 67 | $check_current_user_cap_special == TRUE AND $current_user->ID != $userid AND ( ! $perm->can_see_countings_special_settings() ) ) 68 | $userid = $current_user->ID; 69 | 70 | //Retrieve cached settings if available or from database if not 71 | $cache = wp_cache_get( 'ppc_settings_'.$userid ); 72 | 73 | if( $cache != false AND $complete_with_general ) { 74 | $user_settings = $cache; 75 | } else { 76 | if( $cache === 0 ) { //cache equal to 0 means user has no special settings 77 | $user_settings = $general_settings; 78 | } else { 79 | $user_settings = get_user_option( $ppc_global_settings['option_name'], $userid ); 80 | 81 | //If no special settings for this user are available, get general ones 82 | if( $user_settings == false ) { 83 | $user_settings = $general_settings; 84 | wp_cache_set( 'ppc_settings_'.$userid, 0 ); 85 | 86 | //If user has special settings, complete user settings with general ones if needed (i.e. add only-general settings to the return array of special user's settings) 87 | } else if( $complete_with_general ) { 88 | $user_settings = array_merge( $general_settings, $user_settings ); 89 | wp_cache_set( 'ppc_settings_'.$userid, $user_settings ); 90 | } 91 | } 92 | } 93 | 94 | $return = $user_settings; 95 | 96 | } else { 97 | $return = self::get_settings( 'general' ); 98 | } 99 | 100 | /** 101 | * Filters retrieved settings before returning them. 102 | * 103 | * @since 2.518 104 | * @param $return array to be returned settings array 105 | * @param $userid string user id whose settings are being requested 106 | * @param bool whether can-see-other-users-personalized-settings permission should be checked 107 | * @param bool whether user specific settings should be completed with general ones for options which are not cusomized for that user 108 | */ 109 | $return = apply_filters( 'ppc_settings', $return ); 110 | $return = apply_filters( 'ppc_get_settings', $return, $userid, $check_current_user_cap_special, $complete_with_general ); 111 | 112 | return $return; 113 | } 114 | 115 | /** 116 | * Clears cache of all settings-dependent objects. 117 | * This is DEPRECATED and is now a wrapper of PPC_cache_functions::clear_settings_cache( $userid ). 118 | * 119 | * @access public 120 | * @since 2.601 121 | * @param $userid string userid whose settings cache needs to be flushed 122 | * @return void 123 | */ 124 | static function clear_settings_cache( $userid = 'general' ) { 125 | PPC_cache_functions::clear_settings( $userid ); 126 | } 127 | 128 | /** 129 | * Gets non capitalized input. 130 | * 131 | * Grants compatibility with PHP < 5.3. 132 | * 133 | * @access public 134 | * @since 2.0.9 135 | * @param $string string to lowercase 136 | * @return string lowercased 137 | */ 138 | 139 | static function lcfirst( $string ) { 140 | if( function_exists( 'lcfirst' ) ) 141 | return lcfirst( $string ); 142 | else 143 | return (string) ( strtolower( substr( $string, 0, 1 ) ).substr( $string, 1 ) ); 144 | } 145 | 146 | /** 147 | * Gets the link to the stats page of the requested author with the proper start and end time 148 | * 149 | * @access public 150 | * @since 2.0 151 | * @param $author_id int the author id 152 | * @return string the link to their stats 153 | */ 154 | 155 | static function get_the_author_link( $author_id ) { 156 | global $ppc_global_settings; 157 | 158 | $link = admin_url( $ppc_global_settings['stats_menu_link'].'&author='.$author_id.'&tstart='.$ppc_global_settings['stats_tstart'].'&tend='.$ppc_global_settings['stats_tend'] ); 159 | 160 | if( isset( $_REQUEST['ppc-time-range'] ) AND ! empty( $_REQUEST['ppc-time-range'] ) ) 161 | $link .= '&ppc-time-range='.esc_attr( $_REQUEST['ppc-time-range'] ); 162 | 163 | if( isset( $_REQUEST['paged'] ) AND ! empty( $_REQUEST['paged'] ) ) 164 | $link .= '&paged='.esc_attr( $_REQUEST['paged'] ); 165 | 166 | return apply_filters( 'ppc_get_author_link', $link ); 167 | } 168 | 169 | /** 170 | * Makes sure each user role has or has not the requested capability to see options and stats pages. 171 | * 172 | * Called when updating settings and updating/installing. 173 | * 174 | * @access public 175 | * @since 2.0.4 176 | * @param $allowed_user_roles_options_page array user roles allowed to see plugin options 177 | * @param $allowed_user_roles_stats_page array user roles allowed to see plugin stats 178 | */ 179 | 180 | static function manage_cap_allowed_user_roles_plugin_pages( $allowed_user_roles_options_page, $allowed_user_roles_stats_page ) { 181 | global $wp_roles, $ppc_global_settings; 182 | 183 | if ( ! isset( $wp_roles ) ) 184 | $wp_roles = new WP_Roles(); 185 | 186 | $wp_roles_to_use = array(); 187 | foreach( $wp_roles->role_names as $key => $value ) { 188 | $wp_roles_to_use[] = $key; 189 | } 190 | 191 | $allowed_user_roles_stats_page_add_cap = array_intersect( $allowed_user_roles_stats_page, $wp_roles_to_use ); 192 | $allowed_user_roles_stats_page_remove_cap = array_diff( $wp_roles_to_use, $allowed_user_roles_stats_page ); 193 | $allowed_user_roles_options_page_add_cap = array_intersect( $allowed_user_roles_options_page, $wp_roles_to_use ); 194 | $allowed_user_roles_options_page_remove_cap = array_diff( $wp_roles_to_use, $allowed_user_roles_options_page ); 195 | 196 | foreach( $allowed_user_roles_options_page_add_cap as $single ) { 197 | $current_role = get_role( self::lcfirst( $single ) ); 198 | 199 | if( is_object( $current_role ) AND ! $current_role->has_cap( $ppc_global_settings['cap_manage_options'] ) ) 200 | $current_role->add_cap( $ppc_global_settings['cap_manage_options'] ); 201 | } 202 | 203 | foreach( $allowed_user_roles_options_page_remove_cap as $single ) { 204 | $current_role = get_role( self::lcfirst( $single ) ); 205 | 206 | if( is_object( $current_role ) AND $current_role->has_cap( $ppc_global_settings['cap_manage_options'] ) ) 207 | $current_role->remove_cap( $ppc_global_settings['cap_manage_options'] ); 208 | } 209 | 210 | foreach( $allowed_user_roles_stats_page_add_cap as $single ) { 211 | $current_role = get_role( self::lcfirst( $single ) ); 212 | 213 | if( is_object( $current_role ) AND ! $current_role->has_cap( $ppc_global_settings['cap_access_stats'] ) ) 214 | $current_role->add_cap( $ppc_global_settings['cap_access_stats'] ); 215 | } 216 | 217 | foreach( $allowed_user_roles_stats_page_remove_cap as $single ) { 218 | $current_role = get_role( self::lcfirst( $single ) ); 219 | 220 | if( is_object( $current_role ) AND $current_role->has_cap( $ppc_global_settings['cap_access_stats'] ) ) 221 | $current_role->remove_cap( $ppc_global_settings['cap_access_stats'] ); 222 | } 223 | } 224 | 225 | /** 226 | * Defines default stats time range depending on chosen settings. 227 | * 228 | * Stores settings in plugin's global var. 229 | * 230 | * @access public 231 | * @since 2.1 232 | * @param $settings array plugin settings 233 | */ 234 | static function get_default_stats_time_range( $settings ) { 235 | global $ppc_global_settings; 236 | 237 | //Default time range already done 238 | if( isset( $ppc_global_settings['stats_tstart'] ) ) return; 239 | 240 | //First available post time 241 | $args = array( 242 | 'post_type' => $settings['counting_allowed_post_types'], 243 | 'posts_per_page' => 1, 244 | 'orderby' => 'post_date', 245 | 'order' => 'ASC' 246 | ); 247 | $first_available_post = new WP_Query( $args ); 248 | 249 | if( $first_available_post->no_found_rows === false ) 250 | $first_available_post_time = current_time( 'timestamp' ); 251 | else 252 | $first_available_post_time = strtotime( $first_available_post->posts[0]->post_date ); 253 | 254 | $ppc_global_settings['first_available_post_time'] = $first_available_post_time; 255 | 256 | //Last available post time 257 | $args = array( 258 | 'post_type' => $settings['counting_allowed_post_types'], 259 | 'posts_per_page' => 1, 260 | 'orderby' => 'post_date', 261 | 'order' => 'DESC' 262 | ); 263 | $last_available_post = new WP_Query( $args ); //for future scheduled posts 264 | 265 | if( $last_available_post->no_found_rows === false ) 266 | $last_available_post_time = strtotime( $last_available_post->posts[0]->post_date ); 267 | 268 | if( ! isset( $last_available_post_time ) OR $last_available_post_time < current_time( 'timestamp' ) ) 269 | $last_available_post_time = strtotime( '23:59:59' ); //Pub Bonus needs to select even days without posts in the future, maybe there are publishings 270 | 271 | $ppc_global_settings['last_available_post_time'] = $last_available_post_time; 272 | 273 | //Define default time range 274 | if( $settings['default_stats_time_range_week'] ) { 275 | $ppc_global_settings['stats_tstart'] = strtotime( '00:00:00' ) - ( ( date( 'N' )-1 )*24*60*60 ); 276 | $ppc_global_settings['stats_tend'] = strtotime( '23:59:59' ); 277 | } else if( $settings['default_stats_time_range_month'] ) { 278 | $ppc_global_settings['stats_tstart'] = strtotime( '00:00:00' ) - ( ( date( 'j' )-1 )*24*60*60 ); //starts from timestamp of current day and subtracts seconds for enough days (depending on what day is today) 279 | $ppc_global_settings['stats_tend'] = strtotime( '23:59:59' ); 280 | } else if( $settings['default_stats_time_range_this_year'] ) { 281 | $ppc_global_settings['stats_tstart'] = strtotime( '00:00:00' ) - ( ( date( 'z' ) )*24*60*60 ); //starts from timestamp of current day and subtracts seconds for enough days (depending on what day of the year is today) 282 | $ppc_global_settings['stats_tend'] = strtotime( '23:59:59' ); 283 | } else if( $settings['default_stats_time_range_last_month'] ) { 284 | $prev_month = ( date( 'm' ) > 1 ) ? date( 'm' ) - 1 : 12; 285 | $ppc_global_settings['stats_tstart'] = strtotime( '00:00:00' ) - ( ( date( 'j' )-1 + cal_days_in_month( CAL_GREGORIAN, $prev_month, date( 'Y' ) ) )*24*60*60 ); 286 | $ppc_global_settings['stats_tend'] = strtotime( '23:59:59' ) - ( date( 'j' )*24*60*60 ); 287 | } else if( $settings['default_stats_time_range_all_time'] ) { 288 | $ppc_global_settings['stats_tstart'] = $ppc_global_settings['first_available_post_time']; 289 | $ppc_global_settings['stats_tend'] = $ppc_global_settings['last_available_post_time']; 290 | } else if( $settings['default_stats_time_range_custom'] ) { 291 | $ppc_global_settings['stats_tstart'] = strtotime( '00:00:00' ) - ( $settings['default_stats_time_range_custom_value']*24*60*60 ); 292 | $ppc_global_settings['stats_tend'] = strtotime( '23:59:59' ); 293 | } else if( $settings['default_stats_time_range_start_day'] ) { 294 | $ppc_global_settings['stats_tstart'] = strtotime( $settings['default_stats_time_range_start_day_value'].' 00:00:00' ); 295 | $ppc_global_settings['stats_tend'] = strtotime( '23:59:59' ); 296 | } 297 | } 298 | 299 | /** 300 | * Checks if there is a saved ordering for stats and redirects to the apt ordered stats page in case. 301 | * Stores current ordering, if any. 302 | * 303 | * @since 2.725 304 | * 305 | */ 306 | static function default_stats_order() { 307 | global $ppc_global_settings; 308 | 309 | //Exit if disabled 310 | $general_settings = PPC_general_functions::get_settings( 'general' ); 311 | if( ! $general_settings['save_stats_order'] ) return; 312 | 313 | //If there is a saved sorting, use it 314 | if( ! isset( $_GET['orderby'] ) AND isset( $_COOKIE['ppc_'.$ppc_global_settings['current_page'].'_orderby'] ) ) { 315 | $redirect_url = admin_url( 'admin.php' ).'?'.$_SERVER['QUERY_STRING'].'&orderby='.$_COOKIE['ppc_'.$ppc_global_settings['current_page'].'_orderby']; 316 | 317 | if( isset( $_COOKIE['ppc_'.$ppc_global_settings['current_page'].'_order'] ) ) 318 | $redirect_url .= '&order='.$_COOKIE['ppc_'.$ppc_global_settings['current_page'].'_order']; 319 | 320 | wp_safe_redirect( $redirect_url ); 321 | 322 | } 323 | 324 | //Store stats sorting settings, cookies expire in 6 months 325 | if( isset( $_GET['orderby'] ) ) { 326 | setcookie( 'ppc_'.$ppc_global_settings['current_page'].'_orderby', htmlentities( $_GET['orderby'] ), time()+(86400*180) ); 327 | 328 | if( isset( $_GET['order'] ) ) 329 | setcookie( 'ppc_'.$ppc_global_settings['current_page'].'_order', htmlentities( $_GET['order'] ), time()+(86400*180) ); 330 | } 331 | 332 | } 333 | 334 | /** 335 | * Formats payments for output. 336 | * 337 | * @access public 338 | * @since 2.40 339 | * @param $payment string payment to be formatted 340 | * @return string formatted payment 341 | */ 342 | 343 | static function format_payment( $payment ) { 344 | $general_settings = PPC_general_functions::get_settings( 'general' ); 345 | 346 | return apply_filters( 'ppc_format_payment', sprintf( '%.'.$general_settings['payment_display_round_digits'].'f', $payment ) ); 347 | } 348 | 349 | /** 350 | * Parses visits callback function. 351 | * 352 | * @access public 353 | * @since 2.770 354 | * @param callback to be parsed 355 | * @return mixed (string/array) visits count PHP callable 356 | */ 357 | static function parse_visits_callback_function( $callback = '' ) { 358 | $explode = explode( ',', $callback ); 359 | 360 | $return = $callback; 361 | if( count( $explode ) == 2 ) //if callback is in the form classname, methodname 362 | $return = array( trim( $explode[0] ), trim( $explode[1] ) ); 363 | 364 | return $return; 365 | } 366 | } 367 | 368 | //Compatibility for people who lack the PHP calendar plugin 369 | if( ! function_exists( 'cal_days_in_month' ) ) { 370 | function cal_days_in_month( $calendar, $month, $year ) { 371 | return date( 't', mktime( 0, 0, 0, $month, 1, $year ) ); 372 | } 373 | } 374 | 375 | //Ensuring compatibility with PHP < 5.5 (Requires 5.3, though) 376 | if( ! function_exists( "array_column" ) ) { 377 | function array_column( $array, $column_name ) { 378 | return array_map( function( $element ) use( $column_name ) { 379 | return $element[$column_name]; 380 | }, $array ); 381 | } 382 | } 383 | 384 | //Callback for stats sorting 385 | function ppc_uasort_stats_sort( $a, $b ) { 386 | $result = strnatcasecmp( $a[$_REQUEST['orderby']], $b[$_REQUEST['orderby']] ); //Determine sort order 387 | return ( $_REQUEST['order'] === 'asc' ) ? $result : -$result; //Send final sort direction to usort 388 | } 389 | 390 | //Get a list with how settings should be prioritized (for addons) 391 | //Assumes that every action has a different priority 392 | function ppc_get_settings_priority( $setting_type ) { 393 | global $wp_filter; 394 | $settings_priority = array(); 395 | foreach( $wp_filter['ppc_get_settings']->callbacks as $priority => $callbacks ) { 396 | //$settings_priority[key($callbacks)] = $priority; 397 | if( strpos( key( $callbacks ), $setting_type ) !== false ) 398 | return $priority; 399 | } 400 | return false; 401 | } 402 | 403 | //wp's is_plugin_active is only available in wp_admin, and after admin_init 404 | function ppc_is_plugin_active( $slug ) { 405 | return in_array($slug, apply_filters('active_plugins', get_option('active_plugins'))); 406 | } 407 | --------------------------------------------------------------------------------