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 | * GitHub Import Manager |
||
| 4 | * |
||
| 5 | * @package Writing_On_GitHub |
||
| 6 | */ |
||
| 7 | |||
| 8 | /** |
||
| 9 | * Class Writing_On_GitHub_Import |
||
| 10 | */ |
||
| 11 | class Writing_On_GitHub_Import { |
||
| 12 | |||
| 13 | /** |
||
| 14 | * Application container. |
||
| 15 | * |
||
| 16 | * @var Writing_On_GitHub |
||
| 17 | */ |
||
| 18 | protected $app; |
||
| 19 | |||
| 20 | /** |
||
| 21 | * Initializes a new import manager. |
||
| 22 | * |
||
| 23 | * @param Writing_On_GitHub $app Application container. |
||
| 24 | */ |
||
| 25 | public function __construct( Writing_On_GitHub $app ) { |
||
| 26 | $this->app = $app; |
||
| 27 | } |
||
| 28 | |||
| 29 | /** |
||
| 30 | * Imports a payload. |
||
| 31 | * @param Writing_On_GitHub_Payload $payload |
||
| 32 | * |
||
| 33 | * @return string|WP_Error |
||
| 34 | */ |
||
| 35 | View Code Duplication | public function payload( Writing_On_GitHub_Payload $payload ) { |
|
| 36 | |||
| 37 | $result = $this->app->api()->fetch()->compare( $payload->get_before_commit_id() ); |
||
| 38 | |||
| 39 | if ( is_wp_error( $result ) ) { |
||
| 40 | /* @var WP_Error $result */ |
||
| 41 | return $result; |
||
| 42 | } |
||
| 43 | |||
| 44 | $result = $this->import_files( $result ); |
||
| 45 | |||
| 46 | if ( is_wp_error( $result ) ) { |
||
| 47 | return $files; |
||
| 48 | } |
||
| 49 | |||
| 50 | return __( 'Payload processed', 'writing-on-github' ); |
||
| 51 | } |
||
| 52 | |||
| 53 | /** |
||
| 54 | * import blob by files |
||
| 55 | * @param Writing_On_GitHub_File_Info[] $files |
||
| 56 | * |
||
| 57 | * @return string|WP_Error |
||
|
0 ignored issues
–
show
|
|||
| 58 | */ |
||
| 59 | protected function import_files( $files ) { |
||
| 60 | |||
| 61 | $error = false; |
||
| 62 | $delete_ids = false; |
||
| 63 | |||
| 64 | $result = $this->compare( $files, $delete_ids ); |
||
| 65 | |||
| 66 | if ( is_wp_error( $result ) ) { |
||
| 67 | return $result; |
||
| 68 | } |
||
| 69 | |||
| 70 | if ( $delete_ids ) { |
||
| 71 | View Code Duplication | foreach ($delete_ids as $id) { |
|
| 72 | $result = $this->app->database()->delete_post( $id ); |
||
| 73 | if ( is_wp_error( $result ) ) { |
||
| 74 | if ( $error ) { |
||
| 75 | $error->add( $result->get_error_code(), $result->get_error_message() ); |
||
| 76 | } else { |
||
| 77 | $error = $result; |
||
| 78 | } |
||
| 79 | } |
||
| 80 | } |
||
| 81 | } |
||
| 82 | |||
| 83 | return $error; |
||
| 84 | } |
||
| 85 | |||
| 86 | /** |
||
| 87 | * Imports the latest commit on the master branch. |
||
| 88 | * |
||
| 89 | * @return string|WP_Error |
||
| 90 | */ |
||
| 91 | View Code Duplication | public function master() { |
|
| 92 | $result = $this->app->api()->fetch()->tree_recursive(); |
||
| 93 | |||
| 94 | if ( is_wp_error( $result ) ) { |
||
| 95 | /* @var WP_Error $result */ |
||
| 96 | return $result; |
||
| 97 | } |
||
| 98 | |||
| 99 | $result = $this->import_files( $result ); |
||
| 100 | |||
| 101 | if ( is_wp_error( $result ) ) { |
||
| 102 | return $result; |
||
|
0 ignored issues
–
show
The return type of
return $result; (WP_Error|string|array|false) is incompatible with the return type documented by Writing_On_GitHub_Import::master of type string|WP_Error.
If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design. Let’s take a look at an example: class Author {
private $name;
public function __construct($name) {
$this->name = $name;
}
public function getName() {
return $this->name;
}
}
abstract class Post {
public function getAuthor() {
return 'Johannes';
}
}
class BlogPost extends Post {
public function getAuthor() {
return new Author('Johannes');
}
}
class ForumPost extends Post { /* ... */ }
function my_function(Post $post) {
echo strtoupper($post->getAuthor());
}
Our function Loading history...
|
|||
| 103 | } |
||
| 104 | |||
| 105 | return __( 'Payload processed', 'writing-on-github' ); |
||
| 106 | } |
||
| 107 | |||
| 108 | /** |
||
| 109 | * Do compare |
||
| 110 | * @param Writing_On_GitHub_File_Info[]|WP_Error $files |
||
| 111 | * @param int[] &$delete_ids |
||
| 112 | * |
||
| 113 | * @return string|WP_Error |
||
|
0 ignored issues
–
show
Should the return type not be
WP_Error|string|array? Also, consider making the array more specific, something like array<String>, or String[].
This check compares the return type specified in the If the return type contains the type array, this check recommends the use of
a more specific type like Loading history...
|
|||
| 114 | */ |
||
| 115 | protected function compare( $files, &$delete_ids ) { |
||
| 116 | if ( is_wp_error( $files ) ) { |
||
| 117 | /* @var WP_Error $files */ |
||
| 118 | return $files; |
||
| 119 | } |
||
| 120 | |||
| 121 | $posts = array(); |
||
| 122 | $new = array(); |
||
| 123 | |||
| 124 | $idsmap = array(); |
||
| 125 | |||
| 126 | foreach ( $files as $file ) { |
||
| 127 | if ( ! $this->importable_file( $file ) ) { |
||
| 128 | continue; |
||
| 129 | } |
||
| 130 | |||
| 131 | $blob = $this->app->api()->fetch()->blob( $file ); |
||
| 132 | // network error ? |
||
| 133 | if ( ! $blob instanceof Writing_On_GitHub_Blob ) { |
||
| 134 | continue; |
||
| 135 | } |
||
| 136 | |||
| 137 | if ( $this->importable_raw_file( $blob ) ) { |
||
| 138 | $this->import_raw_file( $blob, $file->status == 'removed' ); |
||
| 139 | continue; |
||
| 140 | } |
||
| 141 | |||
| 142 | if ( ! $this->importable_blob( $blob ) ) { |
||
| 143 | continue; |
||
| 144 | } |
||
| 145 | |||
| 146 | $post = $this->blob_to_post( $blob ); |
||
| 147 | |||
| 148 | if ( $file->status == 'removed' ) { |
||
| 149 | if ( $blob->id() ) { |
||
| 150 | $idsmap[$blob->id()] = true; |
||
| 151 | } |
||
| 152 | } elseif ( $post != false ) { |
||
| 153 | $posts[] = $post; |
||
| 154 | if ( $post->is_new() ) { |
||
| 155 | $new[] = $post; |
||
| 156 | } |
||
| 157 | } |
||
| 158 | } |
||
| 159 | |||
| 160 | foreach ( $posts as $post ) { |
||
| 161 | if ( $post->id() && isset( $idsmap[ $post->id() ] ) ) { |
||
| 162 | unset( $idsmap[ $post->id() ] ); |
||
| 163 | } |
||
| 164 | } |
||
| 165 | $delete_ids = array(); |
||
| 166 | foreach ( $idsmap as $id => $value ) { |
||
| 167 | $delete_ids[] = $id; |
||
| 168 | } |
||
| 169 | |||
| 170 | // $this->app->database()->save_posts( $posts, $commit->author_email() ); |
||
| 171 | |||
| 172 | $result = $this->app->database()->save_posts( $posts ); |
||
| 173 | |||
| 174 | if ( is_wp_error( $result ) ) { |
||
| 175 | return $result; |
||
| 176 | } |
||
| 177 | |||
| 178 | if ( ! empty( $new ) ) { |
||
| 179 | $result = $this->app->export()->new_posts( $new ); |
||
| 180 | |||
| 181 | if ( is_wp_error( $result ) ) { |
||
| 182 | return $result; |
||
| 183 | } |
||
| 184 | } |
||
| 185 | |||
| 186 | return $posts; |
||
| 187 | } |
||
| 188 | |||
| 189 | /** |
||
| 190 | * Checks whether the provided blob should be imported. |
||
| 191 | * |
||
| 192 | * @param Writing_On_GitHub_File_Info $file |
||
| 193 | * |
||
| 194 | * @return bool |
||
| 195 | */ |
||
| 196 | protected function importable_file( Writing_On_GitHub_File_Info $file ) { |
||
| 197 | |||
| 198 | // only _pages and _posts |
||
| 199 | if ( strncasecmp($file->path, '_pages/', strlen('_pages/') ) != 0 && |
||
| 200 | strncasecmp($file->path, '_posts/', strlen('_posts/') ) != 0 && |
||
| 201 | strncasecmp($file->path, 'images/', strlen('images/') ) != 0 ) { |
||
| 202 | return false; |
||
| 203 | } |
||
| 204 | |||
| 205 | |||
| 206 | // if ( ! $file->has_frontmatter() ) { |
||
| 207 | // return false; |
||
| 208 | // } |
||
| 209 | |||
| 210 | return true; |
||
| 211 | } |
||
| 212 | |||
| 213 | /** |
||
| 214 | * Checks whether the provided blob should be imported. |
||
| 215 | * |
||
| 216 | * @param Writing_On_GitHub_Blob $blob Blob to validate. |
||
| 217 | * |
||
| 218 | * @return bool |
||
| 219 | */ |
||
| 220 | protected function importable_blob( Writing_On_GitHub_Blob $blob ) { |
||
| 221 | // global $wpdb; |
||
| 222 | |||
| 223 | // // Skip the repo's readme. |
||
| 224 | // if ( 'readme' === strtolower( substr( $blob->path(), 0, 6 ) ) ) { |
||
| 225 | // return false; |
||
| 226 | // } |
||
| 227 | |||
| 228 | // // If the blob sha already matches a post, then move on. |
||
| 229 | // if ( ! is_wp_error( $this->app->database()->fetch_by_sha( $blob->sha() ) ) ) { |
||
| 230 | // return false; |
||
| 231 | // } |
||
| 232 | |||
| 233 | if ( ! $blob->has_frontmatter() ) { |
||
| 234 | return false; |
||
| 235 | } |
||
| 236 | |||
| 237 | return true; |
||
| 238 | } |
||
| 239 | |||
| 240 | protected function importable_raw_file( Writing_On_GitHub_Blob $blob ) { |
||
| 241 | if ( $blob->has_frontmatter() ) { |
||
| 242 | return false; |
||
| 243 | } |
||
| 244 | |||
| 245 | // only images |
||
| 246 | if ( strncasecmp($blob->path(), 'images/', strlen('images/') ) != 0) { |
||
| 247 | return false; |
||
| 248 | } |
||
| 249 | |||
| 250 | return true; |
||
| 251 | } |
||
| 252 | |||
| 253 | /** |
||
| 254 | * Imports a raw file content into file system. |
||
| 255 | * @param Writing_On_GitHub_Blob $blob |
||
| 256 | * @param bool $is_remove |
||
| 257 | */ |
||
| 258 | protected function import_raw_file( Writing_On_GitHub_Blob $blob, $is_remove ) { |
||
| 259 | $arr = wp_upload_dir(); |
||
| 260 | $path = $arr['basedir'] . '/writing-on-github/' . $blob->path(); |
||
| 261 | if ( $is_remove ) { |
||
| 262 | if ( file_exists($path) ) { |
||
| 263 | unlink($path); |
||
| 264 | } |
||
| 265 | } else { |
||
| 266 | $dirname = dirname($path); |
||
| 267 | if ( ! file_exists($dirname) ) { |
||
| 268 | wp_mkdir_p($dirname); |
||
| 269 | } |
||
| 270 | |||
| 271 | file_put_contents($path, $blob->content()); |
||
| 272 | } |
||
| 273 | } |
||
| 274 | |||
| 275 | /** |
||
| 276 | * Imports a single blob content into matching post. |
||
| 277 | * |
||
| 278 | * @param Writing_On_GitHub_Blob $blob Blob to transform into a Post. |
||
| 279 | * |
||
| 280 | * @return Writing_On_GitHub_Post|false |
||
| 281 | */ |
||
| 282 | protected function blob_to_post( Writing_On_GitHub_Blob $blob ) { |
||
| 283 | $args = array( 'post_content' => $blob->content_import() ); |
||
| 284 | $meta = $blob->meta(); |
||
| 285 | |||
| 286 | $id = false; |
||
| 287 | |||
| 288 | if ( ! empty( $meta ) ) { |
||
| 289 | if ( array_key_exists( 'layout', $meta ) ) { |
||
| 290 | $args['post_type'] = $meta['layout']; |
||
| 291 | unset( $meta['layout'] ); |
||
| 292 | } |
||
| 293 | |||
| 294 | if ( array_key_exists( 'published', $meta ) ) { |
||
| 295 | $args['post_status'] = true === $meta['published'] ? 'publish' : 'draft'; |
||
| 296 | unset( $meta['published'] ); |
||
| 297 | } |
||
| 298 | |||
| 299 | if ( array_key_exists( 'post_title', $meta ) ) { |
||
| 300 | $args['post_title'] = $meta['post_title']; |
||
| 301 | unset( $meta['post_title'] ); |
||
| 302 | } |
||
| 303 | |||
| 304 | if ( array_key_exists( 'post_name', $meta ) ) { |
||
| 305 | $args['post_name'] = $meta['post_name']; |
||
| 306 | unset( $meta['post_name'] ); |
||
| 307 | } |
||
| 308 | |||
| 309 | if ( array_key_exists( 'ID', $meta ) ) { |
||
| 310 | $id = $args['ID'] = $meta['ID']; |
||
| 311 | $blob->set_id($id); |
||
| 312 | unset( $meta['ID'] ); |
||
| 313 | } |
||
| 314 | } |
||
| 315 | |||
| 316 | $meta['_wogh_sha'] = $blob->sha(); |
||
| 317 | |||
| 318 | if ( $id ) { |
||
| 319 | $old_sha = get_post_meta( $id, '_wogh_sha', true ); |
||
| 320 | $old_github_path = get_post_meta( $id, '_wogh_github_path', true ); |
||
| 321 | |||
| 322 | // dont save post when has same sha |
||
| 323 | if ( $old_sha && $old_sha == $meta['_wogh_sha'] && |
||
| 324 | $old_github_path && $old_github_path == $blob->path() ) { |
||
| 325 | return false; |
||
| 326 | } |
||
| 327 | } |
||
| 328 | |||
| 329 | $post = new Writing_On_GitHub_Post( $args, $this->app->api() ); |
||
| 330 | $post->set_old_github_path( $blob->path() ); |
||
| 331 | $post->set_meta( $meta ); |
||
| 332 | $blob->set_id( $post->id() ); |
||
| 333 | |||
| 334 | return $post; |
||
| 335 | } |
||
| 336 | } |
||
| 337 |
This check compares the return type specified in the
@returnannotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.If the return type contains the type array, this check recommends the use of a more specific type like
String[]orarray<String>.