• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Yoast / wordpress-seo / 79aae1805d11dbc567efb60cb8a182619b45a276

13 Jan 2026 10:45AM UTC coverage: 49.695%. First build
79aae1805d11dbc567efb60cb8a182619b45a276

Pull #22884

github

web-flow
Merge 39b5742c0 into b60f6a050
Pull Request #22884: Create the backend needed for manually completing tasks

0 of 106 new or added lines in 4 files covered. (0.0%)

17907 of 36034 relevant lines covered (49.69%)

3.9 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/task-list/user-interface/tasks/manually-complete-task-route.php
1
<?php
2
// phpcs:disable Yoast.NamingConventions.NamespaceName.TooLong -- Needed in the folder structure.
3
namespace Yoast\WP\SEO\Task_List\User_Interface\Tasks;
4

5
use Exception;
6
use WP_REST_Request;
7
use WP_REST_Response;
8
use Yoast\WP\SEO\Conditionals\Task_List_Enabled_Conditional;
9
use Yoast\WP\SEO\Helpers\Capability_Helper;
10
use Yoast\WP\SEO\Main;
11
use Yoast\WP\SEO\Routes\Route_Interface;
12
use Yoast\WP\SEO\Task_List\Domain\Exceptions\Task_Not_Found_Exception;
13
use Yoast\WP\SEO\Task_List\Infrastructure\Manual_Task_Completion_Repository;
14
use Yoast\WP\SEO\Task_List\Infrastructure\Tasks_Collectors\Cached_Tasks_Collector;
15
use Yoast\WP\SEO\Task_List\Infrastructure\Tasks_Collectors\Tasks_Collector;
16

17
/**
18
 * Route to manually set a task as completed (or revert to automatic completion).
19
 */
20
final class Manually_Complete_Task_Route implements Route_Interface {
21

22
        /**
23
         * The namespace of the route.
24
         *
25
         * @var string
26
         */
27
        public const ROUTE_NAMESPACE = Main::API_V1_NAMESPACE;
28

29
        /**
30
         * The route name.
31
         *
32
         * @var string
33
         */
34
        public const ROUTE_NAME = '/manually_complete_task';
35

36
        /**
37
         * The tasks collector.
38
         *
39
         * @var Tasks_Collector
40
         */
41
        private $tasks_collector;
42

43
        /**
44
         * The manual task completion repository.
45
         *
46
         * @var Manual_Task_Completion_Repository
47
         */
48
        private $manual_task_completion_repository;
49

50
        /**
51
         * Holds the capability helper instance.
52
         *
53
         * @var Capability_Helper
54
         */
55
        private $capability_helper;
56

57
        /**
58
         * Returns the needed conditionals.
59
         *
60
         * @return array<string> The conditionals that must be met to load this.
61
         */
NEW
62
        public static function get_conditionals(): array {
×
NEW
63
                return [
×
NEW
64
                        Task_List_Enabled_Conditional::class,
×
NEW
65
                ];
×
66
        }
67

68
        /**
69
         * The constructor.
70
         *
71
         * @param Tasks_Collector                   $tasks_collector                   The collector for all tasks.
72
         * @param Manual_Task_Completion_Repository $manual_task_completion_repository The manual task completion repository.
73
         * @param Capability_Helper                 $capability_helper                 The capability helper.
74
         */
NEW
75
        public function __construct(
×
76
                Tasks_Collector $tasks_collector,
77
                Manual_Task_Completion_Repository $manual_task_completion_repository,
78
                Capability_Helper $capability_helper
79
        ) {
NEW
80
                $this->tasks_collector                   = $tasks_collector;
×
NEW
81
                $this->manual_task_completion_repository = $manual_task_completion_repository;
×
NEW
82
                $this->capability_helper                 = $capability_helper;
×
83
        }
84

85
        /**
86
         * Registers routes.
87
         *
88
         * @return void
89
         */
NEW
90
        public function register_routes() {
×
NEW
91
                \register_rest_route(
×
NEW
92
                        self::ROUTE_NAMESPACE,
×
NEW
93
                        self::ROUTE_NAME,
×
NEW
94
                        [
×
NEW
95
                                [
×
NEW
96
                                        'methods'             => 'POST',
×
NEW
97
                                        'callback'            => [ $this, 'manually_complete_task' ],
×
NEW
98
                                        'permission_callback' => [ $this, 'permission_manage_options' ],
×
NEW
99
                                        'args'                => [
×
NEW
100
                                                'options' => [
×
NEW
101
                                                        'type'       => 'object',
×
NEW
102
                                                        'required'   => true,
×
NEW
103
                                                        'properties' => [
×
NEW
104
                                                                'task_id'   => [
×
NEW
105
                                                                        'type'              => 'string',
×
NEW
106
                                                                        'required'          => true,
×
NEW
107
                                                                        'sanitize_callback' => 'sanitize_text_field',
×
NEW
108
                                                                ],
×
NEW
109
                                                                'completed' => [
×
NEW
110
                                                                        'type'     => 'boolean',
×
NEW
111
                                                                        'required' => true,
×
NEW
112
                                                                ],
×
NEW
113
                                                        ],
×
NEW
114
                                                ],
×
NEW
115
                                        ],
×
NEW
116
                                ],
×
NEW
117
                        ]
×
NEW
118
                );
×
119
        }
120

121
        /**
122
         * Sets a task's manual completion state.
123
         *
124
         * @param WP_REST_Request $request The request.
125
         *
126
         * @return WP_REST_Response The response.
127
         *
128
         * @throws Task_Not_Found_Exception When the task is not found.
129
         */
NEW
130
        public function manually_complete_task( WP_REST_Request $request ): WP_REST_Response {
×
131
                try {
NEW
132
                        $options   = $request->get_param( 'options' );
×
NEW
133
                        $task_id   = $options['task_id'];
×
NEW
134
                        $completed = $options['completed'];
×
135

NEW
136
                        $task = $this->tasks_collector->get_task( $task_id );
×
NEW
137
                        if ( ! $task ) {
×
NEW
138
                                throw new Task_Not_Found_Exception();
×
139
                        }
140

NEW
141
                        if ( $completed ) {
×
NEW
142
                                $this->manual_task_completion_repository->set_task_manually_completed( $task_id );
×
143
                        }
144
                        else {
NEW
145
                                $this->manual_task_completion_repository->clear_task_manual_completion( $task_id );
×
146
                        }
147

148
                        // Invalidate cached task list.
NEW
149
                        \delete_transient( Cached_Tasks_Collector::TASKS_TRANSIENT );
×
150

NEW
151
                        return new WP_REST_Response(
×
NEW
152
                                [
×
NEW
153
                                        'success' => true,
×
NEW
154
                                ],
×
NEW
155
                                200
×
NEW
156
                        );
×
NEW
157
                } catch ( Exception $exception ) {
×
NEW
158
                        return new WP_REST_Response(
×
NEW
159
                                [
×
NEW
160
                                        'success' => false,
×
NEW
161
                                        'error'   => $exception->getMessage(),
×
NEW
162
                                ],
×
NEW
163
                                $exception->getCode()
×
NEW
164
                        );
×
165
                }
166
        }
167

168
        /**
169
         * Permission callback.
170
         *
171
         * @return bool True when user has the 'wpseo_manage_options' capability.
172
         */
NEW
173
        public function permission_manage_options() {
×
NEW
174
                return $this->capability_helper->current_user_can( 'wpseo_manage_options' );
×
175
        }
176
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc