]+>)!i', function( $m ) use ( &$glossary_entries ) { $item_number = count( $glossary_entries ); $glossary_entries[ $item_number ] = $m[0]; return ""; }, $text ); // Wrap full HTML tags with a notranslate class. $text = preg_replace( '/(<.+?>)/', '\\1', $text ); // Break out & back into notranslate for translatable attributes. $text = preg_replace( '/(title|aria-label)=([\'"])([^\\2]+?)\\2/', '\\1=\\2\\3\\2', $text ); // Wrap placeholders with notranslate. $text = preg_replace( '/(%(\d+\$(?:\d+)?)?[bcdefgosuxEFGX])/', '\\1', $text ); // Put the glossaries back! $text = preg_replace_callback( '!()!', function( $m ) use ( $glossary_entries ) { return $glossary_entries[ $m[2] ]; }, $text ); $text = str_replace( array( "\r", "\n" ), "\n", $text ); $text = str_replace( "\t", "\t", $text ); return $text; } /** * Prepares a translation string to be printed out in a translation row by adding an 'extra' return/newline if * it starts with one. * * @since 3.0.0 * * @param string $text A single style handle to enqueue or an array or style handles to enqueue. * @return string The prepared string for output. */ function gp_prepare_translation_textarea( $text ) { if ( gp_startswith( $text, "\r\n" ) ) { $text = "\r\n" . $text; } elseif ( gp_startswith( $text, "\n" ) ) { $text = "\n" . $text; } return $text; } /** * Adds suffixes for use in map_glossary_entries_to_translation_originals(). * * @param array $glossary_entries An array of glossary entries to sort. * * @return array The suffixed entries. */ function gp_glossary_add_suffixes( $glossary_entries ) { if ( empty( $glossary_entries ) ) { return; } $glossary_entries_suffixes = array(); // Create array of glossary terms, longest first. foreach ( $glossary_entries as $key => $value ) { $term = strtolower( $value->term ); // Check if is multiple word term. if ( preg_match( '/\s/', $term ) ) { // Don't add suffix to terms with multiple words. $glossary_entries_suffixes[ $term ] = array(); continue; } $suffixes = array(); if ( 'y' === substr( $term, -1 ) ) { $term = substr( $term, 0, -1 ); $suffixes[] = 'y'; $suffixes[] = 'ies'; $suffixes[] = 'ys'; } elseif ( 'f' === substr( $term, -1 ) ) { $term = substr( $term, 0, -1 ); $suffixes[] = 'f'; $suffixes[] = 'ves'; $terms[] = substr( $term, 0, -1 ) . 'ves'; } elseif ( 'fe' === substr( $term, -2 ) ) { $term = substr( $term, 0, -2 ); $suffixes[] = 'fe'; $suffixes[] = 'ves'; } elseif ( 'an' === substr( $term, -2 ) ) { $term = substr( $term, 0, -2 ); $suffixes[] = 'an'; $suffixes[] = 'en'; } else { $suffixes[] = 's'; $suffixes[] = 'es'; $suffixes[] = 'ed'; $suffixes[] = 'ing'; } $glossary_entries_suffixes[ $term ] = $suffixes; } // Sort by length in descending order. uksort( $glossary_entries_suffixes, function( $a, $b ) { return mb_strlen( $b ) <=> mb_strlen( $a ); } ); return $glossary_entries_suffixes; } /** * Add markup to a translation original to identify the glossary terms. * * @param GP_Translation $translation A GP Translation object. * @param GP_Glossary $glossary A GP Glossary object. * * @return obj The marked up translation entry. */ function map_glossary_entries_to_translation_originals( $translation, $glossary ) { static $terms_search, $glossary_entries_reference, $glossary_entries, $cached_glossary; if ( isset( $terms_search ) && isset( $cached_glossary ) && $cached_glossary === $glossary->id ) { if ( ! $terms_search ) { return $translation; } } else { // Build our glossary search. $glossary_entries = $glossary->get_entries(); $cached_glossary = $glossary->id; if ( empty( $glossary_entries ) ) { $terms_search = false; return $translation; } $glossary_entries_suffixes = gp_glossary_add_suffixes( $glossary_entries ); $glossary_entries_reference = array(); foreach ( $glossary_entries as $id => $value ) { $term = strtolower( $value->term ); if ( ! isset( $glossary_entries_reference[ $term ] ) ) { $glossary_entries_reference[ $term ] = array( $id ); continue; } $glossary_entries_reference[ $term ][] = $id; } $terms_search = '\b('; foreach ( $glossary_entries_suffixes as $term => $suffixes ) { $terms_search .= preg_quote( $term, '/' ); if ( ! empty( $suffixes ) ) { $terms_search .= '(?:' . implode( '|', $suffixes ) . ')?'; } $terms_search .= '|'; $referenced_term = $term; if ( ! isset( $glossary_entries_reference[ $referenced_term ] ) ) { foreach ( $suffixes as $suffix ) { if ( isset( $glossary_entries_reference[ $term . $suffix ] ) ) { $referenced_term = $term . $suffix; } } if ( ! isset( $glossary_entries_reference[ $referenced_term ] ) ) { // This should not happen but we don't want to access a non existing item below. continue; } } $referenced_term = $glossary_entries_reference[ $referenced_term ]; // Add the suffixed terms to the lookup table. foreach ( $suffixes as $suffix ) { if ( isset( $glossary_entries_reference[ $term . $suffix ] ) ) { $glossary_entries_reference[ $term . $suffix ] = array_values( array_unique( array_merge( $glossary_entries_reference[ $term . $suffix ], $referenced_term ) ) ); } else { $glossary_entries_reference[ $term . $suffix ] = $referenced_term; } } } // Remove the trailing |. $terms_search = substr( $terms_search, 0, -1 ); $terms_search .= ')\b'; } // Split the singular string on glossary terms boundaries. $singular_split = preg_split( '/' . $terms_search . '/i', $translation->singular, 0, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE ); // Loop through each chunk of the split to find glossary terms. if ( is_array( $singular_split ) ) { $singular_combined = ''; foreach ( $singular_split as $chunk ) { // Create an escaped version for use later on. $escaped_chunk = esc_translation( $chunk ); // Create a lower case version to compare with the glossary terms. $lower_chunk = strtolower( $chunk ); // Search the glossary terms for a matching entry. if ( isset( $glossary_entries_reference[ $lower_chunk ] ) ) { $glossary_data = array(); // Add glossary data for each matching entry. foreach ( $glossary_entries_reference[ $lower_chunk ] as $glossary_entry_id ) { // Get the glossary entry based on the back reference we created earlier. $glossary_entry = $glossary_entries[ $glossary_entry_id ]; // If this is a locale glossary, make a note for the user. $locale_entry = ''; if ( $glossary_entry->glossary_id !== $glossary->id ) { /* translators: Denotes an entry from the locale glossary in the tooltip */ $locale_entry = _x( 'Locale Glossary', 'Bubble', 'glotpress' ); } // Create the data to be added to the span. $glossary_data[] = array( 'translation' => $glossary_entry->translation, 'pos' => $glossary_entry->part_of_speech, 'comment' => $glossary_entry->comment, 'locale_entry' => $locale_entry, ); } // Add the span and chunk to our output. $singular_combined .= '' . $escaped_chunk . ''; } else { // No term was found so just add the escaped chunk to the output. $singular_combined .= $escaped_chunk; } } // Assign the output to the translation. $translation->singular_glossary_markup = $singular_combined; } else { $translation->singular_glossary_markup = esc_translation( $translation->singular ); } // Add glossary terms to the plural if we have one. if ( $translation->plural ) { // Split the plural string on glossary terms boundaries. $plural_split = @preg_split( '/' . $terms_search . '/i', $translation->plural, 0, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE ); // Loop through each chunk of the split to find glossary terms. if ( is_array( $plural_split ) ) { $plural_combined = ''; foreach ( $plural_split as $chunk ) { // Create an escaped version for use later on. $escaped_chunk = esc_translation( $chunk ); // Create a lower case version to compare with the glossary terms. $lower_chunk = strtolower( $chunk ); // Search the glossary terms for a matching entry. if ( isset( $glossary_entries_reference[ $lower_chunk ] ) ) { $glossary_data = array(); // Add glossary data for each matching entry. foreach ( $glossary_entries_reference[ $lower_chunk ] as $glossary_entry_id ) { // Get the glossary entry based on the back reference we created earlier. $glossary_entry = $glossary_entries[ $glossary_entry_id ]; // If this is a locale glossary, make a note for the user. $locale_entry = ''; if ( $glossary_entry->glossary_id !== $glossary->id ) { /* translators: Denotes an entry from the locale glossary in the tooltip */ $locale_entry = _x( 'Locale Glossary', 'Bubble', 'glotpress' ); } // Create the data to be added to the span. $glossary_data[] = array( 'translation' => $glossary_entry->translation, 'pos' => $glossary_entry->part_of_speech, 'comment' => $glossary_entry->comment, 'locale_entry' => $locale_entry, ); } // Add the span and chunk to our output. $plural_combined .= '' . $escaped_chunk . ''; } else { // No term was found so just add the escaped chunk to the output. $plural_combined .= $escaped_chunk; } } // Assign the output to the translation. $translation->plural_glossary_markup = $plural_combined; } else { $translation->plural_glossary_markup = esc_translation( $translation->plural ); } } return $translation; } function textareas( $entry, $permissions, $index = 0 ) { list( $can_edit, $can_approve ) = $permissions; ?>
warnings[ $index ] ) ) : $referenceable = $entry->warnings[ $index ]; foreach ( $referenceable as $key => $value ) : ?>
translations, $index ) ) ); ?>
have to log in to edit this translation.', 'glotpress' ), esc_url( wp_login_url( gp_url_current() ) ) ); } ?>
_x( 'current', 'Single Status', 'glotpress' ), 'waiting' => _x( 'waiting', 'Single Status', 'glotpress' ), 'fuzzy' => _x( 'fuzzy', 'Single Status', 'glotpress' ), 'old' => _x( 'old', 'Single Status', 'glotpress' ), 'rejected' => _x( 'rejected', 'Single Status', 'glotpress' ), ); if ( isset( $status_labels[ $status ] ) ) { $status = $status_labels[ $status ]; } $status = preg_replace( '/^[+-]/', '', $status ); return $status ? $status : _x( 'untranslated', 'Single Status', 'glotpress' ); } function references( $project, $entry ) { /** * Filter whether to show references of a translation string on a translation row. * * @since 1.0.0 * * @param boolean $references Whether to show references. * @param GP_Project $project The current project. * @param Translation_Entry $entry Translation entry object. */ $show_references = apply_filters( 'gp_show_references', (bool) $entry->references, $project, $entry ); if ( ! $show_references ) { return; } ?>
    references as $reference ) : list( $file, $line ) = array_pad( explode( ':', $reference ), 2, 0 ); $source_url = $project->source_url( $file, $line ); if ( $source_url ) : ?>
  • ' . esc_html( "$file:$line" ) . ''; endif; endforeach; ?>