diff --git a/includes/class-autoloader.php b/includes/class-autoloader.php
new file mode 100644
index 0000000..641f7f6
--- /dev/null
+++ b/includes/class-autoloader.php
@@ -0,0 +1,106 @@
+prefix = $prefix;
+ $this->prefix_length = \strlen( $prefix );
+ $this->path = \rtrim( $path . '/' );
+ }
+
+ /**
+ * Registers Autoloader's autoload function.
+ *
+ * @throws \Exception When autoload_function cannot be registered.
+ *
+ * @param string $prefix Namespace prefix all classes have in common.
+ * @param string $path Path to the files to be loaded.
+ */
+ public static function register_path( $prefix, $path ) {
+ $loader = new self( $prefix, $path );
+ \spl_autoload_register( array( $loader, 'load' ) );
+ }
+
+ /**
+ * Loads a class if its namespace starts with `$this->prefix`.
+ *
+ * @param string $class_name The class to be loaded.
+ */
+ public function load( $class_name ) {
+ if ( \strpos( $class_name, $this->prefix . self::NS_SEPARATOR ) !== 0 ) {
+ return;
+ }
+
+ // Strip prefix from the start (ala PSR-4).
+ $class_name = \substr( $class_name, $this->prefix_length + 1 );
+ $class_name = \strtolower( $class_name );
+ $dir = '';
+
+ $last_ns_pos = \strripos( $class_name, self::NS_SEPARATOR );
+ if ( false !== $last_ns_pos ) {
+ $namespace = \substr( $class_name, 0, $last_ns_pos );
+ $namespace = \str_replace( '_', '-', $namespace );
+ $class_name = \substr( $class_name, $last_ns_pos + 1 );
+ $dir = \str_replace( self::NS_SEPARATOR, DIRECTORY_SEPARATOR, $namespace ) . DIRECTORY_SEPARATOR;
+ }
+
+ $path = $this->path . $dir . 'class-' . \str_replace( '_', '-', $class_name ) . '.php';
+
+ if ( ! \file_exists( $path ) ) {
+ $path = $this->path . $dir . 'interface-' . \str_replace( '_', '-', $class_name ) . '.php';
+ }
+
+ if ( ! \file_exists( $path ) ) {
+ $path = $this->path . $dir . 'trait-' . \str_replace( '_', '-', $class_name ) . '.php';
+ }
+
+ if ( \file_exists( $path ) ) {
+ require_once $path;
+ }
+ }
+}
diff --git a/includes/class-general-settings.php b/includes/class-general-settings.php
index 77cd78f..7f87fe6 100644
--- a/includes/class-general-settings.php
+++ b/includes/class-general-settings.php
@@ -1,18 +1,16 @@
'boolean',
- 'description' => __( 'Single Author Site', 'indieweb' ),
+ 'description' => \__( 'Single Author Site', 'indieweb' ),
'show_in_rest' => true,
- 'default' => is_multi_author() ? 0 : 1,
+ 'default' => \is_multi_author() ? 0 : 1,
)
);
// Set Default Author.
- register_setting(
+ \register_setting(
$section,
'iw_default_author',
array(
'type' => 'integer',
- 'description' => __( 'Default Author ID for this Site', 'indieweb' ),
+ 'description' => \__( 'Default Author ID for this Site', 'indieweb' ),
'show_in_rest' => true,
'default' => 1,
)
);
- register_setting(
+ \register_setting(
$section,
'iw_author_url',
array(
'type' => 'boolean',
- 'description' => __( 'Replace Author URL with User Website URL', 'indieweb' ),
+ 'description' => \__( 'Replace Author URL with User Website URL', 'indieweb' ),
'show_in_rest' => true,
'default' => 1,
)
);
- register_setting(
+ \register_setting(
$section,
'iw_relme_bw',
array(
'type' => 'boolean',
- 'description' => __( 'Black and White Rel-Me Icons', 'indieweb' ),
+ 'description' => \__( 'Black and White Rel-Me Icons', 'indieweb' ),
'show_in_rest' => true,
'default' => 0,
)
@@ -89,56 +87,56 @@ public static function admin_settings() {
// Settings Section.
$section = 'iw_identity_settings';
- add_settings_section(
+ \add_settings_section(
$section, // ID used to identify this section and with which to register options.
- __( 'Identity Settings', 'indieweb' ), // Title to be displayed on the administration page.
- array( 'IndieWeb_General_Settings', 'identity_options_callback' ), // Callback used to render the description of the section.
+ \__( 'Identity Settings', 'indieweb' ), // Title to be displayed on the administration page.
+ array( self::class, 'identity_options_callback' ), // Callback used to render the description of the section.
$page // Page on which to add this section of options.
);
- add_settings_field(
+ \add_settings_field(
'iw_single_author', // ID used to identify the field throughout the theme.
'Single Author Site', // The label to the left of the option interface element.
- array( 'IndieWeb_General_Settings', 'checkbox_callback' ), // The name of the function responsible for rendering the option interface.
+ array( self::class, 'checkbox_callback' ), // The name of the function responsible for rendering the option interface.
$page, // The page on which this option will be displayed.
$section, // The name of the section to which this field belongs.
array( // The array of arguments to pass to the callback. In this case, just a description.
'name' => 'iw_single_author',
- 'description' => __( 'If this website represents a single individual or entity, check this. This setting is disabled if you only have one user who has made a post.', 'indieweb' ),
- 'disabled' => ! is_multi_author(),
+ 'description' => \__( 'If this website represents a single individual or entity, check this. This setting is disabled if you only have one user who has made a post.', 'indieweb' ),
+ 'disabled' => ! \is_multi_author(),
)
);
- add_settings_field(
+ \add_settings_field(
'iw_default_author', // ID used to identify the field throughout the theme.
'Default Author', // The label to the left of the option interface element.
- array( 'IndieWeb_General_Settings', 'default_author_callback' ), // The name of the function responsible for rendering the option interface.
+ array( self::class, 'default_author_callback' ), // The name of the function responsible for rendering the option interface.
$page, // The page on which this option will be displayed.
$section // The name of the section to which this field belongs.
);
- add_settings_field(
+ \add_settings_field(
'iw_author_url', // ID used to identify the field throughout the theme.
- __( 'Use User Website URL for Author', 'indieweb' ), // The label to the left of the option interface element.
- array( 'IndieWeb_General_Settings', 'checkbox_callback' ), // The name of the function responsible for rendering the option interface.
+ \__( 'Use User Website URL for Author', 'indieweb' ), // The label to the left of the option interface element.
+ array( self::class, 'checkbox_callback' ), // The name of the function responsible for rendering the option interface.
$page, // The page on which this option will be displayed.
$section, // The name of the section to which this field belongs.
array( // The array of arguments to pass to the callback. In this case, just a description.
'name' => 'iw_author_url',
- 'description' => __( 'If checked, this will replace the author page URL with the website URL from your user profile.', 'indieweb' ),
+ 'description' => \__( 'If checked, this will replace the author page URL with the website URL from your user profile.', 'indieweb' ),
'disabled' => false,
)
);
- add_settings_field(
+ \add_settings_field(
'iw_relme_bw', // ID used to identify the field throughout the theme.
- __( 'Black and White Icons', 'indieweb' ), // The label to the left of the option interface element.
- array( 'IndieWeb_General_Settings', 'checkbox_callback' ), // The name of the function responsible for rendering the option interface.
+ \__( 'Black and White Icons', 'indieweb' ), // The label to the left of the option interface element.
+ array( self::class, 'checkbox_callback' ), // The name of the function responsible for rendering the option interface.
$page, // The page on which this option will be displayed.
$section, // The name of the section to which this field belongs.
array( // The array of arguments to pass to the callback. In this case, just a description.
'name' => 'iw_relme_bw',
- 'description' => __( 'If checked, the icon colors will not be loaded', 'indieweb' ),
+ 'description' => \__( 'If checked, the icon colors will not be loaded', 'indieweb' ),
'disabled' => false,
)
);
@@ -150,7 +148,7 @@ public static function admin_settings() {
*/
public static function identity_options_callback() {
echo '
';
- esc_html_e(
+ \esc_html_e(
'Using rel=me on a link indicates the link represents the same person or entity as
the current page. On a site with a single author, links to other profiles from their user profile will
appear on the homepage. On a site with multiple authors these links will appear on the author page only.',
@@ -158,7 +156,7 @@ public static function identity_options_callback() {
);
echo '
';
echo '';
- esc_html_e(
+ \esc_html_e(
'The Default Author is the one whose that will be used on the home pages and archive pages. If the single author setting is not set,
on all other pages, the post author links will be used. To display the links, add the
widget, otherwise they will remain hidden. ',
@@ -172,17 +170,17 @@ public static function identity_options_callback() {
*/
public static function general_options_page() {
// If this is not a multi-author site, remove the single author setting.
- if ( ! is_multi_author() ) {
- delete_option( 'iw_single_author' );
+ if ( ! \is_multi_author() ) {
+ \delete_option( 'iw_single_author' );
}
echo '
';
echo ' ';
echo '
';
@@ -194,16 +192,16 @@ public static function general_options_page() {
* @param array $args Field arguments.
*/
public static function checkbox_callback( array $args ) {
- $option = get_option( $args['name'] );
+ $option = \get_option( $args['name'] );
$disabled = isset( $args['disabled'] ) ? $args['disabled'] : false;
$checked = $option;
- echo " ";
- echo " ';
+ echo " ";
+ echo " ';
if ( array_key_exists( 'description', $args ) ) {
- echo '' . esc_html( $args['description'] ) . ' ';
+ echo '' . \esc_html( $args['description'] ) . ' ';
}
}
@@ -211,21 +209,21 @@ public static function checkbox_callback( array $args ) {
* Render the default author dropdown.
*/
public static function default_author_callback() {
- $users = get_users(
+ $users = \get_users(
array(
'orderby' => 'ID',
'fields' => array( 'ID', 'display_name' ),
)
);
- $option = get_option( 'iw_default_author' );
+ $option = \get_option( 'iw_default_author' );
?>
- ID ); ?>>
+ ID ); ?>>
display_name );
+ echo \esc_html( $user->display_name );
?>
diff --git a/includes/class-hcard-author-widget.php b/includes/class-hcard-author-widget.php
deleted file mode 100755
index fda4e1b..0000000
--- a/includes/class-hcard-author-widget.php
+++ /dev/null
@@ -1,156 +0,0 @@
- 'hcard_widget',
- 'description' => __( 'A widget that allows you to display author profile marked up as an h-card', 'indieweb' ),
- 'show_instance_in_rest' => true,
- )
- );
- }
-
- /**
- * Front-end display of widget.
- *
- * @see WP_Widget::widget()
- *
- * @param array $args Widget arguments.
- * @param array $instance Saved values from database.
- */
- public function widget( $args, $instance ) {
- if ( 1 === (int) get_option( 'iw_single_author' ) ) {
- $display_author = get_option( 'iw_default_author' );
- } elseif ( is_single() ) {
- global $wp_query;
- $display_author = $wp_query->post->post_author;
- } else {
- return;
- }
-
- $user_info = get_userdata( $display_author );
-
- // phpcs:ignore
- echo $args['before_widget'];
-
- ?>
-
-
-
-
-
- $v ) {
- if ( in_array( $k, array( 'notes', 'location', 'avatar' ), true ) ) {
- $v = (int) $v;
- }
- $instance[ $k ] = wp_strip_all_tags( $v );
- }
-
- // Apply changes to checkboxes which are unchecked when absent from the POST.
- $instance['reveal_email'] = isset( $new_instance['reveal_email'] ) ? 'on' : '';
-
- return $instance;
- }
-
-
- /**
- * Create the form for the Widget admin.
- *
- * @see WP_Widget::form()
- *
- * @param array $instance Previously saved values from database.
- */
- public function form( $instance ) {
-
- // Set up some default widget settings.
- $defaults = array(
- 'avatar' => 1,
- 'location' => 1,
- 'notes' => 1,
- 'avatar_size' => '125',
- 'email' => 0,
- 'me' => 0,
- );
-
- $instance = wp_parse_args( (array) $instance, $defaults );
- ?>
-
-
-
-
-
-
-
- />
-
-
-
-
- />
-
-
-
-
- />
-
-
-
-
- />
-
-
-
-
- />
-
- initialized ) {
+ return;
+ }
+
+ // Enqueue styles.
+ \add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_style' ) );
+ \add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_style' ) );
+
+ // Admin menu and settings.
+ \add_action( 'admin_menu', array( $this, 'add_menu_item' ), 9 );
+ \add_action( 'admin_menu', array( General_Settings::class, 'admin_menu' ) );
+ \add_action( 'admin_menu', array( General_Settings::class, 'admin_settings' ), 11 );
+ \add_action( 'admin_init', array( $this, 'privacy_declaration' ) );
+
+ // General Settings.
+ \add_action( 'init', array( General_Settings::class, 'register_settings' ) );
+
+ // Third party integrations.
+ \add_action( 'init', array( Integrations::class, 'init' ) );
+
+ // H-Card support.
+ \add_action( 'init', array( User::class, 'init' ) );
+ \add_action( 'widgets_init', array( User::class, 'init_widgets' ) );
+ \add_action( 'widgets_init', array( Author_Widget::class, 'register' ) );
+
+ // We're up and running.
+ \do_action( 'indieweb_loaded' );
+
+ $this->initialized = true;
+ }
+
+ /**
+ * Get the plugin version.
+ *
+ * @return string
+ */
+ public function get_version() {
+ return INDIEWEB_VERSION;
+ }
+
+ /**
+ * Enqueue frontend styles.
+ */
+ public function enqueue_style() {
+ if ( '1' === \get_option( 'iw_relme_bw' ) ) {
+ \wp_enqueue_style( 'indieweb', INDIEWEB_PLUGIN_URL . 'static/css/indieweb-bw.css', array(), $this->get_version() );
+ } else {
+ \wp_enqueue_style( 'indieweb', INDIEWEB_PLUGIN_URL . 'static/css/indieweb.css', array(), $this->get_version() );
+ }
+ }
+
+ /**
+ * Enqueue admin styles.
+ */
+ public function enqueue_admin_style() {
+ \wp_enqueue_style( 'indieweb-admin', INDIEWEB_PLUGIN_URL . 'static/css/indieweb-admin.css', array(), $this->get_version() );
+ }
+
+ /**
+ * Add Top Level Menu Item.
+ */
+ public function add_menu_item() {
+ \add_menu_page(
+ 'IndieWeb',
+ 'IndieWeb',
+ 'manage_options',
+ 'indieweb',
+ array( $this, 'getting_started' ),
+ INDIEWEB_PLUGIN_URL . 'static/img/indieweb.svg'
+ );
+ \add_submenu_page(
+ 'indieweb',
+ \__( 'Extensions', 'indieweb' ), // Page title.
+ \__( 'Extensions', 'indieweb' ), // Menu title.
+ 'manage_options', // Access capability.
+ 'indieweb-installer',
+ array( $this, 'plugin_installer' )
+ );
+ $this->change_menu_title();
+ }
+
+ /**
+ * Changes the menu title.
+ */
+ public function change_menu_title() {
+ global $submenu;
+ if ( isset( $submenu['indieweb'] ) && \current_user_can( 'manage_options' ) ) {
+ // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
+ $submenu['indieweb'][0][0] = \__( 'Getting Started', 'indieweb' );
+ }
+ }
+
+ /**
+ * Callback from `add_plugins_page()` that shows the "Getting Started" page.
+ */
+ public function getting_started() {
+ require_once INDIEWEB_PLUGIN_DIR . '/includes/getting-started.php';
+ }
+
+ /**
+ * Render the plugin installer page.
+ */
+ public function plugin_installer() {
+ echo '' . \esc_html__( 'IndieWeb Plugin Installer', 'indieweb' ) . ' ';
+ echo '' . \esc_html__( 'The below plugins are recommended to enable additional IndieWeb functionality.', 'indieweb' ) . '
';
+ Plugin_Installer::init( $this->register_plugins() );
+ }
+
+ /**
+ * Register the required plugins.
+ */
+ public function register_plugins() {
+ $plugin_array = array(
+ array(
+ 'slug' => 'webmention',
+ ),
+ array(
+ 'slug' => 'micropub',
+ ),
+ array(
+ 'slug' => 'indieweb-post-kinds',
+ ),
+ array(
+ 'slug' => 'syndication-links',
+ ),
+ array(
+ 'slug' => 'indieauth',
+ ),
+ array(
+ 'slug' => 'simple-location',
+ ),
+ array(
+ 'slug' => 'pubsubhubbub',
+ ),
+ array(
+ 'slug' => 'indieblocks',
+ ),
+ );
+ return $plugin_array;
+ }
+
+ /**
+ * Add privacy policy content.
+ */
+ public function privacy_declaration() {
+ if ( \function_exists( 'wp_add_privacy_policy_content' ) ) {
+ $content = \__(
+ 'Users can optionally add additional information to their profile. As this is part of your user profile you have control of this information and can remove
+ it at your discretion.',
+ 'indieweb'
+ );
+ \wp_add_privacy_policy_content(
+ 'Indieweb',
+ \wp_kses_post( \wpautop( $content, false ) )
+ );
+ }
+ }
+}
diff --git a/includes/class-integrations.php b/includes/class-integrations.php
index 4e9d72e..94f41fc 100644
--- a/includes/class-integrations.php
+++ b/includes/class-integrations.php
@@ -1,22 +1,22 @@
-
-
- sanitize_file_name( $plugin['slug'] ),
- 'fields' => array(
- 'short_description' => true,
- 'sections' => false,
- 'requires' => false,
- 'downloaded' => true,
- 'last_updated' => false,
- 'added' => false,
- 'tags' => false,
- 'compatibility' => false,
- 'homepage' => false,
- 'donate_link' => false,
- 'icons' => true,
- 'banners' => true,
- ),
- )
- );
-
- if ( ! is_wp_error( $api ) ) { // Confirm error free.
-
- $main_plugin_file = self::get_plugin_file( $plugin['slug'] ); // Get main plugin file.
- if ( self::check_file_extension( $main_plugin_file ) ) { // Check file extension.
- if ( is_plugin_active( $main_plugin_file ) ) {
- // Plugin activation, confirmed!
- $button_classes = 'button disabled';
- $button_text = __( 'Activated', 'indieweb' );
- } else {
- // It's installed, let's activate it.
- $button_classes = 'activate button button-primary';
- $button_text = __( 'Activate', 'indieweb' );
- }
- }
-
- // Send plugin data to template.
- self::render_template( $plugin, $api, $button_text, $button_classes );
-
- }
-
- endforeach;
- ?>
-
- icons['1x'] ) ) {
- $icon = $api->icons['1x'];
- } else {
- $icon = $api->icons['default'];
- }
-
- $install_url = add_query_arg(
- array(
- 'action' => 'install-plugin',
- 'plugin' => $api->slug,
- '_wpnonce' => wp_create_nonce( 'install-plugin_' . $api->slug ),
- ),
- get_admin_url( null, '/update.php' )
- );
- ?>
-
-
-
-
name ); ?>
-
short_description ); ?>
-
-
author, array( 'a' => array( 'href' => array() ) ) ); ?>
-
-
-
-
- $nonce = isset( $_POST['nonce'] ) ? sanitize_text_field( wp_unslash( $_POST['nonce'] ) ) : '';
- $plugin = isset( $_POST['plugin'] ) ? sanitize_key( wp_unslash( $_POST['plugin'] ) ) : '';
+
+ $plugin,
+ 'slug' => \sanitize_file_name( $plugin['slug'] ),
'fields' => array(
- 'short_description' => false,
+ 'short_description' => true,
'sections' => false,
'requires' => false,
- 'rating' => false,
- 'ratings' => false,
- 'downloaded' => false,
+ 'downloaded' => true,
'last_updated' => false,
'added' => false,
'tags' => false,
'compatibility' => false,
'homepage' => false,
'donate_link' => false,
+ 'icons' => true,
+ 'banners' => true,
),
)
);
- $skin = new WP_Ajax_Upgrader_Skin();
- $upgrader = new Plugin_Upgrader( $skin );
- $upgrader->install( $api->download_link );
+ if ( ! \is_wp_error( $api ) ) { // Confirm error free.
+
+ $main_plugin_file = self::get_plugin_file( $plugin['slug'] ); // Get main plugin file.
+ if ( self::check_file_extension( $main_plugin_file ) ) { // Check file extension.
+ if ( \is_plugin_active( $main_plugin_file ) ) {
+ // Plugin activation, confirmed!
+ $button_classes = 'button disabled';
+ $button_text = \__( 'Activated', 'indieweb' );
+ } else {
+ // It's installed, let's activate it.
+ $button_classes = 'activate button button-primary';
+ $button_text = \__( 'Activate', 'indieweb' );
+ }
+ }
+
+ // Send plugin data to template.
+ self::render_template( $plugin, $api, $button_text, $button_classes );
- if ( $api->name ) {
- $status = 'success';
- $msg = $api->name . ' successfully installed.';
- } else {
- $status = 'failed';
- $msg = 'There was an error installing ' . $api->name . '.';
}
- $json = array(
- 'status' => $status,
- 'msg' => $msg,
- );
+ endforeach;
+ ?>
+
+ icons['1x'] ) ) {
+ $icon = $api->icons['1x'];
+ } else {
+ $icon = $api->icons['default'];
}
+ $install_url = \add_query_arg(
+ array(
+ 'action' => 'install-plugin',
+ 'plugin' => $api->slug,
+ '_wpnonce' => \wp_create_nonce( 'install-plugin_' . $api->slug ),
+ ),
+ \get_admin_url( null, '/update.php' )
+ );
+ ?>
+
+
+
+
name ); ?>
+
short_description ); ?>
+
+
author, array( 'a' => array( 'href' => array() ) ) ); ?>
+
+
+
+ $plugin,
- 'fields' => array(
- 'short_description' => false,
- 'sections' => false,
- 'requires' => false,
- 'rating' => false,
- 'ratings' => false,
- 'downloaded' => false,
- 'last_updated' => false,
- 'added' => false,
- 'tags' => false,
- 'compatibility' => false,
- 'homepage' => false,
- 'donate_link' => false,
- ),
- )
- );
+ // Check our nonce, if they don't match then bounce!
+ if ( ! \wp_verify_nonce( $nonce, 'cnkt_installer_nonce' ) ) {
+ \wp_die( \esc_html( \__( 'Error - unable to verify nonce, please try again.', 'indieweb' ) ) );
+ }
- if ( $api->name ) {
- $main_plugin_file = self::get_plugin_file( $plugin );
- $status = 'success';
- if ( $main_plugin_file ) {
- activate_plugin( $main_plugin_file );
- $msg = $api->name . ' successfully activated.';
- }
- } else {
- $status = 'failed';
- $msg = 'There was an error activating ' . $api->name . '.';
- }
+ // Include required libs for installation.
+ require_once ABSPATH . 'wp-admin/includes/plugin-install.php';
+ require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
+ require_once ABSPATH . 'wp-admin/includes/class-wp-ajax-upgrader-skin.php';
+ require_once ABSPATH . 'wp-admin/includes/class-plugin-upgrader.php';
+
+ // Get Plugin Info.
+ $api = \plugins_api(
+ 'plugin_information',
+ array(
+ 'slug' => $plugin,
+ 'fields' => array(
+ 'short_description' => false,
+ 'sections' => false,
+ 'requires' => false,
+ 'rating' => false,
+ 'ratings' => false,
+ 'downloaded' => false,
+ 'last_updated' => false,
+ 'added' => false,
+ 'tags' => false,
+ 'compatibility' => false,
+ 'homepage' => false,
+ 'donate_link' => false,
+ ),
+ )
+ );
+
+ $skin = new \WP_Ajax_Upgrader_Skin();
+ $upgrader = new \Plugin_Upgrader( $skin );
+ $upgrader->install( $api->download_link );
+
+ if ( $api->name ) {
+ $status = 'success';
+ $msg = $api->name . ' successfully installed.';
+ } else {
+ $status = 'failed';
+ $msg = 'There was an error installing ' . $api->name . '.';
+ }
- $json = array(
- 'status' => $status,
- 'msg' => $msg,
- );
+ $json = array(
+ 'status' => $status,
+ 'msg' => $msg,
+ );
- wp_send_json( $json );
- }
+ \wp_send_json( $json );
+ }
- /**
- * A method to get the main plugin file.
- *
- * @param string $plugin_slug The slug of the plugin.
- * @return string|null The plugin file path or null.
- */
- public static function get_plugin_file( $plugin_slug ) {
- require_once ABSPATH . '/wp-admin/includes/plugin.php'; // Load plugin lib.
- $plugins = get_plugins();
+ /**
+ * Activate plugin via Ajax.
+ */
+ public function cnkt_plugin_activation() {
+ if ( ! \current_user_can( 'install_plugins' ) ) {
+ \wp_die( \esc_html( \__( 'Sorry, you are not allowed to activate plugins on this site.', 'indieweb' ) ) );
+ }
- foreach ( $plugins as $plugin_file => $plugin_info ) {
+ $nonce = isset( $_POST['nonce'] ) ? \sanitize_text_field( \wp_unslash( $_POST['nonce'] ) ) : '';
+ $plugin = isset( $_POST['plugin'] ) ? \sanitize_key( \wp_unslash( $_POST['plugin'] ) ) : '';
- // Get the basename of the plugin e.g. [askismet]/askismet.php.
- $slug = dirname( plugin_basename( $plugin_file ) );
+ // Check our nonce, if they don't match then bounce!
+ if ( ! \wp_verify_nonce( $nonce, 'cnkt_installer_nonce' ) ) {
+ \wp_die( \esc_html( \__( 'Error - unable to verify nonce, please try again.', 'indieweb' ) ) );
+ }
- if ( $slug && $slug === $plugin_slug ) {
- return $plugin_file;
- }
+ // Include required libs for activation.
+ require_once ABSPATH . 'wp-admin/includes/plugin-install.php';
+ require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
+ require_once ABSPATH . 'wp-admin/includes/class-plugin-upgrader.php';
+
+ // Get Plugin Info.
+ $api = \plugins_api(
+ 'plugin_information',
+ array(
+ 'slug' => $plugin,
+ 'fields' => array(
+ 'short_description' => false,
+ 'sections' => false,
+ 'requires' => false,
+ 'rating' => false,
+ 'ratings' => false,
+ 'downloaded' => false,
+ 'last_updated' => false,
+ 'added' => false,
+ 'tags' => false,
+ 'compatibility' => false,
+ 'homepage' => false,
+ 'donate_link' => false,
+ ),
+ )
+ );
+
+ if ( $api->name ) {
+ $main_plugin_file = self::get_plugin_file( $plugin );
+ $status = 'success';
+ if ( $main_plugin_file ) {
+ \activate_plugin( $main_plugin_file );
+ $msg = $api->name . ' successfully activated.';
}
- return null;
+ } else {
+ $status = 'failed';
+ $msg = 'There was an error activating ' . $api->name . '.';
}
- /**
- * A helper to check file extension.
- *
- * @param string $filename The filename of the plugin.
- * @return bool True if PHP file, false otherwise.
- */
- public static function check_file_extension( $filename ) {
- if ( substr( strrchr( $filename, '.' ), 1 ) === 'php' ) {
- // Has .php extension.
- return true;
- } else {
- return false;
+ $json = array(
+ 'status' => $status,
+ 'msg' => $msg,
+ );
+
+ \wp_send_json( $json );
+ }
+
+
+
+
+ /**
+ * A method to get the main plugin file.
+ *
+ * @param string $plugin_slug The slug of the plugin.
+ * @return string|null The plugin file path or null.
+ */
+ public static function get_plugin_file( $plugin_slug ) {
+ require_once ABSPATH . '/wp-admin/includes/plugin.php'; // Load plugin lib.
+ $plugins = \get_plugins();
+
+ foreach ( $plugins as $plugin_file => $plugin_info ) {
+
+ // Get the basename of the plugin e.g. [askismet]/askismet.php.
+ $slug = \dirname( \plugin_basename( $plugin_file ) );
+
+ if ( $slug && $slug === $plugin_slug ) {
+ return $plugin_file;
}
}
+ return null;
+ }
- /**
- * Enqueue admin scripts and scripts localization.
- */
- public function enqueue_scripts() {
- wp_enqueue_script( 'plugin-installer', CNKT_INSTALLER_PATH . 'static/js/installer.js', array( 'jquery' ), IndieWeb_Plugin::$version, true );
- wp_localize_script(
- 'plugin-installer',
- 'cnkt_installer_localize',
- array(
- 'ajax_url' => admin_url( 'admin-ajax.php' ),
- 'admin_nonce' => wp_create_nonce( 'cnkt_installer_nonce' ),
- 'install_now' => __( 'Are you sure you want to install this plugin?', 'indieweb' ),
- 'install_btn' => __( 'Install Now', 'indieweb' ),
- 'activate_btn' => __( 'Activate', 'indieweb' ),
- 'installed_btn' => __( 'Activated', 'indieweb' ),
- )
- );
-
- wp_enqueue_style( 'plugin-installer', CNKT_INSTALLER_PATH . 'static/css/installer.css', array(), IndieWeb_Plugin::$version );
+ /**
+ * A helper to check file extension.
+ *
+ * @param string $filename The filename of the plugin.
+ * @return bool True if PHP file, false otherwise.
+ */
+ public static function check_file_extension( $filename ) {
+ if ( substr( strrchr( $filename, '.' ), 1 ) === 'php' ) {
+ // Has .php extension.
+ return true;
+ } else {
+ return false;
}
}
+ /**
+ * Enqueue admin scripts and scripts localization.
+ */
+ public function enqueue_scripts() {
+ \wp_enqueue_script( 'plugin-installer', CNKT_INSTALLER_PATH . 'static/js/installer.js', array( 'jquery' ), Indieweb::$version, true );
+ \wp_localize_script(
+ 'plugin-installer',
+ 'cnkt_installer_localize',
+ array(
+ 'ajax_url' => \admin_url( 'admin-ajax.php' ),
+ 'admin_nonce' => \wp_create_nonce( 'cnkt_installer_nonce' ),
+ 'install_now' => \__( 'Are you sure you want to install this plugin?', 'indieweb' ),
+ 'install_btn' => \__( 'Install Now', 'indieweb' ),
+ 'activate_btn' => \__( 'Activate', 'indieweb' ),
+ 'installed_btn' => \__( 'Activated', 'indieweb' ),
+ )
+ );
+
+ \wp_enqueue_style( 'plugin-installer', CNKT_INSTALLER_PATH . 'static/css/installer.css', array(), Indieweb::$version );
+ }
+}
+
- // Initialize.
- $connekt_plugin_installer = new IndieWeb_Plugin_Installer();
- $connekt_plugin_installer->start();
-} // End if( class_exists )
+// Initialize.
+$indieweb_plugin_installer = new Plugin_Installer();
+$indieweb_plugin_installer->start();
diff --git a/includes/hcard/class-author-widget.php b/includes/hcard/class-author-widget.php
new file mode 100644
index 0000000..6084834
--- /dev/null
+++ b/includes/hcard/class-author-widget.php
@@ -0,0 +1,155 @@
+ 'hcard_widget',
+ 'description' => \__( 'A widget that allows you to display author profile marked up as an h-card', 'indieweb' ),
+ 'show_instance_in_rest' => true,
+ )
+ );
+ }
+
+ /**
+ * Front-end display of widget.
+ *
+ * @see WP_Widget::widget()
+ *
+ * @param array $args Widget arguments.
+ * @param array $instance Saved values from database.
+ */
+ public function widget( $args, $instance ) {
+ if ( 1 === (int) \get_option( 'iw_single_author' ) ) {
+ $display_author = \get_option( 'iw_default_author' );
+ } elseif ( \is_single() ) {
+ global $wp_query;
+ $display_author = $wp_query->post->post_author;
+ } else {
+ return;
+ }
+
+ $user_info = \get_userdata( $display_author );
+
+ // phpcs:ignore
+ echo $args['before_widget'];
+
+ ?>
+
+
+
+
+
+ $v ) {
+ if ( in_array( $k, array( 'notes', 'location', 'avatar' ), true ) ) {
+ $v = (int) $v;
+ }
+ $instance[ $k ] = \wp_strip_all_tags( $v );
+ }
+
+ // Apply changes to checkboxes which are unchecked when absent from the POST.
+ $instance['reveal_email'] = isset( $new_instance['reveal_email'] ) ? 'on' : '';
+
+ return $instance;
+ }
+
+
+ /**
+ * Create the form for the Widget admin.
+ *
+ * @see WP_Widget::form()
+ *
+ * @param array $instance Previously saved values from database.
+ */
+ public function form( $instance ) {
+
+ // Set up some default widget settings.
+ $defaults = array(
+ 'avatar' => 1,
+ 'location' => 1,
+ 'notes' => 1,
+ 'avatar_size' => '125',
+ 'email' => 0,
+ 'me' => 0,
+ );
+
+ $instance = \wp_parse_args( (array) $instance, $defaults );
+ ?>
+
+
+
+
+
+
+
+ />
+
+
+
+
+ />
+
+
+
+
+ />
+
+
+
+
+ />
+
+
+
+
+ />
+
+ user_url ) ) {
$link = $user_info->user_url;
}
@@ -68,43 +69,43 @@ public static function silos() {
$silos = array(
'github' => array(
'baseurl' => 'https://github.com/%s',
- 'display' => __( 'Github username', 'indieweb' ),
+ 'display' => \__( 'Github username', 'indieweb' ),
),
'twitter' => array(
'baseurl' => 'https://twitter.com/%s',
- 'display' => __( 'X/Twitter username (without @)', 'indieweb' ),
+ 'display' => \__( 'X/Twitter username (without @)', 'indieweb' ),
),
'facebook' => array(
'baseurl' => 'https://www.facebook.com/%s',
- 'display' => __( 'Facebook ID', 'indieweb' ),
+ 'display' => \__( 'Facebook ID', 'indieweb' ),
),
'microblog' => array(
'baseurl' => 'https://micro.blog/%s',
- 'display' => __( 'Micro.blog username', 'indieweb' ),
+ 'display' => \__( 'Micro.blog username', 'indieweb' ),
),
'instagram' => array(
'baseurl' => 'https://www.instagram.com/%s',
- 'display' => __( 'Instagram username', 'indieweb' ),
+ 'display' => \__( 'Instagram username', 'indieweb' ),
),
'flickr' => array(
'baseurl' => 'https://www.flickr.com/people/%s',
- 'display' => __( 'Flickr username', 'indieweb' ),
+ 'display' => \__( 'Flickr username', 'indieweb' ),
),
'bluesky' => array(
'baseurl' => 'https://bsky.app/profile/%s',
- 'display' => __( 'Bluesky Username', 'indieweb' ),
+ 'display' => \__( 'Bluesky Username', 'indieweb' ),
),
'reddit' => array(
'baseurl' => 'https://reddit.com/user/%s',
- 'display' => __( 'Reddit Username', 'indieweb' ),
+ 'display' => \__( 'Reddit Username', 'indieweb' ),
),
'mastodon' => array(
'baseurl' => '%s',
- 'display' => __( 'Mastodon Server (URL)', 'indieweb' ),
+ 'display' => \__( 'Mastodon Server (URL)', 'indieweb' ),
),
);
- return apply_filters( 'wp_relme_silos', $silos );
+ return \apply_filters( 'wp_relme_silos', $silos );
}
@@ -122,8 +123,8 @@ public static function user_contactmethods( $profile_fields ) {
}
// Telephone Number and PGP Key are not silos.
- $profile_fields['tel'] = __( 'Telephone', 'indieweb' );
- $profile_fields['pgp'] = __( 'PGP Key (URL)', 'indieweb' );
+ $profile_fields['tel'] = \__( 'Telephone', 'indieweb' );
+ $profile_fields['pgp'] = \__( 'PGP Key (URL)', 'indieweb' );
return $profile_fields;
}
@@ -135,31 +136,31 @@ public static function user_contactmethods( $profile_fields ) {
public static function address_fields() {
$address = array(
'street_address' => array(
- 'title' => __( 'Street Address', 'indieweb' ),
- 'description' => __( 'Street Number and Name', 'indieweb' ),
+ 'title' => \__( 'Street Address', 'indieweb' ),
+ 'description' => \__( 'Street Number and Name', 'indieweb' ),
),
'extended_address' => array(
- 'title' => __( 'Extended Address', 'indieweb' ),
- 'description' => __( 'Apartment/Suite/Room Name/Number if any', 'indieweb' ),
+ 'title' => \__( 'Extended Address', 'indieweb' ),
+ 'description' => \__( 'Apartment/Suite/Room Name/Number if any', 'indieweb' ),
),
'locality' => array(
- 'title' => __( 'Locality', 'indieweb' ),
- 'description' => __( 'City/State/Village', 'indieweb' ),
+ 'title' => \__( 'Locality', 'indieweb' ),
+ 'description' => \__( 'City/State/Village', 'indieweb' ),
),
'region' => array(
- 'title' => __( 'Region', 'indieweb' ),
- 'description' => __( 'State/County/Province', 'indieweb' ),
+ 'title' => \__( 'Region', 'indieweb' ),
+ 'description' => \__( 'State/County/Province', 'indieweb' ),
),
'postal_code' => array(
- 'title' => __( 'Postal Code', 'indieweb' ),
- 'description' => __( 'Postal Code, such as Zip Code', 'indieweb' ),
+ 'title' => \__( 'Postal Code', 'indieweb' ),
+ 'description' => \__( 'Postal Code, such as Zip Code', 'indieweb' ),
),
'country_name' => array(
- 'title' => __( 'Country Name', 'indieweb' ),
- 'description' => __( 'Country Name', 'indieweb' ),
+ 'title' => \__( 'Country Name', 'indieweb' ),
+ 'description' => \__( 'Country Name', 'indieweb' ),
),
);
- return apply_filters( 'wp_user_address', $address );
+ return \apply_filters( 'wp_user_address', $address );
}
/**
@@ -170,60 +171,60 @@ public static function address_fields() {
public static function extra_fields() {
$extras = array(
'job_title' => array(
- 'title' => __( 'Job Title', 'indieweb' ),
- 'description' => __( 'Title or Role', 'indieweb' ),
+ 'title' => \__( 'Job Title', 'indieweb' ),
+ 'description' => \__( 'Title or Role', 'indieweb' ),
),
'organization' => array(
- 'title' => __( 'Organization', 'indieweb' ),
- 'description' => __( 'Affiliated Organization', 'indieweb' ),
+ 'title' => \__( 'Organization', 'indieweb' ),
+ 'description' => \__( 'Affiliated Organization', 'indieweb' ),
),
'honorific_prefix' => array(
- 'title' => __( 'Honorific Prefix', 'indieweb' ),
- 'description' => __( 'e.g. Mrs., Mr. Dr.', 'indieweb' ),
+ 'title' => \__( 'Honorific Prefix', 'indieweb' ),
+ 'description' => \__( 'e.g. Mrs., Mr. Dr.', 'indieweb' ),
),
);
- return apply_filters( 'wp_user_extrafields', $extras );
+ return \apply_filters( 'wp_user_extrafields', $extras );
}
/**
* Render extended user profile fields.
*
- * @param WP_User $user The user object.
+ * @param \WP_User $user The user object.
*/
public static function extended_user_profile( $user ) {
- echo '' . esc_html__( 'Address', 'indieweb' ) . ' ';
- echo '' . esc_html__( 'Fill in all fields you wish displayed.', 'indieweb' ) . '
';
+ echo '' . \esc_html__( 'Address', 'indieweb' ) . ' ';
+ echo '' . \esc_html__( 'Fill in all fields you wish displayed.', 'indieweb' ) . '
';
echo '';
- echo '' . esc_html__( 'Additional Profile Information', 'indieweb' ) . ' ';
- echo '' . esc_html__( 'Fill in all fields you are wish displayed.', 'indieweb' ) . '
';
+ echo '' . \esc_html__( 'Additional Profile Information', 'indieweb' ) . ' ';
+ echo '' . \esc_html__( 'Fill in all fields you are wish displayed.', 'indieweb' ) . '
';
echo '';
}
/**
* Render a text field for the extended profile.
*
- * @param WP_User $user The user object.
- * @param string $key The field key.
- * @param string $title The field title.
- * @param string $description The field description.
+ * @param \WP_User $user The user object.
+ * @param string $key The field key.
+ * @param string $title The field title.
+ * @param string $description The field description.
*/
public static function extended_profile_text_field( $user, $key, $title, $description ) {
?>
-
+
-
-
+
+
ID );
+ $value = \get_the_author_meta( $key, $user->ID );
if ( is_array( $value ) ) {
$value = implode( "\n", $value );
}
?>
-
+
-
-
+
+
function ( $user ) {
- return get_user_meta( $user['id'], 'first_name', true );
+ return \get_user_meta( $user['id'], 'first_name', true );
},
)
);
@@ -284,27 +285,27 @@ public static function rest_fields() {
* @return bool|void False if permission denied.
*/
public static function save_profile( $user_id ) {
- if ( ! current_user_can( 'edit_user', $user_id ) ) {
+ if ( ! \current_user_can( 'edit_user', $user_id ) ) {
return false;
}
$fields = array_merge( self::extra_fields(), self::address_fields() );
$p = array_filter( $_POST ); // phpcs:ignore
foreach ( $fields as $key => $value ) {
if ( isset( $p[ $key ] ) ) {
- update_user_meta( $user_id, $key, sanitize_text_field( $p[ $key ] ) );
+ \update_user_meta( $user_id, $key, \sanitize_text_field( $p[ $key ] ) );
} else {
- delete_user_meta( $user_id, $key );
+ \delete_user_meta( $user_id, $key );
}
}
if ( isset( $_POST['relme'] ) ) { // phpcs:ignore
$relme = explode( "\n", $_POST['relme'] ); // phpcs:ignore
if ( ! empty( $relme ) ) {
- update_user_meta( $user_id, 'relme', self::clean_urls( $relme ) );
+ \update_user_meta( $user_id, 'relme', self::clean_urls( $relme ) );
} else {
- delete_user_meta( $user_id, 'relme' );
+ \delete_user_meta( $user_id, 'relme' );
}
}
- delete_transient( 'indieweb_mastodon' );
+ \delete_transient( 'indieweb_mastodon' );
}
/**
@@ -318,16 +319,16 @@ public static function clean_url( $url_string ) {
if ( ! filter_var( $url, FILTER_VALIDATE_URL ) ) {
return false;
}
- $host = wp_parse_url( $url, PHP_URL_HOST );
+ $host = \wp_parse_url( $url, PHP_URL_HOST );
if ( ! $host ) {
return false;
}
// Rewrite these to https as needed.
- $secure = apply_filters( 'iwc_rewrite_secure', array( 'facebook.com', 'twitter.com', 'github.com' ) );
+ $secure = \apply_filters( 'iwc_rewrite_secure', array( 'facebook.com', 'twitter.com', 'github.com' ) );
if ( in_array( preg_replace( '/^www\./', '', $host ), $secure, true ) ) {
$url = preg_replace( '/^http:/i', 'https:', $url );
}
- $url = esc_url_raw( $url );
+ $url = \esc_url_raw( $url );
return $url;
}
@@ -341,7 +342,7 @@ public static function clean_url( $url_string ) {
* @uses clean_url
*/
public static function clean_urls( $urls ) {
- $array = array_map( array( 'HCard_User', 'clean_url' ), $urls );
+ $array = array_map( array( self::class, 'clean_url' ), $urls );
return array_filter( array_unique( $array ) );
}
@@ -353,7 +354,7 @@ public static function clean_urls( $urls ) {
*/
public static function get_rel_me( $author_id = null ) {
if ( empty( $author_id ) ) {
- $author_id = get_the_author_meta( 'ID' );
+ $author_id = \get_the_author_meta( 'ID' );
}
if ( empty( $author_id ) || 0 === $author_id ) {
@@ -363,7 +364,7 @@ public static function get_rel_me( $author_id = null ) {
$list = array();
foreach ( self::silos() as $silo => $details ) {
- $socialmeta = get_the_author_meta( $silo, $author_id );
+ $socialmeta = \get_the_author_meta( $silo, $author_id );
if ( ! empty( $socialmeta ) ) {
// If it is not a URL.
@@ -380,7 +381,7 @@ public static function get_rel_me( $author_id = null ) {
}
}
- $relme = get_the_author_meta( 'relme', $author_id );
+ $relme = \get_the_author_meta( 'relme', $author_id );
if ( $relme ) {
if ( ! is_array( $relme ) ) {
@@ -388,7 +389,7 @@ public static function get_rel_me( $author_id = null ) {
}
$relme = self::clean_urls( $relme );
foreach ( $relme as $url ) {
- $list[ preg_replace( '/^www\./', '', wp_parse_url( $url, PHP_URL_HOST ) ) ] = $url;
+ $list[ preg_replace( '/^www\./', '', \wp_parse_url( $url, PHP_URL_HOST ) ) ] = $url;
}
}
return array_unique( $list );
@@ -416,19 +417,19 @@ public static function get_rel_me_list( $author_id = null, $include_rel = false
if ( ! $list ) {
return false;
}
- $author_name = get_the_author_meta( 'display_name', $author_id );
+ $author_name = \get_the_author_meta( 'display_name', $author_id );
$r = array();
foreach ( $list as $silo => $profile_url ) {
- $name = Rel_Me_Domain_Icon_Map::url_to_name( $profile_url );
- $title = Rel_Me_Domain_Icon_Map::get_title( $name );
+ $name = Domain_Icon_Map::url_to_name( $profile_url );
+ $title = Domain_Icon_Map::get_title( $name );
$r[ $silo ] = '' . esc_attr( $silo ) . ' ' . Rel_Me_Domain_Icon_Map::get_icon( $name ) . ' ';
+ $silo . ' url u-url" href="' . \esc_url( $profile_url ) . '" title="' . \esc_attr( $author_name ) . ' @ ' .
+ \esc_attr( $title ) . '">' . \esc_attr( $silo ) . ' ' . Domain_Icon_Map::get_icon( $name ) . '';
}
$r = "\n" . join( " \n", $r ) . " \n ";
- return apply_filters( 'indieweb_rel_me', $r, $author_id, $list ); // phpcs:ignore
+ return \apply_filters( 'indieweb_rel_me', $r, $author_id, $list ); // phpcs:ignore
}
/**
@@ -444,7 +445,7 @@ public static function relme_head_list( $author_id = null ) {
}
$r = array();
foreach ( $list as $silo => $profile_url ) {
- $r[ $silo ] = ' ' . PHP_EOL;
+ $r[ $silo ] = ' ' . PHP_EOL;
}
return join( '', $r );
}
@@ -455,12 +456,12 @@ public static function relme_head_list( $author_id = null ) {
* @return int|null The author ID or null.
*/
public static function get_author() {
- $single_author = get_option( 'iw_single_author' );
- if ( is_front_page() && 1 === (int) $single_author ) {
- return get_option( 'iw_default_author' ); // Set the author ID to default.
- } elseif ( is_author() ) {
- $author = get_user_by( 'slug', get_query_var( 'author_name' ) );
- if ( $author instanceof WP_User ) {
+ $single_author = \get_option( 'iw_single_author' );
+ if ( \is_front_page() && 1 === (int) $single_author ) {
+ return \get_option( 'iw_default_author' ); // Set the author ID to default.
+ } elseif ( \is_author() ) {
+ $author = \get_user_by( 'slug', \get_query_var( 'author_name' ) );
+ if ( $author instanceof \WP_User ) {
return $author->ID;
} else {
return $author;
@@ -478,9 +479,9 @@ public static function pgp() {
if ( ! $author_id ) {
return;
}
- $pgp = get_user_option( 'pgp', $author_id );
+ $pgp = \get_user_option( 'pgp', $author_id );
if ( ! empty( $pgp ) ) {
- printf( ' ', esc_url( $pgp ) );
+ printf( ' ', \esc_url( $pgp ) );
}
}
@@ -512,7 +513,7 @@ public static function get_hcard_display_defaults() {
'email' => false, // Display email.
'me' => true, // Display rel-me links inside h-card.
);
- return apply_filters( 'hcard_display_defaults', $defaults );
+ return \apply_filters( 'hcard_display_defaults', $defaults );
}
/**
@@ -524,31 +525,31 @@ public static function get_hcard_display_defaults() {
* @return string Full path to file.
*/
public static function get_template_file( $file_name ) {
- $theme_template_file = locate_template( 'templates/' . $file_name );
- return $theme_template_file ? $theme_template_file : __DIR__ . '/../templates/' . $file_name;
+ $theme_template_file = \locate_template( 'templates/' . $file_name );
+ return $theme_template_file ? $theme_template_file : \dirname( __DIR__, 2 ) . '/templates/' . $file_name;
}
/**
* Render the h-card for a user.
*
- * @param int|WP_User $user The user ID or object.
- * @param array $args Display arguments.
+ * @param int|\WP_User $user The user ID or object.
+ * @param array $args Display arguments.
* @return string|false The h-card HTML or false.
*/
public static function hcard( $user, $args = array() ) {
if ( ! $user ) {
return false;
}
- $user = new WP_User( $user );
+ $user = new \WP_User( $user );
if ( ! $user ) {
return false;
}
- $args = wp_parse_args( $args, self::get_hcard_display_defaults() );
+ $args = \wp_parse_args( $args, self::get_hcard_display_defaults() );
// Variables are used in the included template file (h-card.php).
// phpcs:disable VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
if ( $args['avatar'] ) {
- $avatar = get_avatar(
+ $avatar = \get_avatar(
$user,
$args['avatar_size'],
'default',
@@ -560,7 +561,7 @@ public static function hcard( $user, $args = array() ) {
} else {
$avatar = '';
}
- $url = $user->has_prop( 'user_url' ) ? $user->get( 'user_url' ) : $url = get_author_posts_url( $user->ID );
+ $url = $user->has_prop( 'user_url' ) ? $user->get( 'user_url' ) : $url = \get_author_posts_url( $user->ID );
$name = $user->get( 'display_name' );
$email = $user->get( 'user_email' );
// phpcs:enable VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
diff --git a/includes/class-relme-domain-icon-map.php b/includes/relme/class-domain-icon-map.php
similarity index 88%
rename from includes/class-relme-domain-icon-map.php
rename to includes/relme/class-domain-icon-map.php
index 335b6d2..d0b6e36 100644
--- a/includes/class-relme-domain-icon-map.php
+++ b/includes/relme/class-domain-icon-map.php
@@ -2,13 +2,15 @@
/**
* Maps domain names to icons from the provided SVG fontset.
*
- * @package IndieWeb
+ * @package Indieweb
*/
+namespace Indieweb\Relme;
+
/**
* Rel-Me Domain Icon Map class.
*/
-class Rel_Me_Domain_Icon_Map {
+class Domain_Icon_Map {
/**
* Common and custom domain to icon mappings.
@@ -70,7 +72,7 @@ public static function split_domain( $domain_string ) {
* @return string|null The icon file path or null if not found.
*/
public static function get_icon_filename( $name ) {
- $svg = sprintf( '%1$s/static/svg/%2$s.svg', plugin_dir_path( __DIR__ ), $name );
+ $svg = sprintf( '%1$s/static/svg/%2$s.svg', \plugin_dir_path( \dirname( __DIR__ ) ), $name );
if ( file_exists( $svg ) ) {
return $svg;
}
@@ -104,7 +106,7 @@ public static function get_icon( $name ) {
$icon = self::get_icon_svg( $name );
$title = self::get_title( $name );
if ( $icon ) {
- return sprintf( '%3$s ', esc_attr( $name ), esc_attr( $title ), $icon );
+ return sprintf( '%3$s ', \esc_attr( $name ), \esc_attr( $title ), $icon );
}
return $name;
}
@@ -129,7 +131,7 @@ public static function get_title( $name ) {
* @return string|false The Mastodon domain or false.
*/
public static function mastodon_url() {
- $mastodon = get_transient( 'indieweb_mastodon' );
+ $mastodon = \get_transient( 'indieweb_mastodon' );
if ( false !== $mastodon ) {
return $mastodon;
}
@@ -144,18 +146,18 @@ public static function mastodon_url() {
),
),
);
- $query = new WP_User_Query( $args );
+ $query = new \WP_User_Query( $args );
$results = $query->get_results();
if ( empty( $results ) ) {
$value = false;
} else {
$user = $results[0];
- $value = get_user_meta( $user->ID, 'mastodon', true );
+ $value = \get_user_meta( $user->ID, 'mastodon', true );
if ( ! empty( $value ) && is_string( $value ) ) {
- $value = wp_parse_url( $value, PHP_URL_HOST );
+ $value = \wp_parse_url( $value, PHP_URL_HOST );
}
}
- set_transient( 'indieweb_mastodon', $value );
+ \set_transient( 'indieweb_mastodon', $value );
}
/**
@@ -165,13 +167,13 @@ public static function mastodon_url() {
* @return string The icon name.
*/
public static function url_to_name( $url ) {
- $scheme = wp_parse_url( $url, PHP_URL_SCHEME );
+ $scheme = \wp_parse_url( $url, PHP_URL_SCHEME );
// The default if not an http link is to return notice.
$return = 'notice';
if ( ( 'http' === $scheme ) || ( 'https' === $scheme ) ) {
$return = 'website'; // Default for web links.
$url = strtolower( $url );
- $domain = wp_parse_url( $url, PHP_URL_HOST );
+ $domain = \wp_parse_url( $url, PHP_URL_HOST );
$domain = str_replace( 'www.', '', $domain ); // Always remove www.
@@ -217,8 +219,10 @@ public static function url_to_name( $url ) {
return 'googlehangouts';
}
// Save the determined mapping into the map so that it will not have to look again on the same page load.
- self::$map[ $domain ] = $return;
- $return = apply_filters( 'indieweb_links_url_to_name', $return, $url );
+ if ( isset( $domain ) ) {
+ self::$map[ $domain ] = $return;
+ }
+ $return = \apply_filters( 'indieweb_links_url_to_name', $return, $url );
return $return;
}
}
diff --git a/includes/class-relme-widget.php b/includes/relme/class-widget.php
old mode 100755
new mode 100644
similarity index 59%
rename from includes/class-relme-widget.php
rename to includes/relme/class-widget.php
index 988a016..8b924bb
--- a/includes/class-relme-widget.php
+++ b/includes/relme/class-widget.php
@@ -2,28 +2,32 @@
/**
* Rel-Me Widget.
*
- * @package IndieWeb
+ * @package Indieweb
*/
+namespace Indieweb\Relme;
+
+use Indieweb\Hcard\User;
+
/**
* Adds widget to display rel-me links for IndieAuth with per-user profile support.
*/
-class RelMe_Widget extends WP_Widget {
+class Widget extends \WP_Widget {
/**
* Widget constructor.
*/
public function __construct() {
parent::__construct(
- 'RelMe_Widget',
- __( 'Show My Profiles on Other Sites', 'indieweb' ),
+ 'Relme_Widget',
+ \__( 'Show My Profiles on Other Sites', 'indieweb' ),
array(
- 'description' => __( 'Adds automatic rel-me URLs based on default author profile information. Rel=me links are links to your presence on other websites and visually appear like many social link widgets', 'indieweb' ),
+ 'description' => \__( 'Adds automatic rel-me URLs based on default author profile information. Rel=me links are links to your presence on other websites and visually appear like many social link widgets', 'indieweb' ),
'show_instance_in_rest' => true,
)
);
- if ( ! is_active_widget( false, false, $this->id_base ) ) {
- add_action( 'wp_head', array( 'HCard_User', 'relme_head' ) );
+ if ( ! \is_active_widget( false, false, $this->id_base ) ) {
+ \add_action( 'wp_head', array( User::class, 'relme_head' ) );
}
}
@@ -38,23 +42,23 @@ public function widget( $args, $instance ) { // phpcs:ignore VariableAnalysis.Co
$default_admin_user = $this->get_default_admin_author_id();
- $single_author = get_option( 'iw_single_author', is_multi_author() ? '0' : '1' );
- $author_id = get_option( 'iw_default_author', $default_admin_user );
+ $single_author = \get_option( 'iw_single_author', \is_multi_author() ? '0' : '1' );
+ $author_id = \get_option( 'iw_default_author', $default_admin_user );
$include_rel = false;
- if ( is_front_page() && '1' === $single_author ) {
+ if ( \is_front_page() && '1' === $single_author ) {
$include_rel = true;
}
- if ( is_author() ) {
- $author_id = ( $authordata instanceof WP_User ) ? $authordata->ID : $author_id;
+ if ( \is_author() ) {
+ $author_id = ( $authordata instanceof \WP_User ) ? $authordata->ID : $author_id;
if ( 0 === (int) $single_author ) {
$include_rel = true;
}
}
- if ( is_singular() && '0' === $single_author ) {
+ if ( \is_singular() && '0' === $single_author ) {
$author_id = $post->post_author;
}
- echo HCard_User::rel_me_list( $author_id, $include_rel ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
+ echo User::rel_me_list( $author_id, $include_rel ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
}
/**
@@ -76,7 +80,7 @@ public function update( $new_instance, $old_instance ) { // phpcs:ignore Variabl
*/
public function form( $instance ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
echo '';
- esc_html_e( 'Displays rel=me links which appear as icons with the logo of the site linked to when possible', 'indieweb' );
+ \esc_html_e( 'Displays rel=me links which appear as icons with the logo of the site linked to when possible', 'indieweb' );
echo '
';
}
@@ -86,7 +90,7 @@ public function form( $instance ) { // phpcs:ignore VariableAnalysis.CodeAnalysi
* @return int Administrator user ID.
*/
public function get_default_admin_author_id() {
- $users = get_users(
+ $users = \get_users(
array(
'role' => 'administrator',
'number' => 1,
diff --git a/indieweb.php b/indieweb.php
index f14cc00..73741db 100755
--- a/indieweb.php
+++ b/indieweb.php
@@ -9,207 +9,42 @@
* License: MIT
* License URI: http://opensource.org/licenses/MIT
* Text Domain: indieweb
- * Domain Path: /languages
*
- * @package IndieWeb
+ * @package Indieweb
*/
-// Initialize plugin.
-add_action( 'plugins_loaded', array( 'IndieWeb_Plugin', 'init' ) );
+namespace Indieweb;
-defined( 'INDIEWEB_ADD_HCARD_SUPPORT' ) || define( 'INDIEWEB_ADD_HCARD_SUPPORT', true );
-defined( 'INDIEWEB_ADD_RELME_SUPPORT' ) || define( 'INDIEWEB_ADD_RELME_SUPPORT', true );
-define( 'CNKT_INSTALLER_PATH', plugins_url( '/', __FILE__ ) );
+\define( 'INDIEWEB_VERSION', '5.0.0' );
-/**
- * IndieWeb Plugin Class
- *
- * @author Matthias Pfefferle
- */
-class IndieWeb_Plugin {
-
- /**
- * Plugin version.
- *
- * @var string
- */
- public static $version;
-
- /**
- * Initialize the plugin, registering WordPress hooks.
- */
- public static function init() {
- self::$version = get_file_data( __FILE__, array( 'Version' => 'Version' ) )['Version'];
- // Enable translation.
- self::enable_translation();
-
- require_once __DIR__ . '/includes/class-plugin-installer.php';
-
- if ( INDIEWEB_ADD_HCARD_SUPPORT ) {
- // Require H-Card Enhancements to User Profile.
- require_once __DIR__ . '/includes/class-relme-domain-icon-map.php';
- require_once __DIR__ . '/includes/class-hcard-user.php';
- require_once __DIR__ . '/includes/class-hcard-author-widget.php';
-
- }
-
- if ( INDIEWEB_ADD_RELME_SUPPORT ) {
- // Require Rel Me Widget Class.
- require_once __DIR__ . '/includes/class-relme-widget.php';
- }
-
- add_action( 'wp_enqueue_scripts', array( 'IndieWeb_Plugin', 'enqueue_style' ) );
-
- add_action( 'admin_enqueue_scripts', array( 'IndieWeb_Plugin', 'enqueue_admin_style' ) );
-
- // Add General Settings Page.
- require_once __DIR__ . '/includes/class-general-settings.php';
+\defined( 'INDIEWEB_ADD_HCARD_SUPPORT' ) || \define( 'INDIEWEB_ADD_HCARD_SUPPORT', true );
+\defined( 'INDIEWEB_ADD_RELME_SUPPORT' ) || \define( 'INDIEWEB_ADD_RELME_SUPPORT', true );
- // Add third party integrations.
- require_once __DIR__ . '/includes/class-integrations.php';
+\define( 'INDIEWEB_PLUGIN_DIR', \plugin_dir_path( __FILE__ ) );
+\define( 'INDIEWEB_PLUGIN_BASENAME', \plugin_basename( __FILE__ ) );
+\define( 'INDIEWEB_PLUGIN_FILE', \plugin_dir_path( __FILE__ ) . '/' . \basename( __FILE__ ) );
+\define( 'INDIEWEB_PLUGIN_URL', \plugin_dir_url( __FILE__ ) );
+\define( 'CNKT_INSTALLER_PATH', \plugins_url( '/', __FILE__ ) );
- // Add menu.
- add_action( 'admin_menu', array( 'IndieWeb_Plugin', 'add_menu_item' ), 9 );
+require_once INDIEWEB_PLUGIN_DIR . '/includes/class-autoloader.php';
- // Privacy Declaration.
- add_action( 'admin_init', array( 'Indieweb_Plugin', 'privacy_declaration' ) );
-
- // We're up and running.
- do_action( 'indieweb_loaded' );
- }
-
- /**
- * Load translation files.
- *
- * A good reference on how to implement translation in WordPress:
- * http://ottopress.com/2012/internationalization-youre-probably-doing-it-wrong/
- */
- public static function enable_translation() {
- // For plugins.
- load_plugin_textdomain(
- 'indieweb',
- false,
- dirname( plugin_basename( __FILE__ ) ) . '/languages/'
- );
- }
-
- /**
- * Enqueue frontend styles.
- */
- public static function enqueue_style() {
- if ( '1' === get_option( 'iw_relme_bw' ) ) {
- wp_enqueue_style( 'indieweb', plugins_url( 'static/css/indieweb-bw.css', __FILE__ ), array(), self::$version );
- } else {
- wp_enqueue_style( 'indieweb', plugins_url( 'static/css/indieweb.css', __FILE__ ), array(), self::$version );
- }
- }
-
- /**
- * Enqueue admin styles.
- */
- public static function enqueue_admin_style() {
- wp_enqueue_style( 'indieweb-admin', plugins_url( 'static/css/indieweb-admin.css', __FILE__ ), array(), self::$version );
- }
-
- /**
- * Add Top Level Menu Item.
- */
- public static function add_menu_item() {
- add_menu_page(
- 'IndieWeb',
- 'IndieWeb',
- 'manage_options',
- 'indieweb',
- array( 'IndieWeb_Plugin', 'getting_started' ),
- plugins_url( 'static/img/indieweb.svg', __FILE__ )
- );
- add_submenu_page(
- 'indieweb',
- __( 'Extensions', 'indieweb' ), // Page title.
- __( 'Extensions', 'indieweb' ), // Menu title.
- 'manage_options', // Access capability.
- 'indieweb-installer',
- array( 'IndieWeb_Plugin', 'plugin_installer' )
- );
- self::change_menu_title();
- }
-
- /**
- * Changes the menu title
- */
- public static function change_menu_title() {
- global $submenu;
- if ( isset( $submenu['indieweb'] ) && current_user_can( 'manage_options' ) ) {
- // phpcs:ignore
- $submenu['indieweb'][0][0] = __( 'Getting Started', 'indieweb' );
- }
- }
-
- /**
- * Callback from `add_plugins_page()` that shows the "Getting Started" page.
- */
- public static function getting_started() {
- require_once __DIR__ . '/includes/getting-started.php';
- }
+if ( INDIEWEB_ADD_HCARD_SUPPORT ) {
+ // Require simple-icons data.
+ require_once INDIEWEB_PLUGIN_DIR . '/includes/simple-icons.php';
+}
- /**
- * Render the plugin installer page.
- */
- public static function plugin_installer() {
- echo '' . esc_html__( 'IndieWeb Plugin Installer', 'indieweb' ) . ' ';
- echo '' . esc_html__( 'The below plugins are recommended to enable additional IndieWeb functionality.', 'indieweb' ) . '
';
- if ( class_exists( 'IndieWeb_Plugin_Installer' ) ) {
- IndieWeb_Plugin_Installer::init( self::register_plugins() );
- }
- }
+// Register the autoloader.
+Autoloader::register_path( __NAMESPACE__, INDIEWEB_PLUGIN_DIR . '/includes' );
- /**
- * Register the required plugins.
- */
- public static function register_plugins() {
- $plugin_array = array(
- array(
- 'slug' => 'webmention',
- ),
- array(
- 'slug' => 'micropub',
- ),
- array(
- 'slug' => 'indieweb-post-kinds',
- ),
- array(
- 'slug' => 'syndication-links',
- ),
- array(
- 'slug' => 'indieauth',
- ),
- array(
- 'slug' => 'simple-location',
- ),
- array(
- 'slug' => 'pubsubhubbub',
- ),
- array(
- 'slug' => 'indieblocks',
- ),
- );
- return $plugin_array;
- }
+// Initialize the plugin.
+$indieweb = Indieweb::get_instance();
+$indieweb->init();
- /**
- * Add privacy policy content.
- */
- public static function privacy_declaration() {
- if ( function_exists( 'wp_add_privacy_policy_content' ) ) {
- $content = __(
- 'Users can optionally add additional information to their profile. As this is part of your user profile you have control of this information and can remove
- it at your discretion.',
- 'indieweb'
- );
- wp_add_privacy_policy_content(
- 'Indieweb',
- wp_kses_post( wpautop( $content, false ) )
- );
- }
- }
+/**
+ * Plugin Version Number used for caching.
+ *
+ * @return string The plugin version.
+ */
+function version() {
+ return INDIEWEB_VERSION;
}
diff --git a/phpcs.xml b/phpcs.xml
index 1a5e979..366cbde 100644
--- a/phpcs.xml
+++ b/phpcs.xml
@@ -21,10 +21,4 @@
-
-
-
-
-
-