From 1392d63e1f6cf0c896c0daa617d7a3583793cbae Mon Sep 17 00:00:00 2001 From: Andrew Shell Date: Mon, 16 Mar 2026 12:49:34 -0500 Subject: [PATCH] Installing phpcs and updating based on WordPress Coding Standards --- .gitignore | 2 + composer.json | 17 ++++ data-storage.php | 23 +++++- notification-request.php | 142 ++++++++++++++++++++++---------- phpcs.xml.dist | 22 +++++ rsscloud.php | 122 ++++++++++++++++++--------- schedule-post-notifications.php | 23 ++++-- send-post-notifications.php | 66 ++++++++++----- 8 files changed, 302 insertions(+), 115 deletions(-) create mode 100644 .gitignore create mode 100644 composer.json create mode 100644 phpcs.xml.dist diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3a9875b --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/vendor/ +composer.lock diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..283b4f4 --- /dev/null +++ b/composer.json @@ -0,0 +1,17 @@ +{ + "name": "developer/rsscloud", + "description": "RSS Cloud plugin for WordPress", + "require-dev": { + "wp-coding-standards/wpcs": "^3.0", + "dealerdirect/phpcodesniffer-composer-installer": "^1.0" + }, + "config": { + "allow-plugins": { + "dealerdirect/phpcodesniffer-composer-installer": true + } + }, + "scripts": { + "lint": "phpcs", + "lint:fix": "phpcbf" + } +} diff --git a/data-storage.php b/data-storage.php index 3c1b2c0..8defb1d 100644 --- a/data-storage.php +++ b/data-storage.php @@ -1,11 +1,28 @@ 'GET', 'timeout' => RSSCLOUD_HTTP_TIMEOUT, 'user-agent' => RSSCLOUD_USER_AGENT, 'port' => $port, ) ); + } + + $challenge = rsscloud_generate_challenge(); + + $post_url1 = sanitize_text_field( wp_unslash( $_POST['url1'] ) ); + $result = wp_safe_remote_get( + $notify_url . '?url=' . esc_url( $post_url1 ) . '&challenge=' . $challenge, + array( + 'method' => 'GET', + 'timeout' => RSSCLOUD_HTTP_TIMEOUT, + 'user-agent' => RSSCLOUD_USER_AGENT, + 'port' => $port, + ) + ); } else { - if ( false === strpos( $notify_url, 'http://' ) ) + if ( false === strpos( $notify_url, 'http://' ) ) { $notify_url = 'http://' . $notify_url; - - $result = wp_safe_remote_post( $notify_url, array( 'method' => 'POST', 'timeout' => RSSCLOUD_HTTP_TIMEOUT, 'user-agent' => RSSCLOUD_USER_AGENT, 'port' => $port, 'body' => array( 'url' => $_POST['url1'] ) ) ); + } + + $post_url1 = sanitize_text_field( wp_unslash( $_POST['url1'] ) ); + $result = wp_safe_remote_post( + $notify_url, + array( + 'method' => 'POST', + 'timeout' => RSSCLOUD_HTTP_TIMEOUT, + 'user-agent' => RSSCLOUD_USER_AGENT, + 'port' => $port, + 'body' => array( 'url' => $post_url1 ), + ) + ); } - if ( isset( $result->errors['http_request_failed'][0] ) ) + if ( isset( $result->errors['http_request_failed'][0] ) ) { rsscloud_notify_result( 'false', 'Error testing notification URL : ' . $result->errors['http_request_failed'][0] ); + } $status_code = (int) $result['response']['code']; - if ( $status_code < 200 || $status_code > 299 ) + if ( $status_code < 200 || $status_code > 299 ) { rsscloud_notify_result( 'false', 'Error testing notification URL. The URL returned HTTP status code: ' . $result['response']['code'] . ' - ' . $result['response']['message'] . '.' ); + } - // challenge must match for domain requests - if ( !empty( $_POST['domain'] ) ) { - if ( empty( $result['body'] ) || $result['body'] != $challenge ) + // Challenge must match for domain requests. + if ( ! empty( $_POST['domain'] ) ) { + if ( empty( $result['body'] ) || $result['body'] !== $challenge ) { rsscloud_notify_result( 'false', 'The response body did not match the challenge string' ); - + } } - // Passed all the tests, add this to the list of notifications for + // Passed all the tests, add this to the list of notifications. foreach ( $_POST as $key => $feed_url ) { - if ( !preg_match( '|url\d+|', $key ) ) + if ( ! preg_match( '|url\d+|', $key ) ) { continue; + } + + $feed_url = sanitize_text_field( wp_unslash( $feed_url ) ); - // Only allow requests for the RSS2 posts feed - if ( $feed_url != $rss2_url ) + // Only allow requests for the RSS2 posts feed. + if ( $feed_url !== $rss2_url ) { rsscloud_notify_result( 'false', "You can only request updates for {$rss2_url}" ); + } - $notify[$feed_url][$notify_url]['protocol'] = $protocol; - $notify[$feed_url][$notify_url]['status'] = 'active'; - $notify[$feed_url][$notify_url]['failure_count'] = 0; + $notify[ $feed_url ][ $notify_url ]['protocol'] = $protocol; + $notify[ $feed_url ][ $notify_url ]['status'] = 'active'; + $notify[ $feed_url ][ $notify_url ]['failure_count'] = 0; } do_action( 'rsscloud_add_notify_subscription' ); rsscloud_update_hub_notifications( $notify ); rsscloud_notify_result( 'true', 'Registration successful.' ); -} // function rsscloud_hub_notify +} diff --git a/phpcs.xml.dist b/phpcs.xml.dist new file mode 100644 index 0000000..c596073 --- /dev/null +++ b/phpcs.xml.dist @@ -0,0 +1,22 @@ + + + WordPress Coding Standards for RSS Cloud plugin. + + + + + + + + . + /vendor/* + + + + + + + + /notification-request.php + + diff --git a/rsscloud.php b/rsscloud.php index 686567e..395369e 100644 --- a/rsscloud.php +++ b/rsscloud.php @@ -1,101 +1,141 @@ query_vars ) ) { - if ( $wp->query_vars['rsscloud'] == 'notify' ) - rsscloud_hub_process_notification_request( ); + if ( 'notify' === $wp->query_vars['rsscloud'] ) { + rsscloud_hub_process_notification_request(); + } exit; } } +/** + * Output an XML notification result and terminate execution. + * + * @param string $success Whether the operation succeeded ('true' or 'false'). + * @param string $msg A message describing the result. + */ function rsscloud_notify_result( $success, $msg ) { - $success = strip_tags( $success ); + $success = wp_strip_all_tags( $success ); $success = ent2ncr( $success ); - $success = esc_html( $success ); + $success = esc_attr( $success ); - $msg = strip_tags( $msg ); + $msg = wp_strip_all_tags( $msg ); $msg = ent2ncr( $msg ); - $msg = esc_html( $msg ); + $msg = esc_attr( $msg ); header( 'Content-Type: text/xml' ); echo "\n"; - echo "\n"; + echo "\n"; exit; } add_action( 'rss2_head', 'rsscloud_add_rss_cloud_element' ); -function rsscloud_add_rss_cloud_element( ) { - if ( !is_feed() ) { + +/** + * Add the cloud element to the RSS2 feed head. + */ +function rsscloud_add_rss_cloud_element() { + if ( ! is_feed() ) { return; } - $cloud = parse_url( get_option( 'home' ) . '/?rsscloud=notify' ); + $cloud = wp_parse_url( get_option( 'home' ) . '/?rsscloud=notify' ); - $cloud['port'] = (int) $cloud['port']; - if ( empty( $cloud['port'] ) ) + $cloud['port'] = isset( $cloud['port'] ) ? (int) $cloud['port'] : 80; + if ( empty( $cloud['port'] ) ) { $cloud['port'] = 80; + } - $cloud['path'] .= "?{$cloud['query']}"; + $cloud['path'] .= "?{$cloud['query']}"; - $cloud['host'] = strtolower( $cloud['host'] ); + $cloud['host'] = strtolower( $cloud['host'] ); - echo ""; echo "\n"; } +/** + * Generate a random challenge string. + * + * @param int $length The length of the challenge string. Default 30. + * @return string The generated challenge string. + */ function rsscloud_generate_challenge( $length = 30 ) { - $chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'; - $chars_length = strlen( $chars ); + $chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'; + $chars_length = strlen( $chars ); - $string = ''; + $string = ''; if ( function_exists( 'openssl_random_pseudo_bytes' ) ) { $string = bin2hex( openssl_random_pseudo_bytes( $length / 2 ) ); } else { - for ( $i = 0; $i < $length; $i++ ) { - $string .= $chars[mt_rand( 0, $chars_length - 1)]; + for ( $i = 0; $i < $length; $i++ ) { + $string .= $chars[ wp_rand( 0, $chars_length - 1 ) ]; } } - return $string; + return $string; } diff --git a/schedule-post-notifications.php b/schedule-post-notifications.php index e3f61aa..46dc5f7 100644 --- a/schedule-post-notifications.php +++ b/schedule-post-notifications.php @@ -1,12 +1,25 @@ $n ) { - if ( $n['status'] != 'active' ) + foreach ( $notify[ $rss2_url ] as $notify_url => $n ) { + if ( 'active' !== $n['status'] ) { continue; + } - if ( $n['protocol'] == 'http-post' ) { - $url = parse_url( $notify_url ); + if ( 'http-post' === $n['protocol'] ) { + $url = parse_url( $notify_url ); $port = 80; - if ( !empty( $url['port'] ) ) + if ( ! empty( $url['port'] ) ) { $port = $url['port']; + } - $result = wp_safe_remote_post( $notify_url, array( 'method' => 'POST', 'timeout' => RSSCLOUD_HTTP_TIMEOUT, 'user-agent' => RSSCLOUD_USER_AGENT, 'port' => $port, 'body' => array( 'url' => $rss2_url ) ) ); + $result = wp_safe_remote_post( + $notify_url, + array( + 'method' => 'POST', + 'timeout' => RSSCLOUD_HTTP_TIMEOUT, + 'user-agent' => RSSCLOUD_USER_AGENT, + 'port' => $port, + 'body' => array( 'url' => $rss2_url ), + ) + ); do_action( 'rsscloud_send_notification' ); - if ( !is_wp_error( $result ) ) + if ( ! is_wp_error( $result ) ) { $status_code = (int) $result['response']['code']; + } if ( is_wp_error( $result ) || ( $status_code < 200 || $status_code > 299 ) ) { do_action( 'rsscloud_notify_failure' ); - $notify[$rss2_url][$notify_url]['failure_count']++; + ++$notify[ $rss2_url ][ $notify_url ]['failure_count']; - if ( $notify[$rss2_url][$notify_url]['failure_count'] > RSSCLOUD_MAX_FAILURES ) { + if ( $notify[ $rss2_url ][ $notify_url ]['failure_count'] > RSSCLOUD_MAX_FAILURES ) { do_action( 'rsscloud_suspend_notification_url' ); - $notify[$rss2_url][$notify_url]['status'] = 'suspended'; + $notify[ $rss2_url ][ $notify_url ]['status'] = 'suspended'; } $need_update = true; - } elseif ( $notify[$rss2_url][$notify_url]['failure_count'] > 0 ) { + } elseif ( $notify[ $rss2_url ][ $notify_url ]['failure_count'] > 0 ) { do_action( 'rsscloud_reset_failure_count' ); - $notify[$rss2_url][$notify_url]['failure_count'] = 0; + $notify[ $rss2_url ][ $notify_url ]['failure_count'] = 0; $need_update = true; } } - } // foreach + } - if ( $need_update ) + if ( $need_update ) { rsscloud_update_hub_notifications( $notify ); - + } }