[ 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 312 $join_type = 'INNER'; 313 314 $sort_bys = wp_list_pluck( gp_get_sort_by_fields(), 'sql_sort_by' ); 315 316 $default_sort = get_user_option( 'gp_default_sort' ); 317 if ( ! is_array( $default_sort ) ) { 318 $default_sort = array( 319 'by' => 'priority', 320 'how' => 'desc', 321 ); 322 } 323 324 $sort_by = gp_array_get( $sort_bys, gp_array_get( $sort, 'by' ), gp_array_get( $sort_bys, $default_sort['by'] ) ); 325 $sort_hows = array( 326 'asc' => 'ASC', 327 'desc' => 'DESC', 328 ); 329 $sort_how = gp_array_get( $sort_hows, gp_array_get( $sort, 'how' ), gp_array_get( $sort_hows, $default_sort['how'] ) ); 330 $collation = 'yes' === gp_array_get( $filters, 'case_sensitive' ) ? 'BINARY' : ''; 331 332 $where = array(); 333 if ( gp_array_get( $filters, 'term' ) ) { 334 $like = "LIKE $collation '%" . ( esc_sql( $wpdb->esc_like( gp_array_get( $filters, 'term' ) ) ) ) . "%'"; 335 336 $term_scope = gp_array_get( $filters, 'term_scope', 'scope_any' ); 337 338 switch ( $term_scope ) { 339 case 'scope_originals': 340 $scope_array = array( 'o.singular', 'o.plural' ); 341 break; 342 case 'scope_translations': 343 $scope_array = array( 't.translation_0', 't.translation_1' ); 344 break; 345 case 'scope_context': 346 $scope_array = array( 'o.context' ); 347 break; 348 case 'scope_references': 349 $scope_array = array( 'o.references' ); 350 break; 351 case 'scope_both': 352 $scope_array = array( 'o.singular', 't.translation_0', 'o.plural', 't.translation_1' ); 353 break; 354 default: 355 $scope_array = array( 'o.singular', 't.translation_0', 'o.plural', 't.translation_1', 'o.context', 'o.references' ); 356 break; 357 } 358 359 $mapped_scope_array = array_map( 360 function( $x ) use ( $like ) { 361 return "($x $like)"; 362 }, 363 $scope_array 364 ); 365 366 $where[] = '(' . implode( ' OR ', $mapped_scope_array ) . ')'; 367 } 368 if ( gp_array_get( $filters, 'before_date_added' ) ) { 369 $where[] = $wpdb->prepare( 't.date_added > %s', gp_array_get( $filters, 'before_date_added' ) ); 370 } 371 if ( gp_array_get( $filters, 'translation_id' ) ) { 372 $where[] = $wpdb->prepare( 't.id = %d', gp_array_get( $filters, 'translation_id' ) ); 373 } 374 if ( gp_array_get( $filters, 'original_id' ) ) { 375 $where[] = $wpdb->prepare( 'o.id = %d', gp_array_get( $filters, 'original_id' ) ); 376 } 377 if ( 'yes' == gp_array_get( $filters, 'warnings' ) ) { 378 $where[] = 't.warnings IS NOT NULL'; 379 $where[] = 't.warnings != ""'; 380 } elseif ( 'no' == gp_array_get( $filters, 'warnings' ) ) { 381 $where[] = 't.warnings IS NULL'; 382 } 383 if ( 'yes' == gp_array_get( $filters, 'with_context' ) ) { 384 $where[] = 'o.context IS NOT NULL'; 385 } 386 if ( 'yes' == gp_array_get( $filters, 'with_comment' ) ) { 387 $where[] = 'o.comment IS NOT NULL AND o.comment <> ""'; 388 } 389 390 if ( 'yes' === gp_array_get( $filters, 'with_plural' ) ) { 391 $where[] = 'o.plural IS NOT NULL'; 392 } 393 394 if ( gp_array_get( $filters, 'user_login' ) ) { 395 $user = get_user_by( 'login', $filters['user_login'] ); 396 // do not return any entries if the user doesn't exist 397 $where[] = $wpdb->prepare( 't.user_id = %d', ( $user && $user->ID ) ? $user->ID : -1 ); 398 } 399 400 if ( ! GP::$permission->current_user_can( 'write', 'project', $project->id ) ) { 401 $where[] = 'o.priority > -2'; 402 } 403 404 $priorities = gp_array_get( $filters, 'priority' ); 405 if ( $priorities ) { 406 $valid_priorities = array_keys( GP::$original->get_static( 'priorities' ) ); 407 $priorities = array_filter( 408 gp_array_get( $filters, 'priority' ), 409 function( $p ) use ( $valid_priorities ) { 410 return in_array( intval( $p ), $valid_priorities, true ); 411 } 412 ); 413 414 $priorities_where = array(); 415 foreach ( $priorities as $single_priority ) { 416 $priorities_where[] = $wpdb->prepare( 'o.priority = %s', $single_priority ); 417 } 418 419 if ( ! empty( $priorities_where ) ) { 420 $priorities_where = '(' . implode( ' OR ', $priorities_where ) . ')'; 421 $where[] = $priorities_where; 422 } 423 }; 424 425 $join_on = array(); 426 $status = gp_array_get( $filters, 'status', 'current_or_waiting_or_fuzzy_or_untranslated' ); 427 $statuses = explode( '_or_', $status ); 428 if ( in_array( 'untranslated', $statuses, true ) ) { 429 if ( array( 'untranslated' ) == $statuses ) { 430 $where[] = 't.translation_0 IS NULL'; 431 } 432 $join_type = 'LEFT'; 433 $join_on[] = "t.status != 'rejected'"; 434 $join_on[] = "t.status != 'old'"; 435 $statuses = array_filter( 436 $statuses, 437 function( $x ) { 438 return 'untranslated' !== $x; 439 } 440 ); 441 } 442 443 $all_statuses = $this->get_static( 'statuses' ); 444 $statuses = array_filter( 445 $statuses, 446 function( $s ) use ( $all_statuses ) { 447 return in_array( $s, $all_statuses, true ); 448 } 449 ); 450 451 if ( ! empty( $statuses ) ) { 452 $statuses_where = array(); 453 foreach ( $statuses as $single_status ) { 454 $statuses_where[] = $wpdb->prepare( 't.status = %s', $single_status ); 455 } 456 $statuses_where = '(' . implode( ' OR ', $statuses_where ) . ')'; 457 $join_on[] = $statuses_where; 458 } 459 460 /** 461 * Filter the SQL WHERE clause to get available translations. 462 * 463 * @since 1.0.0 464 * 465 * @param array $where An array of where conditions. 466 * @param GP_Translation_Set $translation_set Current translation set. 467 */ 468 $where = apply_filters( 'gp_for_translation_where', $where, $translation_set ); 469 470 $where = implode( ' AND ', $where ); 471 if ( $where ) { 472 $where = 'AND ' . $where; 473 } 474 475 $where = 'o.project_id = ' . (int) $project->id . " AND o.status = '+active' " . $where; 476 477 $join_on = implode( ' AND ', $join_on ); 478 if ( $join_on ) { 479 $join_on = 'AND ' . $join_on; 480 } 481 482 $fields = array( 483 't.*', 484 'o.*', 485 't.id as id', 486 'o.id as original_id', 487 't.status as translation_status', 488 'o.status as original_status', 489 't.date_added as translation_added', 490 'o.date_added as original_added', 491 ); 492 493 $join = "$join_type JOIN {$wpdb->gp_translations} AS t ON o.id = t.original_id AND t.translation_set_id = " . (int) $translation_set->id; 494 495 $orderby = sprintf( $sort_by, $sort_how ); 496 497 $limit = $this->sql_limit_for_paging( $page, $this->per_page ); 498 499 /** 500 * Filters the 'for_translation' query SQL clauses. 501 * 502 * @since 2.3.0 503 * 504 * @param array $pieces { 505 * Translation query SQL clauses. 506 * 507 * @type array $fields Fields to select in the query. 508 * @type string $join JOIN clause of the query. 509 * @type string $join_on Conditions for the JOIN clause. 510 * @type string $where WHERE clause of the query. 511 * @type string $orderby Fields for ORDER BY clause. 512 * @type string $limit LIMIT clause of the query. 513 * } 514 * @param GP_Translation_Set $translation_set The translation set object being queried. 515 * @param array $filters An array of search filters. 516 * @param array $sort An array of sort settings. 517 */ 518 $clauses = apply_filters( 'gp_for_translation_clauses', compact( 'fields', 'join', 'join_on', 'where', 'orderby', 'limit' ), $translation_set, $filters, $sort ); 519 520 $fields = isset( $clauses['fields'] ) ? implode( ', ', $clauses['fields'] ) : '*'; 521 $join = isset( $clauses['join'] ) ? $clauses['join'] : ''; 522 $join_on = isset( $clauses['join_on'] ) ? $clauses['join_on'] : ''; 523 $where = isset( $clauses['where'] ) ? $clauses['where'] : ''; 524 $orderby = isset( $clauses['orderby'] ) ? 'ORDER BY ' . $clauses['orderby'] : ''; 525 $limit = isset( $clauses['limit'] ) ? $clauses['limit'] : ''; 526 527 $sql_for_translations = " 528 SELECT SQL_CALC_FOUND_ROWS $fields 529 FROM {$wpdb->gp_originals} as o 530 $join $join_on 531 WHERE $where $orderby $limit"; 532 533 $rows = $this->many_no_map( $sql_for_translations ); 534 535 /** 536 * Filters the rows returned from the for_translation query. 537 * 538 * @since 2.3.0 539 * 540 * @param array $rows Array of arrays returned by the query. 541 * @param GP_Translation_Set $translation_set The translation set object being queried. 542 */ 543 $rows = apply_filters( 'gp_for_translation_rows', $rows, $translation_set ); 544 545 $this->found_rows = $this->found_rows(); 546 $translations = array(); 547 548 foreach ( (array) $rows as $row ) { 549 $row->user = $row->user_last_modified = null; 550 551 if ( $row->user_id && 'no-limit' !== $this->per_page ) { 552 $user = get_userdata( $row->user_id ); 553 if ( $user ) { 554 $row->user = (object) array( 555 'ID' => $user->ID, 556 'user_login' => $user->user_login, 557 'display_name' => $user->display_name, 558 'user_nicename' => $user->user_nicename, 559 ); 560 } 561 } 562 563 if ( $row->user_id_last_modified && 'no-limit' !== $this->per_page ) { 564 $user = get_userdata( $row->user_id_last_modified ); 565 if ( $user ) { 566 $row->user_last_modified = (object) array( 567 'ID' => $user->ID, 568 'user_login' => $user->user_login, 569 'display_name' => $user->display_name, 570 'user_nicename' => $user->user_nicename, 571 ); 572 } 573 } 574 575 $row->translations = array(); 576 for ( $i = 0; $i < $locale->nplurals; $i++ ) { 577 $row->translations[] = $row->{'translation_' . $i}; 578 } 579 $row->references = preg_split( '/\s+/', $row->references, -1, PREG_SPLIT_NO_EMPTY ); 580 $row->extracted_comments = $row->comment; 581 $row->warnings = $row->warnings ? maybe_unserialize( $row->warnings ) : null; 582 unset( $row->comment ); 583 584 // Reduce range by one since we're starting at 0, see GH#516. 585 foreach ( range( 0, $this->get_static( 'number_of_plural_translations' ) - 1 ) as $i ) { 586 $member = "translation_$i"; 587 unset( $row->$member ); 588 } 589 590 $row->row_id = $row->original_id . ( $row->id ? "-$row->id" : '' ); 591 592 if ( '0' !== $row->priority ) { 593 $row->flags = array( 594 'gp-priority: ' . GP_Original::$priorities[ $row->priority ], 595 ); 596 } 597 598 $translations[] = new Translation_Entry( (array) $row ); 599 } 600 unset( $rows ); 601 return $translations; 602 } 603 604 public function set_as_current() { 605 $result = $this->update( 606 array( 'status' => 'old' ), 607 array( 608 'original_id' => $this->original_id, 609 'translation_set_id' => $this->translation_set_id, 610 'status' => 'current', 611 ) 612 ) 613 && $this->update( 614 array( 'status' => 'old' ), 615 array( 616 'original_id' => $this->original_id, 617 'translation_set_id' => $this->translation_set_id, 618 'status' => 'waiting', 619 ) 620 ) 621 && $this->update( 622 array( 'status' => 'old' ), 623 array( 624 'original_id' => $this->original_id, 625 'translation_set_id' => $this->translation_set_id, 626 'status' => 'fuzzy', 627 ) 628 ) 629 && $this->save( 630 array( 631 'status' => 'current', 632 'user_id_last_modified' => get_current_user_id(), 633 ) 634 ); 635 636 return $result; 637 } 638 639 public function reject() { 640 $this->set_status( 'rejected' ); 641 } 642 643 /** 644 * Decides whether the status of a translation can be changed to a desired status. 645 * 646 * @since 2.3.0 647 * 648 * @param string $desired_status The desired status. 649 * @return bool Whether the status can be set. 650 */ 651 public function can_set_status( $desired_status ) { 652 /** 653 * Filters the decision whether a translation can be set to a status. 654 * 655 * @since 2.3.0 656 * 657 * @param string|bool $can_set_status Whether the user can set the desired status. 658 * @param GP_Translation $translation The translation to decide this for. 659 * @param string $desired_status The desired status. 660 */ 661 $can_set_status = apply_filters( 'gp_pre_can_set_translation_status', 'no-verdict', $this, $desired_status ); 662 if ( is_bool( $can_set_status ) ) { 663 return $can_set_status; 664 } 665 666 if ( ! is_bool( $can_set_status ) && 'rejected' === $desired_status && get_current_user_id() === (int) $this->user_id ) { 667 $can_set_status = true; 668 } 669 670 if ( ! is_bool( $can_set_status ) && ( 'current' === $desired_status || 'rejected' === $desired_status ) ) { 671 if ( ! GP::$permission->current_user_can( 'approve', 'translation', $this->id, array( 'translation' => $this ) ) ) { 672 $can_set_status = false; 673 } 674 } 675 676 if ( ! is_bool( $can_set_status ) ) { 677 $can_set_status = true; 678 } 679 680 /** 681 * Filters the decision whether a translation can be set to a status. 682 * 683 * @since 2.3.0 684 * 685 * @param bool $can_set_status Whether the user can set the desired status. 686 * @param GP_Translation $translation The translation to decide this for. 687 * @param string $desired_status The desired status. 688 */ 689 $can_set_status = apply_filters( 'gp_can_set_translation_status', $can_set_status, $this, $desired_status ); 690 691 return $can_set_status; 692 } 693 694 /** 695 * Changes the status of a translation if possible. 696 * 697 * @since 2.3.0 698 * 699 * @param string $status The status to be set. 700 * @return bool Whether the setting of status was successful. 701 */ 702 public function set_status( $status ) { 703 if ( ! $this->can_set_status( $status ) ) { 704 return false; 705 } 706 707 if ( 'current' === $status ) { 708 $updated = $this->set_as_current(); 709 } else { 710 $updated = $this->save( 711 array( 712 'user_id_last_modified' => get_current_user_id(), 713 'status' => $status, 714 ) 715 ); 716 } 717 718 if ( $updated ) { 719 gp_clean_translation_set_cache( $this->translation_set_id ); 720 } 721 722 return $updated; 723 } 724 725 public function translations() { 726 $translations = array(); 727 728 // Reduce range by one since we're starting at 0, see GH#516. 729 foreach ( range( 0, $this->get_static( 'number_of_plural_translations' ) - 1 ) as $i ) { 730 $translations[ $i ] = isset( $this->{"translation_$i"} ) ? $this->{"translation_$i"} : null; 731 } 732 return $translations; 733 } 734 735 /** 736 * Retrieves the last modified date of a translation in a translation set. 737 * 738 * @since 1.0.0 739 * 740 * @param GP_Translation_Set $translation_set The translation set to retrieve the last modified date. 741 * @return string|false The last modified date on success, false on failure. 742 */ 743 public function last_modified( $translation_set ) { 744 $last_modified = wp_cache_get( $translation_set->id, 'translation_set_last_modified' ); 745 // Cached as "" if no translations. 746 if ( '' === $last_modified ) { 747 return false; 748 } elseif ( false !== $last_modified ) { 749 return $last_modified; 750 } 751 752 $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' ); 753 wp_cache_set( $translation_set->id, (string) $last_modified, 'translation_set_last_modified' ); 754 return $last_modified; 755 } 756 757 // Triggers 758 759 /** 760 * Executes after creating a translation. 761 * 762 * @since 1.0.0 763 * 764 * @return bool 765 */ 766 public function after_create() { 767 /** 768 * Fires after a translation was created. 769 * 770 * @since 1.0.0 771 * 772 * @param GP_Translation $translation Translation that was created. 773 */ 774 do_action( 'gp_translation_created', $this ); 775 776 return true; 777 } 778 779 /** 780 * Executes after saving a translation. 781 * 782 * @since 1.0.0 783 * @since 3.0.0 Added the `$original_before` parameter. 784 * 785 * @param GP_Translation $translation_before Translation before the update. 786 * @return bool 787 */ 788 public function after_save( $translation_before ) { 789 /** 790 * Fires after a translation was saved. 791 * 792 * @since 1.0.0 793 * @since 3.0.0 Added the `$original_before` parameter. 794 * 795 * @param GP_Translation $translation Translation following the update. 796 * @param GP_Translation $translation_before Translation before the update. 797 */ 798 do_action( 'gp_translation_saved', $this, $translation_before ); 799 800 return true; 801 } 802 803 /** 804 * Executes after deleting a translation. 805 * 806 * @since 2.0.0 807 * 808 * @return bool 809 */ 810 public function after_delete() { 811 /** 812 * Fires after a translation was deleted. 813 * 814 * @since 2.0.0 815 * 816 * @param GP_Translation $translation Translation that was deleted. 817 */ 818 do_action( 'gp_translation_deleted', $this ); 819 820 return true; 821 } 822 } 823 824 GP::$translation = new GP_Translation();
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 |