[ Index ] |
PHP Cross Reference of GlotPress |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * Things: GP_Translation class 4 * 5 * @package GlotPress 6 * @subpackage Things 7 * @since 1.0.0 8 */ 9 10 /** 11 * Core class used to implement the translations. 12 * 13 * @since 1.0.0 14 */ 15 class GP_Translation extends GP_Thing { 16 17 /** 18 * Number of translations per page. 19 * 20 * @var int $per_page 21 */ 22 public $per_page = 15; 23 24 /** 25 * Name of the database table. 26 * 27 * @var string $table_basename 28 */ 29 public $table_basename = 'gp_translations'; 30 31 /** 32 * List of field names for a translation. 33 * 34 * @var array $field_names 35 */ 36 public $field_names = array( 37 'id', 38 'original_id', 39 'translation_set_id', 40 'translation_0', 41 'translation_1', 42 'translation_2', 43 'translation_3', 44 'translation_4', 45 'translation_5', 46 'user_id', 47 'user_id_last_modified', 48 'status', 49 'date_added', 50 'date_modified', 51 'warnings', 52 ); 53 54 /** 55 * List of field names which have an integer value. 56 * 57 * @var array $int_fields 58 */ 59 public $int_fields = array( 60 'id', 61 'original_id', 62 'translation_set_id', 63 'user_id', 64 'user_id_last_modified', 65 ); 66 67 /** 68 * List of field names which cannot be updated. 69 * 70 * @var array $non_updatable_attributes 71 */ 72 public $non_updatable_attributes = array( 'id' ); 73 74 /** 75 * ID of the translation. 76 * 77 * @var int $id 78 */ 79 public $id; 80 81 /** 82 * ID of the original. 83 * 84 * @var int $original_id 85 */ 86 public $original_id; 87 88 /** 89 * ID of the translation set. 90 * 91 * @var int $translation_set_id 92 */ 93 public $translation_set_id; 94 95 /** 96 * Translation for a singular form. 97 * 98 * @var string $translation_1 99 */ 100 public $translation_0; 101 102 /** 103 * Translation for a plural form. 104 * 105 * @var string $translation_1 106 */ 107 public $translation_1; 108 109 /** 110 * Translation for a second plural form. 111 * 112 * @var string $translation_2 113 */ 114 public $translation_2; 115 116 /** 117 * Translation for a third plural form. 118 * 119 * @var string $translation_3 120 */ 121 public $translation_3; 122 123 /** 124 * Translation for a fourth plural form. 125 * 126 * @var string $translation_4 127 */ 128 public $translation_4; 129 130 /** 131 * Translation for a fifth plural form. 132 * 133 * @var string $translation_5 134 */ 135 public $translation_5; 136 137 /** 138 * ID of a user who submitted the translation. 139 * 140 * @var int $user_id 141 */ 142 public $user_id; 143 144 /** 145 * ID of a user (validator) who last changed the status of the translation. 146 * 147 * @since 2.1.0 148 * 149 * @var int $user_id_last_modified 150 */ 151 public $user_id_last_modified; 152 153 /** 154 * Status of the translation. 155 * 156 * @var string $status 157 */ 158 public $status; 159 160 /** 161 * Date when the translation was added. 162 * 163 * @var string $date_added 164 */ 165 public $date_added; 166 167 /** 168 * Date when the translation was modified. 169 * 170 * @var string $date_added 171 */ 172 public $date_modified; 173 174 /** 175 * List of warnings when translation isn't correct. 176 * 177 * @var array $warnings 178 */ 179 public $warnings; 180 181 /** 182 * Number of found results. 183 * 184 * @var int $found_rows 185 */ 186 public $found_rows; 187 188 /** 189 * List of valid statuses. 190 * 191 * @var array $statuses 192 * @static 193 */ 194 public static $statuses = array( 'current', 'waiting', 'rejected', 'fuzzy', 'old' ); 195 196 /** 197 * Number of supported translations per original. 198 * 199 * @var int $number_of_plural_translations 200 * @static 201 */ 202 public static $number_of_plural_translations = 6; 203 204 public function create( $args ) { 205 $inserted = parent::create( $args ); 206 207 if ( $inserted && is_array( $args ) && isset( $args['translation_set_id'] ) ) { 208 gp_clean_translation_set_cache( $args['translation_set_id'] ); 209 } 210 211 return $inserted; 212 } 213 214 /** 215 * Normalizes an array with key-value pairs representing 216 * a GP_Translation object. 217 * 218 * @since 1.0.0 219 * 220 * @param array $args Arguments for a GP_Translation object. 221 * @return array Normalized arguments for a GP_Translation object. 222 */ 223 public function normalize_fields( $args ) { 224 $args = parent::normalize_fields( $args ); 225 226 if ( isset( $args['translations'] ) && is_array( $args['translations'] ) ) { 227 // Reduce range by one since we're starting at 0, see GH#516. 228 foreach ( range( 0, $this->get_static( 'number_of_plural_translations' ) - 1 ) as $i ) { 229 if ( isset( $args['translations'][ $i ] ) ) { 230 $args[ "translation_$i" ] = $args['translations'][ $i ]; 231 } 232 } 233 unset( $args['translations'] ); 234 } 235 236 // Reduce range by one since we're starting at 0, see GH#516. 237 foreach ( range( 0, $this->get_static( 'number_of_plural_translations' ) - 1 ) as $i ) { 238 if ( isset( $args[ "translation_$i" ] ) ) { 239 $args[ "translation_$i" ] = $args[ "translation_$i" ]; 240 } 241 } 242 243 if ( gp_array_get( $args, 'warnings' ) == array() ) { 244 $args['warnings'] = null; 245 } 246 247 return $args; 248 } 249 250 public function prepare_fields_for_save( $args ) { 251 $args = parent::prepare_fields_for_save( $args ); 252 253 /** 254 * Filters the translation fields before they are saved. 255 * 256 * @since 3.0.0 257 * 258 * @param array $args Translation arguments. 259 * @param GP_Translation $this Translation class. 260 */ 261 $args = apply_filters( 'gp_translation_prepare_for_save', $args, $this ); 262 263 if ( is_array( gp_array_get( $args, 'warnings' ) ) ) { 264 $args['warnings'] = serialize( $args['warnings'] ); 265 } 266 267 return $args; 268 } 269 270 /** 271 * Sets restriction rules for fields. 272 * 273 * @since 1.0.0 274 * 275 * @param GP_Validation_Rules $rules The validation rules instance. 276 */ 277 public function restrict_fields( $rules ) { 278 $rules->translation_0_should_not_be( 'empty_string' ); 279 $rules->translation_1_should_not_be( 'empty_string' ); 280 $rules->translation_2_should_not_be( 'empty_string' ); 281 $rules->translation_3_should_not_be( 'empty_string' ); 282 $rules->translation_4_should_not_be( 'empty_string' ); 283 $rules->translation_5_should_not_be( 'empty_string' ); 284 $rules->status_should_not_be( 'empty' ); 285 $rules->original_id_should_be( 'positive_int' ); 286 $rules->translation_set_id_should_be( 'positive_int' ); 287 $rules->user_id_should_be( 'positive_int' ); 288 $rules->user_id_last_modified_should_not_be( 'empty_string' ); 289 } 290 291 /** 292 * Sets fields of the current GP_Thing object. 293 * 294 * @param array $fields Fields for a GP_Thing object. 295 */ 296 public function set_fields( $fields ) { 297 parent::set_fields( $fields ); 298 if ( $this->warnings ) { 299 $this->warnings = maybe_unserialize( $this->warnings ); 300 } 301 } 302 303 public function for_export( $project, $translation_set, $filters = null ) { 304 return GP::$translation->for_translation( $project, $translation_set, 'no-limit', $filters ? $filters : array( 'status' => 'current_or_untranslated' ) ); 305 } 306 307 public function for_translation( $project, $translation_set, $page, $filters = array(), $sort = array() ) { 308 global $wpdb; 309 310 $locale = GP_Locales::by_slug( $translation_set->locale ); 311 $root_locale = null; 312 $root_translation_set = null; 313 $has_root = false; 314 315 if ( null !== $locale->variant_root ) { 316 $root_for_translation = array(); 317 318 $root_locale = GP_Locales::by_slug( $locale->variant_root ); 319 $root_translation_set = GP::$translation_set->by_project_id_slug_and_locale( $project->id, $translation_set->slug, $locale->variant_root ); 320 321 // Only set the root translation flag if we have a valid root translation set, otherwise there's no point in querying it later. 322 if ( null !== $root_translation_set && false !== $root_translation_set ) { 323 $has_root = true; 324 } 325 } 326 327 $join_type = 'INNER'; 328 329 $sort_bys = wp_list_pluck( gp_get_sort_by_fields(), 'sql_sort_by' ); 330 331 $default_sort = get_user_option( 'gp_default_sort' ); 332 if ( ! is_array( $default_sort ) ) { 333 $default_sort = array( 334 'by' => 'priority', 335 'how' => 'desc', 336 ); 337 } 338 339 $sort_by = gp_array_get( $sort_bys, gp_array_get( $sort, 'by' ), gp_array_get( $sort_bys, $default_sort['by'] ) ); 340 $sort_hows = array( 341 'asc' => 'ASC', 342 'desc' => 'DESC', 343 ); 344 $sort_how = gp_array_get( $sort_hows, gp_array_get( $sort, 'how' ), gp_array_get( $sort_hows, $default_sort['how'] ) ); 345 $collation = 'yes' === gp_array_get( $filters, 'case_sensitive' ) ? 'BINARY' : ''; 346 347 $where = array(); 348 if ( gp_array_get( $filters, 'term' ) ) { 349 $like = "LIKE $collation '%" . ( esc_sql( $wpdb->esc_like( gp_array_get( $filters, 'term' ) ) ) ) . "%'"; 350 351 $term_scope = gp_array_get( $filters, 'term_scope', 'scope_any' ); 352 353 switch ( $term_scope ) { 354 case 'scope_originals': 355 $scope_array = array( 'o.singular', 'o.plural' ); 356 break; 357 case 'scope_translations': 358 $scope_array = array( 't.translation_0', 't.translation_1' ); 359 break; 360 case 'scope_context': 361 $scope_array = array( 'o.context' ); 362 break; 363 case 'scope_references': 364 $scope_array = array( 'o.references' ); 365 break; 366 case 'scope_both': 367 $scope_array = array( 'o.singular', 't.translation_0', 'o.plural', 't.translation_1' ); 368 break; 369 default: 370 $scope_array = array( 'o.singular', 't.translation_0', 'o.plural', 't.translation_1', 'o.context', 'o.references' ); 371 break; 372 } 373 374 $mapped_scope_array = array_map( 375 function( $x ) use ( $like ) { 376 return "($x $like)"; 377 }, 378 $scope_array 379 ); 380 381 $where[] = '(' . implode( ' OR ', $mapped_scope_array ) . ')'; 382 } 383 if ( gp_array_get( $filters, 'before_date_added' ) ) { 384 $where[] = $wpdb->prepare( 't.date_added > %s', gp_array_get( $filters, 'before_date_added' ) ); 385 } 386 if ( gp_array_get( $filters, 'translation_id' ) ) { 387 $where[] = $wpdb->prepare( 't.id = %d', gp_array_get( $filters, 'translation_id' ) ); 388 } 389 if ( gp_array_get( $filters, 'original_id' ) ) { 390 $where[] = $wpdb->prepare( 'o.id = %d', gp_array_get( $filters, 'original_id' ) ); 391 } 392 if ( 'yes' == gp_array_get( $filters, 'warnings' ) ) { 393 $where[] = 't.warnings IS NOT NULL'; 394 $where[] = 't.warnings != ""'; 395 } elseif ( 'no' == gp_array_get( $filters, 'warnings' ) ) { 396 $where[] = 't.warnings IS NULL'; 397 } 398 if ( 'yes' == gp_array_get( $filters, 'with_context' ) ) { 399 $where[] = 'o.context IS NOT NULL'; 400 } 401 if ( 'yes' == gp_array_get( $filters, 'with_comment' ) ) { 402 $where[] = 'o.comment IS NOT NULL AND o.comment <> ""'; 403 } 404 405 if ( 'yes' === gp_array_get( $filters, 'with_plural' ) ) { 406 $where[] = 'o.plural IS NOT NULL'; 407 } 408 409 if ( gp_array_get( $filters, 'user_login' ) ) { 410 $user = get_user_by( 'login', $filters['user_login'] ); 411 // do not return any entries if the user doesn't exist 412 $where[] = $wpdb->prepare( 't.user_id = %d', ( $user && $user->ID ) ? $user->ID : -1 ); 413 } 414 415 if ( ! GP::$permission->current_user_can( 'write', 'project', $project->id ) ) { 416 $where[] = 'o.priority > -2'; 417 } 418 419 $priorities = gp_array_get( $filters, 'priority' ); 420 if ( $priorities ) { 421 $valid_priorities = array_keys( GP::$original->get_static( 'priorities' ) ); 422 $priorities = array_filter( 423 gp_array_get( $filters, 'priority' ), 424 function( $p ) use ( $valid_priorities ) { 425 return in_array( intval( $p ), $valid_priorities, true ); 426 } 427 ); 428 429 $priorities_where = array(); 430 foreach ( $priorities as $single_priority ) { 431 $priorities_where[] = $wpdb->prepare( 'o.priority = %s', $single_priority ); 432 } 433 434 if ( ! empty( $priorities_where ) ) { 435 $priorities_where = '(' . implode( ' OR ', $priorities_where ) . ')'; 436 $where[] = $priorities_where; 437 } 438 }; 439 440 $join_on = array(); 441 $status = gp_array_get( $filters, 'status', 'current_or_waiting_or_fuzzy_or_untranslated' ); 442 $statuses = explode( '_or_', $status ); 443 if ( in_array( 'untranslated', $statuses, true ) ) { 444 if ( array( 'untranslated' ) == $statuses ) { 445 $where[] = 't.translation_0 IS NULL'; 446 } 447 $join_type = 'LEFT'; 448 $join_on[] = 'status != "rejected"'; 449 $join_on[] = 'status != "old"'; 450 $statuses = array_filter( 451 $statuses, 452 function( $x ) { 453 return 'untranslated' !== $x; 454 } 455 ); 456 } 457 458 $all_statuses = $this->get_static( 'statuses' ); 459 $statuses = array_filter( 460 $statuses, 461 function( $s ) use ( $all_statuses ) { 462 return in_array( $s, $all_statuses, true ); 463 } 464 ); 465 466 if ( ! empty( $statuses ) ) { 467 $statuses_where = array(); 468 foreach ( $statuses as $single_status ) { 469 $statuses_where[] = $wpdb->prepare( 'status = %s', $single_status ); 470 } 471 $statuses_where = '(' . implode( ' OR ', $statuses_where ) . ')'; 472 $join_on[] = $statuses_where; 473 } 474 475 /** 476 * Filter the SQL WHERE clause to get available translations. 477 * 478 * @since 1.0.0 479 * 480 * @param array $where An array of where conditions. 481 * @param GP_Translation_Set $translation_set Current translation set. 482 */ 483 $where = apply_filters( 'gp_for_translation_where', $where, $translation_set ); 484 485 $where = implode( ' AND ', $where ); 486 if ( $where ) { 487 $where = 'AND ' . $where; 488 } 489 490 $where = 'o.project_id = ' . (int) $project->id . ' AND o.status = "+active" ' . $where; 491 492 $join_on = implode( ' AND ', $join_on ); 493 if ( $join_on ) { 494 $join_on = 'AND ' . $join_on; 495 } 496 497 $fields = array( 498 't.*', 499 'o.*', 500 't.id as id', 501 'o.id as original_id', 502 't.status as translation_status', 503 'o.status as original_status', 504 't.date_added as translation_added', 505 'o.date_added as original_added', 506 ); 507 508 if ( $has_root ) { 509 $fields[] = 'r.id as root_id'; 510 $fields[] = 'r.original_id as root_original_id'; 511 $fields[] = 'r.translation_set_id as root_translation_set_id'; 512 $fields[] = 'r.translation_0 as root_translation_0'; 513 $fields[] = 'r.translation_1 as root_translation_1'; 514 $fields[] = 'r.translation_2 as root_translation_2'; 515 $fields[] = 'r.translation_3 as root_translation_3'; 516 $fields[] = 'r.translation_4 as root_translation_4'; 517 $fields[] = 'r.translation_5 as root_translation_5'; 518 $fields[] = 'r.user_id as root_user_id'; 519 $fields[] = 'r.status as root_status'; 520 $fields[] = 'r.date_added as root_date_added'; 521 $fields[] = 'r.date_modified as root_date_modified'; 522 $fields[] = 'r.warnings as root_warnings'; 523 $fields[] = 'r.user_id_last_modified as root_user_id_last_modified'; 524 } 525 526 $join = "$join_type JOIN ( SELECT * FROM {$wpdb->gp_translations} WHERE translation_set_id = " . (int) $translation_set->id . " $join_on ) AS t ON o.id = t.original_id"; 527 $root_join = ''; 528 529 if ( $has_root ) { 530 $root_join = "$join_type JOIN ( SELECT * FROM {$wpdb->gp_translations} WHERE translation_set_id = " . (int) $root_translation_set->id . " $join_on ) AS r ON o.id = r.original_id"; 531 } 532 533 $orderby = sprintf( $sort_by, $sort_how ); 534 535 $limit = $this->sql_limit_for_paging( $page, $this->per_page ); 536 537 /** 538 * Filters the 'for_translation' query SQL clauses. 539 * 540 * @since 2.3.0 541 * @since 3.0.0 Removed $join_on and added $root_join clause. Also added $root_translation_set. 542 * 543 * @param array $pieces { 544 * Translation query SQL clauses. 545 * 546 * @type array $fields Fields to select in the query. 547 * @type string $join JOIN clause of the query. 548 * @type string $root_join JOIN clause for the root translation set if it exists, otherwise an empty string. 549 * @type string $where WHERE clause of the query. 550 * @type string $orderby Fields for ORDER BY clause. 551 * @type string $limit LIMIT clause of the query. 552 * } 553 * @param GP_Translation_Set $translation_set The translation set object being queried. 554 * @param array $filters An array of search filters. 555 * @param array $sort An array of sort settings. 556 * @param GP_Translation_Set|null $root_translation_set The root translation set object if one exists, otherwise null. 557 */ 558 $clauses = apply_filters( 'gp_for_translation_clauses', compact( 'fields', 'join', 'root_join', 'where', 'orderby', 'limit' ), $translation_set, $filters, $sort, $root_translation_set ); 559 560 $fields = isset( $clauses['fields'] ) ? implode( ', ', $clauses['fields'] ) : '*'; 561 $join = isset( $clauses['join'] ) ? $clauses['join'] : ''; 562 $root_join = isset( $clauses['root_join'] ) ? $clauses['root_join'] : ''; 563 $where = isset( $clauses['where'] ) ? $clauses['where'] : ''; 564 $orderby = isset( $clauses['orderby'] ) ? 'ORDER BY ' . $clauses['orderby'] : ''; 565 $limit = isset( $clauses['limit'] ) ? $clauses['limit'] : ''; 566 567 $sql_for_translations = " 568 SELECT SQL_CALC_FOUND_ROWS $fields 569 FROM {$wpdb->gp_originals} as o 570 $join 571 $root_join 572 WHERE $where $orderby $limit"; 573 574 $rows = $this->many_no_map( $sql_for_translations ); 575 576 /** 577 * Filters the rows returned from the for_translation query. 578 * 579 * @since 2.3.0 580 * 581 * @param array $rows Array of arrays returned by the query. 582 * @param GP_Translation_Set $translation_set The translation set object being queried. 583 */ 584 $rows = apply_filters( 'gp_for_translation_rows', $rows, $translation_set ); 585 586 $this->found_rows = $this->found_rows(); 587 $translations = array(); 588 589 foreach ( (array) $rows as $row ) { 590 if ( null === $row->id && $has_root ) { 591 $row->id = $row->root_id; 592 $row->original_id = $row->root_original_id; 593 $row->translation_set_id = $row->root_translation_set_id; 594 $row->translation_0 = $row->root_translation_0; 595 $row->translation_1 = $row->root_translation_1; 596 $row->translation_2 = $row->root_translation_2; 597 $row->translation_3 = $row->root_translation_3; 598 $row->translation_4 = $row->root_translation_4; 599 $row->translation_5 = $row->root_translation_5; 600 $row->user_id = $row->root_user_id; 601 $row->status = $row->root_status; 602 $row->date_added = $row->root_date_added; 603 $row->date_modified = $row->root_date_modified; 604 $row->warnings = $row->root_warnings; 605 $row->user_id_last_modified = $row->root_user_id_last_modified; 606 $row->translation_status = $row->root_status; 607 $row->translation_added = $row->root_date_added; 608 } 609 610 $row->user = $row->user_last_modified = null; 611 612 if ( $row->user_id && 'no-limit' !== $this->per_page ) { 613 $user = get_userdata( $row->user_id ); 614 if ( $user ) { 615 $row->user = (object) array( 616 'ID' => $user->ID, 617 'user_login' => $user->user_login, 618 'display_name' => $user->display_name, 619 'user_nicename' => $user->user_nicename, 620 ); 621 } 622 } 623 624 if ( $row->user_id_last_modified && 'no-limit' !== $this->per_page ) { 625 $user = get_userdata( $row->user_id_last_modified ); 626 if ( $user ) { 627 $row->user_last_modified = (object) array( 628 'ID' => $user->ID, 629 'user_login' => $user->user_login, 630 'display_name' => $user->display_name, 631 'user_nicename' => $user->user_nicename, 632 ); 633 } 634 } 635 636 $row->translations = array(); 637 for ( $i = 0; $i < $locale->nplurals; $i++ ) { 638 $row->translations[] = $row->{'translation_' . $i}; 639 } 640 $row->references = preg_split( '/\s+/', $row->references, -1, PREG_SPLIT_NO_EMPTY ); 641 $row->extracted_comments = $row->comment; 642 $row->warnings = $row->warnings ? maybe_unserialize( $row->warnings ) : null; 643 unset( $row->comment ); 644 645 // Reduce range by one since we're starting at 0, see GH#516. 646 foreach ( range( 0, $this->get_static( 'number_of_plural_translations' ) - 1 ) as $i ) { 647 $member = "translation_$i"; 648 unset( $row->$member ); 649 } 650 $row->row_id = $row->original_id . ( $row->id ? "-$row->id" : '' ); 651 $translations[] = new Translation_Entry( (array) $row ); 652 } 653 unset( $rows ); 654 return $translations; 655 } 656 657 public function set_as_current() { 658 $result = $this->update( 659 array( 'status' => 'old' ), 660 array( 661 'original_id' => $this->original_id, 662 'translation_set_id' => $this->translation_set_id, 663 'status' => 'current', 664 ) 665 ) 666 && $this->update( 667 array( 'status' => 'old' ), 668 array( 669 'original_id' => $this->original_id, 670 'translation_set_id' => $this->translation_set_id, 671 'status' => 'waiting', 672 ) 673 ) 674 && $this->update( 675 array( 'status' => 'old' ), 676 array( 677 'original_id' => $this->original_id, 678 'translation_set_id' => $this->translation_set_id, 679 'status' => 'fuzzy', 680 ) 681 ) 682 && $this->save( 683 array( 684 'status' => 'current', 685 'user_id_last_modified' => get_current_user_id(), 686 ) 687 ); 688 689 return $result; 690 } 691 692 public function reject() { 693 $this->set_status( 'rejected' ); 694 } 695 696 /** 697 * Decides whether the status of a translation can be changed to a desired status. 698 * 699 * @since 2.3.0 700 * 701 * @param string $desired_status The desired status. 702 * @return bool Whether the status can be set. 703 */ 704 public function can_set_status( $desired_status ) { 705 /** 706 * Filters the decision whether a translation can be set to a status. 707 * 708 * @since 2.3.0 709 * 710 * @param string|bool $can_set_status Whether the user can set the desired status. 711 * @param GP_Translation $translation The translation to decide this for. 712 * @param string $desired_status The desired status. 713 */ 714 $can_set_status = apply_filters( 'gp_pre_can_set_translation_status', 'no-verdict', $this, $desired_status ); 715 if ( is_bool( $can_set_status ) ) { 716 return $can_set_status; 717 } 718 719 if ( ! is_bool( $can_set_status ) && 'rejected' === $desired_status && get_current_user_id() === (int) $this->user_id ) { 720 $can_set_status = true; 721 } 722 723 if ( ! is_bool( $can_set_status ) && ( 'current' === $desired_status || 'rejected' === $desired_status ) ) { 724 if ( ! GP::$permission->current_user_can( 'approve', 'translation', $this->id, array( 'translation' => $this ) ) ) { 725 $can_set_status = false; 726 } 727 } 728 729 if ( ! is_bool( $can_set_status ) ) { 730 $can_set_status = true; 731 } 732 733 /** 734 * Filters the decision whether a translation can be set to a status. 735 * 736 * @since 2.3.0 737 * 738 * @param bool $can_set_status Whether the user can set the desired status. 739 * @param GP_Translation $translation The translation to decide this for. 740 * @param string $desired_status The desired status. 741 */ 742 $can_set_status = apply_filters( 'gp_can_set_translation_status', $can_set_status, $this, $desired_status ); 743 744 return $can_set_status; 745 } 746 747 /** 748 * Changes the status of a translation if possible. 749 * 750 * @since 2.3.0 751 * 752 * @param string $status The status to be set. 753 * @return bool Whether the setting of status was successful. 754 */ 755 public function set_status( $status ) { 756 if ( ! $this->can_set_status( $status ) ) { 757 return false; 758 } 759 760 if ( 'current' === $status ) { 761 $updated = $this->set_as_current(); 762 } else { 763 $updated = $this->save( 764 array( 765 'user_id_last_modified' => get_current_user_id(), 766 'status' => $status, 767 ) 768 ); 769 } 770 771 if ( $updated ) { 772 gp_clean_translation_set_cache( $this->translation_set_id ); 773 } 774 775 return $updated; 776 } 777 778 public function translations() { 779 $translations = array(); 780 781 // Reduce range by one since we're starting at 0, see GH#516. 782 foreach ( range( 0, $this->get_static( 'number_of_plural_translations' ) - 1 ) as $i ) { 783 $translations[ $i ] = isset( $this->{"translation_$i"} ) ? $this->{"translation_$i"} : null; 784 } 785 return $translations; 786 } 787 788 /** 789 * Retrieves the last modified date of a translation in a translation set. 790 * 791 * @since 1.0.0 792 * 793 * @param GP_Translation_Set $translation_set The translation set to retrieve the last modified date. 794 * @return string|false The last modified date on success, false on failure. 795 */ 796 public function last_modified( $translation_set ) { 797 $last_modified = wp_cache_get( $translation_set->id, 'translation_set_last_modified' ); 798 // Cached as "" if no translations. 799 if ( '' === $last_modified ) { 800 return false; 801 } elseif ( false !== $last_modified ) { 802 return $last_modified; 803 } 804 805 $last_modified = $this->value( "SELECT date_modified FROM {$this->table} WHERE translation_set_id = %d AND status = %s ORDER BY date_modified DESC LIMIT 1", $translation_set->id, 'current' ); 806 wp_cache_set( $translation_set->id, (string) $last_modified, 'translation_set_last_modified' ); 807 return $last_modified; 808 } 809 810 // Triggers 811 812 /** 813 * Executes after creating a translation. 814 * 815 * @since 1.0.0 816 * 817 * @return bool 818 */ 819 public function after_create() { 820 /** 821 * Fires after a translation was created. 822 * 823 * @since 1.0.0 824 * 825 * @param GP_Translation $translation Translation that was created. 826 */ 827 do_action( 'gp_translation_created', $this ); 828 829 return true; 830 } 831 832 /** 833 * Executes after saving a translation. 834 * 835 * @since 1.0.0 836 * @since 3.0.0 Added the `$original_before` parameter. 837 * 838 * @param GP_Translation $translation_before Translation before the update. 839 * @return bool 840 */ 841 public function after_save( $translation_before ) { 842 /** 843 * Fires after a translation was saved. 844 * 845 * @since 1.0.0 846 * @since 3.0.0 Added the `$original_before` parameter. 847 * 848 * @param GP_Translation $translation Translation following the update. 849 * @param GP_Translation $translation_before Translation before the update. 850 */ 851 do_action( 'gp_translation_saved', $this, $translation_before ); 852 853 return true; 854 } 855 856 /** 857 * Executes after deleting a translation. 858 * 859 * @since 2.0.0 860 * 861 * @return bool 862 */ 863 public function after_delete() { 864 /** 865 * Fires after a translation was deleted. 866 * 867 * @since 2.0.0 868 * 869 * @param GP_Translation $translation Translation that was deleted. 870 */ 871 do_action( 'gp_translation_deleted', $this ); 872 873 return true; 874 } 875 } 876 877 GP::$translation = new GP_Translation();
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Sat Jan 16 01:01:52 2021 | Cross-referenced by PHPXref 0.7.1 |