[ Index ] |
PHP Cross Reference of GlotPress |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * Routes: GP_Route_Project class 4 * 5 * @package GlotPress 6 * @subpackage Routes 7 * @since 1.0.0 8 */ 9 10 /** 11 * Core class used to implement the project route. 12 * 13 * @since 1.0.0 14 */ 15 class GP_Route_Project extends GP_Route_Main { 16 17 public function index() { 18 $title = __( 'Projects', 'glotpress' ); 19 $projects = GP::$project->top_level(); 20 $this->tmpl( 'projects', get_defined_vars() ); 21 } 22 23 public function single( $project_path ) { 24 $project = GP::$project->by_path( $project_path ); 25 26 if ( ! $project ) { 27 return $this->die_with_404(); 28 } 29 30 $sub_projects = $project->sub_projects(); 31 $translation_sets = GP::$translation_set->by_project_id( $project->id ); 32 33 foreach ( $translation_sets as $set ) { 34 $locale = GP_Locales::by_slug( $set->locale ); 35 36 $set->name_with_locale = $set->name_with_locale(); 37 $set->current_count = $set->current_count(); 38 $set->untranslated_count = $set->untranslated_count(); 39 $set->waiting_count = $set->waiting_count(); 40 $set->fuzzy_count = $set->fuzzy_count(); 41 $set->percent_translated = $set->percent_translated(); 42 $set->all_count = $set->all_count(); 43 $set->wp_locale = $locale->wp_locale; 44 if ( $this->api ) { 45 $set->last_modified = $set->current_count ? $set->last_modified() : false; 46 } 47 } 48 49 usort( 50 $translation_sets, 51 function( $a, $b ) { 52 return( $a->current_count < $b->current_count ); 53 } 54 ); 55 56 /** 57 * Filter the list of translation sets of a project. 58 * 59 * Can also be used to sort the sets to a custom order. 60 * 61 * @since 1.0.0 62 * 63 * @param GP_Translation_Sets[] $translation_sets An array of translation sets. 64 */ 65 $translation_sets = apply_filters( 'gp_translation_sets_sort', $translation_sets ); 66 67 $title = sprintf( 68 /* translators: %s: project name */ 69 __( '%s project', 'glotpress' ), 70 esc_html( $project->name ) 71 ); 72 $can_write = $this->can( 'write', 'project', $project->id ); 73 $this->tmpl( 'project', get_defined_vars() ); 74 } 75 76 public function personal_options_post( $project_path ) { 77 $project = GP::$project->by_path( $project_path ); 78 79 if ( ! $project ) { 80 return $this->die_with_404(); 81 } 82 83 if ( $this->invalid_nonce_and_redirect( 'set-personal-options_' . $project->id ) ) { 84 return; 85 } 86 87 if ( $this->cannot_and_redirect( 'write', 'project', $project->id ) ) { 88 return; 89 } 90 91 $source_url_templates = get_user_meta( get_current_user_id(), 'gp_source_url_templates', true ); 92 if ( ! is_array( $source_url_templates ) ) { 93 $source_url_templates = array(); 94 } 95 96 $source_url_templates[ $project->id ] = gp_post( 'source-url-template' ); 97 98 if ( update_user_meta( get_current_user_id(), 'gp_source_url_templates', $source_url_templates ) ) { 99 $this->notices[] = 'Source URL template was successfully updated.'; 100 } else { 101 $this->errors[] = 'Error in updating source URL template.'; 102 } 103 $this->redirect( gp_url_project( $project ) ); 104 } 105 106 public function import_originals_get( $project_path ) { 107 $project = GP::$project->by_path( $project_path ); 108 109 if ( ! $project ) { 110 return $this->die_with_404(); 111 } 112 113 if ( $this->cannot_and_redirect( 'write', 'project', $project->id ) ) { 114 return; 115 } 116 117 $kind = 'originals'; 118 $this->tmpl( 'project-import', get_defined_vars() ); 119 } 120 121 public function import_originals_post( $project_path ) { 122 $project = GP::$project->by_path( $project_path ); 123 124 if ( ! $project ) { 125 return $this->die_with_404(); 126 } 127 128 if ( $this->invalid_nonce_and_redirect( 'import-originals_' . $project->id ) ) { 129 return; 130 } 131 132 if ( $this->cannot_and_redirect( 'write', 'project', $project->id ) ) { 133 return; 134 } 135 136 if ( ! is_uploaded_file( $_FILES['import-file']['tmp_name'] ) ) { 137 // TODO: different errors for different upload conditions 138 $this->redirect_with_error( __( 'Error uploading the file.', 'glotpress' ) ); 139 return; 140 } 141 142 $format = gp_get_import_file_format( gp_post( 'format', 'po' ), $_FILES['import-file']['name'] ); 143 144 if ( ! $format ) { 145 $this->redirect_with_error( __( 'No such format.', 'glotpress' ) ); 146 return; 147 } 148 149 $translations = $format->read_originals_from_file( $_FILES['import-file']['tmp_name'] ); 150 151 if ( ! $translations ) { 152 $this->redirect_with_error( __( 'Couldn’t load translations from file!', 'glotpress' ) ); 153 return; 154 } 155 156 list( $originals_added, $originals_existing, $originals_fuzzied, $originals_obsoleted, $originals_error ) = GP::$original->import_for_project( $project, $translations ); 157 158 $notice = sprintf( 159 /* translators: 1: Added strings count. 2: Updated strings count. 3: Fuzzied strings count. 4: Obsoleted strings count. */ 160 __( '%1$s new strings added, %2$s updated, %3$s fuzzied, and %4$s obsoleted.', 'glotpress' ), 161 $originals_added, 162 $originals_existing, 163 $originals_fuzzied, 164 $originals_obsoleted 165 ); 166 167 if ( $originals_error ) { 168 $notice .= ' ' . sprintf( 169 /* translators: %s: number of errors */ 170 _n( '%s new string was not imported due to an error.', '%s new strings were not imported due to an error.', $originals_error, 'glotpress' ), 171 $originals_error 172 ); 173 } 174 175 $this->notices[] = $notice; 176 177 $this->redirect( gp_url_project( $project ) ); 178 } 179 180 public function edit_get( $project_path ) { 181 $project = GP::$project->by_path( $project_path ); 182 183 if ( ! $project ) { 184 return $this->die_with_404(); 185 } 186 187 if ( $this->cannot_and_redirect( 'write', 'project', $project->id ) ) { 188 return; 189 } 190 191 $this->tmpl( 'project-edit', get_defined_vars() ); 192 } 193 194 public function edit_post( $project_path ) { 195 $project = GP::$project->by_path( $project_path ); 196 197 if ( ! $project ) { 198 $this->die_with_404(); 199 } 200 201 if ( $this->invalid_nonce_and_redirect( 'edit-project_' . $project->id ) ) { 202 return; 203 } 204 205 if ( $this->cannot_and_redirect( 'write', 'project', $project->id ) ) { 206 return; 207 } 208 209 $updated_project = new GP_Project( gp_post( 'project' ) ); 210 if ( $this->invalid_and_redirect( $updated_project, gp_url_project( $project, '-edit' ) ) ) { 211 return; 212 } 213 214 // TODO: add id check as a validation rule 215 if ( $project->id == $updated_project->parent_project_id ) { 216 $this->errors[] = __( 'The project cannot be parent of itself!', 'glotpress' ); 217 } elseif ( $project->save( $updated_project ) ) { 218 $this->notices[] = __( 'The project was saved.', 'glotpress' ); 219 } else { 220 $this->errors[] = __( 'Error in saving project!', 'glotpress' ); 221 } 222 223 $project->reload(); 224 225 $this->redirect( gp_url_project( $project ) ); 226 } 227 228 /** 229 * Deletes a project, including sub projects, glossaries, originals, translations sets and translations. 230 * 231 * @since 2.0.0 232 * 233 * @param int $project_path The path of the project to delete. 234 */ 235 public function delete_post( $project_path ) { 236 $project = GP::$project->by_path( $project_path ); 237 238 if ( ! is_object( $project ) ) { 239 240 $this->errors[] = __( 'Error in deleting project!', 'glotpress' ); 241 $this->redirect( gp_url_public_root() ); 242 243 return; 244 } 245 246 if ( $this->invalid_nonce_and_redirect( 'delete-project_' . $project->id ) ) { 247 return; 248 } 249 250 if ( $this->cannot_and_redirect( 'delete', 'project', $project->id ) ) { 251 return; 252 } 253 254 if ( $project->delete() ) { 255 $this->notices[] = sprintf( 256 /* translators: %s: Project name. */ 257 __( 'The project "%s" was deleted.', 'glotpress' ), 258 $project->name 259 ); 260 } else { 261 $this->errors[] = sprintf( 262 /* translators: %s: Project name. */ 263 __( 'Error deleting project "%s"!', 'glotpress' ), 264 $project->name 265 ); 266 } 267 268 $this->redirect( gp_url_public_root() ); 269 } 270 271 /** 272 * Displays the delete page for projects. 273 * 274 * @since 2.0.0 275 * 276 * @param string $project_path The path of the project to delete. 277 */ 278 public function delete_get( $project_path ) { 279 $project = GP::$project->by_path( $project_path ); 280 281 if ( $this->cannot_and_redirect( 'delete', 'project', $project->id ) ) { 282 return; 283 } 284 285 $this->tmpl( 'project-delete', get_defined_vars() ); 286 } 287 288 289 public function new_get() { 290 $project = new GP_Project(); 291 $project->active = 1; 292 $project->parent_project_id = gp_get( 'parent_project_id', null ); 293 294 if ( $this->cannot_and_redirect( 'write', 'project', $project->parent_project_id ) ) { 295 return; 296 } 297 298 $this->tmpl( 'project-new', get_defined_vars() ); 299 } 300 301 public function new_post() { 302 if ( $this->invalid_nonce_and_redirect( 'add-project' ) ) { 303 return; 304 } 305 306 $post = gp_post( 'project' ); 307 $parent_project_id = gp_array_get( $post, 'parent_project_id', null ); 308 309 if ( $this->cannot_and_redirect( 'write', 'project', $parent_project_id ) ) { 310 return; 311 } 312 313 $new_project = new GP_Project( $post ); 314 315 if ( $this->invalid_and_redirect( $new_project ) ) { 316 return; 317 } 318 319 $project = GP::$project->create_and_select( $new_project ); 320 321 if ( ! $project ) { 322 $project = new GP_Project(); 323 $this->errors[] = __( 'Error in creating project!', 'glotpress' ); 324 $this->tmpl( 'project-new', get_defined_vars() ); 325 } else { 326 $this->notices[] = __( 'The project was created!', 'glotpress' ); 327 $this->redirect( gp_url_project( $project ) ); 328 } 329 } 330 331 public function permissions_get( $project_path ) { 332 $project = GP::$project->by_path( $project_path ); 333 334 if ( ! $project ) { 335 return $this->die_with_404(); 336 } 337 338 if ( $this->cannot_and_redirect( 'write', 'project', $project->id ) ) { 339 return; 340 } 341 342 $path_to_root = array_slice( $project->path_to_root(), 1 ); 343 $permissions = GP::$validator_permission->by_project_id( $project->id ); 344 $cmp_fn = function( $x, $y ) { 345 return strcmp( $x->locale_slug, $y->locale_slug ); 346 }; 347 usort( $permissions, $cmp_fn ); 348 $parent_permissions = array(); 349 350 foreach ( $path_to_root as $parent_project ) { 351 $this_parent_permissions = GP::$validator_permission->by_project_id( $parent_project->id ); 352 usort( $this_parent_permissions, $cmp_fn ); 353 foreach ( $this_parent_permissions as $permission ) { 354 $permission->project = $parent_project; 355 } 356 $parent_permissions = array_merge( $parent_permissions, (array) $this_parent_permissions ); 357 } 358 // we can't join on users table 359 foreach ( array_merge( (array) $permissions, (array) $parent_permissions ) as $permission ) { 360 $permission->user = get_user_by( 'id', $permission->user_id ); 361 } 362 $this->tmpl( 'project-permissions', get_defined_vars() ); 363 } 364 365 public function permissions_post( $project_path ) { 366 $project = GP::$project->by_path( $project_path ); 367 368 if ( ! $project ) { 369 return $this->die_with_404(); 370 } 371 372 if ( $this->invalid_nonce_and_redirect( 'add-project-permissions_' . $project->id ) ) { 373 return; 374 } 375 376 if ( $this->cannot_and_redirect( 'write', 'project', $project->id ) ) { 377 return; 378 } 379 380 if ( 'add-validator' == gp_post( 'action' ) ) { 381 $user = get_user_by( 'login', gp_post( 'user_login' ) ); 382 if ( ! $user ) { 383 $this->redirect_with_error( __( 'User wasn’t found!', 'glotpress' ), gp_url_current() ); 384 return; 385 } 386 $new_permission = new GP_Validator_Permission( 387 array( 388 'user_id' => $user->ID, 389 'action' => 'approve', 390 'project_id' => $project->id, 391 'locale_slug' => gp_post( 'locale' ), 392 'set_slug' => gp_post( 'set-slug' ), 393 ) 394 ); 395 if ( $this->invalid_and_redirect( $new_permission, gp_url_current() ) ) { 396 return; 397 } 398 $permission = GP::$validator_permission->create( $new_permission ); 399 400 $permission ? 401 $this->notices[] = __( 'Validator was added.', 'glotpress' ) : $this->errors[] = __( 'Error in adding validator.', 'glotpress' ); 402 } 403 $this->redirect( gp_url_current() ); 404 } 405 406 public function permissions_delete( $project_path, $permission_id ) { 407 if ( $this->invalid_nonce_and_redirect( 'delete-project-permission_' . $permission_id ) ) { 408 return; 409 } 410 411 $project = GP::$project->by_path( $project_path ); 412 413 if ( ! $project ) { 414 $this->die_with_404(); 415 } 416 417 if ( $this->cannot_and_redirect( 'write', 'project', $project->id ) ) { 418 return; 419 } 420 421 $permission = GP::$permission->get( $permission_id ); 422 if ( $permission ) { 423 if ( $permission->delete() ) { 424 $this->notices[] = __( 'Permission was deleted.', 'glotpress' ); 425 } else { 426 $this->errors[] = __( 'Error in deleting permission!', 'glotpress' ); 427 } 428 } else { 429 $this->errors[] = __( 'Permission wasn’t found!', 'glotpress' ); 430 } 431 $this->redirect( gp_url_project( $project, '-permissions' ) ); 432 } 433 434 public function mass_create_sets_get( $project_path ) { 435 $project = GP::$project->by_path( $project_path ); 436 437 if ( ! $project ) { 438 return $this->die_with_404(); 439 } 440 441 if ( $this->cannot_and_redirect( 'write', 'project', $project->id ) ) { 442 return; 443 } 444 445 $this->tmpl( 'project-mass-create-sets', get_defined_vars() ); 446 } 447 448 public function mass_create_sets_post( $project_path ) { 449 $project = GP::$project->by_path( $project_path ); 450 if ( ! $project ) { 451 return $this->die_with_404(); 452 } 453 454 if ( $this->invalid_nonce_and_redirect( 'mass-create-transation-sets_' . $project->id ) ) { 455 return; 456 } 457 458 if ( $this->cannot_and_redirect( 'write', 'project', $project->id ) ) { 459 return; 460 } 461 462 $other_project = GP::$project->get( gp_post( 'project_id' ) ); 463 464 if ( ! $other_project ) { 465 return $this->die_with_error( __( 'Project wasn’found', 'glotpress' ) ); 466 } 467 468 $changes = $project->set_difference_from( $other_project ); 469 470 foreach ( $changes['added'] as $to_add ) { 471 if ( ! GP::$translation_set->create( 472 array( 473 'project_id' => $project->id, 474 'name' => $to_add->name, 475 'locale' => $to_add->locale, 476 'slug' => $to_add->slug, 477 ) 478 ) ) { 479 $this->errors[] = sprintf( 480 /* translators: %s: Translation set name. */ 481 __( 'Couldn’t add translation set named %s', 'glotpress' ), 482 esc_html( $to_add->name ) 483 ); 484 } 485 } 486 foreach ( $changes['removed'] as $to_remove ) { 487 if ( ! $to_remove->delete() ) { 488 $this->errors[] = sprintf( 489 /* translators: %s: Translation set name. */ 490 __( 'Couldn’t delete translation set named %s', 'glotpress' ), 491 esc_html( $to_remove->name ) 492 ); 493 } 494 } 495 if ( empty( $this->errors ) ) { 496 $this->notices[] = __( 'Translation sets were added and removed successfully', 'glotpress' ); 497 } 498 499 $this->redirect( gp_url_project( $project ) ); 500 } 501 502 public function mass_create_sets_preview_post( $project_path ) { 503 $project = GP::$project->by_path( $project_path ); 504 505 if ( ! $project ) { 506 return $this->die_with_404(); 507 } 508 509 if ( $this->cannot_and_redirect( 'write', 'project', $project->id ) ) { 510 return; 511 } 512 513 $other_project = GP::$project->get( gp_post( 'project_id' ) ); 514 515 if ( ! $other_project ) { 516 return $this->die_with_error( __( 'Project wasn’found', 'glotpress' ) ); 517 } 518 519 header( 'Content-Type: application/json' ); 520 echo wp_json_encode( $project->set_difference_from( $other_project ) ); 521 } 522 523 public function branch_project_get( $project_path ) { 524 $project = GP::$project->by_path( $project_path ); 525 526 if ( ! $project ) { 527 return $this->die_with_404(); 528 } 529 530 if ( $this->cannot_and_redirect( 'write', 'project', $project->id ) ) { 531 return; 532 } 533 534 $this->tmpl( 'project-branch', get_defined_vars() ); 535 } 536 537 538 public function branch_project_post( $project_path ) { 539 $post = gp_post( 'project' ); 540 $project = GP::$project->by_path( $project_path ); 541 542 if ( ! $project ) { 543 return $this->die_with_404(); 544 } 545 546 if ( $this->invalid_nonce_and_redirect( 'branch-project_' . $project->id ) ) { 547 return; 548 } 549 550 $parent_project_id = gp_array_get( $post, 'parent_project_id', null ); 551 552 if ( $this->cannot_and_redirect( 'write', 'project', $parent_project_id ) ) { 553 return; 554 } 555 556 $new_project_data = new GP_Project( $post ); 557 if ( $this->invalid_and_redirect( $new_project_data ) ) { 558 return; 559 } 560 561 $new_project_data->active = $project->active; 562 $new_project = GP::$project->create_and_select( $new_project_data ); 563 564 if ( ! $new_project ) { 565 $new_project = new GP_Project(); 566 $this->errors[] = __( 'Error in creating project!', 'glotpress' ); 567 $this->tmpl( 'project-branch', get_defined_vars() ); 568 } else { 569 $new_project->duplicate_project_contents_from( $project ); 570 } 571 572 $this->redirect( gp_url_project( $new_project ) ); 573 } 574 575 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Nov 21 01:01:07 2024 | Cross-referenced by PHPXref 0.7.1 |