404page – your smart custom 404 error page - Version 11.0.0

Version Description

now uses my own Plugin Foundation

Download this release

Release Info

Developer petersplugins
Plugin Icon 128x128 404page – your smart custom 404 error page
Version 11.0.0
Comparing to
See all releases

Code changes from version 10.5 to 11.0.0

404page.php CHANGED
@@ -7,9 +7,9 @@
7
  *
8
  * @wordpress-plugin
9
  * Plugin Name: 404page - your smart custom 404 error page
10
- * Plugin URI: https://petersplugins.com/free-wordpress-plugins/404page/
11
  * Description: Custom 404 the easy way! Set any page as custom 404 error page. No coding needed. Works with (almost) every Theme.
12
- * Version: 10.5
13
  * Author: Peter Raschendorfer
14
  * Author URI: https://petersplugins.com
15
  * Text Domain: 404page
@@ -29,40 +29,4 @@ if ( ! defined( 'WPINC' ) ) {
29
  */
30
  require_once( plugin_dir_path( __FILE__ ) . '/loader.php' );
31
 
32
-
33
- /**
34
- * Theme functions
35
- */
36
-
37
-
38
- // this function can be used by a theme to check if there's an active custom 404 page
39
- function pp_404_is_active() {
40
- return pp_404page()->pp_404_is_active();
41
- }
42
-
43
- // this function can be used by a theme to activate native support
44
- function pp_404_set_native_support() {
45
- pp_404page()->pp_404_set_native_support();
46
- }
47
-
48
- // this function can be used by a theme to get the title of the custom 404 page in native support
49
- function pp_404_get_the_title() {
50
- return pp_404page()->pp_404_get_the_title();
51
- }
52
-
53
- // this function can be used by a theme to print out the title of the custom 404 page in native support
54
- function pp_404_the_title() {
55
- pp_404page()->pp_404_the_title();
56
- }
57
-
58
- // this function can be used by a theme to get the content of the custom 404 page in native support
59
- function pp_404_get_the_content() {
60
- return pp_404page()->pp_404_get_the_content();
61
- }
62
-
63
- // this function can be used by a theme to print out the content of the custom 404 page in native support
64
- function pp_404_the_content() {
65
- return pp_404page()->pp_404_the_content();
66
- }
67
-
68
  ?>
7
  *
8
  * @wordpress-plugin
9
  * Plugin Name: 404page - your smart custom 404 error page
10
+ * Plugin URI: https://petersplugins.com/404page/
11
  * Description: Custom 404 the easy way! Set any page as custom 404 error page. No coding needed. Works with (almost) every Theme.
12
+ * Version: 11.0.0
13
  * Author: Peter Raschendorfer
14
  * Author URI: https://petersplugins.com
15
  * Text Domain: 404page
29
  */
30
  require_once( plugin_dir_path( __FILE__ ) . '/loader.php' );
31
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
32
  ?>
assets/css/404page-ui.css CHANGED
@@ -2,40 +2,7 @@
2
  width: 100%;
3
  }
4
 
5
- #pp-404page-settings .form-table th, .form-table td {
6
- display: block;
7
- width: auto;
8
- }
9
-
10
- #pp-404page-settings .form-table td {
11
- padding: 0;
12
- margin-bottom: 20px;
13
- }
14
-
15
- #pp-404page-settings .form-table td p {
16
- padding: 0;
17
- line-height: 1.2;
18
- margin-bottom: 20px;
19
- }
20
-
21
- #pp-404page-settings .form-table th {
22
- padding: 0;
23
- font-weight: normal;
24
- }
25
-
26
- #pp-404page-settings select {
27
- border: 1px solid #104060;
28
- border-radius:5px;
29
- height: 40px;
30
- line-height: 40px;
31
- margin: 5px 0;
32
- }
33
-
34
- #pp-404page-settings .dashicons-warning, #pp-404page-settings input[type="checkbox"] + label.check.warning:before {
35
- color: #d54e21;
36
- }
37
-
38
- #pp-404page-videos:after {
39
  content: '';
40
  display: block;
41
  width: 0;
@@ -45,7 +12,7 @@
45
  clear: both;
46
  }
47
 
48
- #pp-404page-videos a {
49
  display: block;
50
  margin: 0 12px 12px 0;
51
  width: 300px;
@@ -53,16 +20,16 @@
53
  line-height: 1;
54
  }
55
 
56
- #pp-404page-videos a div {
57
  position: relative;
58
  }
59
 
60
- #pp-404page-videos a img {
61
  width: 100%;
62
  height: auto;
63
  }
64
 
65
- #pp-404page-videos a div:after {
66
  content: '\f236';
67
  font-family: dashicons;
68
  font-size: 60px;
@@ -78,7 +45,7 @@
78
  transition: opacity 0.3s ease-in-out;
79
  }
80
 
81
- #pp-404page-videos a:hover div:after, #pp-404page-videos a:focus div:after {
82
  opacity: 0.8;
83
  }
84
 
2
  width: 100%;
3
  }
4
 
5
+ .pp-404page-videos:after {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6
  content: '';
7
  display: block;
8
  width: 0;
12
  clear: both;
13
  }
14
 
15
+ .pp-404page-videos a {
16
  display: block;
17
  margin: 0 12px 12px 0;
18
  width: 300px;
20
  line-height: 1;
21
  }
22
 
23
+ .pp-404page-videos a div {
24
  position: relative;
25
  }
26
 
27
+ .pp-404page-videos a img {
28
  width: 100%;
29
  height: auto;
30
  }
31
 
32
+ .pp-404page-videos a div:after {
33
  content: '\f236';
34
  font-family: dashicons;
35
  font-size: 60px;
45
  transition: opacity 0.3s ease-in-out;
46
  }
47
 
48
+ .pp-404page-videos a:hover div:after, .pp-404page-videos a:focus div:after {
49
  opacity: 0.8;
50
  }
51
 
assets/css/pp-admin-page-v2.css DELETED
@@ -1,120 +0,0 @@
1
- .pp-admin-page-wrapper h1 {
2
- margin-bottom: 32px;
3
- }
4
-
5
- .pp-admin-page-wrapper h1>span {
6
- display: block;
7
- line-height: 48px;
8
- padding-left: 60px;
9
- background-image: url(../img/pluginicon.png);
10
- background-repeat: no-repeat;
11
- background-color: #4B6F87;
12
- color: #fff;
13
- }
14
-
15
- .rtl .pp-admin-page-wrapper h1>span {
16
- padding-left: 0;
17
- padding-right: 60px;
18
- background-position: right top;
19
- }
20
-
21
- .pp-admin-page-wrapper h1 nav {
22
- text-align: right;
23
- line-height: 1;
24
- border-right: 1px solid #4B6F87;
25
- }
26
-
27
- .rtl .pp-admin-page-wrapper h1 nav {
28
- text-align: left;
29
- }
30
-
31
- .pp-admin-page-wrapper h1 nav a {
32
- display: inline-block;
33
- padding: 6px;
34
- color: #4B6F87;
35
- background-color: #fff;
36
- text-decoration: none;
37
- font-size: 12px;
38
- height: 20px;
39
- line-height: 20px;
40
- border-left: 1px solid #4B6F87;
41
- border-bottom: 1px solid #4B6F87;
42
- }
43
-
44
- .pp-admin-page-wrapper h1 nav a span.text {
45
- white-space: nowrap;
46
- padding-left: 4px;
47
- display: none;
48
- }
49
-
50
- @media only screen and (min-width: 1200px) {
51
- .pp-admin-page-wrapper h1 nav a span.text {
52
- display: inline;
53
- }
54
- }
55
-
56
- .pp-admin-page-wrapper h1 nav a:hover, .pp-admin-page-wrapper h1 nav a:focus {
57
- background-color: #4B6F87;
58
- color: #fff;
59
- }
60
-
61
- .pp-admin-page-hide-th th {
62
- display: none;
63
- }
64
-
65
- .pp-admin-page-wrapper .toggle {
66
- height: 40px;
67
- line-height: 40px;
68
- }
69
-
70
- .pp-admin-page-wrapper .toggle input[type="checkbox"] {
71
- display: none;
72
- }
73
-
74
- .pp-admin-page-wrapper .toggle input[type="checkbox"] + label {
75
- cursor: pointer;
76
- text-indent: -9999px;
77
- width: 80px;
78
- height: 40px;
79
- background: grey;
80
- display: block;
81
- border-radius: 40px;
82
- position: relative;
83
- float: left;
84
- margin-right: 40px;
85
- }
86
-
87
- .rtl .pp-admin-page-wrapper .toggle input[type="checkbox"] + label {
88
- float: right;
89
- margin-left: 40px;
90
- margin-right: 0;
91
- }
92
-
93
- .pp-admin-page-wrapper .toggle input[type="checkbox"]:disabled + label {
94
- background-color: #DDD;
95
- }
96
-
97
- .pp-admin-page-wrapper .toggle input[type="checkbox"] + label:after {
98
- content: '';
99
- position: absolute;
100
- top: 5px;
101
- width: 30px;
102
- height: 30px;
103
- background: #fff;
104
- border-radius: 30px;
105
- transition: 0.3s;
106
- }
107
-
108
- body:not(.rtl) .pp-admin-page-wrapper .toggle input[type="checkbox"] + label:after, .rtl .pp-admin-page-wrapper .toggle input[type="checkbox"]:checked + label:after {
109
- left: 5px;
110
- transform: none;
111
- }
112
-
113
- .pp-admin-page-wrapper .toggle input[type="checkbox"]:enabled:checked + label {
114
- background: #104060;
115
- }
116
-
117
- body:not(.rtl) .pp-admin-page-wrapper .toggle input[type="checkbox"]:checked + label:after, .rtl .pp-admin-page-wrapper .toggle input[type="checkbox"] + label:after {
118
- left: calc(100% - 5px);
119
- transform: translateX(-100%);
120
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
assets/img/pluginicon.png CHANGED
Binary file
assets/js/404page.js CHANGED
@@ -1,19 +1,5 @@
1
- jQuery(document).ready(function($) {
2
-
3
- $( '.pp-404page-admin-notice' ).on( 'click', '.notice-dismiss', function ( event ) {
4
-
5
- event.preventDefault();
6
-
7
- data = {
8
- action: 'pp_404page_dismiss_admin_notice',
9
- pp_404page_dismiss_admin_notice: $( this ).parent().attr( 'id' ),
10
- securekey : pp_404page_security.securekey
11
- };
12
-
13
- $.post( ajaxurl, data );
14
-
15
- return false;
16
-
17
- });
18
-
19
- });
1
+ /**
2
+ * As of version 11.0.0 this file is no longer needed
3
+ *
4
+ * It is only included in the setup to override the file when upgrading from an earlier version
5
+ */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
functions.php ADDED
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * The 404page Plugin Functions
5
+ *
6
+ * @since 11.0.0
7
+ *
8
+ **/
9
+
10
+ // If this file is called directly, abort
11
+ if ( ! defined( 'WPINC' ) ) {
12
+ die;
13
+ }
14
+
15
+
16
+ // this function can be used by a theme to check if there's an active custom 404 page
17
+ function pp_404_is_active() {
18
+
19
+ return pp_404page()->pp_404_is_active();
20
+
21
+ }
22
+
23
+
24
+ // this function can be used by a theme to activate native support
25
+ function pp_404_set_native_support() {
26
+
27
+ pp_404page()->pp_404_set_native_support();
28
+
29
+ }
30
+
31
+
32
+ // this function can be used by a theme to get the title of the custom 404 page in native support
33
+ function pp_404_get_the_title() {
34
+
35
+ return pp_404page()->pp_404_get_the_title();
36
+
37
+ }
38
+
39
+
40
+ // this function can be used by a theme to print out the title of the custom 404 page in native support
41
+ function pp_404_the_title() {
42
+
43
+ pp_404page()->pp_404_the_title();
44
+
45
+ }
46
+
47
+
48
+ // this function can be used by a theme to get the content of the custom 404 page in native support
49
+ function pp_404_get_the_content() {
50
+
51
+ return pp_404page()->pp_404_get_the_content();
52
+
53
+ }
54
+
55
+ // this function can be used by a theme to print out the content of the custom 404 page in native support
56
+ function pp_404_the_content() {
57
+
58
+ return pp_404page()->pp_404_the_content();
59
+
60
+ }
61
+
62
+ ?>
inc/admin/404page-admin-page.php CHANGED
@@ -1,69 +1,9 @@
1
- <div class="wrap pp-admin-page-wrapper" id="pp-404page-settings">
2
- <h1>
3
- <span><?php echo esc_html( $this->_core->get_plugin_name() ); ?></span>
4
- <nav>
5
- <?php $this->show_nav_icons( array(
6
- array(
7
- 'link' => 'https://wordpress.org/support/plugin/' . $this->_core->get_plugin_slug() . '/reviews/',
8
- 'title' => __( 'Please rate Plugin', '404page' ),
9
- 'icon' => 'dashicons-star-filled'
10
- ),
11
- array(
12
- 'link' => 'https://wordpress.org/plugins/' . $this->_core->get_plugin_slug(),
13
- 'title' => __( 'WordPress.org Plugin Page', '404page' ),
14
- 'icon' => 'dashicons-wordpress'
15
- ),
16
- array(
17
- 'link' => 'https://petersplugins.com/docs/' . $this->_core->get_plugin_slug(),
18
- 'title' => __( 'Plugin Doc', '404page' ),
19
- 'icon' => 'dashicons-book-alt'
20
- ),
21
- array(
22
- 'link' => 'https://wordpress.org/support/plugin/' . $this->_core->get_plugin_slug(),
23
- 'title' => __( 'Support', '404page' ),
24
- 'icon' => 'dashicons-editor-help'
25
- ),
26
- array(
27
- 'link' => 'https://petersplugins.com/',
28
- 'title' => __( 'Authors Website', '404page' ),
29
- 'icon' => 'dashicons-admin-home'
30
- ),
31
- array(
32
- 'link' => 'https://www.facebook.com/petersplugins/',
33
- 'title' => __( 'Authors Facebook Page', '404page' ),
34
- 'icon' => 'dashicons-facebook-alt'
35
- )
36
-
37
- ) ); ?>
38
- </nav>
39
- </h1>
40
- <?php settings_errors(); ?>
41
-
42
- <div class="postbox">
43
- <div class="inside">
44
-
45
- <form method="POST" action="options.php">
46
-
47
- <h2><?php esc_html_e( 'General', '404page' ); ?></h2>
48
- <?php settings_fields( '404page_settings' ); ?>
49
- <?php do_settings_sections( '404page_settings_section' ); ?>
50
- <div id="pp-settings-advanced">
51
- <h2><?php esc_html_e( 'Advanced', '404page' ); ?></h2>
52
- <?php do_settings_sections( '404page_settings_section_advanced' ); ?>
53
- </div>
54
- <?php submit_button(); ?>
55
-
56
- </form>
57
-
58
- </div>
59
- </div>
60
-
61
- <div class="postbox">
62
- <div class="inside">
63
- <div id="pp-404page-videos">
64
- <h2><?php esc_html_e( 'Watch the Explainer Videos', '404page' ); ?></h2>
65
- <?php $this->show_videos(); ?>
66
- </div>
67
- </div>
68
- </div>
69
- </div>
1
+ <?php
2
+
3
+ /**
4
+ * As of version 11.0.0 this file is no longer needed
5
+ *
6
+ * It is only included in the setup to override the file when upgrading from an earlier version
7
+ */
8
+
9
+ ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
inc/class-404page-admin.php CHANGED
@@ -15,115 +15,168 @@ if ( ! defined( 'WPINC' ) ) {
15
  */
16
  if ( !class_exists( 'PP_404Page_Admin' ) ) {
17
 
18
- class PP_404Page_Admin {
19
-
20
- /**
21
- * reference to core class
22
- *
23
- * @since 10
24
- * @var object
25
- * @access private
26
- */
27
- private $_core;
28
-
29
-
30
- /**
31
- * reference to settings class
32
- *
33
- * @since 10
34
- * @var object
35
- * @access private
36
- */
37
- private $_settings;
38
-
39
-
40
- /**
41
- * admin handle
42
- *
43
- * @since 10
44
- * @var object
45
- * @access private
46
- */
47
- private $admin_handle;
48
-
49
 
50
  /**
51
- * Initialize the class
52
  *
53
  * @since 10
54
  * @access public
55
  */
56
- public function __construct( $_core, $_settings ) {
57
-
58
- $this->_core = $_core;
59
- $this->_settings = $_settings;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
60
 
61
- $this->init();
 
62
 
 
 
63
  }
64
 
65
 
66
  /**
67
- * Do Init
68
- *
69
- * @since 10
70
- * @access private
71
  */
72
- private function init() {
73
-
74
- add_action( 'admin_init', array( $this, 'admin_init' ) );
75
- add_action( 'admin_menu', array( $this, 'admin_menu' ) );
76
- add_action( 'admin_head', array( $this, 'admin_style' ) );
77
- add_filter( 'plugin_action_links_' . plugin_basename( $this->_core->get_plugin_file() ), array( $this, 'add_settings_links' ) );
78
- add_action( 'admin_enqueue_scripts', array( $this, 'admin_js' ) );
79
- add_action( 'admin_enqueue_scripts', array( $this, 'admin_css' ) );
80
- add_action( 'admin_notices', array( $this, 'admin_notices' ) );
81
- add_action( 'wp_ajax_pp_404page_dismiss_admin_notice', array( $this, 'dismiss_admin_notice' ) );
82
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
83
  }
84
 
85
 
86
  /**
87
- * init admin
88
- * moved to PP_404Page_Admin in v 10
 
 
 
 
 
89
  */
90
- function admin_init() {
91
-
92
- $this->_settings->set_method();
93
-
94
-
95
- add_settings_section( '404page-settings', null, null, '404page_settings_section' );
96
- add_settings_section( '404page-settings', null, null, '404page_settings_section_advanced' );
97
- register_setting( '404page_settings', '404page_page_id' );
98
- register_setting( '404page_settings', '404page_hide' );
99
- register_setting( '404page_settings', '404page_method', array( $this, 'handle_method' ) );
100
- register_setting( '404page_settings', '404page_fire_error' );
101
- register_setting( '404page_settings', '404page_force_error' );
102
- register_setting( '404page_settings', '404page_no_url_guessing' );
103
- register_setting( '404page_settings', '404page_http410_if_trashed' );
104
- add_settings_field( '404page_settings_404page', esc_html__( 'Page to be displayed as 404 page', '404page' ) . '&nbsp;<a class="dashicons dashicons-editor-help" href="' . esc_url( 'https://petersplugins.com/docs/' . $this->_core->get_plugin_slug() . '/#settings_select_page' ) . '"></a>' , array( $this, 'admin_404page' ), '404page_settings_section', '404page-settings', array( 'label_for' => '404page_page_id' ) );
105
- add_settings_field( '404page_settings_hide', '' , array( $this, 'admin_hide' ), '404page_settings_section_advanced', '404page-settings', array( 'label_for' => '404page_hide' ) );
106
- add_settings_field( '404page_settings_fire', '' , array( $this, 'admin_fire404' ), '404page_settings_section_advanced', '404page-settings', array( 'label_for' => '404page_fire_error' ) );
107
- add_settings_field( '404page_settings_force', '' , array( $this, 'admin_force404' ), '404page_settings_section_advanced', '404page-settings', array( 'label_for' => '404page_force_error' ) );
108
- add_settings_field( '404page_settings_noguess', '' , array( $this, 'admin_noguess' ), '404page_settings_section_advanced', '404page-settings', array( 'label_for' => '404page_no_url_guessing' ) );
109
- add_settings_field( '404page_settings_http410', '' , array( $this, 'admin_http410' ), '404page_settings_section_advanced', '404page-settings', array( 'label_for' => '404page_http410_if_trashed' ) );
110
- add_settings_field( '404page_settings_method', '', array( $this, 'admin_method' ), '404page_settings_section_advanced', '404page-settings', array( 'label_for' => '404page_method' ) );
111
  }
112
 
113
 
114
  /**
115
- * handle the method setting
116
  * moved to PP_404Page_Admin in v 10
117
  */
118
- function handle_method( $method ) {
119
 
120
- if ( null === $method ) {
121
-
122
- $method = 'STD';
123
 
 
124
  }
125
 
126
- return $method;
 
 
 
 
 
127
 
128
  }
129
 
@@ -134,9 +187,13 @@ if ( !class_exists( 'PP_404Page_Admin' ) ) {
134
  */
135
  function admin_hide() {
136
 
137
- echo '<p class="toggle"><input type="checkbox" id="404page_hide" name="404page_hide" value="1"' . checked( true, $this->_settings->get_hide(), false ) . '/>';
138
- echo '<label for="404page_hide" class="check"></label>' . esc_html__( 'Hide the selected page from the Pages list', '404page' ) . '&nbsp;<a class="dashicons dashicons-editor-help" href="' . esc_url( 'https://petersplugins.com/docs/' . $this->_core->get_plugin_slug() . '/#settings_hide_page' ) . '"></a><br />';
139
- echo '<span class="dashicons dashicons-info"></span>&nbsp;' . esc_html__( 'For Administrators the page is always visible.', '404page' ) . '</p><div class="clear"></div>';
 
 
 
 
140
 
141
  }
142
 
@@ -147,17 +204,13 @@ if ( !class_exists( 'PP_404Page_Admin' ) ) {
147
  */
148
  function admin_fire404() {
149
 
150
- echo '<p class="toggle"><input type="checkbox" id="404page_fire_error" name="404page_fire_error" value="1"' . checked( true, $this->_settings->get_fire_error(), false ) . '/>';
151
- echo '<label for="404page_fire_error" class="check"></label>' . esc_html__( 'Send an 404 error if the page is accessed directly by its URL', '404page' ) . '&nbsp;<a class="dashicons dashicons-editor-help" href="' . esc_url ( 'https://petersplugins.com/docs/' . $this->_core->get_plugin_slug() . '/#settings_fire_404' ) . '"></a><br />';
152
- echo '<span class="dashicons dashicons-info"></span>&nbsp;' . esc_html__( 'Uncheck this if you want the selected page to be accessible.', '404page' );
153
-
154
- if ( function_exists( 'wpsupercache_activate' ) ) {
155
-
156
- echo '<br /><span class="dashicons dashicons-warning"></span>&nbsp;<strong>' . esc_html__( 'WP Super Cache Plugin detected', '404page' ) . '</strong>. ' . __ ( 'If the page you selected as 404 error page is in cache, always a HTTP code 200 is sent. To avoid this and send a HTTP code 404 you have to exlcude this page from caching', '404page' ) . ' (<a href="' . admin_url( 'options-general.php?page=wpsupercache&tab=settings#rejecturi' ) . '">' . esc_html__( 'Click here', '404page' ) . '</a>).<br />(<a href="' . esc_url( 'https://petersplugins.com/docs/' . $this->_core->get_plugin_slug() . '/#wp_super_cache' ) . '">' . esc_html__( 'Read more', '404page' ) . '</a>)';
157
-
158
- }
159
-
160
- echo '</p><div class="clear"></div>';
161
 
162
  }
163
 
@@ -168,9 +221,13 @@ if ( !class_exists( 'PP_404Page_Admin' ) ) {
168
  */
169
  function admin_force404() {
170
 
171
- echo '<p class="toggle"><input type="checkbox" id="404page_force_error" name="404page_force_error" value="1"' . checked( true, $this->_settings->get_force_error(), false ) . '/>';
172
- echo '<label for="404page_force_error" class="check warning"></label>' . esc_html__( 'Force 404 error after loading page', '404page' ) . '&nbsp;<a class="dashicons dashicons-editor-help" href="' . esc_url( 'https://petersplugins.com/docs/' . $this->_core->get_plugin_slug() . '/#settings_force_404' ) .'"></a>&nbsp;<a class="dashicons dashicons-video-alt3" href="https://youtu.be/09OOCbFLfnI" data-lity></a><br />';
173
- echo '<span class="dashicons dashicons-warning"></span>&nbsp;' . esc_html__( 'Generally this is not needed. It is not recommended to activate this option, unless it is necessary. Please note that this may cause problems with your theme.', '404page' ) . '</p><div class="clear"></div>';
 
 
 
 
174
 
175
  }
176
 
@@ -181,9 +238,13 @@ if ( !class_exists( 'PP_404Page_Admin' ) ) {
181
  */
182
  function admin_noguess() {
183
 
184
- echo '<p class="toggle"><input type="checkbox" id="404page_no_url_guessing" name="404page_no_url_guessing" value="1"' . checked( true, $this->_settings->get_no_url_guessing(), false ) . '/>';
185
- echo '<label for="404page_no_url_guessing" class="check warning"></label>' . esc_html__( 'Disable URL autocorrection guessing', '404page' ) . '&nbsp;<a class="dashicons dashicons-editor-help" href="' . esc_url( 'https://petersplugins.com/docs/' . $this->_core->get_plugin_slug() . '/#settings_stop_guessing' ) . '"></a>&nbsp;<a class="dashicons dashicons-video-alt3" href="https://youtu.be/H0EdtFcAGl4" data-lity></a><br />';
186
- echo '<span class="dashicons dashicons-warning"></span>&nbsp;' . esc_html__( 'This stops WordPress from URL autocorrection guessing. Only activate, if you are sure about the consequences.', '404page' ) . '</p><div class="clear"></div>';
 
 
 
 
187
 
188
  }
189
 
@@ -195,9 +256,13 @@ if ( !class_exists( 'PP_404Page_Admin' ) ) {
195
  */
196
  function admin_http410() {
197
 
198
- echo '<p class="toggle"><input type="checkbox" id="404page_http410_if_trashed" name="404page_http410_if_trashed" value="1"' . checked( true, $this->_settings->get_http410_if_trashed(), false ) . '/>';
199
- echo '<label for="404page_http410_if_trashed" class="check"></label>' . esc_html__( 'Send an HTTP 410 error instead of HTTP 404 in case the requested object is in trash', '404page' ) . '&nbsp;<a class="dashicons dashicons-editor-help" href="' . esc_url( 'https://petersplugins.com/docs/' . $this->_core->get_plugin_slug() . '/#settings_maybe_send_http410' ) .'"></a>&nbsp;<a class="dashicons dashicons-video-alt3" href="https://youtu.be/O5xPM0BMZxM" data-lity></a><br />';
200
- echo '<span class="dashicons dashicons-info"></span>&nbsp;' . esc_html__( 'Check this if you want to inform search engines that the resource requested is no longer available and will not be available again so it can be removed from the search index immediately.', '404page' );
 
 
 
 
201
 
202
  }
203
 
@@ -208,7 +273,9 @@ if ( !class_exists( 'PP_404Page_Admin' ) ) {
208
  */
209
  function admin_method() {
210
 
211
- if ( $this->_settings->get_native() || defined( 'CUSTOMIZR_VER' ) || defined( 'ICL_SITEPRESS_VERSION' ) ) {
 
 
212
 
213
  $dis = ' disabled="disabled"';
214
 
@@ -217,24 +284,24 @@ if ( !class_exists( 'PP_404Page_Admin' ) ) {
217
  $dis = '';
218
  }
219
 
220
- echo '<p class="toggle"><input type="checkbox" id="404page_method" name="404page_method" value="CMP"' . checked( 'CMP', $this->_settings->get_method(), false ) . $dis . '/>';
221
- echo '<label for="404page_method" class="check"></label>' . esc_html__( 'Activate Compatibility Mode', '404page' ) . '&nbsp;<a class="dashicons dashicons-editor-help" href="' . esc_url( 'https://petersplugins.com/docs/' . $this->_core->get_plugin_slug() . '/#settings_operating_method' ) . '"></a>&nbsp;<a class="dashicons dashicons-video-alt3" href="https://youtu.be/wqSepDyQeqY" data-lity></a><br />';
222
  echo '<span class="dashicons dashicons-info"></span>&nbsp;';
223
 
224
- if ( $this->_settings->get_native() ) {
225
 
226
  esc_html_e( 'This setting is not available because the Theme you are using natively supports the 404page plugin.', '404page' );
227
- echo ' (<a href="' . esc_url( 'https://petersplugins.com/docs/' . $this->_core->get_plugin_slug() . '/#native_mode' ) . '">' . esc_html__( 'Read more', '404page' ) . '</a>)';
228
 
229
  } elseif ( defined( 'CUSTOMIZR_VER' ) ) {
230
 
231
  esc_html_e( 'This setting is not availbe because the 404page Plugin works in Customizr Compatibility Mode.', '404page' );
232
- echo ' (<a href="' . esc_url( 'https://petersplugins.com/docs/' . $this->_core->get_plugin_slug() . '/#special_modes' ) .'">' . esc_html__( 'Read more', '404page' ) . '</a>)';
233
 
234
  } elseif ( defined( 'ICL_SITEPRESS_VERSION' ) ) {
235
 
236
  esc_html_e( 'This setting is not availbe because the 404page Plugin works in WPML Mode.', '404page' );
237
- echo ' (<a href="' . esc_url( 'https://petersplugins.com/docs/' . $this->_core->get_plugin_slug() . '/#special_modes' ) . '">' . esc_html__( 'Read more', '404page' ) . '</a>)';
238
 
239
  } else {
240
 
@@ -242,7 +309,7 @@ if ( !class_exists( 'PP_404Page_Admin' ) ) {
242
 
243
  }
244
 
245
- echo '</p><div class="clear"></div>';
246
 
247
  }
248
 
@@ -251,8 +318,9 @@ if ( !class_exists( 'PP_404Page_Admin' ) ) {
251
  * create the menu entry
252
  * moved to PP_404Page_Admin in v 10
253
  */
254
- function admin_menu() {
255
- $this->admin_handle = add_theme_page ( esc_html__( '404 Error Page', "404page" ), esc_html__( '404 Error Page', '404page' ), 'manage_options', '404pagesettings', array( $this, 'show_admin' ) );
 
256
  }
257
 
258
 
@@ -260,13 +328,13 @@ if ( !class_exists( 'PP_404Page_Admin' ) ) {
260
  * add admin css to header
261
  * moved to PP_404Page_Admin in v 10
262
  */
263
- function admin_style() {
264
 
265
- if ( $this->_core->get_id() > 0 ) {
266
 
267
  echo '<style type="text/css">';
268
 
269
- foreach ( $this->_core->get_all_page_ids() as $pid ) {
270
 
271
  echo '#the-list #post-' . $pid . ' .column-title .row-title:before { content: "404"; background-color: #333; color: #FFF; display: inline-block; padding: 0 5px; margin-right: 10px; }';
272
 
@@ -279,38 +347,16 @@ if ( !class_exists( 'PP_404Page_Admin' ) ) {
279
  }
280
 
281
 
282
- /**
283
- * handle the settings field page id
284
- * moved to PP_404Page_Admin in v 10
285
- */
286
- function admin_404page() {
287
-
288
- if ( $this->_core->get_id() < 0 ) {
289
-
290
- echo '<div class="error form-invalid" style="line-height: 3em">' . esc_html__( 'The page you have selected as 404 page does not exist anymore. Please choose another page.', '404page' ) . '</div>';
291
- }
292
-
293
- wp_dropdown_pages( array( 'name' => '404page_page_id', 'id' => 'select404page', 'echo' => 1, 'show_option_none' => esc_html__( '&mdash; NONE (WP default 404 page) &mdash;', '404page'), 'option_none_value' => '0', 'selected' => $this->_core->get_id() ) );
294
-
295
- echo '<div id="404page_edit_link" style="display: none">' . get_edit_post_link( $this->_core->get_id() ) . '</div>';
296
- echo '<div id="404page_test_link" style="display: none">' . get_site_url() . '/404page-test-' . md5( rand() ) . '</div>';
297
- echo '<div id="404page_current_value" style="display: none">' . $this->_core->get_id() . '</div>';
298
- echo '<p class="submit"><input type="button" name="edit_404_page" id="edit_404_page" class="button secondary" value="' . esc_html__( 'Edit Page', '404page' ) . '" />&nbsp;<input type="button" name="test_404_page" id="test_404_page" class="button secondary" value="' . esc_html__( 'Test 404 error', '404page' ) . '" /></p>';
299
-
300
- }
301
-
302
-
303
  /**
304
  * add admin css file
305
  * moved to PP_404Page_Admin in v 10
306
  */
307
  function admin_css() {
308
 
309
- if ( get_current_screen()->id == $this->admin_handle ) {
310
 
311
- wp_enqueue_style( '404pagelity', $this->_core->get_asset_file( 'css', 'lity.min.css' ) );
312
- wp_enqueue_style( 'pp-admin-page', $this->_core->get_asset_file( 'css', 'pp-admin-page-v2.css' ) );
313
- wp_enqueue_style( '404pagecss', $this->_core->get_asset_file( 'css', '404page-ui.css' ) );
314
 
315
  }
316
 
@@ -322,16 +368,11 @@ if ( !class_exists( 'PP_404Page_Admin' ) ) {
322
  * moved to PP_404Page_Admin in v 10
323
  */
324
  function admin_js() {
325
-
326
- wp_enqueue_script( '404pagejs', $this->_core->get_asset_file( 'js', '404page.js' ), 'jquery', $this->_core->get_plugin_version(), true );
327
-
328
- // since 10.4
329
- wp_localize_script( '404pagejs', 'pp_404page_security', array( 'securekey' => $this->get_nonce() ) );
330
 
331
- if ( get_current_screen()->id == $this->admin_handle ) {
332
 
333
- wp_enqueue_script( '404page-ui', $this->_core->get_asset_file( 'js', '404page-ui.js' ), 'jquery', $this->_core->get_plugin_version(), true );
334
- wp_enqueue_script( '404page-lity', $this->_core->get_asset_file( 'js', 'lity.min.js' ), 'jquery', $this->_core->get_plugin_version(), true );
335
 
336
  }
337
 
@@ -344,106 +385,42 @@ if ( !class_exists( 'PP_404Page_Admin' ) ) {
344
  */
345
  function show_admin() {
346
 
347
- if ( !current_user_can( 'manage_options' ) ) {
348
-
349
- wp_die( esc_html__( 'You do not have sufficient permissions to access this page.' ) );
350
-
351
- }
352
-
353
- require_once( plugin_dir_path( $this->_core->get_plugin_file() ) . '/inc/admin/404page-admin-page.php' );
354
-
355
- }
356
-
357
-
358
- /**
359
- * show the nav icons
360
- * @since 6
361
- * moved to PP_404Page_Admin in v 10
362
- */
363
- function show_nav_icons( $icons ) {
364
-
365
- foreach ( $icons as $icon ) {
366
-
367
- echo '<a href="' . esc_url( $icon['link'] ) . '" title="' . $icon['title'] . '"><span class="dashicons ' . $icon['icon'] . '"></span><span class="text">' . $icon['title'] . '</span></a>';
368
-
369
- }
370
-
371
- }
372
-
373
-
374
- /**
375
- * show admin notices
376
- * moved to PP_404Page_Admin in v 10
377
- */
378
- function admin_notices() {
379
-
380
- // @since 8
381
- // show update notice
382
-
383
- /**
384
- * no notice in version 10
385
- *
386
- *
387
- * if ( current_user_can( 'manage_options' ) && get_user_meta( get_current_user_id(), 'pp-404page-update-notice-v9', true ) != 'dismissed' ) {
388
- * ?>
389
- * <div class="notice is-dismissible pp-404page-admin-notice" id="pp-404page-update-notice-v9">
390
- * <p><img src="<?php echo $this->_core->get_asset_file( 'img', '/pluginicon.png' ); ?>" style="width: 48px; height: 48px; float: left; margin-right: 20px" /><strong><?php esc_html_e( 'What\'s new in Version 9?', '404page' ); ?></strong><br /><?php esc_html_e( 'Display a note in Block Editor Gutenberg if the currently edited page is the custom 404 error page.', '404page' ); ?><br />[<a href="https://wordpress.org/plugins/404page/#developers"><?php esc_html_e( 'Changelog', '404page' ); ?></a>]<div class="clear"></div></p>
391
- * </div>
392
- * <?php
393
- * }
394
- *
395
- */
396
-
397
- // invite to follow me
398
- if ( current_user_can( 'manage_options' ) && get_user_meta( get_current_user_id(), 'pp-404page-admin-notice-1', true ) != 'dismissed' ) {
399
- ?>
400
- <div class="notice is-dismissible pp-404page-admin-notice" id="pp-404page-admin-notice-1">
401
- <p><img src="<?php echo $this->_core->get_asset_file( 'img', '/pluginicon.png' ); ?>" style="width: 48px; height: 48px; float: left; margin-right: 20px" /><strong><?php esc_html_e( 'Do you like the 404page plugin?', '404page' ); ?></strong><br /><?php esc_html_e( 'Follow me:', '404page' ); ?> <a class="dashicons dashicons-facebook-alt" href="https://www.facebook.com/petersplugins" title="<?php esc_html_e( 'Authors facebook Page', '404page' ); ?>"></a><div class="clear"></div></p>
402
- </div>
403
- <?php
404
- }
405
-
406
- // ask for rating
407
- // in 30 days at the earliest
408
- if ( ! get_option( 'pp-404page-admin-notice-2-start' ) ) {
409
- update_option( 'pp-404page-admin-notice-2-start', time() + 30 * 24 * 60 * 60 );
410
- }
411
- if ( get_option( 'pp-404page-admin-notice-2-start' ) <= time() ) {
412
- if ( current_user_can( 'manage_options' ) && get_user_meta( get_current_user_id(), 'pp-404page-admin-notice-2', true ) != 'dismissed' ) {
413
- ?>
414
- <div class="notice is-dismissible pp-404page-admin-notice" id="pp-404page-admin-notice-2">
415
- <p><img src="<?php echo $this->_core->get_asset_file( 'img', 'pluginicon.png' ); ?>" style="width: 48px; height: 48px; float: left; margin-right: 20px" /><?php esc_html_e( 'If you like the 404page plugin please support my work with giving it a good rating so that other users know it is helpful for you. Thanks.', '404page' ); ?><br /><a href="<?php echo esc_url( 'https://wordpress.org/support/plugin/' . $this->_core->get_plugin_slug() . '/reviews/#new-post' ); ?>" title="<?php esc_html_e( 'Please rate plugin', '404page' ); ?>"><span class="dashicons dashicons-star-filled"></span><span class="dashicons dashicons-star-filled"></span><span class="dashicons dashicons-star-filled"></span><span class="dashicons dashicons-star-filled"></span><span class="dashicons dashicons-star-filled"></span></a><div class="clear"></div></p>
416
- </div>
417
- <?php
418
- }
419
- }
420
-
421
- }
422
-
423
-
424
- /**
425
- * dismiss an admin notice
426
- * moved to PP_404Page_Admin in v 10
427
- */
428
- function dismiss_admin_notice() {
429
-
430
- // since 10.4 check nonce
431
- if ( $this->check_nonce() ) {
432
-
433
- if ( isset( $_POST['pp_404page_dismiss_admin_notice'] ) ) {
434
-
435
- // since 10.4 check value
436
- if (strpos( $_POST['pp_404page_dismiss_admin_notice'], 'pp-404page-admin-notice-') === 0 ) {
437
 
438
- update_user_meta( get_current_user_id(), sanitize_key( $_POST['pp_404page_dismiss_admin_notice'] ), 'dismissed' );
439
-
440
- }
441
-
442
- }
443
-
444
- }
445
 
446
- wp_die();
447
 
448
  }
449
 
@@ -454,20 +431,22 @@ if ( !class_exists( 'PP_404Page_Admin' ) ) {
454
  */
455
  function add_settings_links( $links ) {
456
 
457
- return array_merge( $links, array( '<a href="' . admin_url( 'themes.php?page=404pagesettings' ) . '" title="' . esc_html__( 'Settings', '404page' ) . '">' . esc_html__( 'Settings', '404page' ) . '</a>', '<a href="' . esc_url( 'https://wordpress.org/support/plugin/' . $this->_core->get_plugin_slug() . '/reviews/' ) . '" title="' . esc_html__( 'Please rate plugin', '404page' ) . '">' . esc_html__( 'Please rate plugin', '404page' ) . '</a>' ) );
458
 
459
  }
460
 
461
 
462
  /**
463
- * show the videos
 
464
  *
465
- * @since 7
466
  * @access private
467
- *
468
- * moved to PP_404Page_Admin in v 10
469
  */
470
- private function show_videos() {
 
 
471
 
472
  $videos = array(
473
  array( 'id' => 'HygoFMwdIuY', 'title' => 'A brief introduction', 'img' => '404page-brief-intro' ),
@@ -480,9 +459,11 @@ if ( !class_exists( 'PP_404Page_Admin' ) ) {
480
 
481
  foreach( $videos as $video ) {
482
 
483
- echo '<a href="' . esc_url( 'https://youtu.be/' . $video['id'] ) . '" title="' . $video['title'] . '" data-lity><div><img src="' . $this->_core->get_asset_file( 'img/videos', $video['img'] . '.png' ) . '" title="' . $video['title'] . '" alt="' . $video['title'] . '"></div></a>';
484
 
485
  }
 
 
486
 
487
  }
488
 
15
  */
16
  if ( !class_exists( 'PP_404Page_Admin' ) ) {
17
 
18
+ class PP_404Page_Admin extends PPF01_Admin {
19
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20
 
21
  /**
22
+ * Do Init
23
  *
24
  * @since 10
25
  * @access public
26
  */
27
+ public function init() {
28
+
29
+ // @since 11.0.0
30
+ $this->init_rating_notice( array(
31
+ 'title' => esc_html( 'Are you happy with the 404page plugin?', '404page' ),
32
+ 'subtitle' => esc_html( 'You\'ve been using this plugin for a while now. Would be great to get some feedback!', '404page' ),
33
+ 'button_yes' => esc_html( 'Yes, I\'m happy with it', '404page' ),
34
+ 'button_no' => esc_html( 'Not really', '404page' ),
35
+ 'button_later' => esc_html( 'Ask me later', '404page' ),
36
+ 'button_close' => esc_html( 'Never show again', '404page' ),
37
+ 'like' => esc_html( 'I\'m really glad you like it. I do not ask for a donation. All I\'m asking you for is to give it a good rating. Thank you very much. If you like, you can follow me on facebook.', '404page' ),
38
+ 'button_rate' => esc_html( 'Yes, I\'d like to rate it', '404page' ),
39
+ 'button_fb' => esc_html( 'Open Facebook page', '404page' ),
40
+ 'dislike' => esc_html( 'I\'m really sorry you don\'t like it. Would you please do me a favor and drop me line, why you are not happy with it? Maybe I can do better...', '404page' ),
41
+ 'button_contact' => esc_html( 'Yes sure', '404page' )
42
+ ),
43
+ array(
44
+ 'rate' => 'https://wordpress.org/support/plugin/' . $this->core()->get_plugin_slug() . '/reviews/',
45
+ 'contact' => 'https://petersplugins.com/contact/',
46
+ 'facebook' => 'https://www.facebook.com/petersplugins/'
47
+ ));
48
+
49
+ $this->add_actions( array(
50
+ 'admin_init',
51
+ 'admin_menu',
52
+ 'admin_head'
53
+ ) );
54
 
55
+ add_action( 'admin_enqueue_scripts', array( $this, 'admin_js' ) );
56
+ add_action( 'admin_enqueue_scripts', array( $this, 'admin_css' ) );
57
 
58
+ add_filter( 'plugin_action_links_' . plugin_basename( $this->core()->get_plugin_file() ), array( $this, 'add_settings_links' ) );
59
+
60
  }
61
 
62
 
63
  /**
64
+ * init admin
65
+ * moved to PP_404Page_Admin in v 10
 
 
66
  */
67
+ function action_admin_init() {
68
+
69
+ $this->settings()->set_method();
70
+
71
+ // @since 11.0.0
72
+ $this->add_setting_sections(
73
+
74
+ array(
75
+
76
+ array(
77
+
78
+ 'section' => 'general',
79
+ 'title' => esc_html__( 'General', '404page' ),
80
+ 'fields' => array(
81
+ array(
82
+ 'key' => 'page_id',
83
+ 'callback' => 'admin_404page'
84
+ )
85
+ )
86
+
87
+ ),
88
+
89
+ array(
90
+
91
+ 'section' => 'advanced',
92
+ 'title' => esc_html__( 'Advanced', '404page' ),
93
+ 'fields' => array(
94
+ array(
95
+ 'key' => 'hide',
96
+ 'callback' => 'admin_hide'
97
+ ),
98
+ array(
99
+ 'key' => 'fire_error',
100
+ 'callback' => 'admin_fire404'
101
+ ),
102
+ array(
103
+ 'key' => 'force_error',
104
+ 'callback' => 'admin_force404'
105
+ ),
106
+ array(
107
+ 'key' => 'no_url_guessing',
108
+ 'callback' => 'admin_noguess'
109
+ ),
110
+ array(
111
+ 'key' => 'http410_if_trashed',
112
+ 'callback' => 'admin_http410'
113
+ ),
114
+ array(
115
+ 'key' => 'method',
116
+ 'callback' => 'admin_method'
117
+ )
118
+
119
+ )
120
+
121
+ ),
122
+
123
+ array(
124
+
125
+ 'section' => 'videos',
126
+ 'title' => esc_html__( 'Explainer Videos', '404page' ),
127
+ 'html' => $this->add_videos(),
128
+ 'nosubmit' => true
129
+
130
+ )
131
+
132
+ )
133
+
134
+ );
135
+
136
  }
137
 
138
 
139
  /**
140
+ * sanitize settings
141
+ * was handle_method() in previous versions
142
+ * as of version 11.0.0 the method is part of the settings array
143
+ *
144
+ * @since 11.0.0
145
+ * @param array $settings array of settings to save
146
+ * @access public
147
  */
148
+ public function sanitize_settings( $settings ) {
149
+
150
+ if ( ! array_key_exists( 'method', $settings ) || ( $settings['method'] != 'STD' && $settings['method'] != 'CMP' ) ) {
151
+
152
+ $settings['method'] = 'STD';
153
+
154
+ }
155
+
156
+ return $settings;
157
+
 
 
 
 
 
 
 
 
 
 
 
158
  }
159
 
160
 
161
  /**
162
+ * handle the settings field page id
163
  * moved to PP_404Page_Admin in v 10
164
  */
165
+ function admin_404page() {
166
 
167
+ echo esc_html__( 'Page to be displayed as 404 page', '404page' ) . '&nbsp;<a class="dashicons dashicons-editor-help" href="' . esc_url( 'https://petersplugins.com/' . $this->core()->get_plugin_slug() . '/manual/#settings_select_page' ) . '"></a>';
168
+
169
+ if ( $this->settings()->get( 'page_id' ) < 0 ) {
170
 
171
+ echo '<div class="error form-invalid" style="line-height: 3em">' . esc_html__( 'The page you have selected as 404 page does not exist anymore. Please choose another page.', '404page' ) . '</div>';
172
  }
173
 
174
+ wp_dropdown_pages( array( 'name' => $this->settings()->get_option_name() . '[page_id]', 'id' => 'select404page', 'echo' => 1, 'show_option_none' => esc_html__( '&mdash; NONE (WP default 404 page) &mdash;', '404page'), 'option_none_value' => '0', 'selected' => $this->settings()->get( 'page_id' ) ) );
175
+
176
+ echo '<div id="404page_edit_link" style="display: none">' . get_edit_post_link( $this->settings()->get( 'page_id' ) ) . '</div>';
177
+ echo '<div id="404page_test_link" style="display: none">' . get_site_url() . '/404page-test-' . md5( rand() ) . '</div>';
178
+ echo '<div id="404page_current_value" style="display: none">' . $this->settings()->get( 'page_id' ) . '</div>';
179
+ echo '<p class="submit"><input type="button" name="edit_404_page" id="edit_404_page" class="button secondary" value="' . esc_html__( 'Edit Page', '404page' ) . '" />&nbsp;<input type="button" name="test_404_page" id="test_404_page" class="button secondary" value="' . esc_html__( 'Test 404 error', '404page' ) . '" /></p>';
180
 
181
  }
182
 
187
  */
188
  function admin_hide() {
189
 
190
+ $this->print_slider_check(
191
+ 'hide',
192
+ esc_html__( 'Hide the selected page from the Pages list', '404page' ),
193
+ 'settings_hide_page',
194
+ false,
195
+ '<span class="dashicons dashicons-info"></span>&nbsp;' . esc_html__( 'For Administrators the page is always visible.', '404page' )
196
+ );
197
 
198
  }
199
 
204
  */
205
  function admin_fire404() {
206
 
207
+ $this->print_slider_check(
208
+ 'fire_error',
209
+ esc_html__( 'Send an 404 error if the page is accessed directly by its URL', '404page' ),
210
+ 'settings_fire_404',
211
+ false,
212
+ '<span class="dashicons dashicons-info"></span>&nbsp;' . esc_html__( 'Uncheck this if you want the selected page to be accessible.', '404page' ) . ( function_exists( 'wpsupercache_activate' ) ? '<br /><span class="dashicons dashicons-warning"></span>&nbsp;<strong>' . esc_html__( 'WP Super Cache Plugin detected', '404page' ) . '</strong>. ' . __ ( 'If the page you selected as 404 error page is in cache, always a HTTP code 200 is sent. To avoid this and send a HTTP code 404 you have to exlcude this page from caching', '404page' ) . ' (<a href="' . admin_url( 'options-general.php?page=wpsupercache&tab=settings#rejecturi' ) . '">' . esc_html__( 'Click here', '404page' ) . '</a>).<br />(<a href="' . esc_url( 'https://petersplugins.com/' . $this->core()->get_plugin_slug() . '/manual/#wp_super_cache' ) . '">' . esc_html__( 'Read more', '404page' ) . '</a>)' : '' )
213
+ );
 
 
 
 
214
 
215
  }
216
 
221
  */
222
  function admin_force404() {
223
 
224
+ $this->print_slider_check(
225
+ 'force_error',
226
+ esc_html__( 'Force 404 error after loading page', '404page' ),
227
+ 'settings_force_404',
228
+ '09OOCbFLfnI',
229
+ '<span class="dashicons dashicons-warning"></span>&nbsp;' . esc_html__( 'Generally this is not needed. It is not recommended to activate this option, unless it is necessary. Please note that this may cause problems with your theme.', '404page' )
230
+ );
231
 
232
  }
233
 
238
  */
239
  function admin_noguess() {
240
 
241
+ $this->print_slider_check(
242
+ 'no_url_guessing',
243
+ esc_html__( 'Disable URL autocorrection guessing', '404page' ),
244
+ 'settings_stop_guessing',
245
+ 'H0EdtFcAGl4',
246
+ '<span class="dashicons dashicons-warning"></span>&nbsp;' . esc_html__( 'This stops WordPress from URL autocorrection guessing. Only activate, if you are sure about the consequences.', '404page' )
247
+ );
248
 
249
  }
250
 
256
  */
257
  function admin_http410() {
258
 
259
+ $this->print_slider_check(
260
+ 'http410_if_trashed',
261
+ esc_html__( 'Send an HTTP 410 error instead of HTTP 404 in case the requested object is in trash', '404page' ),
262
+ 'settings_maybe_send_http410',
263
+ 'O5xPM0BMZxM',
264
+ '<span class="dashicons dashicons-info"></span>&nbsp;' . esc_html__( 'Check this if you want to inform search engines that the resource requested is no longer available and will not be available again so it can be removed from the search index immediately.', '404page' )
265
+ );
266
 
267
  }
268
 
273
  */
274
  function admin_method() {
275
 
276
+ // unfortunately we can't use print_slider_check() here
277
+
278
+ if ( $this->core()->is_native() || defined( 'CUSTOMIZR_VER' ) || defined( 'ICL_SITEPRESS_VERSION' ) ) {
279
 
280
  $dis = ' disabled="disabled"';
281
 
284
  $dis = '';
285
  }
286
 
287
+ echo '<p class="toggle"><span class="slider"><input type="checkbox" id="404page_method" name="404page_method" value="CMP"' . checked( 'CMP', $this->settings()->get( 'method' ), false ) . $dis . '/>';
288
+ echo '<label for="404page_method" class="check"></label></span><span class="caption">' . esc_html__( 'Activate Compatibility Mode', '404page' ) . '&nbsp;<a class="dashicons dashicons-editor-help" href="' . esc_url( 'https://petersplugins.com/' . $this->core()->get_plugin_slug() . '/manual/#settings_operating_method' ) . '"></a>&nbsp;<a class="dashicons dashicons-video-alt3" href="https://youtu.be/wqSepDyQeqY" data-lity></a><br />';
289
  echo '<span class="dashicons dashicons-info"></span>&nbsp;';
290
 
291
+ if ( $this->core()->is_native() ) {
292
 
293
  esc_html_e( 'This setting is not available because the Theme you are using natively supports the 404page plugin.', '404page' );
294
+ echo ' (<a href="' . esc_url( 'https://petersplugins.com/' . $this->core()->get_plugin_slug() . '/manual/#native_mode' ) . '">' . esc_html__( 'Read more', '404page' ) . '</a>)';
295
 
296
  } elseif ( defined( 'CUSTOMIZR_VER' ) ) {
297
 
298
  esc_html_e( 'This setting is not availbe because the 404page Plugin works in Customizr Compatibility Mode.', '404page' );
299
+ echo ' (<a href="' . esc_url( 'https://petersplugins.com/' . $this->core()->get_plugin_slug() . '/manual/#special_modes' ) .'">' . esc_html__( 'Read more', '404page' ) . '</a>)';
300
 
301
  } elseif ( defined( 'ICL_SITEPRESS_VERSION' ) ) {
302
 
303
  esc_html_e( 'This setting is not availbe because the 404page Plugin works in WPML Mode.', '404page' );
304
+ echo ' (<a href="' . esc_url( 'https://petersplugins.com/' . $this->core()->get_plugin_slug() . '/manual/#special_modes' ) . '">' . esc_html__( 'Read more', '404page' ) . '</a>)';
305
 
306
  } else {
307
 
309
 
310
  }
311
 
312
+ echo '</span></p>';
313
 
314
  }
315
 
318
  * create the menu entry
319
  * moved to PP_404Page_Admin in v 10
320
  */
321
+ function action_admin_menu() {
322
+ $screen_id = add_theme_page ( esc_html__( '404 Error Page', "404page" ), esc_html__( '404 Error Page', '404page' ), 'manage_options', '404pagesettings', array( $this, 'show_admin' ) );
323
+ $this->set_screen_id( $screen_id );
324
  }
325
 
326
 
328
  * add admin css to header
329
  * moved to PP_404Page_Admin in v 10
330
  */
331
+ function action_admin_head() {
332
 
333
+ if ( $this->settings()->get( 'page_id' ) > 0 ) {
334
 
335
  echo '<style type="text/css">';
336
 
337
+ foreach ( $this->core()->get_all_page_ids() as $pid ) {
338
 
339
  echo '#the-list #post-' . $pid . ' .column-title .row-title:before { content: "404"; background-color: #333; color: #FFF; display: inline-block; padding: 0 5px; margin-right: 10px; }';
340
 
347
  }
348
 
349
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
350
  /**
351
  * add admin css file
352
  * moved to PP_404Page_Admin in v 10
353
  */
354
  function admin_css() {
355
 
356
+ if ( get_current_screen()->id == $this->get_screen_id() ) {
357
 
358
+ wp_enqueue_style( '404pagelity', $this->core()->get_asset_url( 'css', 'lity.min.css' ) );
359
+ wp_enqueue_style( '404pagecss', $this->core()->get_asset_url( 'css', '404page-ui.css' ) );
 
360
 
361
  }
362
 
368
  * moved to PP_404Page_Admin in v 10
369
  */
370
  function admin_js() {
 
 
 
 
 
371
 
372
+ if ( get_current_screen()->id == $this->get_screen_id() ) {
373
 
374
+ wp_enqueue_script( '404page-ui', $this->core()->get_asset_url( 'js', '404page-ui.js' ), 'jquery', $this->core()->get_plugin_version(), true );
375
+ wp_enqueue_script( '404page-lity', $this->core()->get_asset_url( 'js', 'lity.min.js' ), 'jquery', $this->core()->get_plugin_version(), true );
376
 
377
  }
378
 
385
  */
386
  function show_admin() {
387
 
388
+ $this->add_toolbar_icons( array(
389
+ array(
390
+ 'link' => 'https://wordpress.org/support/plugin/' . $this->core()->get_plugin_slug() . '/reviews/',
391
+ 'title' => __( 'Please rate Plugin', '404page' ),
392
+ 'icon' => 'dashicons-star-filled',
393
+ 'highlight' => true
394
+ ),
395
+ array(
396
+ 'link' => 'https://wordpress.org/plugins/' . $this->core()->get_plugin_slug(),
397
+ 'title' => __( 'WordPress.org Plugin Page', '404page' ),
398
+ 'icon' => 'dashicons-wordpress'
399
+ ),
400
+ array(
401
+ 'link' => 'https://petersplugins.com/' . $this->core()->get_plugin_slug() . '/manual/',
402
+ 'title' => __( 'Plugin Doc', '404page' ),
403
+ 'icon' => 'dashicons-book-alt'
404
+ ),
405
+ array(
406
+ 'link' => 'https://wordpress.org/support/plugin/' . $this->core()->get_plugin_slug(),
407
+ 'title' => __( 'Support', '404page' ),
408
+ 'icon' => 'dashicons-editor-help'
409
+ ),
410
+ array(
411
+ 'link' => 'https://petersplugins.com/',
412
+ 'title' => __( 'Authors Website', '404page' ),
413
+ 'icon' => 'dashicons-admin-home'
414
+ ),
415
+ array(
416
+ 'link' => 'https://www.facebook.com/petersplugins/',
417
+ 'title' => __( 'Authors Facebook Page', '404page' ),
418
+ 'icon' => 'dashicons-facebook-alt'
419
+ )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
420
 
421
+ ) );
 
 
 
 
 
 
422
 
423
+ $this->show( 'manage_options' );
424
 
425
  }
426
 
431
  */
432
  function add_settings_links( $links ) {
433
 
434
+ return array_merge( $links, array( '<a href="' . admin_url( 'themes.php?page=404pagesettings' ) . '" title="' . esc_html__( 'Settings', '404page' ) . '">' . esc_html__( 'Settings', '404page' ) . '</a>', '<a href="' . esc_url( 'https://wordpress.org/support/plugin/' . $this->core()->get_plugin_slug() . '/reviews/' ) . '" title="' . esc_html__( 'Please rate plugin', '404page' ) . '">' . esc_html__( 'Please rate plugin', '404page' ) . '</a>' ) );
435
 
436
  }
437
 
438
 
439
  /**
440
+ * create the HTML code for the videos
441
+ * was show_videos() in previous versions and printed out the HTML
442
  *
443
+ * @since 11.0.0
444
  * @access private
445
+ * @return string HTML code
 
446
  */
447
+ private function add_videos() {
448
+
449
+ $html = '<div class="pp-404page-videos">';
450
 
451
  $videos = array(
452
  array( 'id' => 'HygoFMwdIuY', 'title' => 'A brief introduction', 'img' => '404page-brief-intro' ),
459
 
460
  foreach( $videos as $video ) {
461
 
462
+ $html .= '<a href="' . esc_url( 'https://youtu.be/' . $video['id'] ) . '" title="' . $video['title'] . '" data-lity><div><img src="' . $this->core()->get_asset_url( 'img/videos', $video['img'] . '.png' ) . '" title="' . $video['title'] . '" alt="' . $video['title'] . '"></div></a>';
463
 
464
  }
465
+
466
+ return $html . '</div>';
467
 
468
  }
469
 
inc/class-404page-block-editor.php CHANGED
@@ -15,40 +15,15 @@ if ( ! defined( 'WPINC' ) ) {
15
  */
16
  if ( !class_exists( 'PP_404Page_BlockEditor' ) ) {
17
 
18
- class PP_404Page_BlockEditor {
19
-
20
- /**
21
- * reference to core class
22
- *
23
- * @since 9
24
- * @var object
25
- * @access private
26
- */
27
- private $_core;
28
-
29
-
30
- /**
31
- * Initialize the class
32
- *
33
- * @since 9
34
- * @access public
35
- */
36
- public function __construct( $_core ) {
37
-
38
- $this->_core = $_core;
39
-
40
- $this->init();
41
-
42
- }
43
-
44
 
45
  /**
46
  * Do Init
47
  *
48
  * @since 9
49
- * @access private
50
  */
51
- private function init() {
52
 
53
  add_action( 'admin_head', array( $this, 'admin_style' ) );
54
 
@@ -85,14 +60,14 @@ if ( !class_exists( 'PP_404Page_BlockEditor' ) ) {
85
  private function is_gutenberg_editing() {
86
 
87
  // Is the current screen the page edit screen and is a custom 404 error page defined?
88
- if ( get_current_screen()->id == 'page' && $this->_core->get_id() > 0 ) {
89
 
90
  // Is the block editor active for pages and is the classic editor not loaded?
91
  if ( function_exists( 'use_block_editor_for_post_type' ) && use_block_editor_for_post_type( 'page' ) && ! isset( $_GET['classic-editor'] ) ) {
92
 
93
  global $post;
94
 
95
- $all404pages = $this->_core->get_all_page_ids();
96
 
97
  // Is the currently edited page a custom 404 error page?
98
  if ( in_array( $post->ID, $all404pages ) ) {
15
  */
16
  if ( !class_exists( 'PP_404Page_BlockEditor' ) ) {
17
 
18
+ class PP_404Page_BlockEditor extends PPF01_SubClass {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
 
20
  /**
21
  * Do Init
22
  *
23
  * @since 9
24
+ * @access public
25
  */
26
+ public function init() {
27
 
28
  add_action( 'admin_head', array( $this, 'admin_style' ) );
29
 
60
  private function is_gutenberg_editing() {
61
 
62
  // Is the current screen the page edit screen and is a custom 404 error page defined?
63
+ if ( get_current_screen()->id == 'page' && $this->settings()->get( 'page_id' ) > 0 ) {
64
 
65
  // Is the block editor active for pages and is the classic editor not loaded?
66
  if ( function_exists( 'use_block_editor_for_post_type' ) && use_block_editor_for_post_type( 'page' ) && ! isset( $_GET['classic-editor'] ) ) {
67
 
68
  global $post;
69
 
70
+ $all404pages = $this->core()->get_all_page_ids();
71
 
72
  // Is the currently edited page a custom 404 error page?
73
  if ( in_array( $post->ID, $all404pages ) ) {
inc/class-404page-classic-editor.php CHANGED
@@ -15,40 +15,15 @@ if ( ! defined( 'WPINC' ) ) {
15
  */
16
  if ( !class_exists( 'PP_404Page_ClassicEditor' ) ) {
17
 
18
- class PP_404Page_ClassicEditor {
19
-
20
- /**
21
- * reference to core class
22
- *
23
- * @since 9
24
- * @var object
25
- * @access private
26
- */
27
- private $_core;
28
-
29
-
30
- /**
31
- * Initialize the class
32
- *
33
- * @since 9
34
- * @access public
35
- */
36
- public function __construct( $_core ) {
37
-
38
- $this->_core = $_core;
39
-
40
- $this->init();
41
-
42
- }
43
-
44
 
45
  /**
46
  * Do Init
47
  *
48
  * @since 9
49
- * @access private
50
  */
51
- private function init() {
52
 
53
  add_action( 'admin_head', array( $this, 'admin_style' ) );
54
 
@@ -64,11 +39,11 @@ if ( !class_exists( 'PP_404Page_ClassicEditor' ) ) {
64
  public function admin_style() {
65
 
66
  // we just ignore whether Gutenberg is used or not, because this classes do not exist if Gutenberg is active
67
- if ( get_current_screen()->id == 'page' && $this->_core->get_id() > 0 ) {
68
 
69
  global $post;
70
 
71
- $all404pages = $this->_core->get_all_page_ids();
72
  if ( in_array( $post->ID, $all404pages ) ) {
73
 
74
  ?>
15
  */
16
  if ( !class_exists( 'PP_404Page_ClassicEditor' ) ) {
17
 
18
+ class PP_404Page_ClassicEditor extends PPF01_SubClass {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
 
20
  /**
21
  * Do Init
22
  *
23
  * @since 9
24
+ * @access public
25
  */
26
+ public function init() {
27
 
28
  add_action( 'admin_head', array( $this, 'admin_style' ) );
29
 
39
  public function admin_style() {
40
 
41
  // we just ignore whether Gutenberg is used or not, because this classes do not exist if Gutenberg is active
42
+ if ( get_current_screen()->id == 'page' && $this->settings()->get( 'page_id' ) > 0 ) {
43
 
44
  global $post;
45
 
46
+ $all404pages = $this->core()->get_all_page_ids();
47
  if ( in_array( $post->ID, $all404pages ) ) {
48
 
49
  ?>
inc/class-404page-deprecated.php ADDED
@@ -0,0 +1,78 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * The 404page deprecated class
5
+ *
6
+ * to ensure backward compatibility
7
+ *
8
+ * @since 11.0.0
9
+ */
10
+
11
+ if ( ! defined( 'WPINC' ) ) {
12
+ die;
13
+ }
14
+
15
+ /**
16
+ * The deprecated plugin class
17
+ */
18
+ if ( !class_exists( 'PP_404Page_Deprecated' ) ) {
19
+
20
+ class PP_404Page_Deprecated extends PPF01_SubClass {
21
+
22
+ /**
23
+ * Do Init
24
+ *
25
+ * @since 11.0.0
26
+ * @access public
27
+ */
28
+ public function init() {
29
+
30
+
31
+ // since 11.0.0 all settings are stored in a single serialized value
32
+ // collet all the individual settings from older versions and create the serialized value
33
+ // plus the user meta data are deleted
34
+
35
+ $newkey = str_replace( '-', '_', $this->core()->get_plugin_slug() ) . '_settings';
36
+
37
+ if ( false === get_option( $newkey ) ) {
38
+
39
+ if ( false !== get_option( '404page_page_id' ) ) {
40
+
41
+ $oldkeys = array(
42
+ '404page_page_id',
43
+ '404page_hide',
44
+ '404page_fire_error',
45
+ '404page_force_error',
46
+ '404page_no_url_guessing',
47
+ '404page_http410_if_trashed',
48
+ '404page_method'
49
+ );
50
+
51
+ $newvals = array();
52
+
53
+ foreach ( $oldkeys as $key ) {
54
+
55
+ $newvals[ str_replace( '404page_', '', $key ) ] = get_option( $key );
56
+ delete_option( $key );
57
+
58
+ }
59
+
60
+ update_option( $newkey, $newvals );
61
+
62
+
63
+ // delete user meta for old admin notices for all users
64
+ foreach ( array( 'pp-404page-admin-notice-1', 'pp-404page-admin-notice-2', 'pp-404page-update-notice-v8', 'pp-404page-update-notice-v9' ) as $key ) {
65
+ delete_metadata( 'user', false, $key, false, true );
66
+ }
67
+
68
+ }
69
+
70
+ }
71
+
72
+ }
73
+
74
+ }
75
+
76
+ }
77
+
78
+ ?>
inc/class-404page-settings.php CHANGED
@@ -17,150 +17,29 @@ if ( ! defined( 'WPINC' ) ) {
17
  */
18
  if ( !class_exists( 'PP_404Page_Settings' ) ) {
19
 
20
- class PP_404Page_Settings {
21
-
22
- /**
23
- * Array of settings
24
- *
25
- * @since 7
26
- * @access protected
27
- */
28
- protected $settings;
29
-
30
- /**
31
- * Initialize the settings class
32
- *
33
- * @since 7
34
- */
35
- public function __construct() {
36
-
37
- $this->settings = array();
38
-
39
- $this->settings['404page_page_id'] = $this->get_option_404page_id();
40
- $this->settings['404page_hide'] = $this->get_option_404page_hide();
41
- $this->settings['404page_fire_error'] = $this->get_option_404page_fire_error();
42
- $this->settings['404page_force_error'] = $this->get_option_404page_force_error();
43
- $this->settings['404page_no_url_guessing'] = $this->get_option_404page_no_url_guessing();
44
- $this->settings['404page_http410_if_trashed'] = $this->get_option_404page_http410_if_trashed();
45
- $this->settings['404page_native'] = false;
46
- $this->settings['404page_method'] = 'STD';
47
-
48
- }
49
-
50
-
51
- /**
52
- * get setting - id of the 404 page
53
- *
54
- * @since 7
55
- * @access public
56
- */
57
- public function get_id() {
58
-
59
- return $this->settings['404page_page_id'];
60
-
61
- }
62
-
63
-
64
- /**
65
- * get setting - hide 404 page from page list
66
- *
67
- * @since 7
68
- * @access public
69
- */
70
- public function get_hide() {
71
-
72
- return $this->settings['404page_hide'];
73
-
74
- }
75
-
76
 
77
  /**
78
- * get setting - fire 404 error
79
  *
80
- * @since 7
81
- * @access public
82
- */
83
- public function get_fire_error() {
84
-
85
- return $this->settings['404page_fire_error'];
86
-
87
- }
88
-
89
-
90
- /**
91
- * get setting - force 404 error
92
- *
93
- * @since 7
94
- * @access public
95
- */
96
- public function get_force_error() {
97
-
98
- return $this->settings['404page_force_error'];
99
-
100
- }
101
-
102
-
103
- /**
104
- * get setting - no url guessing
105
- *
106
- * @since 7
107
- * @access public
108
- */
109
- public function get_no_url_guessing() {
110
-
111
- return $this->settings['404page_no_url_guessing'];
112
-
113
- }
114
-
115
-
116
- /**
117
- * get setting - http 410 if trashed
118
- *
119
- * @since 7
120
- * @access public
121
- */
122
- public function get_http410_if_trashed() {
123
-
124
- return $this->settings['404page_http410_if_trashed'];
125
-
126
- }
127
-
128
-
129
- /**
130
- * get setting - native support
131
- *
132
- * @since 7
133
- * @access public
134
- */
135
- public function get_native() {
136
-
137
- return $this->settings['404page_native'];
138
-
139
- }
140
-
141
-
142
- /**
143
- * get setting - method
144
- *
145
- * @since 7
146
- * @access public
147
  */
148
- public function get_method() {
149
 
150
- return $this->settings['404page_method'];
151
-
152
- }
153
-
154
-
155
- /**
156
- * set setting - native support
157
- *
158
- * @since 7
159
- * @access public
160
- */
161
- public function set_native( $active ) {
162
 
163
- $this->settings['404page_native'] = ( $active === true );
 
 
 
 
 
 
 
 
 
 
164
 
165
  }
166
 
@@ -184,113 +63,8 @@ if ( !class_exists( 'PP_404Page_Settings' ) ) {
184
 
185
  }
186
 
187
- }
188
-
189
-
190
- /**
191
- * get the id of the 404 page option
192
- * returns 0 if none is defined, returns -1 if the defined page id does not exist
193
- *
194
- * @since 7
195
- * @access private
196
- */
197
- private function get_option_404page_id() {
198
-
199
- $pageid = get_option( '404page_page_id', 0 );
200
-
201
- if ( $pageid != 0 ) {
202
-
203
- $page = get_post( $pageid );
204
-
205
- if ( !$page || $page->post_status != 'publish' ) {
206
-
207
- $pageid = -1;
208
-
209
- }
210
-
211
- }
212
-
213
- return $pageid;
214
-
215
- }
216
-
217
-
218
- /**
219
- * do we have to hide the selected 404 page from the page list?
220
- *
221
- * @since 7
222
- * @access private
223
- */
224
- private function get_option_404page_hide() {
225
-
226
- return (bool)get_option( '404page_hide', false );
227
-
228
- }
229
-
230
-
231
- /**
232
- * do we have to fire an 404 error if the selected page is accessed directly?
233
- *
234
- * @since 7
235
- * @access private
236
- */
237
- private function get_option_404page_fire_error() {
238
-
239
- return (bool)get_option( '404page_fire_error', true );
240
-
241
- }
242
-
243
-
244
- /**
245
- * do we have to force the 404 error after loading the page?
246
- *
247
- * @since 7
248
- * @access private
249
- */
250
- private function get_option_404page_force_error() {
251
-
252
- return (bool)get_option( '404page_force_error', false );
253
-
254
- }
255
-
256
-
257
- /**
258
- * do we have to disable the URL guessing?
259
- *
260
- * @since 7
261
- * @access private
262
- */
263
- private function get_option_404page_no_url_guessing() {
264
-
265
- return (bool)get_option( '404page_no_url_guessing', false );
266
-
267
- }
268
-
269
-
270
- /**
271
- * do we have to send an http 410 error in case the object is in trash?
272
- *
273
- * @since 7
274
- * @access private
275
- */
276
- private function get_option_404page_http410_if_trashed() {
277
-
278
- return (bool)get_option( '404page_http410_if_trashed', false );
279
-
280
- }
281
-
282
-
283
- /**
284
- * get all option names
285
- *
286
- * @since 7
287
- * @access public
288
- */
289
- public function get_option_names() {
290
-
291
- return array_keys( $this->settings );
292
-
293
- }
294
 
295
  }
296
 
17
  */
18
  if ( !class_exists( 'PP_404Page_Settings' ) ) {
19
 
20
+ class PP_404Page_Settings extends PPF01_Settings {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21
 
22
  /**
23
+ * sanitize settings
24
  *
25
+ * @since 11.0.0
26
+ * @access private
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27
  */
28
+ private function sanitize_settings() {
29
 
30
+ // Set page ID to -1 if the page does not exist or is not published
 
 
 
 
 
 
 
 
 
 
 
31
 
32
+ if ( $this->get( 'page_id' ) != 0 ) {
33
+
34
+ $page = get_post( $this->get( 'page_id' ) );
35
+
36
+ if ( !$page || $page->post_status != 'publish' ) {
37
+
38
+ $this->set( 'page_id', -1 );
39
+
40
+ }
41
+
42
+ }
43
 
44
  }
45
 
63
 
64
  }
65
 
66
+ }
67
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
68
 
69
  }
70
 
inc/class-404page.php CHANGED
@@ -23,60 +23,18 @@ if ( ! defined( 'PP_404' ) ) {
23
  if ( !class_exists( 'PP_404Page' ) ) {
24
 
25
 
26
- class PP_404Page {
27
-
28
- /**
29
- * Instance
30
- *
31
- * @since 8
32
- * @var singleton
33
- * @access protected
34
- */
35
- protected static $_instance = null;
36
-
37
-
38
- /**
39
- * Plugin Main File Path and Name
40
- *
41
- * @since 8
42
- * @var string
43
- * @access private
44
- * was $_file before
45
- */
46
-
47
-
48
- /**
49
- * Plugin Name
50
- *
51
- * @since 1
52
- * @var string
53
- * @access private
54
- */
55
- private $plugin_name;
56
 
57
 
58
  /**
59
- * Plugin Slug
60
  *
61
- * @since 1
62
- * @var string
63
  * @access private
64
  */
65
- private $plugin_slug;
66
-
67
 
68
- /**
69
- * Plugin Version
70
- *
71
- * @since 8
72
- * @var int
73
- * @access private
74
- * was $version before
75
- */
76
- private $plugin_version;
77
-
78
-
79
- private $settings;
80
  private $template;
81
  private $postid;
82
 
@@ -115,144 +73,69 @@ if ( !class_exists( 'PP_404Page' ) ) {
115
 
116
 
117
  /**
118
- * Init the Class
119
- *
120
- * @since 1
121
- * @see getInstance
122
- */
123
- protected function __construct( $settings ) {
124
-
125
- $this->plugin_file = $settings['file'];
126
- $this->plugin_slug = $settings['slug'];
127
- $this->plugin_name = $settings['name'];
128
- $this->plugin_version = $settings['version'];
129
-
130
- $this->get_settings();
131
- $this->load();
132
- }
133
-
134
-
135
- /**
136
- * Prevent Cloning
137
  *
138
- * @since 3
139
- */
140
- protected function __clone() {}
141
-
142
-
143
- /**
144
- * Get the Instance
145
- *
146
- * @since 8
147
- * @param array $settings {
148
- * @type string $file Plugin Main File Path and Name
149
- * @type string $slug Plugin Slug
150
- * @type string $name Plugin Name
151
- * @type int $version Plugin Verion
152
- * }
153
- * @return singleton
154
- */
155
- public static function getInstance( $settings ) {
156
-
157
- if ( null === self::$_instance ) {
158
-
159
- self::$_instance = new self( $settings );
160
-
161
- }
162
-
163
- return self::$_instance;
164
-
165
- }
166
-
167
-
168
- /**
169
- * get plugin file
170
- *
171
- * @since 8
172
- * @access public
173
- */
174
- public function get_plugin_file() {
175
-
176
- return $this->plugin_file;
177
-
178
- }
179
-
180
-
181
- /**
182
- * get plugin slug
183
- *
184
- * @since 8
185
- * @access public
186
- */
187
- public function get_plugin_slug() {
188
-
189
- return $this->plugin_slug;
190
-
191
- }
192
-
193
-
194
- /**
195
- * get plugin name
196
- *
197
- * @since 8
198
- * @access public
199
- */
200
- public function get_plugin_name() {
201
-
202
- return $this->plugin_name;
203
-
204
- }
205
-
206
-
207
- /**
208
- * get plugin version
209
- *
210
- * @since 8
211
- * @access public
212
  */
213
- public function get_plugin_version() {
214
-
215
- return $this->plugin_version;
216
-
217
- }
218
 
219
 
220
  /**
221
- * get all settings
222
- * except 404page_method
223
- * the 404page_method setting is set in function set_mode() because it may be too early here and not everything is loaded properly
224
  *
225
- * since v 7 we have a settings class
226
- */
227
- private function get_settings() {
228
-
229
- $this->settings = new PP_404Page_Settings();
230
-
231
- }
232
-
233
-
234
- /**
235
- * Load
236
- * runs the init() function on firing of init action to ensure everything is loaded properly
237
  */
238
- private function load() {
239
-
240
- add_action( 'init', array( $this, 'add_text_domain' ) );
241
- add_action( 'init', array( $this, 'init' ) );
242
-
243
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
244
 
245
 
246
  /**
247
  * do plugin init
248
  * this runs after init action has fired to ensure everything is loaded properly
 
249
  */
250
- function init() {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
251
 
252
  // as of v 2.2 always call set_mode
253
  // as of v 2.4 we do not need to add an init action hook
254
 
255
- if ( !is_admin() && $this->get_id() > 0 ) {
256
 
257
  // as of v 3.0 we once check if there's a 404 page set and not in all functions separately
258
  $this->set_mode();
@@ -260,36 +143,37 @@ if ( !class_exists( 'PP_404Page' ) ) {
260
  add_filter( 'get_pages', array ( $this, 'remove_404page_from_array' ), 10, 2 );
261
 
262
  // Stop URL guessing if activated
263
- if ( $this->settings->get_no_url_guessing() ) {
264
  add_filter( 'redirect_canonical' ,array ( $this, 'no_url_guessing' ) );
265
  }
266
 
267
  // Remove 404 error page from YOAST sitemap
268
  // only if "Send an 404 error if the page is accessed directly by its URL" is active
269
  // @since 6
270
- if ( $this->settings->get_fire_error() ) {
271
 
272
  add_filter( 'wpseo_exclude_from_sitemap_by_post_ids', function () {
273
- return array( $this->get_id() );
274
  } );
275
 
276
  }
277
 
278
  }
279
 
 
280
  if ( class_exists( 'PP_404Page_Admin' ) ) {
281
 
282
  // load classes only if in admin
283
  // @since 10
284
  // using class_exists( 'PP_404Page_Admin' ) instead of is_admin() as of v 10.3 for compatibilty with iThemes Sync
285
 
286
- $this->admin = new PP_404Page_Admin( $this, $this->settings );
287
- $this->blockeditor = new PP_404Page_BlockEditor( $this );
288
- $this->classiceditor = new PP_404Page_ClassicEditor( $this );
289
 
290
  // Remove 404 page from post list if activated
291
  // not moved to PP_404Page_Admin because we also need exclude_404page() in frontend
292
- if ( $this->settings->get_hide() and $this->get_id() > 0 ) {
293
  add_action( 'pre_get_posts' ,array ( $this, 'exclude_404page' ) );
294
  }
295
 
@@ -298,22 +182,12 @@ if ( !class_exists( 'PP_404Page' ) ) {
298
  }
299
 
300
 
301
- /**
302
- * add text domain
303
- */
304
- function add_text_domain() {
305
-
306
- load_plugin_textdomain( '404page' );
307
-
308
- }
309
-
310
-
311
  /**
312
  * init filters
313
  */
314
  function set_mode() {
315
 
316
- $this->settings->set_method();
317
 
318
  if ( defined( 'CUSTOMIZR_VER' ) ) {
319
 
@@ -328,13 +202,13 @@ if ( !class_exists( 'PP_404Page' ) ) {
328
 
329
  // send http 410 instead of http 404 if requested resource is in trash
330
  // @since 3.2
331
- if ( $this->settings->get_http410_if_trashed() ) {
332
 
333
  add_action( 'template_redirect', array( $this, 'maybe_send_410' ) );
334
 
335
  }
336
 
337
- } elseif ( $this->settings->get_method() != 'STD' ) {
338
 
339
  // Compatibility Mode
340
  // as of v 2.4 we use the the_posts filter instead of posts_results, because the posts array is internally processed after posts_results fires
@@ -348,7 +222,7 @@ if ( !class_exists( 'PP_404Page' ) ) {
348
  // Standard Mode
349
  add_filter( '404_template', array( $this, 'show404_standard_mode' ), 999 );
350
 
351
- if ( $this->settings->get_fire_error() ) {
352
 
353
  add_action( 'template_redirect', array( $this, 'do_404_header_standard_mode' ) );
354
 
@@ -356,7 +230,7 @@ if ( !class_exists( 'PP_404Page' ) ) {
356
 
357
  // send http 410 instead of http 404 if requested resource is in trash
358
  // @since 3.2
359
- if ( $this->settings->get_http410_if_trashed() ) {
360
 
361
  add_action( 'template_redirect', array( $this, 'maybe_send_410' ) );
362
 
@@ -393,7 +267,7 @@ if ( !class_exists( 'PP_404Page' ) ) {
393
  }
394
  // that's it
395
 
396
- if ( ! $this->settings->get_native() ) {
397
 
398
  $wp_query = null;
399
  $wp_query = new WP_Query();
@@ -438,7 +312,7 @@ if ( !class_exists( 'PP_404Page' ) ) {
438
  // that's it
439
 
440
  $pageid = $this->get_page_id();
441
- if ( ! $this->settings->get_native() ) {
442
 
443
  // as of v 10 we also check if $wp_query->query[error] == 404
444
  // this is necessary to bypass a WordPress bug
@@ -478,7 +352,7 @@ if ( !class_exists( 'PP_404Page' ) ) {
478
  } elseif ( 1 == count( $posts ) && 'page' == $posts[0]->post_type ) {
479
 
480
  // Do a 404 if the 404 page is opened directly
481
- if ( $this->settings->get_fire_error() ) {
482
  $curpageid = $posts[0]->ID;
483
 
484
  if ( defined( 'ICL_SITEPRESS_VERSION' ) ) {
@@ -542,7 +416,7 @@ if ( !class_exists( 'PP_404Page' ) ) {
542
  * Standard Mode
543
  */
544
  function do_404_header_standard_mode() {
545
- if ( is_page() && get_the_ID() == $this->get_id() && !is_404() ) {
546
  status_header( 404 );
547
  nocache_headers();
548
  $this->maybe_force_404();
@@ -562,7 +436,7 @@ if ( !class_exists( 'PP_404Page' ) ) {
562
  // send http 410 instead of http 404 if requested resource is in trash
563
  // @since 3.2
564
 
565
- if ( $this->settings->get_http410_if_trashed() && $this->is_url_in_trash( rawurldecode ( ( is_ssl() ? 'https://' : 'http://' ) . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] ) ) ) {
566
 
567
  status_header( 410 );
568
 
@@ -590,13 +464,13 @@ if ( !class_exists( 'PP_404Page' ) ) {
590
  // debug class
591
  // @since 3.1
592
  $debug_class = 'pp404-';
593
- if ( $this->settings->get_native() ) {
594
  $debug_class .= 'native';
595
  } elseif ( defined( 'CUSTOMIZR_VER' ) ) {
596
  $debug_class .= 'customizr';
597
  } elseif ( defined( 'ICL_SITEPRESS_VERSION' ) ) {
598
  $debug_class .= 'wpml';
599
- } elseif ( $this->settings->get_method() != 'STD' ) {
600
  $debug_class .= 'cmp';
601
  } else {
602
  $debug_class .= 'std';
@@ -628,7 +502,7 @@ if ( !class_exists( 'PP_404Page' ) ) {
628
  * Customizr Compatibility Mode
629
  */
630
  function show404title_customizr_mode( $title ) {
631
- if ( ! $this->settings->get_native() ) {
632
  return '<h1 class="entry-title">' . get_the_title( $this->get_page_id() ) . '</h1>';
633
  } else {
634
  return $title;
@@ -641,7 +515,7 @@ if ( !class_exists( 'PP_404Page' ) ) {
641
  * Customizr Compatibility Mode
642
  */
643
  function show404_customizr_mode( $content ) {
644
- if ( ! $this->settings->get_native() ) {
645
  return '<div class="entry-content">' . apply_filters( 'the_content', get_post_field( 'post_content', $this->get_page_id() ) ) . '</div>';
646
  } else {
647
  return $content;
@@ -655,7 +529,7 @@ if ( !class_exists( 'PP_404Page' ) ) {
655
  * Customizr Compatibility Mode
656
  */
657
  function show404articleselectors_customizr_mode( $selectors ) {
658
- if ( ! $this->settings->get_native() ) {
659
  return 'id="post-' . $this->get_page_id() . '" class="' . join( ' ', get_post_class( 'row-fluid', $this->get_page_id() ) ) . '"';
660
  } else {
661
  return $selectors;
@@ -667,7 +541,7 @@ if ( !class_exists( 'PP_404Page' ) ) {
667
  * do we have to force a 404 in wp_head?
668
  */
669
  function maybe_force_404() {
670
- if ( $this->settings->get_force_error() ) {
671
  add_action( 'wp_head', array( $this, 'force_404_start' ), 9.9 );
672
  add_action( 'wp_head', array( $this, 'force_404_end' ), 99 );
673
  }
@@ -983,19 +857,6 @@ if ( !class_exists( 'PP_404Page' ) ) {
983
  return false;
984
 
985
  }
986
-
987
-
988
- /**
989
- * get id of the 404 page
990
- *
991
- * @since 9
992
- * @access public
993
- */
994
- public function get_id() {
995
-
996
- return $this->settings->get_id();
997
-
998
- }
999
 
1000
 
1001
  /**
@@ -1003,7 +864,7 @@ if ( !class_exists( 'PP_404Page' ) ) {
1003
  */
1004
  private function get_page_id() {
1005
 
1006
- $pageid = $this->get_id();
1007
 
1008
  if ( $pageid > 0 ) {
1009
 
@@ -1042,7 +903,7 @@ if ( !class_exists( 'PP_404Page' ) ) {
1042
 
1043
  // WPML is active
1044
  // get an array for all translations
1045
- $pageid = $this->get_id();
1046
  $pages = array( $pageid );
1047
 
1048
  if ( $pageid > 0 ) {
@@ -1134,11 +995,8 @@ if ( !class_exists( 'PP_404Page' ) ) {
1134
  */
1135
  function uninstall_single() {
1136
 
1137
- foreach ( $this->settings->get_option_names() as $option ) {
1138
-
1139
- delete_option( $option );
1140
-
1141
- }
1142
 
1143
  }
1144
 
@@ -1150,14 +1008,14 @@ if ( !class_exists( 'PP_404Page' ) ) {
1150
  // check if there's a custom 404 page set
1151
  function pp_404_is_active() {
1152
 
1153
- return ( $this->get_id() > 0 );
1154
 
1155
  }
1156
 
1157
  // activate the native theme support
1158
  function pp_404_set_native_support() {
1159
 
1160
- $this->settings->set_native( true );
1161
 
1162
  }
1163
 
@@ -1166,7 +1024,7 @@ if ( !class_exists( 'PP_404Page' ) ) {
1166
 
1167
  $title = '';
1168
 
1169
- if ( $this->get_id() > 0 && $this->settings->get_native() ) {
1170
 
1171
  $title = get_the_title( $this->get_page_id() );
1172
 
@@ -1188,7 +1046,7 @@ if ( !class_exists( 'PP_404Page' ) ) {
1188
 
1189
  $content = '';
1190
 
1191
- if ( $this->get_id() > 0 && $this->settings->get_native() ) {
1192
 
1193
  $content = apply_filters( 'the_content', get_post_field( 'post_content', $this->get_page_id() ) );
1194
 
@@ -1207,14 +1065,27 @@ if ( !class_exists( 'PP_404Page' ) ) {
1207
 
1208
 
1209
  /**
1210
- * get path for asset file
 
 
 
 
 
 
 
 
 
 
 
 
 
1211
  *
1212
- * @since 7
1213
  * @access public
1214
  */
1215
- public function get_asset_file( $dir, $file ) {
1216
 
1217
- return plugins_url( 'assets/' . $dir . '/' . $file, $this->get_plugin_file() );
1218
 
1219
  }
1220
 
23
  if ( !class_exists( 'PP_404Page' ) ) {
24
 
25
 
26
+ class PP_404Page extends PPF01_Plugin {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27
 
28
 
29
  /**
30
+ * Native Mode
31
  *
32
+ * @since 11.0.0 - was part of previous settings class
33
+ * @var bool
34
  * @access private
35
  */
36
+ private $native;
 
37
 
 
 
 
 
 
 
 
 
 
 
 
 
38
  private $template;
39
  private $postid;
40
 
73
 
74
 
75
  /**
76
+ * Deprecated Class
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
77
  *
78
+ * @see class-404page-deprecated.php
79
+ * @since 11.0.0
80
+ * @var object
81
+ * @access private
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
82
  */
83
+ private $deprecated;
 
 
 
 
84
 
85
 
86
  /**
87
+ * Init the Class
 
 
88
  *
89
+ * @since 11.0.0
90
+ * was part of __construct before
 
 
 
 
 
 
 
 
 
 
91
  */
92
+ public function plugin_init() {
93
+
94
+ // settings defaults
95
+ // @since 11.0.0
96
+ $defaults = array(
97
+ 'page_id' => 0,
98
+ 'hide' => false,
99
+ 'fire_error' => true,
100
+ 'force_error' => false,
101
+ 'no_url_guessing' => false,
102
+ 'http410_if_trashed' => false,
103
+ 'method' => 'STD'
104
+ );
105
+
106
+ // since 11.0.0 we use add_settings_class() to load the settings
107
+ $this->add_settings_class( 'PP_404Page_Settings', 'class-404page-settings', $this, $defaults );
108
+
109
+ // @since 11.0.0
110
+ $this->add_action( 'init' );
111
+ }
112
 
113
 
114
  /**
115
  * do plugin init
116
  * this runs after init action has fired to ensure everything is loaded properly
117
+ * was init() before 11.0.0
118
  */
119
+ function action_init() {
120
+
121
+ // moved from add_text_domain() in v 11.0.0
122
+ load_plugin_textdomain( '404page' );
123
+
124
+
125
+ // change old stuff to new stuff for backward compatibility
126
+ // since v 11.0.0
127
+ $this->deprecated = $this->add_sub_class_always( 'PP_404Page_Deprecated', 'class-404page-deprecated', $this );
128
+
129
+ // load the following subclasses only on backend
130
+ // using add_sub_class_backend() sinde v 11
131
+ $this->admin = $this->add_sub_class_backend( 'PP_404Page_Admin', 'class-404page-admin', $this, $this->settings() );
132
+ $this->blockeditor = $this->add_sub_class_backend( 'PP_404Page_BlockEditor', 'class-404page-block-editor', $this, $this->settings() );
133
+ $this->classiceditor = $this->add_sub_class_backend( 'PP_404Page_ClassicEditor', 'class-404page-classic-editor', $this, $this->settings() );
134
 
135
  // as of v 2.2 always call set_mode
136
  // as of v 2.4 we do not need to add an init action hook
137
 
138
+ if ( !is_admin() && $this->settings()->get( 'page_id' ) > 0 ) {
139
 
140
  // as of v 3.0 we once check if there's a 404 page set and not in all functions separately
141
  $this->set_mode();
143
  add_filter( 'get_pages', array ( $this, 'remove_404page_from_array' ), 10, 2 );
144
 
145
  // Stop URL guessing if activated
146
+ if ( $this->settings()->get( 'no_url_guessing' ) ) {
147
  add_filter( 'redirect_canonical' ,array ( $this, 'no_url_guessing' ) );
148
  }
149
 
150
  // Remove 404 error page from YOAST sitemap
151
  // only if "Send an 404 error if the page is accessed directly by its URL" is active
152
  // @since 6
153
+ if ( $this->settings()->get( 'fire_error' ) ) {
154
 
155
  add_filter( 'wpseo_exclude_from_sitemap_by_post_ids', function () {
156
+ return array( $this->settings()->get( 'ipage_d' ) );
157
  } );
158
 
159
  }
160
 
161
  }
162
 
163
+
164
  if ( class_exists( 'PP_404Page_Admin' ) ) {
165
 
166
  // load classes only if in admin
167
  // @since 10
168
  // using class_exists( 'PP_404Page_Admin' ) instead of is_admin() as of v 10.3 for compatibilty with iThemes Sync
169
 
170
+ //$this->admin = new PP_404Page_Admin( $this, $this->settings );
171
+ //$this->blockeditor = new PP_404Page_BlockEditor( $this );
172
+ //$this->classiceditor = new PP_404Page_ClassicEditor( $this );
173
 
174
  // Remove 404 page from post list if activated
175
  // not moved to PP_404Page_Admin because we also need exclude_404page() in frontend
176
+ if ( $this->settings()->get( 'hide' ) and $this->settings()->get( 'page_id' ) > 0 ) {
177
  add_action( 'pre_get_posts' ,array ( $this, 'exclude_404page' ) );
178
  }
179
 
182
  }
183
 
184
 
 
 
 
 
 
 
 
 
 
 
185
  /**
186
  * init filters
187
  */
188
  function set_mode() {
189
 
190
+ $this->settings()->set_method();
191
 
192
  if ( defined( 'CUSTOMIZR_VER' ) ) {
193
 
202
 
203
  // send http 410 instead of http 404 if requested resource is in trash
204
  // @since 3.2
205
+ if ( $this->settings()->get( 'http410_if_trashed' ) ) {
206
 
207
  add_action( 'template_redirect', array( $this, 'maybe_send_410' ) );
208
 
209
  }
210
 
211
+ } elseif ( $this->settings()->get( 'method' ) != 'STD' ) {
212
 
213
  // Compatibility Mode
214
  // as of v 2.4 we use the the_posts filter instead of posts_results, because the posts array is internally processed after posts_results fires
222
  // Standard Mode
223
  add_filter( '404_template', array( $this, 'show404_standard_mode' ), 999 );
224
 
225
+ if ( $this->settings()->get( 'fire_error' ) ) {
226
 
227
  add_action( 'template_redirect', array( $this, 'do_404_header_standard_mode' ) );
228
 
230
 
231
  // send http 410 instead of http 404 if requested resource is in trash
232
  // @since 3.2
233
+ if ( $this->settings()->get( 'http410_if_trashed' ) ) {
234
 
235
  add_action( 'template_redirect', array( $this, 'maybe_send_410' ) );
236
 
267
  }
268
  // that's it
269
 
270
+ if ( ! $this->is_native() ) {
271
 
272
  $wp_query = null;
273
  $wp_query = new WP_Query();
312
  // that's it
313
 
314
  $pageid = $this->get_page_id();
315
+ if ( ! $this->is_native() ) {
316
 
317
  // as of v 10 we also check if $wp_query->query[error] == 404
318
  // this is necessary to bypass a WordPress bug
352
  } elseif ( 1 == count( $posts ) && 'page' == $posts[0]->post_type ) {
353
 
354
  // Do a 404 if the 404 page is opened directly
355
+ if ( $this->settings()->get( 'fire_error' ) ) {
356
  $curpageid = $posts[0]->ID;
357
 
358
  if ( defined( 'ICL_SITEPRESS_VERSION' ) ) {
416
  * Standard Mode
417
  */
418
  function do_404_header_standard_mode() {
419
+ if ( is_page() && get_the_ID() == $this->settings()->get( 'page_id' ) && !is_404() ) {
420
  status_header( 404 );
421
  nocache_headers();
422
  $this->maybe_force_404();
436
  // send http 410 instead of http 404 if requested resource is in trash
437
  // @since 3.2
438
 
439
+ if ( $this->settings()->get( 'http410_if_trashed' ) && $this->is_url_in_trash( rawurldecode ( ( is_ssl() ? 'https://' : 'http://' ) . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] ) ) ) {
440
 
441
  status_header( 410 );
442
 
464
  // debug class
465
  // @since 3.1
466
  $debug_class = 'pp404-';
467
+ if ( $this->is_native() ) {
468
  $debug_class .= 'native';
469
  } elseif ( defined( 'CUSTOMIZR_VER' ) ) {
470
  $debug_class .= 'customizr';
471
  } elseif ( defined( 'ICL_SITEPRESS_VERSION' ) ) {
472
  $debug_class .= 'wpml';
473
+ } elseif ( $this->settings()->get( 'method' ) != 'STD' ) {
474
  $debug_class .= 'cmp';
475
  } else {
476
  $debug_class .= 'std';
502
  * Customizr Compatibility Mode
503
  */
504
  function show404title_customizr_mode( $title ) {
505
+ if ( ! $this->is_native() ) {
506
  return '<h1 class="entry-title">' . get_the_title( $this->get_page_id() ) . '</h1>';
507
  } else {
508
  return $title;
515
  * Customizr Compatibility Mode
516
  */
517
  function show404_customizr_mode( $content ) {
518
+ if ( ! $this->is_native() ) {
519
  return '<div class="entry-content">' . apply_filters( 'the_content', get_post_field( 'post_content', $this->get_page_id() ) ) . '</div>';
520
  } else {
521
  return $content;
529
  * Customizr Compatibility Mode
530
  */
531
  function show404articleselectors_customizr_mode( $selectors ) {
532
+ if ( ! $this->is_native() ) {
533
  return 'id="post-' . $this->get_page_id() . '" class="' . join( ' ', get_post_class( 'row-fluid', $this->get_page_id() ) ) . '"';
534
  } else {
535
  return $selectors;
541
  * do we have to force a 404 in wp_head?
542
  */
543
  function maybe_force_404() {
544
+ if ( $this->settings()->get( 'force_error' ) ) {
545
  add_action( 'wp_head', array( $this, 'force_404_start' ), 9.9 );
546
  add_action( 'wp_head', array( $this, 'force_404_end' ), 99 );
547
  }
857
  return false;
858
 
859
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
860
 
861
 
862
  /**
864
  */
865
  private function get_page_id() {
866
 
867
+ $pageid = $this->settings()->get( 'page_id' );
868
 
869
  if ( $pageid > 0 ) {
870
 
903
 
904
  // WPML is active
905
  // get an array for all translations
906
+ $pageid = $this->settings()->get( 'page_id' );
907
  $pages = array( $pageid );
908
 
909
  if ( $pageid > 0 ) {
995
  */
996
  function uninstall_single() {
997
 
998
+ $this->data_remove();
999
+ $this->settings()->remove();
 
 
 
1000
 
1001
  }
1002
 
1008
  // check if there's a custom 404 page set
1009
  function pp_404_is_active() {
1010
 
1011
+ return ( $this->settings()->get( 'page_id' ) > 0 );
1012
 
1013
  }
1014
 
1015
  // activate the native theme support
1016
  function pp_404_set_native_support() {
1017
 
1018
+ $this->set_native();
1019
 
1020
  }
1021
 
1024
 
1025
  $title = '';
1026
 
1027
+ if ( $this->settings()->get( 'page_id' ) > 0 && $this->is_native() ) {
1028
 
1029
  $title = get_the_title( $this->get_page_id() );
1030
 
1046
 
1047
  $content = '';
1048
 
1049
+ if ( $this->settings()->get( 'page_id' ) > 0 && $this->is_native() ) {
1050
 
1051
  $content = apply_filters( 'the_content', get_post_field( 'post_content', $this->get_page_id() ) );
1052
 
1065
 
1066
 
1067
  /**
1068
+ * set native mode
1069
+ *
1070
+ * @since 11.0.0 - was part of previous settings class
1071
+ * @access public
1072
+ */
1073
+ public function set_native() {
1074
+
1075
+ $this->native = true;
1076
+
1077
+ }
1078
+
1079
+
1080
+ /**
1081
+ * is native mode ative
1082
  *
1083
+ * @since 11.0.0 - was part of previous settings class
1084
  * @access public
1085
  */
1086
+ public function is_native() {
1087
 
1088
+ return ( true === $this->native );
1089
 
1090
  }
1091
 
inc/ppf/assets/css/pp-admin-page.css ADDED
@@ -0,0 +1,263 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #wpcontent {
2
+ padding-left: 0 !important;
3
+ }
4
+
5
+ .pp-admin-page-wrapper {
6
+ margin: 0;
7
+ }
8
+
9
+ .pp-admin-notice-area {
10
+ background-color: #1a1a1a;
11
+ padding: 1px 6px;
12
+ }
13
+
14
+ .pp-admin-page-header {
15
+ background-color: #1a1a1a;
16
+ background: linear-gradient(to right bottom, #1a1a1a 0%,#5e5e5e 100%);
17
+ }
18
+
19
+ .rtl .pp-admin-page-header {
20
+ margin-left: 0;
21
+ background: linear-gradient(to left bottom, #1a1a1a 0%,#5e5e5e 100%);
22
+ }
23
+
24
+ .pp-admin-page-header nav {
25
+ margin-right: 12px;
26
+ text-align: right;
27
+ line-height: 1;
28
+ }
29
+
30
+ .rtl .pp-admin-page-header nav {
31
+ text-align: left;
32
+ margin-right: 0;
33
+ margin-left: 12px;
34
+ }
35
+
36
+ .pp-admin-page-header nav a {
37
+ display: inline-block;
38
+ padding: 6px 3px;
39
+ color: #fff;
40
+ text-decoration: none;
41
+ font-size: 12px;
42
+ height: 20px;
43
+ line-height: 20px;
44
+ border-bottom: 2px solid transparent;
45
+ }
46
+
47
+ .pp-admin-page-header nav a span.text {
48
+ white-space: nowrap;
49
+ padding-left: 4px;
50
+ }
51
+
52
+ .rtl .pp-admin-page-header nav a span.text {
53
+ padding-left: 0;
54
+ padding-right: 4px;
55
+ }
56
+
57
+ @media only screen and (max-width: 960px) {
58
+ .pp-admin-page-header nav a {
59
+ font-size: 36px;
60
+ padding: 6px 12px;
61
+ }
62
+ .pp-admin-page-header nav a span.text {
63
+ display: none;
64
+ }
65
+ }
66
+
67
+ .pp-admin-page-header nav a:hover, .pp-admin-page-header nav a:focus {
68
+ border-bottom-color: #fff;
69
+ }
70
+
71
+ .pp-admin-page-title {
72
+ padding: 36px 0 36px 20px;
73
+ }
74
+
75
+ .rtl .pp-admin-page-title {
76
+ padding-left: 0;
77
+ padding-right: 20px;
78
+ }
79
+
80
+ .pp-admin-page-title h1 {
81
+ line-height: 64px;
82
+ padding: 0 0 0 80px;
83
+ background-image: url(../../../../assets/img/pluginicon.png);
84
+ background-repeat: no-repeat;
85
+ color: #fff;
86
+ }
87
+
88
+ .rtl .pp-admin-page-title h1 {
89
+ padding-left: 0;
90
+ padding-right: 80px;
91
+ background-position: right top;
92
+ }
93
+
94
+ @media only screen and (max-width: 960px) {
95
+ .pp-admin-page-title h1 {
96
+ line-height: 1.2;
97
+ min-height: 64px;
98
+ }
99
+ }
100
+
101
+ .pp-admin-page-header .tab-navigation {
102
+ display: flex;
103
+ flex-wrap: wrap;
104
+ margin: 0 24px;
105
+ list-style: none;
106
+ }
107
+
108
+ .pp-admin-page-header .tab-navigation li {
109
+ margin: 0;
110
+ }
111
+
112
+ .pp-admin-page-header .tab-navigation .tabset {
113
+ padding: 12px 24px;
114
+ font-size: 18px;
115
+ color: #fff;
116
+ cursor: pointer;
117
+ background: none;
118
+ border: none;
119
+ border-top-left-radius: 3px;
120
+ border-top-right-radius: 3px;
121
+ outline: none;
122
+ transition: 0.3s all;
123
+ }
124
+
125
+ .pp-admin-page-header .tab-navigation .tabset:hover {
126
+ background-color: rgba( 255, 255, 255, 0.3 );
127
+ }
128
+
129
+ .pp-admin-page-header .tab-navigation .tabset.current, .pp-admin-page-header .tab-navigation .tabset.current:hover {
130
+ background-color: #fff;
131
+ color: #1a1a1a;
132
+ }
133
+
134
+ .pp-admin-page-inner {
135
+ padding: 24px;
136
+ background-color: #fff;
137
+ }
138
+
139
+ .pp-admin-page-inner .tab-panel .panel {
140
+ display: none;
141
+ }
142
+
143
+ .pp-admin-page-inner .tab-panel .panel.current {
144
+ display: block;
145
+ }
146
+
147
+ .pp-admin-page-inner .tab-panel .panel.current.nosubmit ~ .submit {
148
+ display: none;
149
+ }
150
+
151
+ .pp-admin-page-inner .tab-panel p.submit {
152
+ padding-bottom: 0;
153
+ margin-bottom: 0;
154
+ }
155
+
156
+ .wp-core-ui .pp-admin-page-inner .tab-panel .button-primary {
157
+ background-color: #fe7f0f;
158
+ border: 1px solid #febf87;
159
+ box-shadow: none;
160
+ text-shadow: none;
161
+ font-size: 16px;
162
+ line-height: 1;
163
+ height: auto;
164
+ padding: 6px 12px;
165
+ }
166
+
167
+ .wp-core-ui .pp-admin-page-inner .tab-panel .button-primary:hover, .wp-core-ui .pp-admin-page-inner .tab-panel .button-primary:focus {
168
+ border-color: #fe7f0f;
169
+ }
170
+
171
+ .pp-admin-page-wrapper .form-table th, .form-table td {
172
+ display: block;
173
+ width: auto;
174
+ }
175
+
176
+ .pp-admin-page-wrapper .form-table td {
177
+ padding: 0;
178
+ margin-bottom: 20px;
179
+ }
180
+
181
+ .pp-admin-page-wrapper .form-table td p {
182
+ padding: 0;
183
+ line-height: 1.2;
184
+ margin-bottom: 20px;
185
+ }
186
+
187
+ .pp-admin-page-wrapper .form-table th {
188
+ display: none;
189
+ }
190
+
191
+ .wp-admin .pp-admin-page-wrapper select {
192
+ border: 1px solid #1a1a1a;
193
+ border-radius: 2px;
194
+ padding: 6px;
195
+ line-height: auto;
196
+ height: auto;
197
+ }
198
+
199
+ .pp-admin-page-wrapper .toggle {
200
+ display: flex;
201
+ }
202
+
203
+ .pp-admin-page-wrapper .toggle .slider {
204
+ width: 120px;
205
+ }
206
+
207
+ .pp-admin-page-wrapper .toggle .caption {
208
+ flex: 1;
209
+ }
210
+
211
+ .pp-admin-page-wrapper .toggle input[type="checkbox"] {
212
+ display: none;
213
+ }
214
+
215
+ .pp-admin-page-wrapper .toggle input[type="checkbox"] + label {
216
+ cursor: pointer;
217
+ text-indent: -9999px;
218
+ width: 80px;
219
+ height: 40px;
220
+ background: #5e5e5e;
221
+ display: block;
222
+ border-radius: 40px;
223
+ position: relative;
224
+ transition: 0.3s all;
225
+ }
226
+
227
+ .pp-admin-page-wrapper .toggle input[type="checkbox"]:disabled + label {
228
+ background-color: #DDD;
229
+ }
230
+
231
+ .pp-admin-page-wrapper .toggle input[type="checkbox"] + label:after {
232
+ content: '';
233
+ position: absolute;
234
+ top: 5px;
235
+ width: 30px;
236
+ height: 30px;
237
+ background: #fff;
238
+ border-radius: 30px;
239
+ transition: 0.3s all;
240
+ }
241
+
242
+ body:not(.rtl) .pp-admin-page-wrapper .toggle input[type="checkbox"] + label:after, .rtl .pp-admin-page-wrapper .toggle input[type="checkbox"]:checked + label:after {
243
+ left: 5px;
244
+ transform: none;
245
+ }
246
+
247
+ .pp-admin-page-wrapper .toggle input[type="checkbox"]:enabled:checked + label {
248
+ background: #1a1a1a;
249
+ }
250
+
251
+ body:not(.rtl) .pp-admin-page-wrapper .toggle input[type="checkbox"]:checked + label:after, .rtl .pp-admin-page-wrapper .toggle input[type="checkbox"] + label:after {
252
+ left: calc(100% - 5px);
253
+ transform: translateX(-100%);
254
+ }
255
+
256
+ .form-table.pp-admin-section-fields {
257
+ margin-top: 0;
258
+ }
259
+
260
+ .pp-admin-page-wrapper .highlight, .pp-admin-page-inner a, .pp-admin-page-inner a:hover, .pp-admin-page-inner a:focus {
261
+ color: #fe7f0f;
262
+ background-color: transparent;
263
+ }
inc/ppf/assets/js/jquery.cookie.js ADDED
@@ -0,0 +1,117 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*!
2
+ * jQuery Cookie Plugin v1.4.1
3
+ * https://github.com/carhartl/jquery-cookie
4
+ *
5
+ * Copyright 2013 Klaus Hartl
6
+ * Released under the MIT license
7
+ */
8
+ (function (factory) {
9
+ if (typeof define === 'function' && define.amd) {
10
+ // AMD
11
+ define(['jquery'], factory);
12
+ } else if (typeof exports === 'object') {
13
+ // CommonJS
14
+ factory(require('jquery'));
15
+ } else {
16
+ // Browser globals
17
+ factory(jQuery);
18
+ }
19
+ }(function ($) {
20
+
21
+ var pluses = /\+/g;
22
+
23
+ function encode(s) {
24
+ return config.raw ? s : encodeURIComponent(s);
25
+ }
26
+
27
+ function decode(s) {
28
+ return config.raw ? s : decodeURIComponent(s);
29
+ }
30
+
31
+ function stringifyCookieValue(value) {
32
+ return encode(config.json ? JSON.stringify(value) : String(value));
33
+ }
34
+
35
+ function parseCookieValue(s) {
36
+ if (s.indexOf('"') === 0) {
37
+ // This is a quoted cookie as according to RFC2068, unescape...
38
+ s = s.slice(1, -1).replace(/\\"/g, '"').replace(/\\\\/g, '\\');
39
+ }
40
+
41
+ try {
42
+ // Replace server-side written pluses with spaces.
43
+ // If we can't decode the cookie, ignore it, it's unusable.
44
+ // If we can't parse the cookie, ignore it, it's unusable.
45
+ s = decodeURIComponent(s.replace(pluses, ' '));
46
+ return config.json ? JSON.parse(s) : s;
47
+ } catch(e) {}
48
+ }
49
+
50
+ function read(s, converter) {
51
+ var value = config.raw ? s : parseCookieValue(s);
52
+ return $.isFunction(converter) ? converter(value) : value;
53
+ }
54
+
55
+ var config = $.cookie = function (key, value, options) {
56
+
57
+ // Write
58
+
59
+ if (value !== undefined && !$.isFunction(value)) {
60
+ options = $.extend({}, config.defaults, options);
61
+
62
+ if (typeof options.expires === 'number') {
63
+ var days = options.expires, t = options.expires = new Date();
64
+ t.setTime(+t + days * 864e+5);
65
+ }
66
+
67
+ return (document.cookie = [
68
+ encode(key), '=', stringifyCookieValue(value),
69
+ options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE
70
+ options.path ? '; path=' + options.path : '',
71
+ options.domain ? '; domain=' + options.domain : '',
72
+ options.secure ? '; secure' : ''
73
+ ].join(''));
74
+ }
75
+
76
+ // Read
77
+
78
+ var result = key ? undefined : {};
79
+
80
+ // To prevent the for loop in the first place assign an empty array
81
+ // in case there are no cookies at all. Also prevents odd result when
82
+ // calling $.cookie().
83
+ var cookies = document.cookie ? document.cookie.split('; ') : [];
84
+
85
+ for (var i = 0, l = cookies.length; i < l; i++) {
86
+ var parts = cookies[i].split('=');
87
+ var name = decode(parts.shift());
88
+ var cookie = parts.join('=');
89
+
90
+ if (key && key === name) {
91
+ // If second argument (value) is a function it's a converter...
92
+ result = read(cookie, value);
93
+ break;
94
+ }
95
+
96
+ // Prevent storing a cookie that we couldn't decode.
97
+ if (!key && (cookie = read(cookie)) !== undefined) {
98
+ result[name] = cookie;
99
+ }
100
+ }
101
+
102
+ return result;
103
+ };
104
+
105
+ config.defaults = {};
106
+
107
+ $.removeCookie = function (key, options) {
108
+ if ($.cookie(key) === undefined) {
109
+ return false;
110
+ }
111
+
112
+ // Must not alter options, thus extending a fresh object...
113
+ $.cookie(key, '', $.extend({}, options, { expires: -1 }));
114
+ return !$.cookie(key);
115
+ };
116
+
117
+ }));
inc/ppf/assets/js/pp-admin-page.js ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ jQuery( document ).ready(function( $ ) {
2
+
3
+
4
+ $( '.tab-navigation .tabset' ).click( function() {
5
+
6
+ if ( $( this ).not( '.current' ) ) {
7
+
8
+ $( '.tab-panel .panel.current' ).removeClass( 'current ');
9
+ $( '#' + $(this).data('tab-content') ).addClass( 'current' );
10
+
11
+ $( '.tab-navigation .tabset.current' ).removeClass( 'current ');
12
+ $( this ).addClass( 'current' );
13
+
14
+ $.cookie( '404page_current_tab', $( '.tab-navigation .tabset.current' ).attr('id') );
15
+
16
+ }
17
+
18
+ });
19
+
20
+
21
+ var current_tab = jQuery.cookie( '404page_current_tab' );
22
+ if ( current_tab === undefined ) {
23
+ current_tab = $( '.tab-navigation .tabset:first' ).attr('id');
24
+ $.removeCookie( '404page_current_tab' );
25
+ }
26
+ $( '#' + current_tab ).trigger( 'click' );
27
+
28
+
29
+ });
inc/ppf/loader.php ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Plugin Foundation Loader
5
+ *
6
+ * Peter's Plugins Foundation 01
7
+ *
8
+ * @package PPF01
9
+ * @author Peter Raschendorfer
10
+ * @license GPL2+
11
+ */
12
+
13
+ require_once ( __DIR__ . '/ppf-class.php' );
14
+ require_once ( __DIR__ . '/ppf-subclass.php' );
15
+ require_once ( __DIR__ . '/ppf-plugin.php' );
16
+ require_once ( __DIR__ . '/ppf-settings.php' );
17
+ require_once ( __DIR__ . '/ppf-admin.php' );
18
+
19
+ ?>
inc/ppf/ppf-admin.php ADDED
@@ -0,0 +1,606 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Admin Class
5
+ *
6
+ * Peter's Plugins Foundation 01
7
+ *
8
+ * @package PPF01
9
+ * @author Peter Raschendorfer
10
+ * @license GPL2+
11
+ */
12
+
13
+ if ( !class_exists( 'PPF01_Admin' ) ) {
14
+
15
+
16
+ abstract class PPF01_Admin extends PPF01_SubClass {
17
+
18
+
19
+ /**
20
+ * settings sections
21
+ *
22
+ * @since PPF01
23
+ * @var string
24
+ * @access private
25
+ */
26
+ private $_sections;
27
+
28
+
29
+ /**
30
+ * toolbar
31
+ *
32
+ * @since PPF01
33
+ * @var string
34
+ * @access private
35
+ */
36
+ private $_toolbar;
37
+
38
+
39
+ /**
40
+ * id of screen
41
+ *
42
+ * this can be set via set_screen_id()
43
+ *
44
+ * @since PPF01
45
+ * @var array
46
+ * @access private
47
+ */
48
+ private $_my_screen_id;
49
+
50
+
51
+ /**
52
+ * add multiple setting sections
53
+ *
54
+ * @since PPF01
55
+ * @param array $sections array of setting sections to add
56
+ * @access public
57
+ * @see add_settings()
58
+ */
59
+ public function add_setting_sections( $sections ) {
60
+
61
+ $this->_sections = $sections;
62
+
63
+ foreach( $sections as $section ) {
64
+
65
+ if ( array_key_exists( 'fields', $section ) ) {
66
+
67
+ $this->add_settings( $section );
68
+
69
+ }
70
+
71
+ }
72
+
73
+ // Register the options
74
+ register_setting( $this->core()->get_plugin_slug(), $this->settings()->get_option_name(), array( 'sanitize_callback' => array( $this, 'sanitize_callback' ) ) );
75
+
76
+
77
+ }
78
+
79
+
80
+ /**
81
+ * helper function to add a complete setting section
82
+ *
83
+ * @since PPF01
84
+ * @param array $settings array of settings to add
85
+ * string $section => ID of the section
86
+ * string $title => title for section (used by print_setting_sections())
87
+ * string $html => HTML code to add to this section
88
+ * array $fields => multidimensional array of fields to add
89
+ * string $key => key of the option array
90
+ * string $callback => function to call
91
+ * bool $nosubmit => this section should not show the submit button
92
+ * @access private
93
+ */
94
+ private function add_settings( $settings ) {
95
+
96
+ $section_id = $this->core()->get_plugin_slug() . '-' . $settings['section'];
97
+
98
+ add_settings_section( $section_id, '', null, $this->core()->get_plugin_slug() );
99
+
100
+ foreach ( $settings['fields'] as $field ) {
101
+
102
+ $field_id = $this->core()->get_plugin_slug() . '-' . $field['key'];
103
+
104
+ add_settings_field( $field_id, '' , array( $this, $field['callback'] ), $this->core()->get_plugin_slug(), $section_id );
105
+
106
+ }
107
+
108
+ return;
109
+
110
+ }
111
+
112
+
113
+ /**
114
+ * helper function to print out a slider styled checkbox
115
+ *
116
+ * @since PPF01
117
+ * @param string $key option key name
118
+ * @param string $title title
119
+ * @param string $help anchor to link to in manual
120
+ * @param string $video YouTube video ID
121
+ * @param string $note second line
122
+ * @param bool $disabled true/false (optional)
123
+ * @access public
124
+ */
125
+ public function print_slider_check( $key, $title, $help, $video, $note, $disabled = false ) {
126
+
127
+ $dis = '';
128
+ if ( $disabled ) {
129
+ $dis = ' disabled="disabled"';
130
+ }
131
+
132
+ $hlp = '';
133
+ if ( ! empty( $help ) ) {
134
+ $hlp = $this->add_manual_link( $help );
135
+ }
136
+
137
+ $vid = '';
138
+ if ( ! empty( $video ) ) {
139
+ $vid = $this->add_video_link( $video );
140
+ }
141
+
142
+ $add = '';
143
+ if ( ! empty( $note ) ) {
144
+ $add = '<br />' . $note;
145
+ }
146
+
147
+ echo '<p class="toggle"><span class="slider"><input type="checkbox" name="' . $this->settings()->get_option_key_name( $key ) . '" id="' . $this->core()->get_plugin_slug() . '-' . $key . '" value="1"' . checked( true, $this->settings()->get( $key ), false ) . $dis . ' /><label for="' . $this->core()->get_plugin_slug() . '-' . $key . '" class="check"></label></span><span class="caption">' . $title . $hlp . $vid . $add . '</span></p>';
148
+
149
+ }
150
+
151
+
152
+ /**
153
+ * helper function to add a plugin manual link
154
+ *
155
+ * @since PPF01
156
+ * @param string $anchor name of the anchor to link to
157
+ * @return string
158
+ * @access private
159
+ */
160
+ private function add_manual_link( $anchor = '' ) {
161
+
162
+ return ' <a class="dashicons dashicons-editor-help" href="https://petersplugins.com/' . $this->core()->get_plugin_slug() . '/manual/#' . $anchor . '"></a>';
163
+
164
+ }
165
+
166
+ /**
167
+ * helper function to add a video link
168
+ *
169
+ * @since PPF01
170
+ * @param string $youtubeid ID of the YouTube video
171
+ * @return string
172
+ * @access private
173
+ */
174
+ private function add_video_link( $youtubeid = '' ) {
175
+
176
+ return ' <a class="dashicons dashicons-video-alt3" href="https://youtu.be/' . $youtubeid . '" data-lity></a>';
177
+
178
+ }
179
+
180
+
181
+ /**
182
+ * print out setting sections
183
+ * it is not possible to use do_settings_sections() because we are not able to create a tabbed interface
184
+ *
185
+ * @since PPF01
186
+ * @access public
187
+ * @see add_settings()
188
+ */
189
+ public function print_setting_sections() {
190
+
191
+ foreach( $this->_sections as $section ) {
192
+
193
+ $section_id = $this->core()->get_plugin_slug() . '-' . $section['section'];
194
+ $extraclass = '';
195
+
196
+ if ( array_key_exists( 'nosubmit', $section ) && true === $section['nosubmit'] ) {
197
+
198
+ $extraclass = ' nosubmit';
199
+ }
200
+
201
+ echo '<div class="panel' . $extraclass . '" id="content-' . $section_id . '">';
202
+
203
+ if ( array_key_exists( 'html', $section ) ) {
204
+
205
+ echo '<div class="pp-admin-section-html">';
206
+ echo $section['html'];
207
+ echo '</div>';
208
+
209
+ }
210
+
211
+ if ( array_key_exists( 'fields', $section ) ) {
212
+
213
+ echo '<table class="form-table pp-admin-section-fields">';
214
+ do_settings_fields( $this->core()->get_plugin_slug(), $section_id );
215
+ echo '</table>';
216
+
217
+ }
218
+
219
+ echo '</div>';
220
+
221
+ }
222
+
223
+ }
224
+
225
+
226
+ /**
227
+ * print out setting sections navigation
228
+ *
229
+ * @since PPF01
230
+ * @access public
231
+ * @see add_settings()
232
+ */
233
+ public function print_setting_sections_nav() {
234
+
235
+ echo '<ul class="tab-navigation">';
236
+
237
+ foreach( $this->_sections as $section ) {
238
+
239
+ $section_id = $this->core()->get_plugin_slug() . '-' . $section['section'];
240
+
241
+ //echo '<li><a href="#' . $section_id . '"' . $first . '>' . $section['title'] . '</a></li>';
242
+
243
+ // echo '<li><input type="radio" name="tabset" id="tab-' . $section_id . '" data-tab-content="content-' . $section_id . '"aria-controls="' . $section['title'] . '"' . $sel . '><label for="tab-' . $section_id . '">' . $section['title'] . '</label>';
244
+
245
+ echo '<li><div class="tabset" id="tab-' . $section_id . '" data-tab-content="content-' . $section_id . '">' . $section['title'] . '</div>';
246
+
247
+ }
248
+
249
+ echo '</ul>';
250
+
251
+ }
252
+
253
+
254
+ /**
255
+ * sanitize the posted values
256
+ *
257
+ * @since PPF01
258
+ * @param array $settings array of settings to save
259
+ * @access public
260
+ */
261
+ public function sanitize_callback( $settings ) {
262
+
263
+ foreach ( $this->settings()->get_defaults() as $key => $value ) {
264
+
265
+ if ( true === is_bool( $value ) ) {
266
+
267
+ if ( ! array_key_exists( $key, $settings ) ) {
268
+
269
+ // we have to add the missing keys
270
+ // HTML forms only send data if a checkbox is checked
271
+ // missing keys would be overwritten with their default on next load
272
+ // this concerns only boolean values
273
+ // if key does not exist the checkbox was not checked
274
+ // so we have to handle it as false
275
+ $settings[$key] = false;
276
+
277
+ } else {
278
+
279
+ // also we check if a given value is boolean
280
+ // otherwise we reset it to false
281
+ // this is for security
282
+ // so it is not possible to pass non boolean values
283
+ // if a checkbox was checked we get 1
284
+ // so we only have to check for 1
285
+
286
+ if ( 1 != $settings[$key] ) {
287
+
288
+ $settings[$key] = false;
289
+
290
+ }
291
+
292
+ }
293
+
294
+ }
295
+
296
+ }
297
+
298
+ // it is not possible to do other sanitation because we do not know what to do
299
+ // more sanitation has to be done by the plugin itself
300
+
301
+ return $this->sanitize_settings( $settings );
302
+
303
+ }
304
+
305
+
306
+ /**
307
+ * sanitize the settings
308
+ * called by sanitize_callback()
309
+ * this can be used to sanitize the settings after missing keys have been added
310
+ *
311
+ * @since PPF01
312
+ * @param array $settings array of settings to save
313
+ * @access public
314
+ */
315
+ public function sanitize_settings( $settings ) {
316
+
317
+ return $settings;
318
+
319
+ }
320
+
321
+
322
+ /**
323
+ * add toolbar icons
324
+ *
325
+ * @since PPF01
326
+ * @param array $icons array of icons to show in toolbar
327
+ * string $link => URL to link to
328
+ * string $title => title to show
329
+ * string $icon => icon to use from dashicons
330
+ * @access public
331
+ */
332
+ public function add_toolbar_icons( $icons ) {
333
+
334
+ $this->_toolbar = '<nav>';
335
+
336
+ foreach ( $icons as $icon ) {
337
+
338
+ $extraclass = '';
339
+
340
+ if ( isset( $icon['highlight'] ) && true === $icon['highlight'] ) {
341
+
342
+ $extraclass = ' highlight';
343
+
344
+ }
345
+
346
+ $this->_toolbar .= '<a href="' . esc_url( $icon['link'] ) . '" title="' . $icon['title'] . '"><span class="dashicons ' . $icon['icon'] . $extraclass . '"></span><span class="text">' . $icon['title'] . '</span></a>';
347
+
348
+ }
349
+
350
+ $this->_toolbar .= '</nav>';
351
+
352
+ }
353
+
354
+
355
+ /**
356
+ * show the admin page
357
+ *
358
+ * @since PPF01
359
+ * @param string $capability minimum required capability to show page (optional)
360
+ * @access public
361
+ */
362
+ public function show( $capability = 'read' ) {
363
+
364
+ if ( !current_user_can( $capability ) ) {
365
+
366
+ wp_die( esc_html__( 'You do not have sufficient permissions to access this page.' ) );
367
+
368
+ }
369
+
370
+ settings_errors();
371
+
372
+ echo '<div class="wrap pp-admin-page-wrapper" id="pp-' . $this->core()->get_plugin_slug() . '-settings"><div class="pp-admin-notice-area"><div class="wp-header-end"></div></div>';
373
+ echo '<div class="pp-admin-page-header">';
374
+ echo $this->_toolbar;
375
+ echo '<div class="pp-admin-page-title"><h1>' . $this->core()->get_plugin_shortname() . '</h1></div>';
376
+ $this->print_setting_sections_nav();
377
+ echo '</div>';
378
+ echo '<div class="pp-admin-page-inner"><form method="POST" action="options.php">';
379
+ echo '<div class="tab-panel">';
380
+ settings_fields( $this->core()->get_plugin_slug() );
381
+ $this->print_setting_sections();
382
+ submit_button();
383
+ echo '</div></form></div></div>';
384
+
385
+ wp_enqueue_style( 'ppf01', $this->get_foundation_asset_url( 'css', 'pp-admin-page.css' ) );
386
+
387
+ wp_enqueue_script( 'ppf01-cookie', $this->get_foundation_asset_url( 'js', 'jquery.cookie.js' ), array( 'jquery' ), false, true );
388
+ wp_enqueue_script( 'ppf01', $this->get_foundation_asset_url( 'js', 'pp-admin-page.js' ), array( 'jquery', 'ppf01-cookie' ), false, true );
389
+
390
+ }
391
+
392
+
393
+ /**
394
+ * set screen id
395
+ *
396
+ * @since PPF01
397
+ * @param string $id id of screen
398
+ * @access public
399
+ */
400
+ public function set_screen_id( $id ) {
401
+
402
+ $this->_my_screen_id = $id;
403
+
404
+ }
405
+
406
+
407
+ /**
408
+ * get screen id
409
+ *
410
+ * @since PPF01
411
+ * @return string
412
+ * @access public
413
+ */
414
+ public function get_screen_id() {
415
+
416
+ return $this->_my_screen_id;
417
+
418
+ }
419
+
420
+
421
+ /**
422
+ * show admin notice to ask for rating
423
+ * this function does not show the notice immediately
424
+ * this function just needs to be called and it takes care of everything
425
+ *
426
+ * @since PPF01
427
+ * @param array $content array of texts to show
428
+ * string $title => e.g. 'Are you happy with the example plugin?'
429
+ * string $subtitle => e.g. 'You've been using this plugin for a while now. Would be great to get some feedback!'
430
+ * string $button_yes => e.g. 'Yes, I'm happy with it'
431
+ * string $button_no => e.g. 'Not really'
432
+ * string $button_later => e.g. 'Ask me later'
433
+ * string $button_close => e.g. 'Never show again'
434
+ * string $like => e.g. 'I'm really glad you like it. I do not ask for a donation. All I'm asking you for is to give it a good rating. Thank you very much. If you like, you can follow me on facebook.
435
+ * string $button_rate => e.g. 'Yes, I'd like to rate it'
436
+ * string $button_fb => e.g. 'Open Facebook page'
437
+ * string $dislike => e.g. 'I'm really sorry you don't like it. Would you please do me a favor and drop me line, why you are not happy with it? Maybe I can do better...'
438
+ * string $button_contact => e.g. 'Yes sure'
439
+ * @param array $links array of links
440
+ * string $rate => e.g. https://wordpress.org/support/plugin/example/reviews/
441
+ * string $contact => e.g. https://petersplugins.com/contact/
442
+ * string $facebook => e.g.https://www.facebook.com/petersplugins/
443
+ * @access public
444
+ */
445
+ public function init_rating_notice( $content, $links ) {
446
+
447
+ // quit immediately if message has already been closed
448
+ if ( 'YES' == $this->core()->data_get( 'ask_rating_closed' ) ) {
449
+ return;
450
+ }
451
+
452
+ $show_notice_start = $this->core()->data_get( 'ask_rating_start' );
453
+
454
+ // if start date is not set, set it and quit immediately
455
+ if ( false === $show_notice_start ) {
456
+ $this->core()->data_set( 'ask_rating_start', time() + 30 * DAY_IN_SECONDS );
457
+ $this->core()->data_save();
458
+ return;
459
+ }
460
+
461
+ // quit immediately if start date is not reached yet
462
+ if ( time() < $show_notice_start ) {
463
+ return;
464
+ }
465
+
466
+ // quit immediately if current user is not an admin
467
+ if ( ! current_user_can( 'manage_options' ) ) {
468
+ return;
469
+ }
470
+
471
+ $prefix = 'pp-' . $this->core()->get_plugin_slug();
472
+ $nonce = wp_create_nonce( $prefix );
473
+
474
+ // prepare to show notice
475
+ add_action( 'admin_notices', function() use( $content, $links, $prefix, $nonce ) {
476
+
477
+ // show notice only on certain pages
478
+ // it's not possible to check this earlier, because we need the id of the current screen for that
479
+ if ( ! in_array( get_current_screen()->id, array( 'dashboard', 'themes', 'plugins', 'options-general' , $this->get_screen_id() ) ) ) {
480
+ return;
481
+ }
482
+
483
+
484
+ ?>
485
+ <div class="notice notice-info" id="<?php echo $prefix; ?>-review-notice">
486
+ <h3 style="margin-bottom: 0"><?php echo $content['title']; ?></h3>
487
+ <div class="<?php echo $prefix; ?>-review-notice-container">
488
+ <div id="<?php echo $prefix; ?>-review-step-1" class="<?php echo $prefix; ?>-review-notice-step">
489
+ <p><?php echo $content['subtitle']; ?></p>
490
+ <p><a id="<?php echo $prefix; ?>-review-happy" class="button button-primary" href="javascript:void(0);"><?php echo $content['button_yes']; ?></a> <a id="<?php echo $prefix; ?>-review-unhappy" class="button" href="javascript:void(0);"><?php echo $content['button_no']; ?></a></p>
491
+ </div>
492
+ <div id="<?php echo $prefix; ?>-review-step-like" class="<?php echo $prefix; ?>-review-notice-step">
493
+ <p><?php echo $content['like']; ?></p>
494
+ <p><a class="button button-primary" href="<?php echo $links['rate']; ?>"><?php echo $content['button_rate']; ?></a> <a class="button" href="<?php echo $links['facebook']; ?>"><?php echo $content['button_fb']; ?></a></p>
495
+ </div>
496
+ <div id="<?php echo $prefix; ?>-review-step-dislike" class="<?php echo $prefix; ?>-review-notice-step">
497
+ <p><?php echo $content['dislike']; ?></p>
498
+ <p><a class="button button-primary" href="<?php echo $links['contact']; ?>"><?php echo $content['button_contact']; ?></a></p>
499
+ </div>
500
+ </div>
501
+ <p class="wp-clearfix"><a id="<?php echo $prefix; ?>-review-later" class="<?php echo $prefix; ?>-review-action" href="javascript:void(0);"><?php echo $content['button_later']; ?></a> <a id="<?php echo $prefix; ?>-review-close" class="<?php echo $prefix; ?>-review-action" href="javascript:void(0);"><?php echo $content['button_close']; ?></a></p>
502
+
503
+ <style type="text/css">
504
+ #<?php echo $prefix; ?>-review-step-like, #<?php echo $prefix; ?>-review-step-dislike {
505
+ display: none;
506
+ }
507
+ #<?php echo $prefix; ?>-review-later, #<?php echo $prefix; ?>-review-close, #<?php echo $prefix; ?>-review-later:before, #<?php echo $prefix; ?>-review-close:before {
508
+ display: block;
509
+ height: 20px;
510
+ line-height: 20px;
511
+ text-decoration: none;
512
+ }
513
+ #<?php echo $prefix; ?>-review-later, #<?php echo $prefix; ?>-review-close {
514
+ float: left;
515
+ position: relative;
516
+ padding-left: 22px;
517
+ }
518
+ #<?php echo $prefix; ?>-review-later {
519
+ margin-right: 12px;
520
+ }
521
+ #<?php echo $prefix; ?>-review-later:before, #<?php echo $prefix; ?>-review-close:before {
522
+ font-family: dashicons;
523
+ font-size: 20px;
524
+ position: absolute;
525
+ left: 0;
526
+ top: 0;
527
+ }
528
+ #<?php echo $prefix; ?>-review-later:before {
529
+ content: "\f508";
530
+ }
531
+ #<?php echo $prefix; ?>-review-close:before {
532
+ content: "\f153";
533
+ }
534
+ </style>
535
+
536
+ <script type="text/javascript">
537
+ jQuery( function( $ ) {
538
+
539
+ $( "#<?php echo $prefix; ?>-review-happy" ).click( function() {
540
+ $( "#<?php echo $prefix; ?>-review-step-1" ).fadeOut( 400, function() {
541
+ $( "#<?php echo $prefix; ?>-review-step-like" ).fadeIn();
542
+ });
543
+ } );
544
+
545
+ $( "#<?php echo $prefix; ?>-review-unhappy" ).click( function() {
546
+ $( "#<?php echo $prefix; ?>-review-step-1" ).fadeOut( 400, function() {
547
+ $( "#<?php echo $prefix; ?>-review-step-dislike" ).fadeIn();
548
+ });
549
+ } );
550
+
551
+ $( ".<?php echo $prefix; ?>-review-action" ).click( function() {
552
+
553
+ $.post(
554
+ ajaxurl, {
555
+ action : "<?php echo $prefix; ?>-review-action",
556
+ command : $(this).attr( "id" ),
557
+ securekey : "<?php echo $nonce; ?>"
558
+ }
559
+ );
560
+ $( "#<?php echo $prefix; ?>-review-notice" ).fadeOut();
561
+
562
+ } );
563
+
564
+ } );
565
+ </script>
566
+
567
+ </div>
568
+ <?php
569
+
570
+ } );
571
+
572
+
573
+ // prepare for ajax
574
+ add_action( 'wp_ajax_' . $prefix . '-review-action', function() use( $prefix ) {
575
+
576
+ check_ajax_referer( $prefix, 'securekey' ); // dies if check fails
577
+
578
+ if ( isset( $_POST['command'] ) ) {
579
+
580
+ if ( $prefix . '-review-later' == $_POST['command'] ) {
581
+
582
+ // move start date 14 days into future
583
+ $this->core()->data_set( 'ask_rating_start', time() + 14 * DAY_IN_SECONDS );
584
+ $this->core()->data_save();
585
+
586
+ }
587
+
588
+ if ( $prefix . '-review-close' == $_POST['command'] ) {
589
+
590
+ // do not show notice again
591
+ $this->core()->data_set( 'ask_rating_closed', 'YES' );
592
+ $this->core()->data_save();
593
+
594
+ }
595
+
596
+ }
597
+
598
+ wp_die();
599
+
600
+ } );
601
+
602
+ }
603
+
604
+ }
605
+
606
+ }
inc/ppf/ppf-class.php ADDED
@@ -0,0 +1,155 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Base Class
5
+ *
6
+ * Peter's Plugins Foundation 01
7
+ *
8
+ * @package PPF01
9
+ * @author Peter Raschendorfer
10
+ * @license GPL2+
11
+ */
12
+
13
+
14
+ // No need to check this in all files
15
+ if ( ! defined( 'WPINC' ) ) {
16
+
17
+ die;
18
+
19
+ }
20
+
21
+
22
+ if ( !class_exists( 'PPF01_Class' ) ) {
23
+
24
+
25
+ abstract class PPF01_Class {
26
+
27
+
28
+ /**
29
+ * foundation dir
30
+ *
31
+ * @since PPF01
32
+ * @var string
33
+ * @access private
34
+ */
35
+ private $_dir;
36
+
37
+
38
+ /**
39
+ * Init the Class
40
+ *
41
+ * @since PPF01
42
+ * @see getInstance
43
+ */
44
+ public function __construct() {
45
+
46
+ $ca = class_parents( $this );
47
+ $rc = new ReflectionClass( end( $ca ) );
48
+ $this->_dir = dirname($rc->getFileName());
49
+
50
+ }
51
+
52
+
53
+ /**
54
+ * get doundation directory
55
+ *
56
+ * @since PPF01
57
+ * @access protected
58
+ * @return string
59
+ */
60
+ protected function get_foundation_dir() {
61
+
62
+ return $this->_dir;
63
+
64
+ }
65
+
66
+
67
+ /**
68
+ * get url for foundation asset file
69
+ *
70
+ * @since PPF01
71
+ * @access protected
72
+ * @param string $dir sub-directory of assets dir (js, css)
73
+ * @param string $file filename
74
+ * @return string
75
+ */
76
+ protected function get_foundation_asset_url( $dir, $file ) {
77
+
78
+ return plugins_url() . str_replace( WP_PLUGIN_DIR, '', $this->get_foundation_dir() ) . '/assets/' . $dir . '/' . $file;
79
+
80
+ }
81
+
82
+
83
+ /**
84
+ * get path for foundation asset file
85
+ *
86
+ * @since PPF01
87
+ * @access protected
88
+ * @param string $dir sub-directory of assets dir (js, css)
89
+ * @param string $file filename
90
+ * @return string
91
+ */
92
+ protected function get_foundation_asset_path( $dir, $file ) {
93
+
94
+ return plugin_dir_path( $this->get_foundation_dir() ) . 'assets/' . $dir . '/' . $file;
95
+
96
+ }
97
+
98
+
99
+ /**
100
+ * add action
101
+ *
102
+ * @since PPF01
103
+ * @access public
104
+ * @param string $wpaction name of the action to add
105
+ * @param int $priority priority - optional - default 10
106
+ * @param int $accepted_args number of arguments the function accepts - optional - default 1
107
+ */
108
+ public function add_action( $wpaction, $priority = 10, $accepted_args = 1 ) {
109
+
110
+ add_action( $wpaction, array( $this, 'action_' . $wpaction ), $priority, $accepted_args );
111
+
112
+ }
113
+
114
+
115
+ /**
116
+ * add multiple actions
117
+ * this function does not allow to specify priority and accepted_args
118
+ *
119
+ * @since PPF01
120
+ * @access public
121
+ * @param array $actions array of actions to add
122
+ * @see add_action()
123
+ */
124
+ public function add_actions( $actions ) {
125
+
126
+ foreach ( $actions as $action ) {
127
+
128
+ $this->add_action( $action );
129
+
130
+ }
131
+
132
+ }
133
+
134
+
135
+ /**
136
+ * add filter
137
+ *
138
+ * @since PPF01
139
+ * @access public
140
+ * @param string $wpfilter name of the filter to add
141
+ * @param int $priority priority - optional - default 10
142
+ * @param int $accepted_args number of arguments the function accepts - optional - default 1
143
+ */
144
+ public function add_filter( $wpfilter, $priority = 10, $accepted_args = 1 ) {
145
+
146
+ add_filter( $wpfilter, array( $this, 'filter_' . $wpfilter ), $priority, $accepted_args );
147
+
148
+ }
149
+
150
+
151
+ }
152
+
153
+ }
154
+
155
+ ?>
inc/ppf/ppf-plugin.php ADDED
@@ -0,0 +1,533 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Plugin Base Class
5
+ *
6
+ * Peter's Plugins Foundation 01
7
+ *
8
+ * @package PPF01
9
+ * @author Peter Raschendorfer
10
+ * @license GPL2+
11
+ */
12
+
13
+
14
+ if ( !class_exists( 'PPF01_Plugin' ) ) {
15
+
16
+
17
+ abstract class PPF01_Plugin extends PPF01_Class {
18
+
19
+ /**
20
+ * Instance
21
+ *
22
+ * @since PPF01
23
+ * @var singleton
24
+ * @access protected
25
+ */
26
+ protected static $_instance = null;
27
+
28
+
29
+ /**
30
+ * Plugin Name
31
+ *
32
+ * @since PPF01
33
+ * @var string
34
+ * @access private
35
+ */
36
+ private $plugin_name;
37
+
38
+
39
+ /**
40
+ * Plugin Short Name (for Display)
41
+ *
42
+ * @since PPF01
43
+ * @var string
44
+ * @access private
45
+ */
46
+ private $plugin_shortname;
47
+
48
+
49
+ /**
50
+ * Plugin File
51
+ *
52
+ * @since PPF01
53
+ * @var string
54
+ * @access private
55
+ */
56
+ private $plugin_file;
57
+
58
+
59
+ /**
60
+ * Plugin Base Dir
61
+ *
62
+ * @since PPF01
63
+ * @var string
64
+ * @access private
65
+ */
66
+ private $plugin_dir;
67
+
68
+
69
+ /**
70
+ * Plugin Slug
71
+ *
72
+ * @since PPF01
73
+ * @var string
74
+ * @access private
75
+ */
76
+ private $plugin_slug;
77
+
78
+
79
+ /**
80
+ * Plugin Version
81
+ *
82
+ * @since PPF01
83
+ * @var int
84
+ * @access private
85
+ */
86
+ private $plugin_version;
87
+
88
+
89
+ /**
90
+ * name of plugin data in databse (meta_key)
91
+ *
92
+ * @since PPF01
93
+ * @var string
94
+ * @access private
95
+ */
96
+ private $_data_key;
97
+
98
+
99
+ /**
100
+ * stored data
101
+ *
102
+ * @since PPF01
103
+ * @var array
104
+ * @access private
105
+ */
106
+ private $_data;
107
+
108
+
109
+ /**
110
+ * Settings Class ( if the plugin uses settings )
111
+ *
112
+ * @since PPF01
113
+ * @var object
114
+ * @access private
115
+ */
116
+ private $settings;
117
+
118
+
119
+ /**
120
+ * Init the Class
121
+ *
122
+ * @since PPF01
123
+ * @see getInstance
124
+ */
125
+ protected function __construct( $settings ) {
126
+
127
+ $this->plugin_file = $settings['file'];
128
+ $this->plugin_slug = $settings['slug'];
129
+ $this->plugin_name = $settings['name'];
130
+ $this->plugin_shortname = $settings['shortname'];
131
+ $this->plugin_version = $settings['version'];
132
+
133
+ $this->plugin_dir = dirname( $settings['file'] );
134
+
135
+ $this->_data_key = str_replace( '-', '_', $settings['slug'] ) . '_data';
136
+ $this->data_load();
137
+
138
+ $this->plugin_install_update();
139
+
140
+ $this->plugin_init();
141
+ }
142
+
143
+
144
+
145
+ /**
146
+ * plugin init
147
+ *
148
+ * force to be defined
149
+ *
150
+ * @since PPF01
151
+ */
152
+ abstract public function plugin_init();
153
+
154
+
155
+ /**
156
+ * Prevent Cloning
157
+ *
158
+ * @since PPF01
159
+ */
160
+ protected function __clone() {}
161
+
162
+
163
+ /**
164
+ * Get the Instance
165
+ *
166
+ * @since PPF01
167
+ * @param array $settings {
168
+ * @type string $file Plugin Main File Path and Name
169
+ * @type string $slug Plugin Slug
170
+ * @type string $name Plugin Name
171
+ * @type string $version Plugin Verion
172
+ * }
173
+ * @return singleton
174
+ */
175
+ public static function getInstance( $settings ) {
176
+
177
+ if ( null === static::$_instance ) {
178
+
179
+ static::$_instance = new static( $settings );
180
+
181
+ }
182
+
183
+ return static::$_instance;
184
+
185
+ }
186
+
187
+
188
+ /**
189
+ * get plugin file
190
+ *
191
+ * @since PPF01
192
+ * @access public
193
+ * @return string
194
+ */
195
+ public function get_plugin_file() {
196
+
197
+ return $this->plugin_file;
198
+
199
+ }
200
+
201
+
202
+ /**
203
+ * get plugin slug
204
+ *
205
+ * @since PPF01
206
+ * @access public
207
+ * @return string
208
+ */
209
+ public function get_plugin_slug() {
210
+
211
+ return $this->plugin_slug;
212
+
213
+ }
214
+
215
+
216
+ /**
217
+ * get plugin name
218
+ *
219
+ * @since PPF01
220
+ * @access public
221
+ * @return string
222
+ */
223
+ public function get_plugin_name() {
224
+
225
+ return $this->plugin_name;
226
+
227
+ }
228
+
229
+
230
+ /**
231
+ * get plugin shortname
232
+ *
233
+ * @since PPF01
234
+ * @access public
235
+ * @return string
236
+ */
237
+ public function get_plugin_shortname() {
238
+
239
+ return $this->plugin_shortname;
240
+
241
+ }
242
+
243
+
244
+ /**
245
+ * get plugin version
246
+ *
247
+ * @since PPF01
248
+ * @access public
249
+ * @return string
250
+ */
251
+ public function get_plugin_version() {
252
+
253
+ return $this->plugin_version;
254
+
255
+ }
256
+
257
+
258
+ /**
259
+ * get url for asset file
260
+ *
261
+ * @since PPF01
262
+ * @access public
263
+ * @param string $dir sub-directory of assets dir (js, css)
264
+ * @param string $file filename
265
+ * @return string
266
+ */
267
+ public function get_asset_url( $dir, $file ) {
268
+
269
+ return plugins_url( 'assets/' . $dir . '/' . $file, $this->get_plugin_file() );
270
+
271
+ }
272
+
273
+
274
+ /**
275
+ * get path for asset file
276
+ *
277
+ * @since PPF01
278
+ * @access public
279
+ * @param string $dir sub-directory of assets dir (js, css)
280
+ * @param string $file filename
281
+ * @return string
282
+ */
283
+ public function get_asset_path( $dir, $file ) {
284
+
285
+ return plugin_dir_path( $this->get_plugin_file() ) . 'assets/' . $dir . '/' . $file;
286
+
287
+ }
288
+
289
+
290
+ /**
291
+ * add a sub class
292
+ *
293
+ * @since PPF01
294
+ * @access private
295
+ * @param string $class name of the class
296
+ * @param string $file class file without extension php (must bei located in inc dir)
297
+ * @param object $_core the core class
298
+ * @param object $_settings the settings class (optional)
299
+ * @return class
300
+ */
301
+ private function add_sub_class( $class, $file, $_core, $_settings = false ) {
302
+
303
+ require_once plugin_dir_path( $this->get_plugin_file() ) . 'inc/' . $file . '.php';
304
+ return new $class( $_core, $_settings);
305
+
306
+ }
307
+
308
+
309
+ /**
310
+ * add a sub class as well in frontend as in backend
311
+ *
312
+ * @since PPF01
313
+ * @access public
314
+ * @uses add_sub_class()
315
+ * @return class
316
+ */
317
+ public function add_sub_class_always( $class, $file, $_core, $_settings = false ) {
318
+
319
+ return $this->add_sub_class( $class, $file, $_core, $_settings );
320
+
321
+ }
322
+
323
+
324
+ /**
325
+ * add a sub class only in frontend
326
+ *
327
+ * @since PPF01
328
+ * @access public
329
+ * @uses add_sub_class()
330
+ * @return class or false
331
+ */
332
+ public function add_sub_class_frontend( $class, $file, $_core, $_settings = false ) {
333
+
334
+ if ( ! is_admin() ) {
335
+
336
+ return $this->add_sub_class( $class, $file, $_core, $_settings );
337
+
338
+ }
339
+
340
+ return false;
341
+
342
+ }
343
+
344
+
345
+ /**
346
+ * add a sub class only in backend
347
+ *
348
+ * @since PPF01
349
+ * @access public
350
+ * @uses add_sub_class()
351
+ * @return class or false
352
+ */
353
+ public function add_sub_class_backend( $class, $file, $_core, $_settings = false ) {
354
+
355
+ if ( is_admin() ) {
356
+
357
+ return $this->add_sub_class( $class, $file, $_core, $_settings );
358
+
359
+ }
360
+
361
+ return false;
362
+
363
+ }
364
+
365
+
366
+ /**
367
+ * add the settings class ( if the plugin uses settings )
368
+ *
369
+ * @since PPF01
370
+ * @access public
371
+ * @param string $class name of the class
372
+ * @param string $file class file without extension php (must bei located in inc dir)
373
+ * @param object $_core the core class
374
+ * @param object $defaults the settings defaults
375
+ */
376
+ public function add_settings_class( $class, $file, $_core, $defaults ) {
377
+
378
+ require_once plugin_dir_path( $this->get_plugin_file() ) . 'inc/' . $file . '.php';
379
+ $this->settings = new $class( $_core, $defaults );
380
+
381
+ }
382
+
383
+
384
+ /**
385
+ * get settings class
386
+ *
387
+ * @since PPF01
388
+ * @access public
389
+ * @return object
390
+ */
391
+ public function settings() {
392
+
393
+ return $this->settings;
394
+
395
+ }
396
+
397
+
398
+ /**
399
+ * do plugin install or update
400
+ *
401
+ * @since PPF01
402
+ * @access private
403
+ */
404
+ private function plugin_install_update() {
405
+
406
+ $version = $this->data_get( 'current_version' );
407
+
408
+ if ( false === $version || version_compare( $version, $this->get_plugin_version(), '<' ) ) {
409
+
410
+ if ( false === $version ) {
411
+
412
+ // the plugin was not installed before (or the plugin foundation was not used before...)
413
+
414
+ $this->do_plugin_install();
415
+
416
+ } else {
417
+
418
+ // do updates if needed
419
+ $this->do_plugin_update( $version, $this->get_plugin_version() );
420
+
421
+ }
422
+
423
+ $this->data_set( 'current_version', $this->get_plugin_version() );
424
+ $this->data_save();
425
+
426
+ }
427
+
428
+ }
429
+
430
+
431
+ /**
432
+ * plugin install
433
+ *
434
+ * to be overwritten
435
+ *
436
+ * @since PPF01
437
+ * @access public
438
+ */
439
+ public function do_plugin_install() {}
440
+
441
+
442
+ /**
443
+ * plugin update
444
+ *
445
+ * to be overwritten
446
+ *
447
+ * @since PPF01
448
+ * @access public
449
+ */
450
+ public function do_plugin_update( $stored_version, $actual_version ) {}
451
+
452
+
453
+ /**
454
+ * load plugin data from database
455
+ *
456
+ * @since PPF01
457
+ * @access public
458
+ */
459
+ public function data_load() {
460
+
461
+ $this->_data = get_option( $this->_data_key, array() );
462
+
463
+
464
+ }
465
+
466
+ /**
467
+ * get a data value
468
+ *
469
+ * @since PPF01
470
+ * @param string $key data key
471
+ * @access public
472
+ */
473
+ public function data_get( $key ) {
474
+
475
+ if ( array_key_exists( $key, $this->_data ) ) {
476
+
477
+ return $this->_data[$key];
478
+
479
+ } else {
480
+
481
+ return false;
482
+
483
+ }
484
+
485
+ }
486
+
487
+
488
+ /**
489
+ * set a data value
490
+ *
491
+ * @since PPF01
492
+ * @param string $key data key
493
+ * @param string $value new value
494
+ * @access public
495
+ */
496
+ public function data_set( $key, $value ) {
497
+
498
+ return $this->_data[$key] = $value;
499
+
500
+ }
501
+
502
+
503
+ /**
504
+ * save data to database
505
+ *
506
+ * @since PPF01
507
+ * @access public
508
+ */
509
+ public function data_save() {
510
+
511
+ update_option( $this->_data_key, $this->_data );
512
+
513
+ }
514
+
515
+
516
+ /**
517
+ * remove all data from database
518
+ *
519
+ * @since PPF01
520
+ * @access public
521
+ */
522
+ public function data_remove() {
523
+
524
+ delete_option( $this->_data_key );
525
+
526
+ }
527
+
528
+
529
+ }
530
+
531
+ }
532
+
533
+ ?>
inc/ppf/ppf-settings.php ADDED
@@ -0,0 +1,206 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Settings Class
5
+ *
6
+ * Peter's Plugins Foundation 01
7
+ *
8
+ * @package PPF01
9
+ * @author Peter Raschendorfer
10
+ * @license GPL2+
11
+ */
12
+
13
+ if ( !class_exists( 'PPF01_Settings' ) ) {
14
+
15
+
16
+ abstract class PPF01_Settings extends PPF01_SubClass {
17
+
18
+ /**
19
+ * name of settings in databse (meta_key)
20
+ *
21
+ * @since PPF01
22
+ * @var string
23
+ * @access private
24
+ */
25
+ private $_key;
26
+
27
+
28
+ /**
29
+ * current settings
30
+ *
31
+ * @since PPF01
32
+ * @var array
33
+ * @access private
34
+ */
35
+ private $_settings;
36
+
37
+
38
+ /**
39
+ * settings defaults
40
+ *
41
+ * @since PPF01
42
+ * @var array
43
+ * @access private
44
+ */
45
+ private $_defaults;
46
+
47
+
48
+ /**
49
+ * Init the Class
50
+ *
51
+ * @since PPF01
52
+ * @access public
53
+ */
54
+ public function __construct( $_core, $defaults ) {
55
+
56
+ parent::__construct( $_core, false );
57
+
58
+ $this->_key = $this->get_option_name();
59
+ $this->_defaults = $defaults;
60
+ $this->load();
61
+
62
+ }
63
+
64
+
65
+ /**
66
+ * Sub-Class init
67
+ * do nothing
68
+ *
69
+ * @since PPF01
70
+ * @access public
71
+ */
72
+ public function init() {
73
+ }
74
+
75
+
76
+ /**
77
+ * get option name for settings
78
+ *
79
+ * @since PPF01
80
+ * @access public
81
+ * @return string option name
82
+ */
83
+ public function get_option_name() {
84
+
85
+ return str_replace( '-', '_', $this->core()->get_plugin_slug() ) . '_settings';
86
+
87
+ }
88
+
89
+
90
+ /**
91
+ * load settings from database
92
+ * settings are automatically loaded, but reload can be forced from outside
93
+ *
94
+ * @since PPF01
95
+ * @access public
96
+ */
97
+ public function load() {
98
+
99
+ $this->_settings = get_option( $this->_key, array() );
100
+ $this->_settings = wp_parse_args( $this->_settings, $this->_defaults );
101
+ $this->sanitize_settings();
102
+
103
+ }
104
+
105
+
106
+ /**
107
+ * sanitize settings
108
+ * this function can be used to sanitize settings after they are loaded
109
+ *
110
+ * @since PPF01
111
+ * @access private
112
+ */
113
+ private function sanitize_settings() {
114
+
115
+ // Just to be defined here
116
+
117
+ }
118
+
119
+
120
+ /**
121
+ * get a settings value
122
+ *
123
+ * @since PPF01
124
+ * @param string $key settings key
125
+ * @access public
126
+ */
127
+ public function get( $key ) {
128
+
129
+ return $this->_settings[$key];
130
+
131
+ }
132
+
133
+
134
+ /**
135
+ * set a settings value
136
+ *
137
+ * @since PPF01
138
+ * @param string $key settings key
139
+ * @param string $value new value
140
+ * @access public
141
+ */
142
+ public function set( $key, $value ) {
143
+
144
+ return $this->_settings[$key] = $value;
145
+
146
+ }
147
+
148
+
149
+ /**
150
+ * save settings to database
151
+ *
152
+ * @since PPF01
153
+ * @access public
154
+ */
155
+ public function save() {
156
+
157
+ update_option( $this->_key, $this->_settings );
158
+
159
+ }
160
+
161
+
162
+ /**
163
+ * get option key name for HTML form fields
164
+ *
165
+ * @since PPF01
166
+ * @param string $key settings key
167
+ * @access public
168
+ * @return string option key name
169
+ */
170
+ public function get_option_key_name( $key ) {
171
+
172
+ return $this->get_option_name() . '[' . $key . ']';
173
+
174
+ }
175
+
176
+
177
+ /**
178
+ * get the defaults
179
+ *
180
+ * @since PPF01
181
+ * @access public
182
+ * @return array defaults
183
+ */
184
+ public function get_defaults() {
185
+
186
+ return $this->_defaults;
187
+
188
+ }
189
+
190
+
191
+ /**
192
+ * remove
193
+ *
194
+ * @since PPF01
195
+ * @access public
196
+ */
197
+ public function remove() {
198
+
199
+ delete_option( $this->_key );
200
+
201
+ }
202
+
203
+
204
+ }
205
+
206
+ }
inc/ppf/ppf-subclass.php ADDED
@@ -0,0 +1,95 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Plugin Base Sub-Class
5
+ *
6
+ * Peter's Plugins Foundation 01
7
+ *
8
+ * @package PPF01
9
+ * @author Peter Raschendorfer
10
+ * @license GPL2+
11
+ */
12
+
13
+ if ( !class_exists( 'PPF01_SubClass' ) ) {
14
+
15
+
16
+ abstract class PPF01_SubClass extends PPF01_Class {
17
+
18
+ /**
19
+ * reference to core class
20
+ *
21
+ * @since PPF01
22
+ * @var object
23
+ * @access private
24
+ */
25
+ private $_core;
26
+
27
+
28
+ /**
29
+ * reference to settings class
30
+ *
31
+ * @since PPF01
32
+ * @var object
33
+ * @access private
34
+ */
35
+ private $_settings;
36
+
37
+
38
+ /**
39
+ * Init the Class
40
+ *
41
+ * @since PPF01
42
+ * @access public
43
+ */
44
+ public function __construct( $_core, $_settings = false ) {
45
+
46
+ parent::__construct();
47
+
48
+ $this->_core = $_core;
49
+ $this->_settings = $_settings;
50
+
51
+ $this->init();
52
+
53
+ }
54
+
55
+
56
+ /**
57
+ * Sub-Class init
58
+ *
59
+ * force to be defined
60
+ *
61
+ * @since PPF01
62
+ */
63
+ abstract public function init();
64
+
65
+
66
+ /**
67
+ * get core class
68
+ *
69
+ * @since PPF01
70
+ * @access public
71
+ * @return object
72
+ */
73
+ public function core() {
74
+
75
+ return $this->_core;
76
+
77
+ }
78
+
79
+
80
+ /**
81
+ * get settings class
82
+ *
83
+ * @since PPF01
84
+ * @access public
85
+ * @return object
86
+ */
87
+ public function settings() {
88
+
89
+ return $this->_settings;
90
+
91
+ }
92
+
93
+ }
94
+
95
+ }
loader.php CHANGED
@@ -14,21 +14,16 @@ if ( ! defined( 'WPINC' ) ) {
14
 
15
 
16
  /**
17
- * Load files
 
 
 
 
 
 
 
18
  */
19
  require_once( plugin_dir_path( __FILE__ ) . '/inc/class-404page.php' );
20
- require_once( plugin_dir_path( __FILE__ ) . '/inc/class-404page-settings.php' );
21
-
22
- if ( is_admin() ) {
23
-
24
- // load files only if in admin
25
- // @since 10
26
-
27
- require_once( plugin_dir_path( __FILE__ ) . '/inc/class-404page-admin.php' );
28
- require_once( plugin_dir_path( __FILE__ ) . '/inc/class-404page-block-editor.php' );
29
- require_once( plugin_dir_path( __FILE__ ) . '/inc/class-404page-classic-editor.php' );
30
-
31
- }
32
 
33
 
34
  /**
@@ -37,10 +32,11 @@ if ( is_admin() ) {
37
  function pp_404page() {
38
 
39
  return PP_404Page::getInstance( array(
40
- 'file' => dirname( __FILE__ ) . '/404page.php',
41
- 'slug' => pathinfo( dirname( __FILE__ ) . '/404page.php', PATHINFO_FILENAME ),
42
- 'name' => '404page - your smart custom 404 error page',
43
- 'version' => '10.5'
 
44
  ) );
45
 
46
  }
14
 
15
 
16
  /**
17
+ * Load Plugin Foundation
18
+ * @since 11.0.0
19
+ */
20
+ require_once( plugin_dir_path( __FILE__ ) . '/inc/ppf/loader.php' );
21
+
22
+
23
+ /**
24
+ * Load Plugin Main File
25
  */
26
  require_once( plugin_dir_path( __FILE__ ) . '/inc/class-404page.php' );
 
 
 
 
 
 
 
 
 
 
 
 
27
 
28
 
29
  /**
32
  function pp_404page() {
33
 
34
  return PP_404Page::getInstance( array(
35
+ 'file' => dirname( __FILE__ ) . '/404page.php',
36
+ 'slug' => pathinfo( dirname( __FILE__ ) . '/404page.php', PATHINFO_FILENAME ),
37
+ 'name' => '404page - your smart custom 404 error page',
38
+ 'shortname' => '404page',
39
+ 'version' => '11.0.0'
40
  ) );
41
 
42
  }
readme.txt CHANGED
@@ -3,7 +3,7 @@ Contributors: petersplugins
3
  Tags: page, 404, error, error page, 404 page, page not found, page not found error, 404 error page, missing, broken link, template, 404 link, seo, custom 404, custom 404 page, custom 404 error, custom 404 error page, customize 404, customize 404 page, customize 404 error page, classicpress
4
  Requires at least: 4.0
5
  Tested up to: 5.2
6
- Stable tag: 10.5
7
  Requires PHP: 5.4
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
@@ -12,7 +12,7 @@ Create your custom 404 error page the easy way! No coding. Works with most Theme
12
 
13
  == Description ==
14
 
15
- <strong>With 90,000+ active installations the [404page](https://petersplugins.com/free-wordpress-plugins/404page/) plugin is the most used plugin to create a customized 404 error page in WordPress.</strong>
16
 
17
  Bringing visitors to your website takes time and effort. Every visitor is important. The default 404 error page of most themes do not provide any information on what to find on your site. A first tme visitor, who does not know you, is left in a dead end and leaves your website. Set up a helpful custom 404 error page to keep him on your site.
18
 
@@ -34,7 +34,7 @@ The only requirement for this plugin is that you change the Permalink Structure
34
 
35
  == Docs & Support ==
36
 
37
- [Plugin Manual](http://petersplugins.com/docs/404page/)
38
 
39
  [Support Forum](https://wordpress.org/support/plugin/404page)
40
 
@@ -133,11 +133,10 @@ This plugin is compatible with [ClassicPress](https://www.classicpress.net/).
133
 
134
  == Screenshots ==
135
 
136
- 1. The default 404 error page of the currently used themme (WP Bootstrap Starter used for this example)
137
- 2. Editing the custom 404 error page using the Classic Editor
138
- 3. Editing the custom 404 error page using the Block Editor (Gutenberg)
139
- 4. Select the created page as 404 error page
140
- 5. The custom 404 error page in action
141
 
142
  == Frequently Asked Questions ==
143
 
@@ -158,6 +157,9 @@ Please use the [Support Forum](https://wordpress.org/support/plugin/404page).
158
 
159
  == Changelog ==
160
 
 
 
 
161
  = 10.5 (2019-04-01) =
162
  * some more security improvements
163
 
@@ -290,6 +292,9 @@ Please use the [Support Forum](https://wordpress.org/support/plugin/404page).
290
 
291
  == Upgrade Notice ==
292
 
 
 
 
293
  = 10.5 =
294
  some more security improvements
295
 
3
  Tags: page, 404, error, error page, 404 page, page not found, page not found error, 404 error page, missing, broken link, template, 404 link, seo, custom 404, custom 404 page, custom 404 error, custom 404 error page, customize 404, customize 404 page, customize 404 error page, classicpress
4
  Requires at least: 4.0
5
  Tested up to: 5.2
6
+ Stable tag: 11.0.0
7
  Requires PHP: 5.4
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
12
 
13
  == Description ==
14
 
15
+ <strong>With 100,000+ active installations the [404page](https://petersplugins.com/404page/) plugin is the most used plugin to create a customized 404 error page in WordPress.</strong>
16
 
17
  Bringing visitors to your website takes time and effort. Every visitor is important. The default 404 error page of most themes do not provide any information on what to find on your site. A first tme visitor, who does not know you, is left in a dead end and leaves your website. Set up a helpful custom 404 error page to keep him on your site.
18
 
34
 
35
  == Docs & Support ==
36
 
37
+ [Plugin Manual](https://petersplugins.com/404page/manual/)
38
 
39
  [Support Forum](https://wordpress.org/support/plugin/404page)
40
 
133
 
134
  == Screenshots ==
135
 
136
+ 1. The default 404 error page of the Twenty Nineteen theme
137
+ 2. Create a custom 404 error page
138
+ 3. Select the created page as 404 error page
139
+ 4. The custom 404 error page in action
 
140
 
141
  == Frequently Asked Questions ==
142
 
157
 
158
  == Changelog ==
159
 
160
+ = 11.0.0 (2019-08-13) =
161
+ * mostly rewritten based on my own newly created Plugin Foundation
162
+
163
  = 10.5 (2019-04-01) =
164
  * some more security improvements
165
 
292
 
293
  == Upgrade Notice ==
294
 
295
+ = 11.0.0 =
296
+ now uses my own Plugin Foundation
297
+
298
  = 10.5 =
299
  some more security improvements
300