← All changes
|
json-endpoints/class.wpcom-json-api-list-dropdown-pages-endpoint.php
+225
-0
16.2-beta
→
16.3
View file →
| @@ -1,0 +1,225 @@ | ||
| 1 | +<?php // phpcs:ignore WordPress.Files.FileName.InvalidClassFileName | |
| 2 | + | |
| 3 | +if ( ! defined( 'ABSPATH' ) ) { | |
| 4 | + exit( 0 ); | |
| 5 | +} | |
| 6 | + | |
| 7 | +/** | |
| 8 | + * List dropdown pages endpoint. | |
| 9 | + */ | |
| 10 | +new WPCOM_JSON_API_List_Dropdown_Pages_Endpoint( | |
| 11 | + array( | |
| 12 | + | |
| 13 | + 'description' => 'Get a list of pages to be displayed as options in a select-a-page-dropdown.', | |
| 14 | + 'min_version' => '1.1', | |
| 15 | + 'max_version' => '1.1', | |
| 16 | + | |
| 17 | + 'group' => 'posts', | |
| 18 | + 'stat' => 'posts:dropdown-pages', | |
| 19 | + | |
| 20 | + 'method' => 'GET', | |
| 21 | + 'path' => '/sites/%s/dropdown-pages/', | |
| 22 | + 'path_labels' => array( | |
| 23 | + '$site' => '(int|string) Site ID or domain', | |
| 24 | + ), | |
| 25 | + | |
| 26 | + 'allow_fallback_to_jetpack_blog_token' => true, | |
| 27 | + | |
| 28 | + 'example_request' => 'https://public-api.wordpress.com/rest/v1.1/sites/en.blog.wordpress.com/dropdown-pages/', | |
| 29 | + ) | |
| 30 | +); | |
| 31 | + | |
| 32 | +/** | |
| 33 | + * Endpoint class responsible for listing pages to be displayed as options in a select-a-page-dropdown. | |
| 34 | + * | |
| 35 | + * /sites/%s/dropdown-pages/ -> $blog_id | |
| 36 | + * | |
| 37 | + * @phan-constructor-used-for-side-effects | |
| 38 | + */ | |
| 39 | +class WPCOM_JSON_API_List_Dropdown_Pages_Endpoint extends WPCOM_JSON_API_Endpoint { | |
| 40 | + | |
| 41 | + /** | |
| 42 | + * Page object format. | |
| 43 | + * | |
| 44 | + * @var array | |
| 45 | + */ | |
| 46 | + public $dropdown_page_object_format = array( | |
| 47 | + 'ID' => '(int) The page ID.', | |
| 48 | + 'title' => '(string) The page title.', | |
| 49 | + 'children' => '(array:dropdown_page) An array of child pages.', | |
| 50 | + ); | |
| 51 | + | |
| 52 | + /** | |
| 53 | + * The response format. | |
| 54 | + * | |
| 55 | + * @var array | |
| 56 | + */ | |
| 57 | + public $response_format = array( | |
| 58 | + 'found' => '(int) The number of pages found.', | |
| 59 | + 'dropdown_pages' => '(array:dropdown_page) An array of dropdown_page objects.', | |
| 60 | + ); | |
| 61 | + | |
| 62 | + /** | |
| 63 | + * List of pages indexed by their page ID. | |
| 64 | + * | |
| 65 | + * @var array<int,WP_Post> | |
| 66 | + */ | |
| 67 | + private $pages_by_id = array(); | |
| 68 | + | |
| 69 | + /** | |
| 70 | + * List of pages indexed by their parent page ID. | |
| 71 | + * | |
| 72 | + * @var array<int,WP_Post> | |
| 73 | + */ | |
| 74 | + private $pages_by_parent = array(); | |
| 75 | + | |
| 76 | + /** | |
| 77 | + * API callback. | |
| 78 | + * | |
| 79 | + * @param string $path - the path. | |
| 80 | + * @param int $blog_id - the blog ID. | |
| 81 | + * @return stdClass[] $pages - An array of page objects. Each page object includes ID and title properties and may include children property. This makes each page object a tree-like data structure. | |
| 82 | + */ | |
| 83 | + public function callback( $path = '', $blog_id = 0 ) { | |
| 84 | + $blog_id = $this->api->switch_to_blog_and_validate_user( $this->api->get_blog_id( $blog_id ) ); | |
| 85 | + if ( is_wp_error( $blog_id ) ) { | |
| 86 | + return $blog_id; | |
| 87 | + } | |
| 88 | + | |
| 89 | + $pages = get_pages(); | |
| 90 | + | |
| 91 | + if ( empty( $pages ) ) { | |
| 92 | + return array( | |
| 93 | + 'found' => 0, | |
| 94 | + 'dropdown_pages' => array(), | |
| 95 | + ); | |
| 96 | + } | |
| 97 | + | |
| 98 | + $this->pages_by_id = self::to_pages_by_id( $pages ); | |
| 99 | + $this->pages_by_parent = self::to_pages_by_parent( $pages ); | |
| 100 | + $dropdown_pages = $this->create_dropdown_pages(); | |
| 101 | + return array( | |
| 102 | + 'found' => count( $dropdown_pages ), | |
| 103 | + 'dropdown_pages' => $dropdown_pages, | |
| 104 | + ); | |
| 105 | + } | |
| 106 | + | |
| 107 | + /** | |
| 108 | + * Convert a list of pages to a list of pages by page ID. | |
| 109 | + * | |
| 110 | + * @param array<WP_Post> $pages - array of pages. | |
| 111 | + * @return array<int,WP_Post> $pages_by_page_id - indexed array of pages by page ID where index is page ID. | |
| 112 | + */ | |
| 113 | + private static function to_pages_by_id( $pages ) { | |
| 114 | + $pages_by_page_id = array(); | |
| 115 | + foreach ( $pages as $page ) { | |
| 116 | + if ( isset( $page->ID ) ) { | |
| 117 | + $pages_by_page_id[ $page->ID ] = $page; | |
| 118 | + } | |
| 119 | + } | |
| 120 | + return $pages_by_page_id; | |
| 121 | + } | |
| 122 | + | |
| 123 | + /** | |
| 124 | + * Convert a list of pages to a list of pages by parent. | |
| 125 | + * | |
| 126 | + * @param array<WP_Post> $pages - array of pages. | |
| 127 | + * @return array<int,WP_Post> $pages_by_parent - indexed array of pages by parent where index is page ID. | |
| 128 | + */ | |
| 129 | + private static function to_pages_by_parent( $pages ) { | |
| 130 | + $pages_by_parent = array(); | |
| 131 | + foreach ( $pages as $page ) { | |
| 132 | + if ( empty( $page->post_parent ) ) { | |
| 133 | + $pages_by_parent['root'][] = $page; | |
| 134 | + } else { | |
| 135 | + $pages_by_parent[ $page->post_parent ][] = $page; | |
| 136 | + } | |
| 137 | + } | |
| 138 | + return $pages_by_parent; | |
| 139 | + } | |
| 140 | + | |
| 141 | + /** | |
| 142 | + * Convert a list of pages to a list of dropdown pages. | |
| 143 | + * | |
| 144 | + * @return array<stdClass> $dropdown_pages - array of dropdown pages. | |
| 145 | + */ | |
| 146 | + private function create_dropdown_pages() { | |
| 147 | + $dropdown_pages = array(); | |
| 148 | + | |
| 149 | + if ( ! empty( $this->pages_by_parent['root'] ) ) { | |
| 150 | + foreach ( $this->pages_by_parent['root'] as $root_page ) { | |
| 151 | + $dropdown_pages[] = $this->to_dropdown_page( $root_page ); | |
| 152 | + } | |
| 153 | + } | |
| 154 | + | |
| 155 | + if ( ! empty( $this->pages_by_id ) ) { | |
| 156 | + // In case there were some orphans | |
| 157 | + // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable | |
| 158 | + foreach ( $this->pages_by_id as $_page_id => $page ) { | |
| 159 | + $dropdown_pages[] = $this->to_dropdown_page( $page ); | |
| 160 | + } | |
| 161 | + } | |
| 162 | + | |
| 163 | + return $dropdown_pages; | |
| 164 | + } | |
| 165 | + | |
| 166 | + /** | |
| 167 | + * Convert a page to a dropdown page. | |
| 168 | + * | |
| 169 | + * @param WP_Post $page - the page. | |
| 170 | + * @return stdClass|false $dropdown_page - the dropdown page. | |
| 171 | + */ | |
| 172 | + private function to_dropdown_page( $page ) { | |
| 173 | + if ( ! isset( $page->ID ) ) { | |
| 174 | + return false; | |
| 175 | + } | |
| 176 | + | |
| 177 | + $title = $this->get_page_title( $page ); | |
| 178 | + | |
| 179 | + if ( ! isset( $this->pages_by_parent[ $page->ID ] ) ) { | |
| 180 | + unset( $this->pages_by_id[ $page->ID ] ); | |
| 181 | + return (object) array( | |
| 182 | + 'ID' => $page->ID, | |
| 183 | + 'title' => $title, | |
| 184 | + ); | |
| 185 | + } | |
| 186 | + | |
| 187 | + $children = array(); | |
| 188 | + foreach ( $this->pages_by_parent[ $page->ID ] as $child_page ) { | |
| 189 | + $children[] = $this->to_dropdown_page( $child_page ); | |
| 190 | + } | |
| 191 | + | |
| 192 | + unset( $this->pages_by_id[ $page->ID ] ); | |
| 193 | + unset( $this->pages_by_parent[ $page->ID ] ); | |
| 194 | + return (object) array( | |
| 195 | + 'ID' => $page->ID, | |
| 196 | + 'title' => $title, | |
| 197 | + 'children' => $children, | |
| 198 | + ); | |
| 199 | + } | |
| 200 | + | |
| 201 | + /** | |
| 202 | + * Get the page title. | |
| 203 | + * | |
| 204 | + * @param WP_Post $page - the page. | |
| 205 | + * @return string $page_title - the page title. | |
| 206 | + */ | |
| 207 | + private function get_page_title( $page ) { | |
| 208 | + $title = $page->post_title; | |
| 209 | + if ( '' === $title ) { | |
| 210 | + /* translators: %d: ID of a post. */ | |
| 211 | + $title = sprintf( __( '#%d (no title)', 'jetpack' ), $page->ID ); | |
| 212 | + } | |
| 213 | + | |
| 214 | + /** | |
| 215 | + * Filters the page title when creating an HTML drop-down list of pages. | |
| 216 | + * | |
| 217 | + * @since 3.1.0 | |
| 218 | + * | |
| 219 | + * @param string $title Page title. | |
| 220 | + * @param WP_Post $page Page data object. | |
| 221 | + */ | |
| 222 | + $title = apply_filters( 'list_pages', $title, $page ); | |
| 223 | + return $title; | |
| 224 | + } | |
| 225 | +} | |