[ Index ]

PHP Cross Reference of GlotPress

title

Body

[close]

/gp-includes/routes/ -> translation.php (source)

   1  <?php
   2  /**
   3   * Routes: GP_Route_Translation class
   4   *
   5   * @package GlotPress
   6   * @subpackage Routes
   7   * @since 1.0.0
   8   */
   9  
  10  /**
  11   * Core class used to implement the translation route.
  12   *
  13   * @since 1.0.0
  14   */
  15  class GP_Route_Translation extends GP_Route_Main {
  16  
  17  	public function import_translations_get( $project_path, $locale_slug, $translation_set_slug ) {
  18          $project = GP::$project->by_path( $project_path );
  19          $locale = GP_Locales::by_slug( $locale_slug );
  20  
  21          if ( ! $project || ! $locale ) {
  22              return $this->die_with_404();
  23          }
  24  
  25          $translation_set = GP::$translation_set->by_project_id_slug_and_locale( $project->id, $translation_set_slug, $locale_slug );
  26  
  27          if ( ! $translation_set ) {
  28              return $this->die_with_404();
  29          }
  30  
  31          $can_import_current = $this->can( 'approve', 'translation-set', $translation_set->id );
  32          $can_import_waiting = $can_import_current || $this->can( 'import-waiting', 'translation-set', $translation_set->id );
  33  
  34          if ( ! $can_import_current && ! $can_import_waiting ) {
  35              $this->redirect_with_error( __( 'You are not allowed to do that!', 'glotpress' ) );
  36              return;
  37          }
  38  
  39          $kind = 'translations';
  40          $this->tmpl( 'project-import', get_defined_vars() );
  41      }
  42  
  43  	public function import_translations_post( $project_path, $locale_slug, $translation_set_slug ) {
  44          $project = GP::$project->by_path( $project_path );
  45          $locale = GP_Locales::by_slug( $locale_slug );
  46  
  47          if ( ! $project || ! $locale ) {
  48              return $this->die_with_404();
  49          }
  50  
  51          if ( $this->invalid_nonce_and_redirect( 'import-translations_' . $project->id ) ) {
  52              return;
  53          }
  54  
  55          $translation_set = GP::$translation_set->by_project_id_slug_and_locale( $project->id, $translation_set_slug, $locale_slug );
  56  
  57          if ( ! $translation_set ) {
  58              return $this->die_with_404();
  59          }
  60  
  61          $can_import_current = $this->can( 'approve', 'translation-set', $translation_set->id );
  62          $can_import_waiting = $can_import_current || $this->can( 'import-waiting', 'translation-set', $translation_set->id );
  63  
  64          if ( ! $can_import_current && ! $can_import_waiting ) {
  65              $this->redirect_with_error( __( 'You are not allowed to do that!', 'glotpress' ) );
  66              return;
  67          }
  68  
  69          $import_status = gp_post( 'status', 'waiting' );
  70  
  71          $allowed_import_status = array();
  72          if ( $can_import_current ) {
  73              $allowed_import_status[] = 'current';
  74          }
  75          if ( $can_import_waiting ) {
  76              $allowed_import_status[] = 'waiting';
  77          }
  78  
  79          if ( ! in_array( $import_status, $allowed_import_status, true ) ) {
  80              $this->redirect_with_error( __( 'Invalid translation status.', 'glotpress' ) );
  81              return;
  82          }
  83  
  84          if ( !is_uploaded_file( $_FILES['import-file']['tmp_name'] ) ) {
  85              $this->redirect_with_error( __( 'Error uploading the file.', 'glotpress' ) );
  86              return;
  87          }
  88  
  89          $format = gp_get_import_file_format( gp_post( 'format', 'po' ), $_FILES['import-file']['name'] );
  90  
  91          if ( ! $format ) {
  92              $this->redirect_with_error( __( 'No such format.', 'glotpress' ) );
  93              return;
  94          }
  95  
  96          $translations = $format->read_translations_from_file( $_FILES['import-file']['tmp_name'], $project );
  97          if ( ! $translations ) {
  98              $this->redirect_with_error( __( 'Couldn&#8217;t load translations from file!', 'glotpress' ) );
  99              return;
 100          }
 101  
 102          $translations_added = $translation_set->import( $translations, $import_status );
 103          $this->notices[] = sprintf( _n( '%s translation was added', '%s translations were added', $translations_added, 'glotpress' ), $translations_added );
 104  
 105          $this->redirect( gp_url_project( $project, gp_url_join( $locale->slug, $translation_set->slug ) ) );
 106      }
 107  
 108  	public function export_translations_get( $project_path, $locale_slug, $translation_set_slug ) {
 109          $project = GP::$project->by_path( $project_path );
 110          $locale = GP_Locales::by_slug( $locale_slug );
 111  
 112          if ( ! $project || ! $locale ) {
 113              return $this->die_with_404();
 114          }
 115  
 116          $translation_set = GP::$translation_set->by_project_id_slug_and_locale( $project->id, $translation_set_slug, $locale_slug );
 117  
 118          if ( ! $translation_set ) {
 119              return $this->die_with_404();
 120          }
 121  
 122          $get_format = gp_get( 'format', 'po' );
 123  
 124          // If for some reason we were passed in an array or object from the get parameters, don't use it.
 125          if ( ! is_string( $get_format ) ) {
 126              $get_format = '.po';
 127          }
 128  
 129          $format = gp_array_get( GP::$formats, $get_format, null );
 130  
 131          if ( ! $format ) {
 132              return $this->die_with_404();
 133          }
 134  
 135          /**
 136           * Filter the locale in the file name of the translation set export.
 137           *
 138           * @since 1.0.0
 139           *
 140           * @param string    $slug   Slug of the locale.
 141           * @param GP_Locale $locale The current locale.
 142           */
 143          $export_locale = apply_filters( 'gp_export_locale', $locale->slug, $locale );
 144          $filename = sprintf( $format->filename_pattern . '.' . $format->extension, str_replace( '/', '-', $project->path ), $export_locale );
 145  
 146          /**
 147           * Filter the filename of the translation set export.
 148           *
 149           * @since 1.0.0
 150           *
 151           * @param string             $filename        Filename of the exported translation set.
 152           * @param GP_Format          $format          Format of the export.
 153           * @param GP_Locale          $locale          Locale of the export.
 154           * @param GP_Project         $project         Project the translation set belongs to.
 155           * @param GP_Translation_Set $translation_set The translation set to be exported.
 156           */
 157          $filename = apply_filters( 'gp_export_translations_filename', $filename, $format, $locale, $project, $translation_set );
 158  
 159          $entries = GP::$translation->for_export( $project, $translation_set, gp_get( 'filters' ) );
 160  
 161          if ( gp_has_translation_been_updated( $translation_set ) ) {
 162              $last_modified = gmdate( 'D, d M Y H:i:s', gp_gmt_strtotime( GP::$translation->last_modified( $translation_set ) ) ) . ' GMT';
 163              $this->headers_for_download( $filename, $last_modified );
 164  
 165              echo $format->print_exported_file( $project, $locale, $translation_set, $entries );
 166  
 167          // As has_translation_been_updated() compared against HTTP_IF_MODIFIED_SINCE here, send an appropriate header.
 168          } else {
 169              $this->status_header( 304 );
 170          }
 171      }
 172  
 173  	public function translations_get( $project_path, $locale_slug, $translation_set_slug ) {
 174          $project = GP::$project->by_path( $project_path );
 175          $locale = GP_Locales::by_slug( $locale_slug );
 176  
 177          if ( ! $project || ! $locale ) {
 178              return $this->die_with_404();
 179          }
 180  
 181          $translation_set = GP::$translation_set->by_project_id_slug_and_locale( $project->id, $translation_set_slug, $locale_slug );
 182  
 183          if ( ! $translation_set ) {
 184              return $this->die_with_404();
 185          }
 186  
 187          $glossary = $this->get_extended_glossary( $translation_set, $project );
 188  
 189          $page = gp_get( 'page', 1 );
 190          $filters = gp_get( 'filters', array() );
 191          $sort = gp_get( 'sort', array() );
 192  
 193          if ( is_array( $sort ) && 'random' === gp_array_get( $sort, 'by' ) ) {
 194              add_filter( 'gp_pagination', '__return_null' );
 195          }
 196  
 197          $per_page = (int) get_user_option( 'gp_per_page' );
 198          if ( 0 === $per_page ) {
 199              $per_page = GP::$translation->per_page;
 200          } else {
 201              GP::$translation->per_page = $per_page;
 202          }
 203  
 204          if ( ! is_array( $filters ) ) {
 205              $filters = array();
 206          }
 207  
 208          if ( ! is_array( $sort ) ) {
 209              $sort = array();
 210          }
 211  
 212          $translations = GP::$translation->for_translation( $project, $translation_set, $page, $filters, $sort );
 213          $total_translations_count = GP::$translation->found_rows;
 214  
 215          $can_edit = $this->can( 'edit', 'translation-set', $translation_set->id );
 216          $can_write = $this->can( 'write', 'project', $project->id );
 217          $can_approve = $this->can( 'approve', 'translation-set', $translation_set->id );
 218          $can_import_current = $can_approve;
 219          $can_import_waiting = $can_approve || $this->can( 'import-waiting', 'translation-set', $translation_set->id );
 220          $url = gp_url_project( $project, gp_url_join( $locale->slug, $translation_set->slug ) );
 221          $set_priority_url = gp_url( '/originals/%original-id%/set_priority');
 222          $discard_warning_url = gp_url_project( $project, gp_url_join( $locale->slug, $translation_set->slug, '-discard-warning' ) );
 223          $set_status_url = gp_url_project( $project, gp_url_join( $locale->slug, $translation_set->slug, '-set-status' ) );
 224          $new_note_url        = gp_url( '/notes/-new' );
 225          $edit_note_url       = gp_url( '/notes/-edit' );
 226          $delete_note_url     = gp_url( '/notes/-delete' );
 227          $bulk_action = gp_url_join( $url, '-bulk' );
 228  
 229          // Add action to use different font for translations
 230          add_action( 'gp_head', function() use ( $locale ) {
 231              return gp_preferred_sans_serif_style_tag( $locale );
 232          } );
 233  
 234          $this->tmpl( 'translations', get_defined_vars() );
 235      }
 236  
 237  	public function translations_post( $project_path, $locale_slug, $translation_set_slug ) {
 238          $project = GP::$project->by_path( $project_path );
 239          $locale = GP_Locales::by_slug( $locale_slug );
 240  
 241          if ( ! $project || ! $locale ) {
 242              return $this->die_with_404();
 243          }
 244  
 245          $original_id = gp_post( 'original_id' );
 246  
 247          if ( ! $this->verify_nonce( 'add-translation_' . $original_id ) ) {
 248              return $this->die_with_error( __( 'An error has occurred. Please try again.', 'glotpress' ), 403 );
 249          }
 250  
 251          $translation_set = GP::$translation_set->by_project_id_slug_and_locale( $project->id, $translation_set_slug, $locale_slug );
 252  
 253          $this->can_or_forbidden( 'edit', 'translation-set', $translation_set->id );
 254  
 255          if ( ! $translation_set ) {
 256              return $this->die_with_404();
 257          }
 258  
 259          $glossary = $this->get_extended_glossary( $translation_set, $project );
 260  
 261          $output = array();
 262          foreach( gp_post( 'translation', array() ) as $original_id => $translations) {
 263              $data = compact('original_id');
 264              $data['user_id'] = get_current_user_id();
 265              $data['translation_set_id'] = $translation_set->id;
 266  
 267              // Reduce range by one since we're starting at 0, see GH#516.
 268              foreach ( range( 0, GP::$translation->get_static( 'number_of_plural_translations' ) - 1 ) as $i ) {
 269                  if ( isset( $translations[ $i ] ) ) {
 270                      $data[ "translation_$i" ] = $translations[ $i ];
 271                  }
 272              }
 273  
 274              if ( isset( $data['status'] ) ) {
 275                  $set_status = $data['status'];
 276              } else {
 277                  $set_status = 'waiting';
 278              }
 279  
 280              $data['status'] = 'waiting';
 281  
 282              if ( $this->can( 'approve', 'translation-set', $translation_set->id ) || $this->can( 'write', 'project', $project->id ) ) {
 283                  $set_status = 'current';
 284              } else {
 285                  $set_status = 'waiting';
 286              }
 287  
 288              $original = GP::$original->get( $original_id );
 289              $data['warnings'] = GP::$translation_warnings->check( $original->singular, $original->plural, $translations, $locale );
 290  
 291  
 292              $existing_translations = GP::$translation->for_translation( $project, $translation_set, 'no-limit', array('original_id' => $original_id, 'status' => 'current_or_waiting' ), array() );
 293              foreach( $existing_translations as $e ) {
 294                  if ( array_pad( $translations, $locale->nplurals, null ) == $e->translations ) {
 295                      return $this->die_with_error( __( 'Identical current or waiting translation already exists.', 'glotpress' ), 200 );
 296                  }
 297              }
 298  
 299              $translation = GP::$translation->create( $data );
 300  
 301              if ( ! $translation ) {
 302                  return $this->die_with_error( __( 'Error in saving the translation!', 'glotpress' ) );
 303              }
 304  
 305              if ( ! $translation->validate() ) {
 306                  $error_output = '<ul>';
 307                  foreach ($translation->errors as $error) {
 308                      $error_output .= '<li>' . $error . '</li>';
 309                  }
 310                  $error_output .= '</ul>';
 311                  $translation->delete();
 312  
 313                  return $this->die_with_error( $error_output, 200 );
 314              }
 315              else {
 316                  if ( 'current' === $set_status ) {
 317                      $translation->set_status( 'current' );
 318                  }
 319  
 320                  $translations = GP::$translation->for_translation( $project, $translation_set, 'no-limit', array('translation_id' => $translation->id), array() );
 321  
 322                  if ( ! empty( $translations ) ) {
 323                      $translation = $translations[0];
 324  
 325                      $can_edit = $this->can( 'edit', 'translation-set', $translation_set->id );
 326                      $can_write = $this->can( 'write', 'project', $project->id );
 327                      $can_approve = $this->can( 'approve', 'translation-set', $translation_set->id );
 328                      $can_approve_translation = $this->can( 'approve', 'translation', $translation->id, array( 'translation' => $translation ) );
 329  
 330                      $output[ $original_id ] = gp_tmpl_get_output( 'translation-row', get_defined_vars() );
 331                  } else {
 332                      $output[ $original_id ] = false;
 333                  }
 334              }
 335          }
 336          echo wp_json_encode( $output );
 337      }
 338  
 339  	public function bulk_post( $project_path, $locale_slug, $translation_set_slug ) {
 340          $project = GP::$project->by_path( $project_path );
 341          $locale = GP_Locales::by_slug( $locale_slug );
 342  
 343          if ( ! $project || ! $locale ) {
 344              return $this->die_with_404();
 345          }
 346  
 347          $translation_set = GP::$translation_set->by_project_id_slug_and_locale( $project->id, $translation_set_slug, $locale_slug );
 348  
 349          if ( ! $translation_set ) {
 350              return $this->die_with_404();
 351          }
 352  
 353          if ( $this->invalid_nonce_and_redirect( 'bulk-actions' ) ) {
 354              return;
 355          }
 356  
 357          if ( $this->cannot_and_redirect( 'approve', 'translation-set', $translation_set->id ) ) {
 358              return;
 359          }
 360  
 361          $bulk = gp_post('bulk');
 362          $bulk['row-ids'] = array_filter( explode( ',', $bulk['row-ids'] ) );
 363          if ( ! empty( $bulk['row-ids'] ) ) {
 364              switch( $bulk['action'] ) {
 365                  case 'approve':
 366                  case 'reject' :
 367                      $this->_bulk_approve( $bulk );
 368                      break;
 369                  case 'fuzzy':
 370                      $this->_bulk_fuzzy( $bulk );
 371                      break;
 372                  case 'set-priority':
 373                      $this->_bulk_set_priority( $project, $bulk );
 374              }
 375  
 376              /**
 377               * Bulk action for translation set allows handling of custom actions.
 378               *
 379               * @since 1.0.0
 380               *
 381               * @param GP_Project         $project         The current project.
 382               * @param GP_Locale          $locale          The current locale.
 383               * @param GP_Translation_Set $translation_set The current translation set.
 384               * @param array              $bulk            {
 385               *     The bulk action data, read from the POST.
 386               *
 387               *     @type string $action      Action value chosen from the drop down menu.
 388               *     @type string $priority    The selected value from the priority drop down menu.
 389               *     @type string $redirect_to The URL that after the bulk actions are executed the
 390               *                               browser is redirected to.
 391               *     @type array  $row-ids     An array of strings of row IDs.
 392               * }
 393               */
 394              do_action( 'gp_translation_set_bulk_action_post', $project, $locale, $translation_set, $bulk );
 395          }
 396          else {
 397              $this->errors[] = 'No translations were supplied.';
 398          }
 399  
 400          $bulk['redirect_to'] = esc_url_raw( $bulk['redirect_to'] );
 401          $this->redirect( $bulk['redirect_to'] );
 402      }
 403  
 404  	private function _bulk_approve( $bulk ) {
 405  
 406          $action = $bulk['action'];
 407  
 408          $ok = $error = 0;
 409          $new_status = 'approve' == $action? 'current' : 'rejected';
 410          foreach( $bulk['row-ids'] as $row_id ) {
 411              $translation_id = gp_array_get( explode( '-', $row_id ), 1 );
 412              $translation = GP::$translation->get( $translation_id );
 413              if ( !$translation ) continue;
 414              if ( $translation->set_status( $new_status ) )
 415                  $ok++;
 416              else
 417                  $error++;
 418          }
 419  
 420          if ( 0 === $error) {
 421              $this->notices[] = 'approve' == $action?
 422                      sprintf( _n('%d translation was approved.', '%d translations were approved.', $ok, 'glotpress' ), $ok ):
 423                      sprintf( _n('%d translation was rejected.', '%d translations were rejected.', $ok, 'glotpress' ), $ok );
 424          } else {
 425              if ( $ok > 0 ) {
 426                  $message = 'approve' == $action?
 427                          sprintf( _n('Error with approving %s translation.', 'Error with approving %s translations.', $error, 'glotpress' ), $error ):
 428                          sprintf( _n('Error with rejecting %s translation.', 'Error with rejecting %s translations.', $error, 'glotpress' ), $error );
 429                  $message .= ' ';
 430                  $message .= 'approve' == $action?
 431                          sprintf( _n(
 432                                  'The remaining %s translation was approved successfully.',
 433                                  'The remaining %s translations were approved successfully.', $ok, 'glotpress' ), $ok ):
 434                          sprintf( _n(
 435                                  'The remaining %s translation was rejected successfully.',
 436                                  'The remaining %s translations were rejected successfully.', $ok, 'glotpress' ), $ok );
 437                  $this->errors[] = $message;
 438              } else {
 439                  $this->errors[] = 'approve' == $action?
 440                          sprintf( _n(
 441                                  'Error with approving %s translation.',
 442                                  'Error with approving all %s translation.', $error, 'glotpress' ), $error ):
 443                          sprintf( _n(
 444                                  'Error with rejecting %s translation.',
 445                                  'Error with rejecting all %s translation.', $error, 'glotpress' ), $error );
 446              }
 447          }
 448      }
 449  
 450      /**
 451       * Processes the bulk action to set translations to fuzzy.
 452       *
 453       * @since 2.3.0
 454       *
 455       * @param array $bulk The bulk data to process.
 456       */
 457  	private function _bulk_fuzzy( $bulk ) {
 458          $ok = $error = 0;
 459  
 460          foreach ( $bulk['row-ids'] as $row_id ) {
 461              $translation_id = gp_array_get( explode( '-', $row_id ), 1 );
 462              $translation = GP::$translation->get( $translation_id );
 463  
 464              if ( ! $translation ) {
 465                  continue;
 466              }
 467  
 468              if ( $translation->set_status( 'fuzzy' ) ) {
 469                  $ok++;
 470              } else {
 471                  $error++;
 472              }
 473          }
 474  
 475          if ( 0 === $error ) {
 476              $this->notices[] = sprintf( _n( '%d translation was marked as fuzzy.', '%d translations were marked as fuzzy.', $ok, 'glotpress' ), $ok );
 477          } else {
 478              if ( $ok > 0 ) {
 479                  $message = sprintf( _n( 'Error with marking %s translation as fuzzy.', 'Error with marking %s translations as fuzzy.', $error, 'glotpress' ), $error );
 480                  $message .= ' ';
 481                  $message .= sprintf( _n( 'The remaining %s translation was marked as fuzzy successfully.', 'The remaining %s translations were marked as fuzzy successfully.', $ok, 'glotpress' ), $ok );
 482  
 483                  $this->errors[] = $message;
 484              } else {
 485                  $this->errors[] = sprintf( _n( 'Error with marking %s translation as fuzzy.', 'Error with marking all %s translation as fuzzy.', $error, 'glotpress' ), $error );
 486              }
 487          }
 488      }
 489  
 490  	private function _bulk_set_priority( $project, $bulk ) {
 491  
 492          if ( $this->cannot_and_redirect( 'write', 'project', $project->id ) ){
 493              return;
 494          }
 495  
 496          $ok = $error = 0;
 497          foreach( $bulk['row-ids'] as $row_id ) {
 498              $original_id = gp_array_get( explode( '-', $row_id ), 0 );
 499              $original = GP::$original->get( $original_id );
 500  
 501              if ( ! $original ) {
 502                  continue;
 503              }
 504  
 505              $original->priority = $bulk['priority'];
 506  
 507              if ( ! $original->validate() ) {
 508                  return $this->die_with_error( 'Invalid priority value!' );
 509              }
 510  
 511              if ( ! $original->save() ) {
 512                  $error++;
 513              } else {
 514                  $ok ++;
 515              }
 516          }
 517  
 518          if ( 0 === $error) {
 519              $this->notices[] = sprintf( _n( 'Priority of %d original was modified.', 'Priority of %d originals were modified.', $ok, 'glotpress' ), $ok );
 520          } else {
 521              if ( $ok > 0 ) {
 522                  $message = sprintf( _n( 'Error modifying priority of %d original.', 'Error modifying priority of %d originals.', $error, 'glotpress' ), $error );
 523                  $message.= sprintf( _n( 'The remaining %d original was modified successfully.', 'The remaining %d originals were modified successfully.', $ok, 'glotpress' ), $ok );
 524  
 525                  $this->errors[] = $message;
 526              } else {
 527                  $this->errors[] = sprintf( _n( 'Error modifying priority of %d original.', 'Error modifying priority of all %d originals.', $error, 'glotpress' ), $error );
 528              }
 529          }
 530  
 531      }
 532  
 533  	public function discard_warning( $project_path, $locale_slug, $translation_set_slug ) {
 534          $index = gp_post( 'index' );
 535          $key = gp_post( 'key' );
 536  
 537          if ( ! $this->verify_nonce( 'discard-warning_' . $index . $key ) ) {
 538              return $this->die_with_error( __( 'An error has occurred. Please try again.', 'glotpress' ), 403 );
 539          }
 540  
 541          return $this->edit_single_translation( $project_path, $locale_slug, $translation_set_slug, array( $this, 'discard_warning_edit_function' ) );
 542      }
 543  
 544  	public function set_status( $project_path, $locale_slug, $translation_set_slug ) {
 545          $status         = gp_post( 'status' );
 546          $translation_id = gp_post( 'translation_id' );
 547  
 548          if ( ! $this->verify_nonce( 'update-translation-status-' . $status . '_' . $translation_id ) ) {
 549              return $this->die_with_error( __( 'An error has occurred. Please try again.', 'glotpress' ), 403 );
 550          }
 551  
 552          return $this->edit_single_translation( $project_path, $locale_slug, $translation_set_slug, array( $this, 'set_status_edit_function' ) );
 553      }
 554  
 555  	private function edit_single_translation( $project_path, $locale_slug, $translation_set_slug, $edit_function ) {
 556          $project = GP::$project->by_path( $project_path );
 557          $locale = GP_Locales::by_slug( $locale_slug );
 558  
 559          if ( ! $project || ! $locale ) {
 560              return $this->die_with_404();
 561          }
 562  
 563          $translation_set = GP::$translation_set->by_project_id_slug_and_locale( $project->id, $translation_set_slug, $locale_slug );
 564  
 565          if ( ! $translation_set ) {
 566              return $this->die_with_404();
 567          }
 568  
 569          $glossary = $this->get_extended_glossary( $translation_set, $project );
 570  
 571          $translation = GP::$translation->get( gp_post( 'translation_id' ) );
 572  
 573          if ( ! $translation ) {
 574              return $this->die_with_error( 'Translation doesn&#8217;t exist!' );
 575          }
 576  
 577          $this->can_approve_translation_or_forbidden( $translation );
 578  
 579          call_user_func( $edit_function, $project, $locale, $translation_set, $translation );
 580  
 581          $translations = GP::$translation->for_translation( $project, $translation_set, 'no-limit', array('translation_id' => $translation->id, 'status' => 'either'), array() );
 582          if ( ! empty( $translations ) ) {
 583              $translation = $translations[0];
 584  
 585              $can_edit = $this->can( 'edit', 'translation-set', $translation_set->id );
 586              $can_write = $this->can( 'write', 'project', $project->id );
 587              $can_approve = $this->can( 'approve', 'translation-set', $translation_set->id );
 588              $can_approve_translation = $this->can( 'approve', 'translation', $translation->id, array( 'translation' => $translation ) );
 589  
 590              $this->tmpl( 'translation-row', get_defined_vars() );
 591          } else {
 592              return $this->die_with_error( 'Error in retrieving translation!' );
 593          }
 594      }
 595  
 596      /**
 597       * Discard a warning.
 598       *
 599       * @since 1.0.0
 600       *
 601       * @param GP_Project         $project         The project.
 602       * @param GP_Locale          $locale          The GlotPress locale.
 603       * @param GP_Translation_Set $translation_set The translation set.
 604       * @param GP_Translation     $translation     The translation object.
 605       */
 606  	private function discard_warning_edit_function( $project, $locale, $translation_set, $translation ) {
 607          if ( ! isset( $translation->warnings[ gp_post( 'index' ) ][ gp_post( 'key' ) ] ) ) {
 608              return $this->die_with_error( 'The warning doesn&#8217;exist!' );
 609          }
 610  
 611          $warning = array(
 612              'project_id' => $project->id,
 613              'translation_set' =>$translation_set->id,
 614              'translation' => $translation->id,
 615              'warning' => gp_post( 'key' ),
 616              'user' => get_current_user_id()
 617          );
 618  
 619          /**
 620           * Fires before a warning gets discarded.
 621           *
 622           * @since 1.0.0
 623           *
 624           * @param array $warning {
 625           *     @type string $project_id      ID of the project.
 626           *     @type string $translation_set ID of the translation set.
 627           *     @type string $translation     ID of the translation.
 628           *     @type string $warning         The warning key.
 629           *     @type int    $user            Current user's ID.
 630           * }
 631           */
 632          do_action_ref_array( 'gp_warning_discarded', $warning );
 633  
 634          unset( $translation->warnings[gp_post( 'index' )][gp_post( 'key' )] );
 635          if ( empty( $translation->warnings[gp_post( 'index' )] ) ) {
 636              unset( $translation->warnings[gp_post( 'index' )] );
 637          }
 638  
 639          $res = $translation->save();
 640  
 641          if ( false === $res || null === $res ) {
 642              return $this->die_with_error( 'Error in saving the translation!' );
 643          }
 644      }
 645  
 646  	private function set_status_edit_function( $project, $locale, $translation_set, $translation ) {
 647          $res = $translation->set_status( gp_post( 'status' ) );
 648  
 649          if ( ! $res ) {
 650              return $this->die_with_error( 'Error in saving the translation status!' );
 651          }
 652      }
 653  
 654  	private function can_approve_translation_or_forbidden( $translation ) {
 655          $can_reject_self = (get_current_user_id() == $translation->user_id && $translation->status == "waiting");
 656          if ( $can_reject_self ) {
 657              return;
 658          }
 659          $this->can_or_forbidden( 'approve', 'translation', $translation->id, null, array( 'translation' => $translation ) );
 660      }
 661  
 662      /**
 663       * Get the glossary for the translation set.
 664       *
 665       * This also fetches contents from a potential locale glossary, as well as from a parent project.
 666       *
 667       * @since 2.3.0
 668       *
 669       * @param  GP_Translation_Set $translation_set Translation set for which to retrieve the glossary.
 670       * @param  GP_Project         $project         Project for finding potential parent projects.
 671       * @return GP_Glossary Extended glossary.
 672       */
 673  	protected function get_extended_glossary( $translation_set, $project ) {
 674          $glossary = GP::$glossary->by_set_or_parent_project( $translation_set, $project );
 675  
 676          $locale_glossary_project_id = 0;
 677          $locale_glossary_translation_set = GP::$translation_set->by_project_id_slug_and_locale( $locale_glossary_project_id, $translation_set->slug, $translation_set->locale );
 678  
 679          if ( ! $locale_glossary_translation_set ) {
 680              return $glossary;
 681          }
 682  
 683          $locale_glossary = GP::$glossary->by_set_id( $locale_glossary_translation_set->id );
 684  
 685          // Return locale glossary if a project has no glossary.
 686          if ( false === $glossary && $locale_glossary instanceof GP_Glossary ) {
 687              return $locale_glossary;
 688          }
 689  
 690          if ( $glossary instanceof GP_Glossary && $locale_glossary instanceof GP_Glossary && $locale_glossary->id !== $glossary->id ) {
 691              $glossary->merge_with_glossary( $locale_glossary );
 692          }
 693  
 694          return $glossary;
 695      }
 696  }


Generated: Sat Aug 17 01:01:56 2019 Cross-referenced by PHPXref 0.7.1