Skip to content
Draft
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
45 changes: 40 additions & 5 deletions classes/class-badges.php
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,19 @@ public function __construct() {
* @return \Progress_Planner\Badges\Badge[]
*/
public function get_badges( $context ) {
return isset( $this->$context ) ? $this->$context : [];
// phpcs:ignore Generic.Commenting.DocComment.MissingShort -- Inline @var for PHPStan.
/** @var \Progress_Planner\Badges\Badge[] $badges */
$badges = isset( $this->$context ) ? $this->$context : [];

/**
* Filter the badges for a context.
*
* @param \Progress_Planner\Badges\Badge[] $badges The badges.
* @param string $context The badges context.
*
* @return \Progress_Planner\Badges\Badge[]
*/
return \apply_filters( 'progress_planner_badges', $badges, $context );
}

/**
Expand All @@ -101,7 +113,18 @@ public function get_badge( $badge_id ) {
}
}
}
return null;

/**
* Filter for retrieving a single badge by ID.
*
* Allows external plugins to provide custom badges.
*
* @param \Progress_Planner\Badges\Badge|null $badge The badge object or null.
* @param string $badge_id The badge ID.
*
* @return \Progress_Planner\Badges\Badge|null
*/
return \apply_filters( 'progress_planner_get_badge', null, $badge_id );
}

/**
Expand Down Expand Up @@ -183,6 +206,8 @@ public function get_latest_completed_badge() {
// Get the settings for badges (stores completion dates).
$settings = \progress_planner()->get_settings()->get( 'badges', [] );

// phpcs:ignore Generic.Commenting.DocComment.MissingShort -- Inline @var for PHPStan.
/** @var string|null $latest_date */
$latest_date = null;

// Loop through all badge contexts to find the most recently completed badge.
Expand All @@ -204,20 +229,30 @@ public function get_latest_completed_badge() {
if ( null === $latest_date ) {
$this->latest_completed_badge = $badge;
if ( isset( $settings[ $badge->get_id() ]['date'] ) ) {
$latest_date = $settings[ $badge->get_id() ]['date'];
$latest_date = (string) $settings[ $badge->get_id() ]['date'];
}
continue;
}

// Compare completion dates as Unix timestamps to find the most recent.
// Using >= ensures that if multiple badges complete simultaneously, the last one processed wins.
if ( \DateTime::createFromFormat( 'Y-m-d H:i:s', $settings[ $badge->get_id() ]['date'] )->format( 'U' ) >= \DateTime::createFromFormat( 'Y-m-d H:i:s', $latest_date )->format( 'U' ) ) {
$latest_date = $settings[ $badge->get_id() ]['date'];
if ( \DateTime::createFromFormat( 'Y-m-d H:i:s', (string) $settings[ $badge->get_id() ]['date'] )->format( 'U' ) >= \DateTime::createFromFormat( 'Y-m-d H:i:s', $latest_date )->format( 'U' ) ) {
$latest_date = (string) $settings[ $badge->get_id() ]['date'];
$this->latest_completed_badge = $badge;
}
}
}

/**
* Filter the latest completed badge.
*
* @param \Progress_Planner\Badges\Badge|null $badge The latest completed badge.
* @param string|null $latest_date The latest completion date.
*
* @return \Progress_Planner\Badges\Badge|null
*/
$this->latest_completed_badge = \apply_filters( 'progress_planner_latest_completed_badge', $this->latest_completed_badge, $latest_date );

return $this->latest_completed_badge;
}
}
26 changes: 19 additions & 7 deletions classes/class-plugin-upgrade-tasks.php
Original file line number Diff line number Diff line change
Expand Up @@ -104,14 +104,26 @@ protected function add_initial_onboarding_tasks() {
public function maybe_add_onboarding_tasks() {
$onboard_task_provider_ids = \apply_filters( 'prpl_onboarding_task_providers', [] );

// Privacy policy is not accepted, so it's a fresh install.
$fresh_install = ! \progress_planner()->is_privacy_policy_accepted();

// Check if task providers option exists, it will not on fresh installs and v1.0.4 and older.
$old_task_providers = \get_option( 'progress_planner_previous_version_task_providers', [] );
// Check if task providers option exists. If not, it's either a fresh install or upgrading from v1.0.4 or older.
$old_task_providers = \get_option( 'progress_planner_previous_version_task_providers', [] );
$task_providers_option_set = false !== \get_option( 'progress_planner_previous_version_task_providers', false );

// Fresh install detection:
// - Option doesn't exist AND privacy policy not yet accepted (standalone fresh install)
// - Option doesn't exist AND running as branded/hosted version (pp-hosts fresh install, privacy auto-accepted)
// In these cases, save current providers as baseline without showing upgrade popover.
if ( ! $task_providers_option_set ) {
$is_branded_version = \defined( 'PROGRESS_PLANNER_BRANDING_ID' );
$is_privacy_policy_pending = ! \progress_planner()->is_privacy_policy_accepted();

if ( $is_branded_version || $is_privacy_policy_pending ) {
// Fresh install - save current providers as baseline and skip upgrade popover.
\update_option( 'progress_planner_previous_version_task_providers', \array_unique( $onboard_task_provider_ids ), SORT_REGULAR );
return;
}

// We're upgrading from v1.0.4 or older, set the old task providers to what we had before the upgrade.
if ( ! $fresh_install && empty( $old_task_providers ) ) {
// Upgrading from v1.0.4 or older (standalone, privacy accepted but no task providers option).
// Set baseline to what existed before the upgrade.
$old_task_providers = [
'core-blogdescription',
'wp-debug-display',
Expand Down
23 changes: 18 additions & 5 deletions classes/class-suggested-tasks.php
Original file line number Diff line number Diff line change
Expand Up @@ -100,12 +100,25 @@ public function init(): void {
* @return void
*/
public function insert_activity( string $task_id ): void {
/**
* Filter the activity category for a completed task.
*
* Allows customizing the category used when recording task completion activities.
* For example, onboarding tasks may use 'onboarding_task' instead of 'suggested_task'
* to exclude them from monthly badge calculations.
*
* @param string $category The activity category (default: 'suggested_task').
* @param string $task_id The task ID being completed.
*/
$category = \apply_filters( 'progress_planner_task_activity_category', 'suggested_task', $task_id );

// Insert an activity.
$activity = new Suggested_Task_Activity();
$activity->type = 'completed';
$activity->data_id = (string) $task_id;
$activity->date = new \DateTime();
$activity->user_id = \get_current_user_id();
$activity = new Suggested_Task_Activity();
$activity->category = $category;
$activity->type = 'completed';
$activity->data_id = (string) $task_id;
$activity->date = new \DateTime();
$activity->user_id = \get_current_user_id();
$activity->save();

// Allow other classes to react to the completion of a suggested task.
Expand Down
1 change: 1 addition & 0 deletions views/popovers/badge-streak.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
<?php \progress_planner()->the_view( 'popovers/parts/badge-streak-progressbar.php', [ 'prpl_context' => 'content' ] ); ?>
</div>
</div>
<?php \do_action( 'progress_planner_popover_after_streak_sections' ); ?>
<div class="footer">
<div class="string-freeze-explain">
<h2><?php \esc_html_e( 'Streak freeze', 'progress-planner' ); ?></h2>
Expand Down
1 change: 1 addition & 0 deletions views/popovers/monthly-badges.php
Original file line number Diff line number Diff line change
Expand Up @@ -70,5 +70,6 @@ class="prpl-badge"
</div>
</div>
<?php endforeach; ?>
<?php \do_action( 'progress_planner_popover_after_badge_groups' ); ?>
</div>
</div>
Loading