From f23fd8701cb95a765add05f73403aec09bc6cb7e Mon Sep 17 00:00:00 2001 From: Carsten Bach Date: Fri, 15 Sep 2023 17:28:33 +0200 Subject: [PATCH] WIP Fix CS issues --- .phpcs.xml | 2 + .../namespace.php | 26 +- inc/distributor/namespace.php | 93 +++-- inc/feed-pull/auto-setup.php | 169 ++++---- inc/feed-pull/import.php | 83 ++-- inc/feed-pull/namespace.php | 13 +- inc/ft-network-sourcelinks/namespace.php | 18 +- inc/namespace.php | 11 +- inc/rss-bridge/bridges.php | 386 +++++++++--------- inc/rss-bridge/class-detector.php_ | 28 +- inc/rss-bridge/detector.php | 304 +++++++------- inc/rss-bridge/namespace.php | 31 +- inc/term-management-tools/namespace.php | 14 +- inc/utility-taxonomy/namespace.php | 11 +- phpstan.neon | 7 + 15 files changed, 599 insertions(+), 597 deletions(-) diff --git a/.phpcs.xml b/.phpcs.xml index 070fb8e..4ddfa0e 100644 --- a/.phpcs.xml +++ b/.phpcs.xml @@ -7,6 +7,7 @@ + */templates/* */tests/* + */wordpress/* */wp-content/* diff --git a/inc/distributor-remote-quickedit/namespace.php b/inc/distributor-remote-quickedit/namespace.php index 7efc929..7ebf441 100644 --- a/inc/distributor-remote-quickedit/namespace.php +++ b/inc/distributor-remote-quickedit/namespace.php @@ -7,12 +7,11 @@ namespace Figuren_Theater\Data\Distributor_Remote_Quickedit; -use FT_VENDOR_DIR; - use Figuren_Theater; -use function Figuren_Theater\get_config; +use FT_VENDOR_DIR; use function add_action; + use function is_admin; use function is_network_admin; use function is_user_admin; @@ -22,25 +21,34 @@ /** * Bootstrap module, when enabled. + * + * @return void */ -function bootstrap() { +function bootstrap() :void { add_action( 'plugins_loaded', __NAMESPACE__ . '\\load_plugin', 9 ); } -function load_plugin() { +/** + * Conditionally load the plugin itself and its modifications. + * + * @return void + */ +function load_plugin() :void { $config = Figuren_Theater\get_config()['modules']['data']; - if ( ! $config['distributor-remote-quickedit'] ) - return; // early + if ( ! $config['distributor-remote-quickedit'] ) { + return; + } // Do only load in "normal" admin view // Not for: // - and public views // - network-admin views - // - user-admin views - if ( ! is_admin() || is_network_admin() || is_user_admin() ) + // - user-admin views. + if ( ! is_admin() || is_network_admin() || is_user_admin() ) { return; + } require_once FT_VENDOR_DIR . PLUGINPATH; // phpcs:ignore WordPressVIPMinimum.Files.IncludingFile.UsingCustomConstant } diff --git a/inc/distributor/namespace.php b/inc/distributor/namespace.php index 175ab2f..8f43d52 100644 --- a/inc/distributor/namespace.php +++ b/inc/distributor/namespace.php @@ -11,47 +11,54 @@ namespace Figuren_Theater\Data\Distributor; -use FT_VENDOR_DIR; - -use WP_DEBUG; -use WP_ENVIRONMENT_TYPE; - -use WP_Post; - use Figuren_Theater; + use Figuren_Theater\FeaturesRepo; use Figuren_Theater\Network\Users; + use Figuren_Theater\Options; -use function Figuren_Theater\get_config; +use FT_VENDOR_DIR; use function add_action; use function add_filter; use function current_user_can; -use function remove_menu_page; + use function remove_action; +use function remove_menu_page; +use WP_DEBUG; +use WP_ENVIRONMENT_TYPE; +use WP_Post; const BASENAME = 'distributor/distributor.php'; const PLUGINPATH = '/10up/' . BASENAME; /** * Bootstrap module, when enabled. + * + * @return void */ -function bootstrap() { +function bootstrap() :void { add_action( 'Figuren_Theater\loaded', __NAMESPACE__ . '\\filter_options', 11 ); add_action( 'plugins_loaded', __NAMESPACE__ . '\\load_plugin', 0 ); } -function load_plugin() { +/** + * Conditionally load the plugin itself and its modifications. + * + * @return void + */ +function load_plugin() :void { - // because this makes things visible - // to normal 'administrator' users - if ( ! defined( 'DISTRIBUTOR_DEBUG' ) && 'local' === WP_ENVIRONMENT_TYPE ) + // Because this makes things visible + // to normal 'administrator' users. + if ( ! defined( 'DISTRIBUTOR_DEBUG' ) && 'local' === WP_ENVIRONMENT_TYPE ) { define( 'DISTRIBUTOR_DEBUG', WP_DEBUG ); + } - // the plugin checks for option 'active_sitewide_plugins' - // so we need to filter 'active_sitewide_plugins' + // The plugin checks for option 'active_sitewide_plugins' + // so we need to filter 'active_sitewide_plugins'. add_filter( 'site_option_active_sitewide_plugins', __NAMESPACE__ . '\\filter_site_option', 0 ); require_once FT_VENDOR_DIR . PLUGINPATH; // phpcs:ignore WordPressVIPMinimum.Files.IncludingFile.UsingCustomConstant @@ -59,7 +66,7 @@ function load_plugin() { // Filters the arguments for registering a post type. add_filter( 'register_post_type_args', __NAMESPACE__ . '\\register_post_type_args', 20, 2 ); - // Remove plugins menu + // Remove plugins menu. add_action( 'network_admin_menu', __NAMESPACE__ . '\\remove_menu', 11 ); add_action( 'admin_menu', __NAMESPACE__ . '\\remove_menu', 11 ); @@ -77,8 +84,7 @@ function admin_init() { // Allow bypassing of all media processing. add_filter( 'dt_push_post_media', __NAMESPACE__ . '\\dt_push_post_media' ); - // - add_filter( 'dt_push_post_args', __NAMESPACE__ . '\\dt_push_post_args', 9, 4 ); + add_filter( 'dt_push_post_args', __NAMESPACE__ . '\\dt_push_post_args', 9, 4 ); add_filter( 'dt_pull_post_args', __NAMESPACE__ . '\\dt_pull_post_args', 9, 4 ); // Filter Distributor capabilities allowed to syndicate content. @@ -88,15 +94,14 @@ function admin_init() { // \add_filter( 'pre_site_option_external_updates-distributor', [ $this, 'pre_disable_updatecheck' ] ); } - - function filter_site_option( $active_sitewide_plugins ) { - // prevents the default admin-notice for missing plugin files, - // which gets triggered by the FT_VENDOR_DIR path construct + // Prevents the default admin-notice for missing plugin files, + // which gets triggered by the FT_VENDOR_DIR path construct. global $pagenow; - if ( 'plugins.php' === $pagenow ) + if ( 'plugins.php' === $pagenow ) { return $active_sitewide_plugins; + } $active_sitewide_plugins[ BASENAME ] = BASENAME; return $active_sitewide_plugins; @@ -130,23 +135,20 @@ function filter_options() : void { BASENAME ); - } - - function remove_menu() : void { remove_menu_page( 'distributor' ); } function remove_columns_from_lists() : void { - // unclutter the UI for "normal" users + // Unclutter the UI for "normal" users. // if ( 'this-site-is-not-a-network-hub' && ! \is_main_site( null, 1 ) ) - if ( ! Figuren_Theater\FT::site()->has_feature( [ FeaturesRepo\Feature__core__contenthub::SLUG ] ) ) + if ( ! Figuren_Theater\FT::site()->has_feature( [ FeaturesRepo\Feature__core__contenthub::SLUG ] ) ) { remove_action( 'admin_init', 'Distributor\\SyndicatedPostUI\\setup_columns' ); + } } - /** * [pre_disable_updatecheck description] * @@ -164,7 +166,6 @@ function pre_disable_updatecheck() { } */ - /** * Filters the arguments for registering a post type. * @@ -176,16 +177,15 @@ function pre_disable_updatecheck() { * See the register_post_type() function for accepted arguments. * @param string $post_type Post type key. */ -function register_post_type_args( array $args, String $post_type ) : array { - if ( in_array( $post_type, ['dt_ext_connection','dt_subscription']) ) { +function register_post_type_args( array $args, string $post_type ) : array { + if ( in_array( $post_type, [ 'dt_ext_connection', 'dt_subscription' ], true ) ) { $args['can_export'] = current_user_can( 'manage_sites' ); - $args['show_ui'] = false; // disable this anoying 'dt_subscription'-menu, as it is only needed for ext. connections + $args['show_ui'] = false; // Disable this anoying 'dt_subscription'-menu, as it is only needed for ext. connections. } return $args; } - /** * Filter Distributor capabilities allowed to syndicate content. * @@ -195,11 +195,11 @@ function register_post_type_args( array $args, String $post_type ) : array { * * @see https://10up.github.io/distributor/dt_syndicatable_capabilities.html * - * @param String $capabilities default: edit_posts The capability allowed to syndicate content. - * @return [type] [description] + * @param string $capabilities default: edit_posts The capability allowed to syndicate content. + * + * @return string [description] */ -function dt_syndicatable_capabilities( String $capabilities ) : string -{ +function dt_syndicatable_capabilities( string $capabilities ) : string { return 'manage_sites'; } @@ -219,25 +219,24 @@ function dt_syndicatable_capabilities( String $capabilities ) : string * * @return {bool} If Distributor should push the post media. */ -function dt_push_post_media($value) -{ +function dt_push_post_media( $value ) { return false; } -function dt_push_post_args($new_post_args, $post, $connection_args, $connection) : array { +function dt_push_post_args( $new_post_args, $post, $connection_args, $connection ) : array { return push_pull_default_args( $new_post_args, $post ); } -function dt_pull_post_args($new_post_args, $remote_post_id, $remote_post, $connection) : array { +function dt_pull_post_args( $new_post_args, $remote_post_id, $remote_post, $connection ) : array { return push_pull_default_args( $new_post_args, $remote_post ); } function push_pull_default_args( array $new_post_args, WP_Post $original_post ) : array { - // set author to machine user - $new_post_args['post_author'] = Users\ft_bot::id(); + // Set author to machine user. + $new_post_args['post_author'] = Users\ft_bot::id(); - // by default 'Distributor' sets the current date as new published_date - $new_post_args['post_date'] = $original_post->post_date; + // By default 'Distributor' sets the current date as new published_date. + $new_post_args['post_date'] = $original_post->post_date; // ..and all related dates ... $new_post_args['post_date_gmt'] = $original_post->post_date_gmt; $new_post_args['post_modified'] = $original_post->post_modified; diff --git a/inc/feed-pull/auto-setup.php b/inc/feed-pull/auto-setup.php index e7c96ec..fc2d245 100644 --- a/inc/feed-pull/auto-setup.php +++ b/inc/feed-pull/auto-setup.php @@ -16,30 +16,24 @@ namespace Figuren_Theater\Data\Feed_Pull; -use Figuren_Theater\UtilityFeaturesRepo; - use Figuren_Theater\Data\Rss_Bridge; -use Figuren_Theater\Network\Features; -use Figuren_Theater\Network\Post_Types; // use FP_DELETED_OPTION_NAME; // 'fp_deleted_syndicated' use function add_action; -use function add_filter; use function get_post; -use function get_post_meta; use function get_posts; +use function get_post_meta; use function get_term_by; -use function has_term; use function is_wp_error; use function wp_delete_post; use function wp_insert_post; use function wp_slash; // const LINK_PT = Post_Types\Post_Type__ft_link::NAME; -const LINK_PT = 'ft_link'; +const LINK_PT = 'ft_link'; // const UTILITY_TAX = Features\UtilityFeaturesManager::TAX; -const UTILITY_TAX = 'hm-utility'; +const UTILITY_TAX = 'hm-utility'; // const UTILITY_TERM = UtilityFeaturesRepo\UtilityFeature__ft_link__feedpull_import::SLUG; //'feedpull-import',; const UTILITY_TERM = 'feedpull-import'; @@ -64,7 +58,6 @@ function admin_init() { add_action( 'before_delete_post', __NAMESPACE__ . '\\delete_feed_post_on_trash' ); } - /** * Create or update a feed post * when a link post with the "import" term @@ -74,64 +67,62 @@ function admin_init() { */ function create_feed_post( WP_Post $post ) : void { - // Bail if post type is not a Link - if ( $post->post_type !== LINK_PT ) { - return; - } - - // look for a platform suggestion - // which use user may have given during registration - // see: Figuren_Theater\src\FeaturesAssets\core-my-registration\wp_core.php - $suggestion = get_post_meta( $post->ID, '_ft_platform', true ) ?? null; - - // get bridged URL - $fp_feed_url = esc_url( - Rss_Bridge\get_bridged_url( $post->post_content, $suggestion ), - 'https', - 'db' - ); - - // Bail, if not importable - if ( ! $fp_feed_url ) { - return; - } - - // prepare the insert arguments - $insert_args = wp_slash( array( - 'post_author' => $post->post_author, - 'post_type' => FEED_POSTTYPE, - 'post_title' => 'Feed: ' . $post->post_content, - 'post_parent' => $post->ID, - 'post_status' => 'publish', + // Bail if post type is not a Link + if ( $post->post_type !== LINK_PT ) { + return; + } + + // look for a platform suggestion + // which use user may have given during registration + // see: Figuren_Theater\src\FeaturesAssets\core-my-registration\wp_core.php + $suggestion = get_post_meta( $post->ID, '_ft_platform', true ) ?? null; + + // get bridged URL + $fp_feed_url = esc_url( + Rss_Bridge\get_bridged_url( $post->post_content, $suggestion ), + 'https', + 'db' + ); + + // Bail, if not importable + if ( ! $fp_feed_url ) { + return; + } + + // prepare the insert arguments + $insert_args = wp_slash( [ + 'post_author' => $post->post_author, + 'post_type' => FEED_POSTTYPE, + 'post_title' => 'Feed: ' . $post->post_content, + 'post_parent' => $post->ID, + 'post_status' => 'publish', 'menu_order' => 0, 'comment_status' => 'closed', 'ping_status' => 'closed', - 'meta_input' => [ - 'fp_feed_url' => $fp_feed_url, - ADAPTER_POSTMETA => '' // @todo #16 // array_key of one of the get_bridges() array. - ], - 'tax_input' => [ - UTILITY_TAX => [ - - ], - ], - )); - - // Create the feed post with the link post as parent. - $feed_post_id = wp_insert_post( $insert_args ); - - if (is_wp_error($feed_post_id)) { - // Log an error if the feed post could not be created. - error_log( - sprintf( - 'Error creating feed post for link post with ID %d: %s', - $post->ID, - $feed_post_id->get_error_message() - ) - ); - } + 'meta_input' => [ + 'fp_feed_url' => $fp_feed_url, + ADAPTER_POSTMETA => '', // @todo #16 // array_key of one of the get_bridges() array. + ], + 'tax_input' => [ + UTILITY_TAX => [], + ], + ]); + + // Create the feed post with the link post as parent. + $feed_post_id = wp_insert_post( $insert_args ); + + if ( is_wp_error( $feed_post_id ) ) { + // Log an error if the feed post could not be created. + error_log( + sprintf( + 'Error creating feed post for link post with ID %d: %s', + $post->ID, + $feed_post_id->get_error_message() + ) + ); + } } /** @@ -147,8 +138,7 @@ function create_feed_post( WP_Post $post ) : void { * @param array $old_tt_ids Old array of term taxonomy IDs. */ function add_or_delete_feed_post( int $object_id, array $terms, array $new_terms, string $taxonomy, bool $append, array $old_terms ) : void { - // - $import_term_id = get_import_term_id(); + $import_term_id = get_import_term_id(); // Return early if not the utility taxonomy or not the 'import' term being added or removed. if ( $taxonomy !== UTILITY_TAX || ! in_array( $import_term_id, $new_terms ) && ! in_array( $import_term_id, $old_terms ) ) { @@ -158,7 +148,7 @@ function add_or_delete_feed_post( int $object_id, array $terms, array $new_terms $post = get_post( $object_id ); // Return early if not a link post. - if ( ! is_a($post, 'WP_Post') || $post->post_type !== LINK_PT ) { + if ( ! is_a( $post, 'WP_Post' ) || $post->post_type !== LINK_PT ) { return; } @@ -168,16 +158,14 @@ function add_or_delete_feed_post( int $object_id, array $terms, array $new_terms // // Term is new and not yet assigned if ( in_array( $import_term_id, $new_terms ) && ! in_array( $import_term_id, $old_terms ) ) { - // - create_feed_post( $post ); + create_feed_post( $post ); - // Term is not assigned, but was previously + // Term is not assigned, but was previously } elseif ( ! in_array( $import_term_id, $new_terms ) && in_array( $import_term_id, $old_terms ) ) { - // - $feed_post_id = get_feed_from_link( $object_id ); + $feed_post_id = get_feed_from_link( $object_id ); if ( $feed_post_id ) { - // Delete without trash bin - wp_delete_post( $feed_post_id, true ); + // Delete without trash bin + wp_delete_post( $feed_post_id, true ); } } } @@ -188,29 +176,28 @@ function add_or_delete_feed_post( int $object_id, array $terms, array $new_terms * @param int $post_id The ID of the post being trashed. */ function delete_feed_post_on_trash( int $post_id ) : void { - $post = get_post( $post_id ); - - // Bail if post type is not a Link - if ( $post->post_type !== LINK_PT ) { - return; - } - // Delete feed post - wp_delete_post( get_feed_from_link( $post_id ), true ); -} + $post = get_post( $post_id ); + // Bail if post type is not a Link + if ( $post->post_type !== LINK_PT ) { + return; + } + // Delete feed post + wp_delete_post( get_feed_from_link( $post_id ), true ); +} function get_feed_from_link( int $link_post_id ) : int { - $feed_post = get_posts( array( - 'post_type' => FEED_POSTTYPE, - 'post_parent' => $link_post_id, - 'numberposts' => 1, - ) ); + $feed_post = get_posts( [ + 'post_type' => FEED_POSTTYPE, + 'post_parent' => $link_post_id, + 'numberposts' => 1, + ] ); - return ( empty($feed_post) ) ? 0 : $feed_post[0]->ID; + return ( empty( $feed_post ) ) ? 0 : $feed_post[0]->ID; } function get_import_term_id() : int { - $term = get_term_by('slug', UTILITY_TERM, UTILITY_TAX); - // Get the "import" term ID. - return (is_wp_error( $term )) ? 0 : $term->term_id; + $term = get_term_by( 'slug', UTILITY_TERM, UTILITY_TAX ); + // Get the "import" term ID. + return ( is_wp_error( $term ) ) ? 0 : $term->term_id; } diff --git a/inc/feed-pull/import.php b/inc/feed-pull/import.php index 36fe25c..e4c07af 100644 --- a/inc/feed-pull/import.php +++ b/inc/feed-pull/import.php @@ -9,24 +9,18 @@ use Figuren_Theater\Data\Rss_Bridge; -use Figuren_Theater\Network\Features; use Figuren_Theater\Network\Taxonomies; use Figuren_Theater\Network\Users; use function add_action; use function add_filter; -use function delete_option; use function do_blocks; use function get_post; use function get_post_meta; use function get_post_parent; -use function get_post_type; -use function get_the_terms; -use function sanitize_text_field; use function sanitize_textarea_field; -use function wp_list_pluck; +use function sanitize_text_field; use function wp_parse_args; -use function wp_set_object_terms; use function wp_slash; function bootstrap_import() { @@ -39,17 +33,11 @@ function init() { // for debugging only // delete_option( 'fp_deleted_syndicated' ); - - - // https://github.com/tlovett1/feed-pull/blob/45d667c1275cca0256bd03ed6fa1655cdf26f064/includes/class-fp-pull.php#L274 add_filter( 'fp_pre_post_insert_value', __NAMESPACE__ . '\\fp_pre_post_insert_value', 10, 4 ); - - add_filter( 'fp_post_args', __NAMESPACE__ . '\\fp_post_args', 10, 3 ); - add_filter( 'default_post_metadata', __NAMESPACE__ . '\\default_post_metadata', 10, 3 ); add_filter( 'update_post_metadata', __NAMESPACE__ . '\\dont_update_post_metadata', 1000, 3 ); } @@ -72,17 +60,16 @@ function get_default_static_metas() : array { // 'fp_feed_url', // that should not treated by our filters - 'fp_posts_xpath', // this should come from a defined BridgeAdapter - 'fp_field_map', // this should come from a defined BridgeAdapter - #'fp_post_status', // this should NOT come from a defined BridgeAdapter - #'fp_post_type', // this should NOT come from a defined BridgeAdapter - 'fp_allow_updates', // this should come from a defined BridgeAdapter - 'fp_new_post_categories', // this should come from a defined BridgeAdapter + 'fp_posts_xpath', // this should come from a defined BridgeAdapter + 'fp_field_map', // this should come from a defined BridgeAdapter + // 'fp_post_status', // this should NOT come from a defined BridgeAdapter + // 'fp_post_type', // this should NOT come from a defined BridgeAdapter + 'fp_allow_updates', // this should come from a defined BridgeAdapter + 'fp_new_post_categories', // this should come from a defined BridgeAdapter // 'fp_custom_namespaces', // this should come from a defined BridgeAdapter // 'fp_namespace_prefix', // this should come from a defined BridgeAdapter // 'fp_namespace_url', // this should come from a defined BridgeAdapter - // //////////////////////////////////////////////////// // post_meta of an imported DESTINATION_POSTTYPE post // //////////////////////////////////////////////////// @@ -126,13 +113,13 @@ function default_post_metadata( mixed $value, int $object_id, string $meta_key ) $adapter = get_post_meta( $object_id, ADAPTER_POSTMETA, true ); $bridges = Rss_Bridge\get_bridges(); - if ( ! isset($bridges[$adapter])) { + if ( ! isset( $bridges[ $adapter ] ) ) { return $value; } - $adapter = $bridges[$adapter]; + $adapter = $bridges[ $adapter ]; - switch ($meta_key) { + switch ( $meta_key ) { case 'fp_posts_xpath': return $adapter['fp_posts_xpath'] ?? 'feed/entry'; // Atom @@ -140,8 +127,8 @@ function default_post_metadata( mixed $value, int $object_id, string $meta_key ) case 'fp_field_map': return $adapter['fp_field_map'] ?? get_fp_field_map(); - #case 'fp_post_status': - # return 'pending'; + // case 'fp_post_status': + // return 'pending'; // case 'fp_post_type': // return $adapter['fp_post_type'] ?? DESTINATION_POSTTYPE; @@ -152,8 +139,8 @@ function default_post_metadata( mixed $value, int $object_id, string $meta_key ) case 'fp_new_post_categories': return []; - #case 'fp_source_feed_id': - # return get_fp_source_feed_id( $object_id ); + // case 'fp_source_feed_id': + // return get_fp_source_feed_id( $object_id ); default: return $value; @@ -167,21 +154,20 @@ function default_post_metadata( mixed $value, int $object_id, string $meta_key ) * @return array List of feed-fields and their mappings within WordPress, following the 'feed-pull'-plugin conventions. */ function get_fp_field_map() : array { - return array ( - array ( + return [ + [ 'source_field' => 'title', // Atom 'destination_field' => 'post_title', 'mapping_type' => 'post_field', - ), - array ( + ], + [ 'source_field' => 'id', // Atom 'destination_field' => 'guid', 'mapping_type' => 'post_field', - ), - ); + ], + ]; } - /** * Normally the 'fp_source_feed_id' post_meta holds an post_ID. * @@ -190,7 +176,6 @@ function get_fp_field_map() : array { * * The post_meta is later on, only used within a simple empty() check, * - * * @return string function get_fp_source_feed_id( int $post_id ) : int|false { @@ -212,7 +197,6 @@ function get_fp_source_feed_id( int $post_id ) : int|false { } */ - /** * Short-circuits updating metadata of a specific type. * @@ -238,7 +222,7 @@ function get_fp_source_feed_id( int $post_id ) : int|false { * this value. Otherwise, update all entries. */ function dont_update_post_metadata( $check, int $object_id, string $meta_key, mixed $meta_value ) : mixed { -/* + /* // one special-operation // but instead of writing to post_meta // we are creating a taxonomy relation @@ -264,7 +248,7 @@ function dont_update_post_metadata( $check, int $object_id, string $meta_key, mi ); } } -*/ + */ // Send non-null, falsy return to prevent feed-pull post_meta from being written|updated if ( in_array( $meta_key, get_default_static_metas() ) ) { return false; @@ -274,9 +258,9 @@ function dont_update_post_metadata( $check, int $object_id, string $meta_key, mi return $check; } - /** * [fp_pre_post_insert_value description] + * * @param [mixed] $pre_filter_post_value [description] * @param [array] $field [description] * @@ -291,20 +275,22 @@ function dont_update_post_metadata( $check, int $object_id, string $meta_key, mi * * @return [type] [description] */ -function fp_pre_post_insert_value( $pre_filter_post_value, $field, $post, $source_feed_id ): string { +function fp_pre_post_insert_value( $pre_filter_post_value, $field, $post, $source_feed_id ): string { - if ( 'post_title' == $field['destination_field'] ) + if ( 'post_title' == $field['destination_field'] ) { return sanitize_text_field( $pre_filter_post_value ); + } - if ( 'post_excerpt' == $field['destination_field'] ) + if ( 'post_excerpt' == $field['destination_field'] ) { return sanitize_textarea_field( $pre_filter_post_value ); + } if ( 'post_content' == $field['destination_field'] ) { - /* + /* $tags_to_strip = Array("figure","font" ); foreach ($tags_to_strip as $tag) { - $pre_filter_post_value = preg_replace("/<\\/?" . $tag . "(.|\\s)*?>/",'',$pre_filter_post_value); + $pre_filter_post_value = preg_replace("/<\\/?" . $tag . "(.|\\s)*?>/",'',$pre_filter_post_value); } serialize_block( $block );*/ // return \wpautop( \wp_kses_post( $pre_filter_post_value ), true ); @@ -316,8 +302,6 @@ function fp_pre_post_insert_value( $pre_filter_post_value, $field, $post, $sourc return $pre_filter_post_value; } - - /** * Change the arguments for the new or to-update 'post' post * that gets inserted|updated directly after this filter. @@ -345,7 +329,7 @@ function fp_post_args( array $new_post_args, $post, int $source_feed_id ) : arra // strip (maybe) filled excerpt // if we can auto-generate it if ( ! empty( $new_post_args['post_content'] ) && ! empty( $new_post_args['post_excerpt'] ) ) { - unset($new_post_args['post_excerpt']); + unset( $new_post_args['post_excerpt'] ); } $new_post_args = wp_parse_args( $import_args, $new_post_args ); @@ -353,11 +337,10 @@ function fp_post_args( array $new_post_args, $post, int $source_feed_id ) : arra return wp_slash( $new_post_args ); } - function get_import_args_from_source( int $source_feed_id ) : array { // 1. get sourced 'ft_link' post, // which is the parent of the 'fp_feed' that is sourcing this post - $ft_link = get_post_parent( get_post( $source_feed_id ) ); + $ft_link = get_post_parent( get_post( $source_feed_id ) ); // 2. get sourced 'ft_link_shadow'-term-id $TAX_Shadow = Taxonomies\TAX_Shadow::init(); @@ -367,7 +350,7 @@ function get_import_args_from_source( int $source_feed_id ) : array { ); // 3. translate 'utility-tax' terms at the source - // into post-fields of the import + // into post-fields of the import // $args = get_post_fields_from_utility_terms( $source_feed_id ) + [ $args = [ 'tax_input' => [ diff --git a/inc/feed-pull/namespace.php b/inc/feed-pull/namespace.php index e41fb99..a0564f1 100644 --- a/inc/feed-pull/namespace.php +++ b/inc/feed-pull/namespace.php @@ -41,18 +41,25 @@ /** * Bootstrap module, when enabled. + * + * @return void */ -function bootstrap() { +function bootstrap() :void { add_action( 'Figuren_Theater\loaded', __NAMESPACE__ . '\\filter_options', 11 ); add_action( 'init', __NAMESPACE__ . '\\load_plugin', 0 ); } -function load_plugin() { +/** + * Conditionally load the plugin itself and its modifications. + * + * @return void + */ +function load_plugin() :void { $config = Figuren_Theater\get_config()['modules']['data']; if ( ! $config['feed-pull'] ) - return; // early + return; // Do only load in "normal" admin view // Not for: diff --git a/inc/ft-network-sourcelinks/namespace.php b/inc/ft-network-sourcelinks/namespace.php index 270eee2..0ada667 100644 --- a/inc/ft-network-sourcelinks/namespace.php +++ b/inc/ft-network-sourcelinks/namespace.php @@ -8,10 +8,7 @@ namespace Figuren_Theater\Data\FT_Network_Sourcelinks; use FT_VENDOR_DIR; - use function add_action; -// use function is_network_admin; -// use function is_user_admin; const BASENAME = 'ft-network-sourcelinks/ft-network-sourcelinks.php'; const PLUGINPATH = '/figuren-theater/' . BASENAME; @@ -26,15 +23,12 @@ function bootstrap() { add_action( 'plugins_loaded', __NAMESPACE__ . '\\load_plugin', 9 ); } -function load_plugin() { - - // Do only load in "normal" admin view - // and public views - // Not for: - // - network-admin views - // - user-admin views - #if ( is_network_admin() || is_user_admin() ) - # return; +/** + * Conditionally load the plugin itself and its modifications. + * + * @return void + */ +function load_plugin() :void { require_once FT_VENDOR_DIR . PLUGINPATH; // phpcs:ignore WordPressVIPMinimum.Files.IncludingFile.UsingCustomConstant } diff --git a/inc/namespace.php b/inc/namespace.php index 97a5a57..8e5b896 100644 --- a/inc/namespace.php +++ b/inc/namespace.php @@ -8,15 +8,16 @@ namespace Figuren_Theater\Data; use Altis; -use function Altis\register_module; /** * Register module. + * + * @return void */ -function register() { +function register() :void { $default_settings = [ - 'enabled' => true, // needs to be set + 'enabled' => true, // Needs to be set. 'distributor-remote-quickedit' => false, 'feed-pull' => false, ]; @@ -35,8 +36,10 @@ function register() { /** * Bootstrap module, when enabled. + * + * @return void */ -function bootstrap() { +function bootstrap() :void { Distributor\bootstrap(); Distributor_Remote_Quickedit\bootstrap(); diff --git a/inc/rss-bridge/bridges.php b/inc/rss-bridge/bridges.php index ab0a1c1..10e33be 100644 --- a/inc/rss-bridge/bridges.php +++ b/inc/rss-bridge/bridges.php @@ -8,7 +8,6 @@ namespace Figuren_Theater\Data\Rss_Bridge; - // Does NOT work // // Youtube @@ -58,220 +57,219 @@ function get_bridges() : array { // Mastodon - // NO WAY // - other than a sarcastic blog post - // // facebook.com // weebly.com - return array( + return [ - "twitter" => array( - "pattern" => '#^(https?://)?(www\.)?twitter\.com/([a-zA-Z0-9_]+)(/.*)?(\\?.*)?(\\#.*?)?$#i', - "bridge_name" => 'Twitter', - "bridge_url_data" => function($bridge, $url) { - preg_match($bridge['pattern'], $url, $matches); - return [ - 'u' => $matches[3], - ]; - }, - #"feed_url" => "https://twitter.com/%s.rss", - #"feed_url_data" => function($pattern, $url) { - # preg_match($pattern, $url, $matches); - # return $matches[3]; - #} - ), + 'twitter' => [ + 'pattern' => '#^(https?://)?(www\.)?twitter\.com/([a-zA-Z0-9_]+)(/.*)?(\\?.*)?(\\#.*?)?$#i', + 'bridge_name' => 'Twitter', + 'bridge_url_data' => function( $bridge, $url ) { + preg_match( $bridge['pattern'], $url, $matches ); + return [ + 'u' => $matches[3], + ]; + }, + // "feed_url" => "https://twitter.com/%s.rss", + // "feed_url_data" => function($pattern, $url) { + // preg_match($pattern, $url, $matches); + // return $matches[3]; + // } + ], - "tumblr" => array( - "pattern" => '#^(https?://)?([a-z0-9-]+)\.tumblr\.com(/.*)?$#i', - "bridge_name" => 'FeedMerger', - "bridge_url_data" => function($bridge, $url, $platform = null) { - if ($platform) { - $url = get_custom_feed_url( $bridge, $url, $platform ); - } else { - $url = get_feed_url( $bridge, $url ); - } - return [ - 'url' => urlencode($url) - ]; - }, - "feed_url" => "https://%s.tumblr.com/rss", - "feed_url_data" => function($pattern, $url) { - preg_match($pattern, $url, $matches); - return $matches[2]; - } - ), - "medium" => array( - "pattern" => '#^(https?://)?([a-z0-9-]+\.)?medium\.com/@([a-zA-Z0-9_]+)(/.*)?$#i', - "bridge_name" => 'FeedMerger', - "bridge_url_data" => function($bridge, $url, $platform = null) { - $url = get_feed_url( $bridge, $url ); - return [ - 'url' => urlencode( $url ) - ]; - }, - "feed_url" => "https://medium.com/feed/@%s", - "feed_url_data" => function($pattern, $url) { - preg_match($pattern, $url, $matches); - return $matches[3]; - } - ), + 'tumblr' => [ + 'pattern' => '#^(https?://)?([a-z0-9-]+)\.tumblr\.com(/.*)?$#i', + 'bridge_name' => 'FeedMerger', + 'bridge_url_data' => function( $bridge, $url, $platform = null ) { + if ( $platform ) { + $url = get_custom_feed_url( $bridge, $url, $platform ); + } else { + $url = get_feed_url( $bridge, $url ); + } + return [ + 'url' => urlencode( $url ), + ]; + }, + 'feed_url' => 'https://%s.tumblr.com/rss', + 'feed_url_data' => function( $pattern, $url ) { + preg_match( $pattern, $url, $matches ); + return $matches[2]; + }, + ], + 'medium' => [ + 'pattern' => '#^(https?://)?([a-z0-9-]+\.)?medium\.com/@([a-zA-Z0-9_]+)(/.*)?$#i', + 'bridge_name' => 'FeedMerger', + 'bridge_url_data' => function( $bridge, $url, $platform = null ) { + $url = get_feed_url( $bridge, $url ); + return [ + 'url' => urlencode( $url ), + ]; + }, + 'feed_url' => 'https://medium.com/feed/@%s', + 'feed_url_data' => function( $pattern, $url ) { + preg_match( $pattern, $url, $matches ); + return $matches[3]; + }, + ], - "webflow" => array( - "pattern" => '#^(https?://)?([a-zA-Z0-9_-]+)\.webflow\.com(/.*)?$#i', - "bridge_name" => 'FeedMerger', - "bridge_url_data" => function($bridge, $url, $platform = null) { - if ($platform) { - $url = get_custom_feed_url( $bridge, $url, $platform ); - } else { - $url = get_feed_url( $bridge, $url ); - } - return [ - 'url' => urlencode($url) - ]; - }, - "feed_url" => "https://%s.webflow.com/blog/rss.xml", - "feed_url_data" => function($pattern, $url) { - preg_match($pattern, $url, $matches); - return $matches[2]; - } - ), + 'webflow' => [ + 'pattern' => '#^(https?://)?([a-zA-Z0-9_-]+)\.webflow\.com(/.*)?$#i', + 'bridge_name' => 'FeedMerger', + 'bridge_url_data' => function( $bridge, $url, $platform = null ) { + if ( $platform ) { + $url = get_custom_feed_url( $bridge, $url, $platform ); + } else { + $url = get_feed_url( $bridge, $url ); + } + return [ + 'url' => urlencode( $url ), + ]; + }, + 'feed_url' => 'https://%s.webflow.com/blog/rss.xml', + 'feed_url_data' => function( $pattern, $url ) { + preg_match( $pattern, $url, $matches ); + return $matches[2]; + }, + ], - "blogspot" => array( - "pattern" => '#^(https?://)?([a-zA-Z0-9_-]+)\.blogspot\.com(/.*)?$#i', - "bridge_name" => 'FeedMerger', - "bridge_url_data" => function($bridge, $url, $platform = null) { - if ($platform) { - $url = get_custom_feed_url( $bridge, $url, $platform ); - } else { - $url = get_feed_url( $bridge, $url ); - } - return [ - 'url' => urlencode($url) - ]; - }, - "feed_url" => "https://%s.blogspot.com/feeds/posts/default", - "feed_url_data" => function($pattern, $url) { - preg_match($pattern, $url, $matches); - return $matches[2]; - } - ), + 'blogspot' => [ + 'pattern' => '#^(https?://)?([a-zA-Z0-9_-]+)\.blogspot\.com(/.*)?$#i', + 'bridge_name' => 'FeedMerger', + 'bridge_url_data' => function( $bridge, $url, $platform = null ) { + if ( $platform ) { + $url = get_custom_feed_url( $bridge, $url, $platform ); + } else { + $url = get_feed_url( $bridge, $url ); + } + return [ + 'url' => urlencode( $url ), + ]; + }, + 'feed_url' => 'https://%s.blogspot.com/feeds/posts/default', + 'feed_url_data' => function( $pattern, $url ) { + preg_match( $pattern, $url, $matches ); + return $matches[2]; + }, + ], -"jimdo" => array( - "pattern" => '#^(https?://)?([a-zA-Z0-9_-]+\.)*jimdo\.com(/.*)?$#i', - "feed_url" => "https://%sjimdo.com/rss.xml", - "feed_url_data" => function($pattern, $url) { - preg_match($pattern, $url, $matches); - return $matches[2]; - } -), + 'jimdo' => [ + 'pattern' => '#^(https?://)?([a-zA-Z0-9_-]+\.)*jimdo\.com(/.*)?$#i', + 'feed_url' => 'https://%sjimdo.com/rss.xml', + 'feed_url_data' => function( $pattern, $url ) { + preg_match( $pattern, $url, $matches ); + return $matches[2]; + }, + ], - "wordpress" => array( - "pattern" => '#^(https?://)?([a-zA-Z0-9_-]+)\.wordpress\.com(/.*)?$#i', - "bridge_name" => 'WordPress', - "bridge_url_data" => function($bridge, $url, $platform = null) { - return [ - 'url' => urlencode($url) - ]; - }, - "feed_url" => "https://%s.wordpress.com/feed/", - "feed_url_data" => function($pattern, $url) { - preg_match($pattern, $url, $matches); - return $matches[2]; - } - ), + 'wordpress' => [ + 'pattern' => '#^(https?://)?([a-zA-Z0-9_-]+)\.wordpress\.com(/.*)?$#i', + 'bridge_name' => 'WordPress', + 'bridge_url_data' => function( $bridge, $url, $platform = null ) { + return [ + 'url' => urlencode( $url ), + ]; + }, + 'feed_url' => 'https://%s.wordpress.com/feed/', + 'feed_url_data' => function( $pattern, $url ) { + preg_match( $pattern, $url, $matches ); + return $matches[2]; + }, + ], + 'youtube' => [ + 'pattern' => '#^(https?://)?(www\.)?youtube\.com/(channel/|@)([a-zA-Z0-9_-]+)$#i', + // "bridge_url" => "https://www.youtube.com/feeds/videos.xml?%s", + 'bridge_name' => 'YouTube', + 'bridge_url_data' => function( $bridge, $url ) { + preg_match( $bridge['pattern'], $url, $matches ); + $id = ( $matches[3] == 'channel' ) ? 'channel_id' : 'user'; + return [ + $id => $matches[4], + 'min' => '', // needed default + 'max' => '', // needed default + ]; + }, + // "feed_url" => "https://www.youtube.com/feeds/videos.xml?%s", + // "feed_url_data" => function($pattern, $url) { + // preg_match($pattern, $url, $matches); + // $id = ($matches[3] == 'channel') ? 'channel_id' : 'user'; + // return "$id=$matches[4]"; + // } + ], + /* + WORKING BACKUP "youtube" => array( - "pattern" => '#^(https?://)?(www\.)?youtube\.com/(channel/|@)([a-zA-Z0-9_-]+)$#i', - // "bridge_url" => "https://www.youtube.com/feeds/videos.xml?%s", - "bridge_name" => 'YouTube', - "bridge_url_data" => function($bridge, $url) { - preg_match($bridge['pattern'], $url, $matches); - $id = ($matches[3] == 'channel') ? 'channel_id' : 'user'; - return [ - $id => $matches[4], - 'min' => '', // needed default - 'max' => '', // needed default - ]; - }, - #"feed_url" => "https://www.youtube.com/feeds/videos.xml?%s", - #"feed_url_data" => function($pattern, $url) { - # preg_match($pattern, $url, $matches); - # $id = ($matches[3] == 'channel') ? 'channel_id' : 'user'; - # return "$id=$matches[4]"; - #} - ), - /* WORKING BACKUP - "youtube" => array( - "pattern" => '#^(https?://)?(www\.)?youtube\.com/(channel/|@)([a-zA-Z0-9_-]+)$#i', - "feed_url" => "https://www.youtube.com/feeds/videos.xml?%s", - "feed_url_data" => function($pattern, $url) { - preg_match($pattern, $url, $matches); - $id = ($matches[3] == 'channel') ? 'channel_id' : 'user'; - return "$id=$matches[4]"; - } + "pattern" => '#^(https?://)?(www\.)?youtube\.com/(channel/|@)([a-zA-Z0-9_-]+)$#i', + "feed_url" => "https://www.youtube.com/feeds/videos.xml?%s", + "feed_url_data" => function($pattern, $url) { + preg_match($pattern, $url, $matches); + $id = ($matches[3] == 'channel') ? 'channel_id' : 'user'; + return "$id=$matches[4]"; + } ), "youtube" => array( - "pattern" => '#^(https?://)?(www\.)?youtube\.com/channel/([a-zA-Z0-9_-]+)$#i', - "feed_url" => "https://www.youtube.com/feeds/videos.xml?channel_id=%s", - "feed_url_data" => function($pattern, $url) { - preg_match($pattern, $url, $matches); - return $matches[3]; - } + "pattern" => '#^(https?://)?(www\.)?youtube\.com/channel/([a-zA-Z0-9_-]+)$#i', + "feed_url" => "https://www.youtube.com/feeds/videos.xml?channel_id=%s", + "feed_url_data" => function($pattern, $url) { + preg_match($pattern, $url, $matches); + return $matches[3]; + } ),*/ -"vimeo" => array( - "pattern" => '#^(https?://)?(www\.)?vimeo\.com/([a-zA-Z0-9_-]+)$#i', - "feed_url" => "https://vimeo.com/%s/videos/rss", - "feed_url_data" => function($pattern, $url) { - preg_match($pattern, $url, $matches); - return $matches[3]; - } -), + 'vimeo' => [ + 'pattern' => '#^(https?://)?(www\.)?vimeo\.com/([a-zA-Z0-9_-]+)$#i', + 'feed_url' => 'https://vimeo.com/%s/videos/rss', + 'feed_url_data' => function( $pattern, $url ) { + preg_match( $pattern, $url, $matches ); + return $matches[3]; + }, + ], - "flickr" => array( - "pattern" => '#^(https?://)?(www\.)?flickr\.com/photos/([a-zA-Z0-9@]+)(/albums/([a-zA-Z0-9_-]+))?/?#i', - "bridge_name" => 'Flickr', - "bridge_url_data" => function($bridge, $url) { - preg_match($bridge['pattern'], $url, $matches); - return [ - 'id' => $matches[3], - ]; - }, - #"feed_url" => "https://www.flickr.com/photos/%s/rss", - #"feed_url_data" => function($pattern, $url) { - # preg_match($pattern, $url, $matches); - # return $matches[3]; - #} - ), - - "tiktok" => array( - "pattern" => '#^(https?://)?(www\.)?tiktok\.com/@([a-zA-Z0-9_]+)(/.*)?(\\?.*)?(\\#.*?)?$#i', - "bridge_name" => 'FeedMerger', - "bridge_url_data" => function($bridge, $url) { - $url = get_feed_url( $bridge, $url ); - return [ - 'url' => urlencode( $url ) - ]; - }, - "feed_url" => "https://www.tiktok.com/@%s/rss", - "feed_url_data" => function($pattern, $url) { - preg_match($pattern, $url, $matches); - return $matches[3]; - } - ), + 'flickr' => [ + 'pattern' => '#^(https?://)?(www\.)?flickr\.com/photos/([a-zA-Z0-9@]+)(/albums/([a-zA-Z0-9_-]+))?/?#i', + 'bridge_name' => 'Flickr', + 'bridge_url_data' => function( $bridge, $url ) { + preg_match( $bridge['pattern'], $url, $matches ); + return [ + 'id' => $matches[3], + ]; + }, + // "feed_url" => "https://www.flickr.com/photos/%s/rss", + // "feed_url_data" => function($pattern, $url) { + // preg_match($pattern, $url, $matches); + // return $matches[3]; + // } + ], - #"facebook" => array( - # "pattern" => '#^(https?://)?(www\.)?facebook\.com/([a-zA-Z0-9.-]+)/?$#i', - # "feed_url" => "https://www.facebook.com/%s/posts/rss", - # "feed_url_data" => function($pattern, $url) { - # preg_match($pattern, $url, $matches); - # return $matches[3]; - # } - #), + 'tiktok' => [ + 'pattern' => '#^(https?://)?(www\.)?tiktok\.com/@([a-zA-Z0-9_]+)(/.*)?(\\?.*)?(\\#.*?)?$#i', + 'bridge_name' => 'FeedMerger', + 'bridge_url_data' => function( $bridge, $url ) { + $url = get_feed_url( $bridge, $url ); + return [ + 'url' => urlencode( $url ), + ]; + }, + 'feed_url' => 'https://www.tiktok.com/@%s/rss', + 'feed_url_data' => function( $pattern, $url ) { + preg_match( $pattern, $url, $matches ); + return $matches[3]; + }, + ], + // "facebook" => array( + // "pattern" => '#^(https?://)?(www\.)?facebook\.com/([a-zA-Z0-9.-]+)/?$#i', + // "feed_url" => "https://www.facebook.com/%s/posts/rss", + // "feed_url_data" => function($pattern, $url) { + // preg_match($pattern, $url, $matches); + // return $matches[3]; + // } + // ), - ); + ]; } diff --git a/inc/rss-bridge/class-detector.php_ b/inc/rss-bridge/class-detector.php_ index 222eaca..b53a7fa 100644 --- a/inc/rss-bridge/class-detector.php_ +++ b/inc/rss-bridge/class-detector.php_ @@ -21,8 +21,12 @@ function bootstrap_detector() { add_action( 'plugins_loaded', __NAMESPACE__ . '\\load_plugin', 9 ); } - -function load_plugin() { +/** + * Conditionally load the plugin itself and its modifications. + * + * @return void + */ +function load_plugin() :void { // Do only load in "normal" admin view // and public views @@ -31,7 +35,7 @@ function load_plugin() { // - user-admin views #if ( is_network_admin() || is_user_admin() ) # return; - + require_once PLUGINPATH; } */ @@ -51,18 +55,18 @@ class Detector * The Class Object */ static private $instance = null; - + function __construct() {} public static function get_importable_services() : array { - + return [ ]; } public static function find_importable_endpoint( int $post_ID, WP_Post $post, bool $update ) : void { - + // run only on the first run if ( $update ) return; @@ -72,7 +76,7 @@ class Detector return; // make sure it is a well formed URL - $new_url = esc_url( + $new_url = esc_url( $post->post_content, [ 'http', @@ -87,12 +91,12 @@ class Detector // well prepared, // let's go - // + // // hand the URL to our RSS-detective if ( static::has_importable_endpoint( $new_url ) ){ // we found something ... } - # wp_set_object_terms( + # wp_set_object_terms( # $post_ID, # [ # 'is-importable', @@ -109,7 +113,7 @@ class Detector $found = false; foreach ( static::get_importable_services() as $url_to_search => $pattern ) { - + if ( $found ) return $found; @@ -117,11 +121,11 @@ class Detector #\do_action( 'qm/info', sprintf( $pattern, $new_url ) . ' can be imported.' ); $found = true; - do_action( + do_action( __NAMESPACE__ . '\\found_importable_endpoint', sprintf( $pattern, $new_url ) ); - } + } } if ( $found ) diff --git a/inc/rss-bridge/detector.php b/inc/rss-bridge/detector.php index bf83788..7617893 100644 --- a/inc/rss-bridge/detector.php +++ b/inc/rss-bridge/detector.php @@ -19,7 +19,6 @@ const CustomDomainRegex = '/^[a-zA-Z0-9]+([\-\.]{1}[a-zA-Z0-9]+)*\.[a-zA-Z]{2,}$/i'; - /** * Extracts the custom domain from a given URL. * @@ -28,42 +27,40 @@ * @return string|null The extracted custom domain, or null if not found. */ function get_custom_domain( string $url ): ?string { - // Get the host name from the URL. - $parts = parse_url($url); - if (!isset($parts['host'])) { - return null;// Invalid URL, no host found. - } - $host = $parts['host']; - - // Check if the custom domain is valid. - $matches = []; - # $customDomainRegex = '/^[a-zA-Z0-9]+([\-\.]{1}[a-zA-Z0-9]+)*\.[a-zA-Z]{2,}$/i'; - $customDomainRegex = CustomDomainRegex; - preg_match($customDomainRegex, $host, $matches); - - return isset($matches[0]) ? $matches[0] : null; -} - + // Get the host name from the URL. + $parts = parse_url( $url ); + if ( ! isset( $parts['host'] ) ) { + return null;// Invalid URL, no host found. + } + $host = $parts['host']; -function get_bridge_for_domain(string $domain): ?array { - $bridges = get_bridges(); - foreach ($bridges as $bridge) { + // Check if the custom domain is valid. + $matches = []; + // $customDomainRegex = '/^[a-zA-Z0-9]+([\-\.]{1}[a-zA-Z0-9]+)*\.[a-zA-Z]{2,}$/i'; + $customDomainRegex = CustomDomainRegex; + preg_match( $customDomainRegex, $host, $matches ); - if (preg_match($bridge['pattern'], $domain, $matches)) { - return $bridge; - } - } - return null; + return isset( $matches[0] ) ? $matches[0] : null; } -function get_bridge_for_platform(string $platform): ?array { - $bridges = get_bridges(); - if (isset($bridges[$platform])) { - return $bridges[$platform]; - } - return null; +function get_bridge_for_domain( string $domain ): ?array { + $bridges = get_bridges(); + foreach ( $bridges as $bridge ) { + + if ( preg_match( $bridge['pattern'], $domain, $matches ) ) { + return $bridge; + } + } + return null; } +function get_bridge_for_platform( string $platform ): ?array { + $bridges = get_bridges(); + if ( isset( $bridges[ $platform ] ) ) { + return $bridges[ $platform ]; + } + return null; +} /** * Generate an RSS Bridge URL from the given bridge name and parameters. @@ -76,153 +73,148 @@ function get_bridge_for_platform(string $platform): ?array { * @example https://figuren.test/content/mu-plugins/rss-bridge-master/?action=display&bridge=WordPressBridge&url=https%3A%2F%2Fjuliaraab.de%2F&limit=3&content-selector=&format=Atom */ function generate_rss_bridge_url_from_params( string $bridge, array $params ) : string { - // - // $rss_bridge_base_url = get_site_url( null, '/content/mu-plugins/rss-bridge-master/index.php' ); - $rss_bridge_base_url = plugins_url( 'index.php', dirname( PLUGINPATH ) ); - - - // $query_params = http_build_query( [ 'format' => 'Atom', 'bridge' => $bridge ] + $params ); - // return 'https://..../display/?' . $query_params; - - // Build the query string parameters for the RSS Bridge API URL. - $params = wp_parse_args( - $params, - [ - 'action' => 'display', - 'format' => 'Atom', - 'bridge' => $bridge - ] - ); - - // Combine the query string parameters with the base URL. - return esc_url_raw( - add_query_arg( - $params, - $rss_bridge_base_url - ) - ); + // + // $rss_bridge_base_url = get_site_url( null, '/content/mu-plugins/rss-bridge-master/index.php' ); + $rss_bridge_base_url = plugins_url( 'index.php', dirname( PLUGINPATH ) ); + + // $query_params = http_build_query( [ 'format' => 'Atom', 'bridge' => $bridge ] + $params ); + // return 'https://..../display/?' . $query_params; + + // Build the query string parameters for the RSS Bridge API URL. + $params = wp_parse_args( + $params, + [ + 'action' => 'display', + 'format' => 'Atom', + 'bridge' => $bridge, + ] + ); + + // Combine the query string parameters with the base URL. + return esc_url_raw( + add_query_arg( + $params, + $rss_bridge_base_url + ) + ); } function get_bridge_url( array $bridge, string $url, ?string $platform = null ) : ?string { - if ( ! isset($bridge['bridge_url_data'])) { + if ( ! isset( $bridge['bridge_url_data'] ) ) { return null; } - // Call the bridge to get the feed URL - $bridge_url_data = call_user_func($bridge['bridge_url_data'], $bridge, $url, $platform ); + // Call the bridge to get the feed URL. + $bridge_url_data = call_user_func( $bridge['bridge_url_data'], $bridge, $url, $platform ); - // the bridged feed - return generate_rss_bridge_url_from_params( $bridge['bridge_name'], $bridge_url_data ); + // The bridged feed. + return generate_rss_bridge_url_from_params( $bridge['bridge_name'], $bridge_url_data ); } - function get_custom_feed_url( array $bridge, string $url, ?string $platform = null ) : string { - if ($platform) { - $domain = get_custom_domain($url); - } - if (is_string($domain)) { - $url_parts = parse_url($url); - $feed_url_parts = parse_url($bridge['feed_url']); + if ( $platform ) { + $domain = get_custom_domain( $url ); + } + if ( is_string( $domain ) ) { + $url_parts = parse_url( $url ); + $feed_url_parts = parse_url( $bridge['feed_url'] ); - // update the host with the custom domain-name - $feed_url_parts['host'] = $url_parts['host']; + // Update the host with the custom domain-name. + $feed_url_parts['host'] = $url_parts['host']; - // re-glue everything together - $custom_feed_url = $feed_url_parts["scheme"]."://".$feed_url_parts["host"].$feed_url_parts['path']; + // Re-glue everything together. + $custom_feed_url = $feed_url_parts['scheme'] . '://' . $feed_url_parts['host'] . $feed_url_parts['path']; - // create a pseudo-bridge for the next run of get_feed_url() - $bridge['feed_url'] = $custom_feed_url; - $bridge['pattern'] = CustomDomainRegex; - } + // Create a pseudo-bridge for the next run of get_feed_url(). + $bridge['feed_url'] = $custom_feed_url; + $bridge['pattern'] = CustomDomainRegex; + } - return get_feed_url( $bridge, $url ); + return get_feed_url( $bridge, $url ); } function get_feed_url( array $bridge, string $url ) : string { - if ( ! isset($bridge['feed_url_data'])) { + if ( ! isset( $bridge['feed_url_data'] ) ) { return ''; } - // Call the bridge to get the feed URL - $feed_url = call_user_func($bridge['feed_url_data'], $bridge['pattern'], $url ); + // Call the bridge to get the feed URL. + $feed_url = call_user_func( $bridge['feed_url_data'], $bridge['pattern'], $url ); - // the normal feed - return sprintf($bridge['feed_url'], $feed_url ); + // the normal feed + return sprintf( $bridge['feed_url'], $feed_url ); } function is_feed_ok( string $url ) : bool { - $response = wp_remote_get( set_url_scheme( $url, 'https' ) ); + $response = wp_remote_get( set_url_scheme( $url, 'https' ) ); - if ( ! is_wp_error( $response ) ) { - $status = wp_remote_retrieve_response_code( $response ); - // if ( 200 == $status || 301 == $status || 302 == $status ) { - if ( 200 == $status ) { - return true; - } - } + if ( ! is_wp_error( $response ) ) { + $status = wp_remote_retrieve_response_code( $response ); + if ( 200 == $status ) { + return true; + } + } - return false; + return false; } - /** * Detect which rss-brige to use, * based on the given URL and|or * the suggested bridge given by the author * - * @param string $url The websites source URL to get data from - * @param string $suggested_bridge Suggested bridge given by the author during post_creation. + * @param string $url The websites source URL to get data from + * @param string $platform Suggested bridge given by the author during post_creation. * * @return string URL to the feed */ -function get_bridged_url(string $url, ?string $platform = null): ?string { - // Remove any trailing slashes from the URL - $url = rtrim($url, '/'); - - $bridge = false; - - // Extract the domain from the URL - if ($platform) { - $bridge = get_bridge_for_platform($platform); - } - - // - // Check if we have a bridge for the domain - // if no platform was given or - // even if a platform was set, but nothing was found - if (!$bridge) { - $bridge = get_bridge_for_domain($url); - } - - // try to find a bridge Adapter - if ($bridge) { - $bridged_url = get_bridge_url( $bridge, $url, $platform ); - #if ($bridged_url) { - # // the bridged feed - # return $bridged_url; - #} - } +function get_bridged_url( string $url, ?string $platform = null ): ?string { + // Remove any trailing slashes from the URL. + $url = rtrim( $url, '/' ); + + $bridge = false; + + // Extract the domain from the URL. + if ( $platform ) { + $bridge = get_bridge_for_platform( $platform ); + } + + // + // Check if we have a bridge for the domain + // if no platform was given or + // even if a platform was set, but nothing was found. + if ( ! $bridge ) { + $bridge = get_bridge_for_domain( $url ); + } + + // Try to find a bridge Adapter. + if ( $bridge ) { + $bridged_url = get_bridge_url( $bridge, $url, $platform ); + // if ($bridged_url) { + // // the bridged feed + // return $bridged_url; + // } + } /* WORKING, used as fallback */ - if ($bridge && !$bridged_url) { - // the normal feed - $bridged_url = get_feed_url( $bridge, $url ); - } + if ( $bridge && ! $bridged_url ) { + // the normal feed + $bridged_url = get_feed_url( $bridge, $url ); + } - // Make sure we have a valid response, - // which means status codes 200, 301 or 302 - if ( is_feed_ok( $bridged_url ) ) { - return $bridged_url; - } + // Make sure we have a valid response, + // which means status codes 200, 301 or 302. + if ( is_feed_ok( $bridged_url ) ) { + return $bridged_url; + } return null; } - -############################################################################## -########################## just for debugging ################################ -############################################################################## +// +// just for debugging ################################ +// /* echo '
';
@@ -230,22 +222,22 @@ function get_bridged_url(string $url, ?string $platform = null): ?string {
 echo "

"; echo "

"; $given_urls = [ - ['https://scubulus.org','webflow'], - ['https://tata.live','blogspot'], - ['https://ololololololololol.com/','tumblr'], + ['https://scubulus.org','webflow'], + ['https://tata.live','blogspot'], + ['https://ololololololololol.com/','tumblr'], ['https://theaterpaedagpgik.leipzig','jimdo'], - ['https://mein.schickes.figuren.theater/','wordpress'], - ['https://ft123.wordpress.com/','wordpress'], - ['https://ft123.abc/','wordpress'], - ['https://ft123.xyz/abcdefghjik/','wordpress'], + ['https://mein.schickes.figuren.theater/','WordPress'], + ['https://ft123.wordpress.com/','wordpress'], + ['https://ft123.abc/','WordPress'], + ['https://ft123.xyz/abcdefghjik/','WordPress'], ]; $output_urls = $given_urls; // this line just helps debugging foreach ($output_urls as $given_url) { - $rss_bridge_url = get_bridged_url($given_url[0], $given_url[1]); - // $rss_bridge_url = get_bridge_from_url($given_url); - echo "$given_url[0]\n"; - echo "==> $rss_bridge_url\n\n\n"; + $rss_bridge_url = get_bridged_url($given_url[0], $given_url[1]); + // $rss_bridge_url = get_bridge_from_url($given_url); + echo "$given_url[0]\n"; + echo "==> $rss_bridge_url\n\n\n"; } @@ -257,22 +249,22 @@ function get_bridged_url(string $url, ?string $platform = null): ?string { 'https://ololololololololol.tumblr.com/', 'https://theaterpaedagpgik-leipzig.jimdo.com', 'https://ft123.wordpress.com/cat-or-tag-or-term/', - 'https://www.facebook.com/figuren.theater.dach/', + 'https://www.facebook.com/figuren.theater.dach/', 'https://www.tiktok.com/@olaf_scholz', - 'https://medium.com/@ololololololololol/', - 'https://twitter.com/figuren_theater', - 'https://twitter.com/OpenAI/status/1104858619893089282', - 'https://www.youtube.com/channel/UCBR8-60-B28hp2BmDPdntcQ', - 'https://www.youtube.com/@paulpanether', - 'https://www.flickr.com/photos/127356892@N06/49741958331/in/album-72157713692908818/', + 'https://medium.com/@ololololololololol/', + 'https://twitter.com/figuren_theater', + 'https://twitter.com/OpenAI/status/1104858619893089282', + 'https://www.youtube.com/channel/UCBR8-60-B28hp2BmDPdntcQ', + 'https://www.youtube.com/@paulpanether', + 'https://www.flickr.com/photos/127356892@N06/49741958331/in/album-72157713692908818/', ]; $output_urls = $given_urls; // this line just helps debugging foreach ($output_urls as $given_url) { - $rss_bridge_url = get_bridged_url($given_url); - // $rss_bridge_url = get_bridge_from_url($given_url); - echo "$given_url\n"; - echo "==> $rss_bridge_url\n\n\n"; + $rss_bridge_url = get_bridged_url($given_url); + // $rss_bridge_url = get_bridge_from_url($given_url); + echo "$given_url\n"; + echo "==> $rss_bridge_url\n\n\n"; } diff --git a/inc/rss-bridge/namespace.php b/inc/rss-bridge/namespace.php index 8d36ba1..9a7d520 100644 --- a/inc/rss-bridge/namespace.php +++ b/inc/rss-bridge/namespace.php @@ -7,43 +7,46 @@ namespace Figuren_Theater\Data\Rss_Bridge; -use FT_VENDOR_DIR; - use Figuren_Theater; -use function Figuren_Theater\get_config; use function add_action; use function is_admin; use function is_network_admin; use function is_user_admin; - const BASENAME = 'rss-bridge/index.php'; const PLUGINPATH = '/rss-bridge/' . BASENAME; /** * Bootstrap module, when enabled. + * + * @return void */ -function bootstrap() { +function bootstrap() :void { add_action( 'init', __NAMESPACE__ . '\\load_plugin' ); } - -function load_plugin() { - $config = Figuren_Theater\get_config()['modules']['data']; - if ( ! $config['feed-pull'] ) - return; // early +/** + * Conditionally load the plugin itself and its modifications. + * + * @return void + */ +function load_plugin() :void { + $config = Figuren_Theater\get_config()['modules']['data']; + if ( ! $config['feed-pull'] ) { + return; + } // Do only load in "normal" admin view // Not for: // - public views // - network-admin views - // - user-admin views - if ( is_network_admin() || is_user_admin() || ! is_admin() ) + // - user-admin views. + if ( is_network_admin() || is_user_admin() || ! is_admin() ) { return; + } - #require_once PLUGINPATH; - + // require_once FT_VENDOR_DIR . PLUGINPATH; // phpcs:ignore WordPressVIPMinimum.Files.IncludingFile.UsingCustomConstant // @todo #19 When / where to load rss-bridge? } diff --git a/inc/term-management-tools/namespace.php b/inc/term-management-tools/namespace.php index ca9f317..d78678b 100644 --- a/inc/term-management-tools/namespace.php +++ b/inc/term-management-tools/namespace.php @@ -18,16 +18,24 @@ /** * Bootstrap module, when enabled. + * + * @return void */ -function bootstrap() { +function bootstrap() :void { add_action( 'plugins_loaded', __NAMESPACE__ . '\\load_plugin' ); } -function load_plugin() { +/** + * Conditionally load the plugin itself and its modifications. + * + * @return void + */ +function load_plugin() :void { - if ( ! is_admin() || wp_doing_cron() ) + if ( ! is_admin() || wp_doing_cron() ) { return; + } require_once FT_VENDOR_DIR . PLUGINPATH; // phpcs:ignore WordPressVIPMinimum.Files.IncludingFile.UsingCustomConstant } diff --git a/inc/utility-taxonomy/namespace.php b/inc/utility-taxonomy/namespace.php index 4364103..9a4e276 100644 --- a/inc/utility-taxonomy/namespace.php +++ b/inc/utility-taxonomy/namespace.php @@ -16,13 +16,20 @@ /** * Bootstrap module, when enabled. + * + * @return void */ -function bootstrap() { +function bootstrap() :void { add_action( 'plugins_loaded', __NAMESPACE__ . '\\load_plugin' ); } -function load_plugin() { +/** + * Conditionally load the plugin itself and its modifications. + * + * @return void + */ +function load_plugin() :void { require_once FT_VENDOR_DIR . PLUGINPATH; // phpcs:ignore WordPressVIPMinimum.Files.IncludingFile.UsingCustomConstant } diff --git a/phpstan.neon b/phpstan.neon index 3de0362..a4492e4 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -8,6 +8,12 @@ parameters: - templates/ - plugin.php excludePaths: + analyseAndScan: + # The RSS-Bridge configuration file must not follow other standards then RSS-Bridge's standards. + - templates/htdocs/vendor/rss-bridge + # Prevent phpstan from multiple definitions of the same things, + # because we already use phpstan/wordpress-stubs + - wordpress/ analyse: - vendor/ # "/wp-content/" is created during composer install, @@ -18,3 +24,4 @@ parameters: ignoreErrors: # Find a nicer way instead of ignoring this Error on every ft-module - '#Function Altis\\register_module not found\.#' + - '#Function Figuren_Theater\\get_config not found\.#'