litefeel /
writing-on-github
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
| 1 | <?php |
||
| 2 | /** |
||
| 3 | * Database interface. |
||
| 4 | * @package Writing_On_GitHub |
||
| 5 | */ |
||
| 6 | |||
| 7 | /** |
||
| 8 | * Class Writing_On_GitHub_Database |
||
| 9 | */ |
||
| 10 | class Writing_On_GitHub_Database { |
||
| 11 | |||
| 12 | /** |
||
| 13 | * Application container. |
||
| 14 | * |
||
| 15 | * @var Writing_On_GitHub |
||
| 16 | */ |
||
| 17 | protected $app; |
||
| 18 | |||
| 19 | /** |
||
| 20 | * Currently whitelisted post types. |
||
| 21 | * |
||
| 22 | * @var array |
||
| 23 | */ |
||
| 24 | protected $whitelisted_post_types = array( 'post', 'page' ); |
||
| 25 | |||
| 26 | /** |
||
| 27 | * Currently whitelisted post statuses. |
||
| 28 | * |
||
| 29 | * @var array |
||
| 30 | */ |
||
| 31 | protected $whitelisted_post_statuses = array( 'publish' ); |
||
| 32 | |||
| 33 | /** |
||
| 34 | * Instantiates a new Database object. |
||
| 35 | * |
||
| 36 | * @param Writing_On_GitHub $app Application container. |
||
| 37 | */ |
||
| 38 | public function __construct( Writing_On_GitHub $app ) { |
||
| 39 | $this->app = $app; |
||
| 40 | } |
||
| 41 | |||
| 42 | /** |
||
| 43 | * Queries the database for all of the supported posts. |
||
| 44 | * |
||
| 45 | * @param bool $force |
||
| 46 | * |
||
| 47 | * @return Writing_On_GitHub_Post[]|WP_Error |
||
| 48 | */ |
||
| 49 | public function fetch_all_supported( $force = false ) { |
||
| 50 | $args = array( |
||
| 51 | 'post_type' => $this->get_whitelisted_post_types(), |
||
| 52 | 'post_status' => $this->get_whitelisted_post_statuses(), |
||
| 53 | 'nopaging' => true, |
||
| 54 | 'fields' => 'ids', |
||
| 55 | ); |
||
| 56 | |||
| 57 | $query = new WP_Query( apply_filters( 'wogh_pre_fetch_all_supported', $args ) ); |
||
| 58 | |||
| 59 | $post_ids = $query->get_posts(); |
||
| 60 | |||
| 61 | if ( ! $post_ids ) { |
||
| 62 | return new WP_Error( |
||
| 63 | 'no_results', |
||
| 64 | __( 'Querying for supported posts returned no results.', 'writing-on-github' ) |
||
| 65 | ); |
||
| 66 | } |
||
| 67 | |||
| 68 | /* @var Writing_On_GitHub_Post[] $results */ |
||
| 69 | $results = array(); |
||
| 70 | foreach ( $post_ids as $post_id ) { |
||
| 71 | // Do not export posts that have already been exported |
||
| 72 | if ( $force || ! get_post_meta( $post_id, '_wogh_sha', true ) || |
||
| 73 | ! get_post_meta( $post_id, '_wogh_github_path', true ) ) { |
||
| 74 | |||
| 75 | $results[] = new Writing_On_GitHub_Post( $post_id, $this->app->api() ); |
||
| 76 | } |
||
| 77 | } |
||
| 78 | |||
| 79 | return $results; |
||
| 80 | } |
||
| 81 | |||
| 82 | /** |
||
| 83 | * Queries a post and returns it if it's supported. |
||
| 84 | * |
||
| 85 | * @param int $post_id Post ID to fetch. |
||
| 86 | * |
||
| 87 | * @return WP_Error|Writing_On_GitHub_Post |
||
| 88 | */ |
||
| 89 | public function fetch_by_id( $post_id ) { |
||
| 90 | $post = new Writing_On_GitHub_Post( $post_id, $this->app->api() ); |
||
| 91 | |||
| 92 | if ( ! $this->is_post_supported( $post ) ) { |
||
| 93 | return new WP_Error( |
||
| 94 | 'unsupported_post', |
||
| 95 | sprintf( |
||
| 96 | __( |
||
| 97 | 'Post ID %s is not supported by WOGH. See wiki to find out how to add support.', |
||
| 98 | 'writing-on-github' |
||
| 99 | ), |
||
| 100 | $post_id |
||
| 101 | ) |
||
| 102 | ); |
||
| 103 | } |
||
| 104 | |||
| 105 | return $post; |
||
| 106 | } |
||
| 107 | |||
| 108 | /** |
||
| 109 | * Saves an array of Post objects to the database |
||
| 110 | * and associates their author as well as their latest |
||
| 111 | * |
||
| 112 | * @param Writing_On_GitHub_Post[] $posts Array of Posts to save. |
||
| 113 | * |
||
| 114 | * @return string|WP_Error |
||
| 115 | */ |
||
| 116 | public function save_posts( array $posts ) { |
||
|
0 ignored issues
–
show
|
|||
| 117 | |||
| 118 | /** |
||
| 119 | * Whether an error has occurred. |
||
| 120 | * |
||
| 121 | * @var WP_Error|false $error |
||
| 122 | */ |
||
| 123 | $error = false; |
||
| 124 | |||
| 125 | foreach ( $posts as $post ) { |
||
| 126 | $args = apply_filters( 'wogh_pre_import_args', $this->post_args( $post ), $post ); |
||
| 127 | |||
| 128 | remove_filter( 'content_save_pre', 'wp_filter_post_kses' ); |
||
| 129 | $post_id = $post->is_new() ? |
||
| 130 | wp_insert_post( $args, true ) : |
||
| 131 | wp_update_post( $args, true ); |
||
| 132 | add_filter( 'content_save_pre', 'wp_filter_post_kses' ); |
||
| 133 | |||
| 134 | if ( is_wp_error( $post_id ) ) { |
||
| 135 | /* @var WP_Error $post_id */ |
||
| 136 | $error = wogh_append_error( $error, $post_id ); |
||
| 137 | |||
| 138 | // Abort saving if updating the post fails. |
||
| 139 | continue; |
||
| 140 | } |
||
| 141 | |||
| 142 | if ( $post->is_new() ) { |
||
| 143 | $author = false; |
||
| 144 | $meta = $post->get_meta(); |
||
| 145 | if ( ! empty( $meta ) && ! empty( $meta['author'] ) ) { |
||
| 146 | $author = $meta['author']; |
||
| 147 | } |
||
| 148 | $user = $this->fetch_commit_user( $author ); |
||
| 149 | $user_id = is_wp_error( $user ) ? 0 : $user->ID; |
||
| 150 | $this->set_post_author( $post_id, $user_id ); |
||
| 151 | } |
||
| 152 | |||
| 153 | $post->set_post( get_post( $post_id ) ); |
||
| 154 | |||
| 155 | $meta = apply_filters( 'wogh_pre_import_meta', $post->get_meta(), $post ); |
||
| 156 | |||
| 157 | // unset( $meta['tags'] ); |
||
| 158 | // unset( $meta['categories'] ); |
||
| 159 | // unset( $meta['author'] ); |
||
| 160 | // unset( $meta['post_date'] ); |
||
| 161 | // unset( $meta['post_excerpt'] ); |
||
| 162 | // unset( $meta['permalink'] ); |
||
| 163 | // unset( $meta['link'] ); |
||
| 164 | |||
| 165 | // foreach ( $meta as $key => $value ) { |
||
| 166 | // update_post_meta( $post_id, $key, $value ); |
||
| 167 | // } |
||
| 168 | } |
||
| 169 | |||
| 170 | if ( $error ) { |
||
| 171 | return $error; |
||
| 172 | } |
||
| 173 | |||
| 174 | return __( 'Successfully saved posts.', 'writing-on-github' ); |
||
| 175 | } |
||
| 176 | |||
| 177 | protected function post_args( $post ) { |
||
| 178 | $args = $post->get_args(); |
||
| 179 | $meta = $post->get_meta(); |
||
| 180 | |||
| 181 | // prevent backslash loss |
||
| 182 | $args['post_content'] = addslashes( $args['post_content'] ); |
||
| 183 | |||
| 184 | // update tags |
||
| 185 | if ( ! empty( $meta['tags'] ) ) { |
||
| 186 | $args['tags_input'] = $meta['tags']; |
||
| 187 | } |
||
| 188 | |||
| 189 | // update categories |
||
| 190 | if ( ! empty( $meta['categories'] ) ) { |
||
| 191 | $categories = $meta['categories']; |
||
| 192 | if ( ! is_array( $categories ) ) { |
||
| 193 | $categories = array( $categories ); |
||
| 194 | } |
||
| 195 | $terms = get_terms( array( |
||
| 196 | 'taxonomy' => 'category', |
||
| 197 | 'fields' => 'id=>name', |
||
| 198 | 'hide_empty' => 0, |
||
| 199 | 'name' => $categories |
||
| 200 | ) |
||
| 201 | ); |
||
| 202 | $map = array(); |
||
| 203 | foreach ( $categories as $name ) { |
||
| 204 | $map[$name] = 1; |
||
| 205 | } |
||
| 206 | |||
| 207 | $ids = array(); |
||
| 208 | if ( ! empty( $terms ) ) { |
||
| 209 | foreach ( $terms as $id => $name ) { |
||
| 210 | $ids[] = $id; |
||
| 211 | unset( $map[$name] ); |
||
| 212 | } |
||
| 213 | } |
||
| 214 | |||
| 215 | // create new terms |
||
| 216 | if ( ! empty( $map ) ) { |
||
| 217 | foreach ( $map as $name => $value ) { |
||
| 218 | $term = wp_insert_term( $name, 'category', array( 'parent' => 0 ) ); |
||
| 219 | // array('term_id' => $term_id, 'term_taxonomy_id' => $tt_id); |
||
| 220 | $ids[] = $term['term_id']; |
||
| 221 | } |
||
| 222 | } |
||
| 223 | |||
| 224 | $args['post_category'] = $ids; |
||
| 225 | } |
||
| 226 | |||
| 227 | return $args; |
||
| 228 | } |
||
| 229 | |||
| 230 | private function get_post_id_by_filename( $filename, $pattern ) { |
||
| 231 | preg_match( $pattern , $filename, $matches ); |
||
| 232 | $title = $matches[4]; |
||
| 233 | |||
| 234 | $query = new WP_Query( array( |
||
| 235 | 'name' => $title, |
||
| 236 | 'posts_per_page' => 1, |
||
| 237 | 'post_type' => $this->get_whitelisted_post_types(), |
||
| 238 | 'fields' => 'ids', |
||
| 239 | ) ); |
||
| 240 | |||
| 241 | $post_id = $query->get_posts(); |
||
| 242 | $post_id = array_pop( $post_id ); |
||
| 243 | return $post_id; |
||
| 244 | } |
||
| 245 | |||
| 246 | /** |
||
| 247 | * Deletes a post from the database based on its GitHub path. |
||
| 248 | * |
||
| 249 | * @param string $path Path of Post to delete. |
||
| 250 | * |
||
| 251 | * @return string|WP_Error |
||
| 252 | */ |
||
| 253 | public function delete_post_by_path( $path ) { |
||
| 254 | $query = new WP_Query( array( |
||
| 255 | 'meta_key' => '_wogh_github_path', |
||
| 256 | 'meta_value' => $path, |
||
| 257 | 'meta_compare' => '=', |
||
| 258 | 'posts_per_page' => 1, |
||
| 259 | 'fields' => 'ids', |
||
| 260 | ) ); |
||
| 261 | |||
| 262 | $post_id = $query->get_posts(); |
||
| 263 | $post_id = array_pop( $post_id ); |
||
| 264 | |||
| 265 | if ( ! $post_id ) { |
||
| 266 | $parts = explode( '/', $path ); |
||
| 267 | $filename = array_pop( $parts ); |
||
| 268 | $directory = $parts ? array_shift( $parts ) : ''; |
||
| 269 | |||
| 270 | if ( false !== strpos( $directory, 'post' ) ) { |
||
| 271 | $post_id = get_post_id_by_filename( $filename, '/([0-9]{4})-([0-9]{2})-([0-9]{2})-(.*)\.md/' ); |
||
| 272 | } |
||
| 273 | |||
| 274 | if ( ! $post_id ) { |
||
| 275 | $post_id = get_post_id_by_filename( $filename, '/(.*)\.md/' ); |
||
| 276 | } |
||
| 277 | } |
||
| 278 | |||
| 279 | if ( ! $post_id ) { |
||
| 280 | return new WP_Error( |
||
| 281 | 'path_not_found', |
||
| 282 | sprintf( |
||
| 283 | __( 'Post not found for path %s.', 'writing-on-github' ), |
||
| 284 | $path |
||
| 285 | ) |
||
| 286 | ); |
||
| 287 | } |
||
| 288 | |||
| 289 | $result = wp_delete_post( $post_id ); |
||
| 290 | |||
| 291 | // If deleting fails... |
||
| 292 | View Code Duplication | if ( false === $result ) { |
|
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. Loading history...
|
|||
| 293 | $post = get_post( $post_id ); |
||
| 294 | |||
| 295 | // ...and the post both exists and isn't in the trash... |
||
| 296 | if ( $post && 'trash' !== $post->post_status ) { |
||
| 297 | // ... then something went wrong. |
||
| 298 | return new WP_Error( |
||
| 299 | 'db_error', |
||
| 300 | sprintf( |
||
| 301 | __( 'Failed to delete post ID %d.', 'writing-on-github' ), |
||
| 302 | $post_id |
||
| 303 | ) |
||
| 304 | ); |
||
| 305 | } |
||
| 306 | } |
||
| 307 | |||
| 308 | return sprintf( |
||
| 309 | __( 'Successfully deleted post ID %d.', 'writing-on-github' ), |
||
| 310 | $post_id |
||
| 311 | ); |
||
| 312 | } |
||
| 313 | |||
| 314 | public function delete_post( $post_id ) { |
||
| 315 | $result = wp_delete_post( $post_id ); |
||
| 316 | |||
| 317 | // If deleting fails... |
||
| 318 | View Code Duplication | if ( false === $result ) { |
|
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. Loading history...
|
|||
| 319 | $post = get_post( $post_id ); |
||
| 320 | |||
| 321 | // ...and the post both exists and isn't in the trash... |
||
| 322 | if ( $post && 'trash' !== $post->post_status ) { |
||
| 323 | // ... then something went wrong. |
||
| 324 | return new WP_Error( |
||
| 325 | 'db_error', |
||
| 326 | sprintf( |
||
| 327 | __( 'Failed to delete post ID %d.', 'writing-on-github' ), |
||
| 328 | $post_id |
||
| 329 | ) |
||
| 330 | ); |
||
| 331 | } |
||
| 332 | } |
||
| 333 | |||
| 334 | return sprintf( |
||
| 335 | __( 'Successfully deleted post ID %d.', 'writing-on-github' ), |
||
| 336 | $post_id |
||
| 337 | ); |
||
| 338 | } |
||
| 339 | |||
| 340 | /** |
||
| 341 | * Returns the list of post type permitted. |
||
| 342 | * |
||
| 343 | * @return array |
||
| 344 | */ |
||
| 345 | protected function get_whitelisted_post_types() { |
||
| 346 | return apply_filters( 'wogh_whitelisted_post_types', $this->whitelisted_post_types ); |
||
| 347 | } |
||
| 348 | |||
| 349 | /** |
||
| 350 | * Returns the list of post status permitted. |
||
| 351 | * |
||
| 352 | * @return array |
||
| 353 | */ |
||
| 354 | protected function get_whitelisted_post_statuses() { |
||
| 355 | return apply_filters( 'wogh_whitelisted_post_statuses', $this->whitelisted_post_statuses ); |
||
| 356 | } |
||
| 357 | |||
| 358 | /** |
||
| 359 | * Formats a whitelist array for a query. |
||
| 360 | * |
||
| 361 | * @param array $whitelist Whitelisted posts to format into query. |
||
| 362 | * |
||
| 363 | * @return string Whitelist formatted for query |
||
| 364 | */ |
||
| 365 | protected function format_for_query( $whitelist ) { |
||
| 366 | foreach ( $whitelist as $key => $value ) { |
||
| 367 | $whitelist[ $key ] = "'$value'"; |
||
| 368 | } |
||
| 369 | |||
| 370 | return implode( ', ', $whitelist ); |
||
| 371 | } |
||
| 372 | |||
| 373 | /** |
||
| 374 | * Verifies that both the post's status & type |
||
| 375 | * are currently whitelisted |
||
| 376 | * |
||
| 377 | * @param Writing_On_GitHub_Post $post Post to verify. |
||
| 378 | * |
||
| 379 | * @return boolean True if supported, false if not. |
||
| 380 | */ |
||
| 381 | protected function is_post_supported( Writing_On_GitHub_Post $post ) { |
||
| 382 | if ( wp_is_post_revision( $post->id ) ) { |
||
| 383 | return false; |
||
| 384 | } |
||
| 385 | |||
| 386 | // We need to allow trashed posts to be queried, but they are not whitelisted for export. |
||
| 387 | if ( ! in_array( $post->status(), $this->get_whitelisted_post_statuses() ) && 'trash' !== $post->status() ) { |
||
| 388 | return false; |
||
| 389 | } |
||
| 390 | |||
| 391 | if ( ! in_array( $post->type(), $this->get_whitelisted_post_types() ) ) { |
||
| 392 | return false; |
||
| 393 | } |
||
| 394 | |||
| 395 | if ( $post->has_password() ) { |
||
| 396 | return false; |
||
| 397 | } |
||
| 398 | |||
| 399 | return apply_filters( 'wogh_is_post_supported', true, $post ); |
||
| 400 | } |
||
| 401 | |||
| 402 | /** |
||
| 403 | * Retrieves the commit user for a provided display name |
||
| 404 | * |
||
| 405 | * Searches for a user with provided display name or returns |
||
| 406 | * the default user saved in the database. |
||
| 407 | * |
||
| 408 | * @param string $display_name User display name to search for. |
||
| 409 | * |
||
| 410 | * @return WP_Error|WP_User |
||
| 411 | */ |
||
| 412 | protected function fetch_commit_user( $display_name ) { |
||
| 413 | // If we can't find a user and a default hasn't been set, |
||
| 414 | // we're just going to set the revision author to 0. |
||
| 415 | $user = false; |
||
| 416 | |||
| 417 | if ( ! empty( $display_name ) ) { |
||
| 418 | $search_string = esc_attr( $display_name ); |
||
| 419 | $query = new WP_User_Query( array( |
||
| 420 | 'search' => "{$search_string}", |
||
| 421 | 'search_columns' => array( |
||
| 422 | 'display_name', |
||
| 423 | 'user_nicename', |
||
| 424 | 'user_login', |
||
| 425 | ) |
||
| 426 | ) ); |
||
| 427 | $users = $query->get_results(); |
||
| 428 | $user = empty($users) ? false : $users[0]; |
||
| 429 | } |
||
| 430 | |||
| 431 | if ( ! $user ) { |
||
| 432 | // Use the default user. |
||
| 433 | $user = get_user_by( 'id', (int) get_option( 'wogh_default_user' ) ); |
||
| 434 | } |
||
| 435 | |||
| 436 | if ( ! $user ) { |
||
| 437 | return new WP_Error( |
||
| 438 | 'user_not_found', |
||
| 439 | sprintf( |
||
| 440 | __( 'Commit user not found for email %s', 'writing-on-github' ), |
||
| 441 | |||
| 442 | ) |
||
| 443 | ); |
||
| 444 | } |
||
| 445 | |||
| 446 | return $user; |
||
| 447 | } |
||
| 448 | |||
| 449 | // /** |
||
| 450 | // * Sets the author latest revision |
||
| 451 | // * of the provided post ID to the provided user. |
||
| 452 | // * |
||
| 453 | // * @param int $post_id Post ID to update revision author. |
||
| 454 | // * @param int $user_id User ID for revision author. |
||
| 455 | // * |
||
| 456 | // * @return string|WP_Error |
||
| 457 | // */ |
||
| 458 | // protected function set_revision_author( $post_id, $user_id ) { |
||
| 459 | // $revision = wp_get_post_revisions( $post_id ); |
||
| 460 | |||
| 461 | // if ( ! $revision ) { |
||
| 462 | // $new_revision = wp_save_post_revision( $post_id ); |
||
| 463 | |||
| 464 | // if ( ! $new_revision || is_wp_error( $new_revision ) ) { |
||
| 465 | // return new WP_Error( 'db_error', 'There was a problem saving a new revision.' ); |
||
| 466 | // } |
||
| 467 | |||
| 468 | // // `wp_save_post_revision` returns the ID, whereas `get_post_revision` returns the whole object |
||
| 469 | // // in order to be consistent, let's make sure we have the whole object before continuing. |
||
| 470 | // $revision = get_post( $new_revision ); |
||
| 471 | |||
| 472 | // if ( ! $revision ) { |
||
| 473 | // return new WP_Error( 'db_error', 'There was a problem retrieving the newly recreated revision.' ); |
||
| 474 | // } |
||
| 475 | // } else { |
||
| 476 | // $revision = array_shift( $revision ); |
||
| 477 | // } |
||
| 478 | |||
| 479 | // return $this->set_post_author( $revision->ID, $user_id ); |
||
| 480 | // } |
||
| 481 | |||
| 482 | /** |
||
| 483 | * Updates the user ID for the provided post ID. |
||
| 484 | * |
||
| 485 | * Bypassing triggering any hooks, including creating new revisions. |
||
| 486 | * |
||
| 487 | * @param int $post_id Post ID to update. |
||
| 488 | * @param int $user_id User ID to update to. |
||
| 489 | * |
||
| 490 | * @return string|WP_Error |
||
| 491 | */ |
||
| 492 | protected function set_post_author( $post_id, $user_id ) { |
||
| 493 | global $wpdb; |
||
| 494 | |||
| 495 | $result = $wpdb->update( |
||
| 496 | $wpdb->posts, |
||
| 497 | array( |
||
| 498 | 'post_author' => (int) $user_id, |
||
| 499 | ), |
||
| 500 | array( |
||
| 501 | 'ID' => (int) $post_id, |
||
| 502 | ), |
||
| 503 | array( '%d' ), |
||
| 504 | array( '%d' ) |
||
| 505 | ); |
||
| 506 | |||
| 507 | if ( false === $result ) { |
||
| 508 | return new WP_Error( 'db_error', $wpdb->last_error ); |
||
| 509 | } |
||
| 510 | |||
| 511 | if ( 0 === $result ) { |
||
| 512 | return sprintf( |
||
| 513 | __( 'No change for post ID %d.', 'writing-on-github' ), |
||
| 514 | $post_id |
||
| 515 | ); |
||
| 516 | } |
||
| 517 | |||
| 518 | clean_post_cache( $post_id ); |
||
| 519 | |||
| 520 | return sprintf( |
||
| 521 | __( 'Successfully updated post ID %d.', 'writing-on-github' ), |
||
| 522 | $post_id |
||
| 523 | ); |
||
| 524 | } |
||
| 525 | |||
| 526 | // * |
||
| 527 | // * Update the provided post's blob sha. |
||
| 528 | // * |
||
| 529 | // * @param Writing_On_GitHub_Post $post Post to update. |
||
| 530 | // * @param string $sha Sha to update to. |
||
| 531 | // * |
||
| 532 | // * @return bool|int |
||
| 533 | |||
| 534 | // public function set_post_sha( $post, $sha ) { |
||
| 535 | // return update_post_meta( $post->id, '_wogh_sha', $sha ); |
||
| 536 | // } |
||
| 537 | } |
||
| 538 |
A high number of execution paths generally suggests many nested conditional statements and make the code less readible. This can usually be fixed by splitting the method into several smaller methods.
You can also find more information in the “Code” section of your repository.