Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Staging release: v20250114.1 #6099

Merged
merged 5 commits into from
Jan 14, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions 000-vip-init.php
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,9 @@
if ( ( defined( 'USE_VIP_ELASTICSEARCH' ) && USE_VIP_ELASTICSEARCH ) || // legacy constant name
( defined( 'VIP_ENABLE_VIP_SEARCH' ) && true === VIP_ENABLE_VIP_SEARCH ) ) {
require_once __DIR__ . '/search/search.php';
if ( ! defined( 'VIP_SEARCH_ENABLED_BY' ) ) {
define( 'VIP_SEARCH_ENABLED_BY', 'constant' );
}
}

// Set WordPress environment type
Expand Down
2 changes: 2 additions & 0 deletions config/class-site-details-index.php
Original file line number Diff line number Diff line change
Expand Up @@ -260,10 +260,12 @@ public function get_search_info() {
$search_info['enabled'] = true;
$search_info['query_integration_enabled'] = \Automattic\VIP\Search\Search::is_query_integration_enabled();
$search_info['network_enabled'] = defined( 'EP_IS_NETWORK' ) && true === constant( 'EP_IS_NETWORK' );
$search_info['enabled_by'] = defined( 'VIP_SEARCH_ENABLED_BY' ) ? constant( 'VIP_SEARCH_ENABLED_BY' ) : 'unknown';
} else {
$search_info['enabled'] = false;
$search_info['query_integration_enabled'] = false;
$search_info['network_enabled'] = false;
$search_info['enabled_by'] = false;
}

return $search_info;
Expand Down
3 changes: 1 addition & 2 deletions cron/cron-control/.github/workflows/ci-grunt.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ env:

jobs:
build:
if: "!contains(github.event.head_commit.message, '[ci skip]')"
name: Run Grunt tasks
runs-on: ubuntu-latest
steps:
Expand All @@ -24,7 +23,7 @@ jobs:
uses: actions/[email protected]
with:
node-version: ${{ env.NODE_VERSION }}
caching: true
cache: npm

- name: Install dependencies
run: npm ci --ignore-scripts
Expand Down
29 changes: 9 additions & 20 deletions cron/cron-control/.github/workflows/ci-php.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,15 @@ jobs:
test:
name: Run tests
runs-on: ubuntu-latest
if: "!contains(github.event.head_commit.message, '[ci skip]')"
strategy:
fail-fast: false
matrix:
php:
- "7.4"
- "8.0"
- "8.1"
- "8.2"
- "8.3"
- "8.4"
wpmu:
- "0"
- "1"
Expand All @@ -34,6 +36,9 @@ jobs:
- 3306
options: --health-cmd="healthcheck.sh --innodb_initialized" --health-interval=5s --health-timeout=2s --health-retries=3
steps:
- name: Install svn
run: sudo apt-get update && sudo apt-get install -y subversion

- name: Check out source code
uses: actions/[email protected]

Expand All @@ -42,24 +47,8 @@ jobs:
with:
php-version: ${{ matrix.php }}

- name: Get composer cache directory
id: composer-cache
run: echo "::set-output name=dir::$(composer config cache-files-dir)"

- name: Cache Composer packages
uses: actions/[email protected]
with:
path: ${{ steps.composer-cache.outputs.dir }}
key: ${{ runner.os }}-php-${{ matrix.php }}-${{ hashFiles('**/composer.lock') }}
restore-keys: |
${{ runner.os }}-php-${{ matrix.php }}
${{ runner.os }}-php-

- name: Validate composer.json and composer.lock
run: composer validate

- name: Install dependencies
run: composer install --prefer-dist --no-progress --no-interaction --ignore-platform-reqs
- name: Install PHP Dependencies
uses: ramsey/[email protected]

- name: Verify MariaDB connection
run: |
Expand Down
21 changes: 3 additions & 18 deletions cron/cron-control/.github/workflows/phpcs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,32 +12,17 @@ jobs:
codestyle:
name: Run code style check
runs-on: ubuntu-latest
if: "!contains(github.event.head_commit.message, '[ci skip]')"
steps:
- name: Check out source code
uses: actions/[email protected]

- name: Set up PHP
uses: shivammathur/setup-php@v2
with:
php-version: 7.4
php-version: 8.1

- name: Get composer cache directory
id: composer-cache
run: echo "::set-output name=dir::$(composer config cache-files-dir)"

- name: Cache Composer packages
uses: actions/[email protected]
with:
path: ${{ steps.composer-cache.outputs.dir }}
key: ${{ runner.os }}-php-7.4-${{ hashFiles('**/composer.lock') }}
restore-keys: ${{ runner.os }}-php-7.4

- name: Validate composer.json and composer.lock
run: composer validate

- name: Install dependencies
run: composer install --prefer-dist --no-progress --no-interaction --ignore-platform-reqs
- name: Install PHP Dependencies
uses: ramsey/[email protected]

- name: Add error matcher
run: echo "::add-matcher::$(pwd)/.github/checkstyle-problem-matcher.json"
Expand Down
143 changes: 142 additions & 1 deletion cron/cron-control/__tests__/unit-tests/test-internal-events.php
Original file line number Diff line number Diff line change
Expand Up @@ -74,12 +74,27 @@ function test_prune_duplicate_events() {
$duplicate_recurring_event2 = Utils::create_test_event( [ 'timestamp' => time() + 200, 'action' => 'recurring_event', 'schedule' => 'hourly', 'interval' => \HOUR_IN_SECONDS ] );
$unique_recurring_event = Utils::create_test_event( [ 'timestamp' => time() + 100, 'action' => 'recurring_event', 'schedule' => 'hourly', 'interval' => \HOUR_IN_SECONDS, 'args' => [ 'unique' ] ] );

// This prevent events starting with `wp_` from being scheduled, like wp_version_check,
// wp_update_plugins or wp_update_themes to avoid affecting the count assertions.
$prevent_wp_cron_events = function ( $event ) {
if ( str_starts_with( $event->hook, 'wp_' ) ) {
return false;
}
return $event;
};

// Filter to block any WordPress core cron events so the test events are isolated.
add_filter( 'schedule_event', $prevent_wp_cron_events );

// Run the pruning.
Cron_Control\Internal_Events::instance()->clean_legacy_data();

// Remove the filter after the pruning calls.
remove_filter( 'schedule_event', $prevent_wp_cron_events );

// Should have 5 events left, and the oldest IDs should have been kept..
$remaining_events = Cron_Control\Events::query( [ 'limit' => 100, 'orderby' => 'ID', 'order' => 'ASC' ] );
$this->assertEquals( 5, count( $remaining_events ), 'correct number of registered events left after pruning' );
$this->assertCount( 5, $remaining_events, 'correct number of registered events left after pruning' );
$this->assertEquals( $remaining_events[0]->get_id(), $original_single_event->get_id(), 'original single event was kept' );
$this->assertEquals( $remaining_events[1]->get_id(), $duplicate_single_event->get_id(), 'duplicate single event was also kept' );
$this->assertEquals( $remaining_events[2]->get_id(), $unique_single_event->get_id(), 'unique single event was kept' );
Expand All @@ -92,4 +107,130 @@ function test_prune_duplicate_events() {
$this->assertEquals( $duplicate_recurring_1->get_status(), Cron_Control\Events_Store::STATUS_COMPLETED, 'duplicate recurring event 1 was marked as completed' );
$this->assertEquals( $duplicate_recurring_2->get_status(), Cron_Control\Events_Store::STATUS_COMPLETED, 'duplicate recurring event 2 was marked as completed' );
}

function test_force_publish_missed_schedules() {
// Define the filter callback to override post status.
$future_insert_filter = function ( $data ) {
if ( 'publish' === $data['post_status'] ) {
$data['post_status'] = 'future'; // Ensure it remains future even if the date is in the past.
}
return $data;
};

// Add the filter to ensure 'future' posts with past dates are not auto-published.
add_filter( 'wp_insert_post_data', $future_insert_filter );

// Create two posts with a 'future' status.
$this->factory()->post->create(
array(
'post_title' => 'Future post that should be published',
'post_status' => 'future',
'post_type' => 'post',
'post_date' => gmdate( 'Y-m-d H:i:s', time() - 1000 ),
)
);

$this->factory()->post->create(
array(
'post_title' => 'Future post that should not be published',
'post_status' => 'future',
'post_type' => 'post',
'post_date' => gmdate( 'Y-m-d H:i:s', time() + 1000 ),
)
);

// Remove the filter after creating the test posts.
remove_filter( 'wp_insert_post_data', $future_insert_filter );

// Count posts with 'future' status before running the method.
$future_posts_before = get_posts(
array(
'post_status' => 'future',
'numberposts' => -1,
)
);

$this->assertCount( 2, $future_posts_before, 'Two posts should be scheduled initially.' );

// Run the function to publish missed schedules.
Cron_Control\Internal_Events::instance()->force_publish_missed_schedules();

// Query posts again after running the function.
$future_posts_after = get_posts(
array(
'post_status' => 'future',
'post_type' => 'post',
'numberposts' => -1,
)
);

$published_posts = get_posts(
array(
'post_status' => 'publish',
'post_type' => 'post',
'numberposts' => -1,
)
);

// Assert counts after the function runs.
$this->assertCount( 1, $future_posts_after, 'One post should still be scheduled.' );
$this->assertCount( 1, $published_posts, 'One post should be published.' );
}

public function test_confirm_scheduled_posts() {
// Create posts with 'future' status.
$future_posts = array(
$this->factory()->post->create(
array(
'post_title' => '1 hour in the future',
'post_status' => 'future',
'post_type' => 'post',
'post_date' => gmdate( 'Y-m-d H:i:s', strtotime( '+1 hour' ) ),
)
),
$this->factory()->post->create(
array(
'post_title' => '2 hours in the future',
'post_status' => 'future',
'post_type' => 'post',
'post_date' => gmdate( 'Y-m-d H:i:s', strtotime( '+2 hours' ) ),
)
),
$this->factory()->post->create(
array(
'post_title' => '3 hours in the future',
'post_status' => 'future',
'post_type' => 'post',
'post_date' => gmdate( 'Y-m-d H:i:s', strtotime( '+3 hours' ) ),
)
),
);

// Clear existing cron events to isolate the test.
Utils::clear_cron_table();

// Query all cron events to confirm none exist.
$events = Cron_Control\Events::query();
$this->assertEmpty( $events, 'No scheduled events should exist initially.' );

// Call the method to confirm scheduled posts.
Cron_Control\Internal_Events::instance()->confirm_scheduled_posts();

// Verify that cron jobs are scheduled for each future post.
foreach ( $future_posts as $future_post_id ) {
$timestamp = wp_next_scheduled( 'publish_future_post', array( $future_post_id ) );
$this->assertNotFalse( $timestamp, "Cron job should be scheduled for post ID: $future_post_id." );
}

// Reschedule one post with a different timestamp and call the method again.
$future_post_gmt_time = strtotime( get_gmt_from_date( get_post( $future_posts[0] )->post_date ) . ' GMT' );
wp_clear_scheduled_hook( 'publish_future_post', array( $future_posts[0] ) );
wp_schedule_single_event( $future_post_gmt_time - 3600, 'publish_future_post', array( $future_posts[0] ) ); // Schedule 1 hour earlier.

Cron_Control\Internal_Events::instance()->confirm_scheduled_posts();

// Verify the post's cron job has been rescheduled to the correct timestamp.
$rescheduled_timestamp = wp_next_scheduled( 'publish_future_post', array( $future_posts[0] ) );
$this->assertEquals( $future_post_gmt_time, $rescheduled_timestamp, 'Cron job for post 1 should be rescheduled to the correct timestamp.' );
}
}
4 changes: 2 additions & 2 deletions cron/cron-control/includes/class-internal-events.php
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ public function is_internal_event( $action ): bool {
public function force_publish_missed_schedules() {
global $wpdb;

$missed_posts = $wpdb->get_col( $wpdb->prepare( "SELECT ID FROM {$wpdb->posts} WHERE post_status = 'future' AND post_date <= %s LIMIT 0,100;", current_time( 'mysql', false ) ) );
$missed_posts = $wpdb->get_col( $wpdb->prepare( "SELECT ID FROM {$wpdb->posts} p JOIN (SELECT DISTINCT post_type FROM {$wpdb->posts}) AS t ON p.post_type = t.post_type WHERE post_status = 'future' AND post_date <= %s LIMIT 0,100;", current_time( 'mysql', false ) ) );

foreach ( $missed_posts as $missed_post ) {
$missed_post = absint( $missed_post );
Expand All @@ -168,7 +168,7 @@ public function confirm_scheduled_posts() {

do {
$offset = max( 0, $page - 1 ) * $quantity;
$future_posts = $wpdb->get_results( $wpdb->prepare( "SELECT ID, post_date FROM {$wpdb->posts} WHERE post_status = 'future' AND post_date > %s LIMIT %d,%d", current_time( 'mysql', false ), $offset, $quantity ) );
$future_posts = $wpdb->get_results( $wpdb->prepare( "SELECT ID, post_date FROM {$wpdb->posts} p JOIN (SELECT DISTINCT post_type FROM {$wpdb->posts}) AS t ON p.post_type = t.post_type WHERE post_status = 'future' AND post_date > %s LIMIT %d,%d", current_time( 'mysql', false ), $offset, $quantity ) );

if ( ! empty( $future_posts ) ) {
foreach ( $future_posts as $future_post ) {
Expand Down
28 changes: 14 additions & 14 deletions cron/cron-control/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions integrations/enterprise-search.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ public function load(): void {
} else {
require_once __DIR__ . '/../search/search.php';
}

if ( ! defined( 'VIP_SEARCH_ENABLED_BY' ) ) {
define( 'VIP_SEARCH_ENABLED_BY', 'integration' );
}
}

/**
Expand Down
2 changes: 1 addition & 1 deletion jetpack
Submodule jetpack updated 559 files
Loading
Loading