738 lines
20 KiB
PHP
738 lines
20 KiB
PHP
<?php
|
|
|
|
/**
|
|
* Retrieves a value from $_POST.
|
|
*
|
|
* @param string $key Name of post value.
|
|
* @param string|array $default Optional. Value to return if `$_POST[ $key ]` doesn't exist. Default empty.
|
|
* @return string|array Value of `$_POST[ $key ]` if exists or `$default`.
|
|
*/
|
|
function gp_post( $key, $default = '' ) {
|
|
// phpcs:ignore WordPress.Security.NonceVerification -- Helper to retrieve item from the request.
|
|
return wp_unslash( gp_array_get( $_POST, $key, $default ) );
|
|
}
|
|
|
|
/**
|
|
* Retrieves a value from $_GET.
|
|
*
|
|
* @param string $key Name of get value.
|
|
* @param string|array $default Optional. Value to return if `$_GET[ $key ]` doesn't exist. Default empty.
|
|
* @return string|array Value of `$_GET[ $key ]` if exists or `$default`.
|
|
*/
|
|
function gp_get( $key, $default = '' ) {
|
|
// phpcs:ignore WordPress.Security.NonceVerification -- Helper to retrieve item from the request.
|
|
return wp_unslash( gp_array_get( $_GET, $key, $default ) );
|
|
}
|
|
|
|
/**
|
|
* Prints a nonce hidden field for route actions.
|
|
*
|
|
* @since 2.0.0
|
|
*
|
|
* @see wp_nonce_field()
|
|
*
|
|
* @param int|string $action Action name.
|
|
* @param bool $echo Optional. Whether to display or return hidden form field. Default true.
|
|
* @return string Nonce field HTML markup.
|
|
*/
|
|
function gp_route_nonce_field( $action, $echo = true ) {
|
|
return wp_nonce_field( $action, '_gp_route_nonce', true, $echo );
|
|
}
|
|
|
|
/**
|
|
* Retrieves a URL with a nonce added to URL query for route actions.
|
|
*
|
|
* @since 2.0.0
|
|
*
|
|
* @see wp_nonce_url()
|
|
*
|
|
* @param string $url URL to add nonce action.
|
|
* @param int|string $action Action name.
|
|
* @return string Escaped URL with nonce action added.
|
|
*/
|
|
function gp_route_nonce_url( $url, $action ) {
|
|
return wp_nonce_url( $url, $action, $name = '_gp_route_nonce' );
|
|
}
|
|
|
|
/**
|
|
* Retrieves a value from $array
|
|
*
|
|
* @param array $array
|
|
* @param string $key name of array value
|
|
* @param mixed $default value to return if $array[$key] doesn't exist. Default is ''
|
|
* @return mixed $array[$key] if exists or $default
|
|
*/
|
|
function gp_array_get( $array, $key, $default = '' ) {
|
|
return ( is_scalar( $key ) && isset( $array[ $key ] ) ) ? $array[ $key ] : $default;
|
|
}
|
|
|
|
function gp_const_get( $name, $default = '' ) {
|
|
return defined( $name ) ? constant( $name ) : $default;
|
|
}
|
|
|
|
function gp_const_set( $name, $value ) {
|
|
if ( defined( $name ) ) {
|
|
return false;
|
|
}
|
|
define( $name, $value );
|
|
return true;
|
|
}
|
|
|
|
|
|
function gp_member_get( $object, $key, $default = '' ) {
|
|
return ( is_string( $key ) && property_exists( $object, $key ) ) ? $object->$key : $default;
|
|
}
|
|
|
|
/**
|
|
* Makes from an array of arrays a flat array.
|
|
*
|
|
* @param array $array the arra to flatten
|
|
* @return array flattenned array
|
|
*/
|
|
function gp_array_flatten( $array ) {
|
|
$res = array();
|
|
foreach ( $array as $value ) {
|
|
$res = array_merge( $res, is_array( $value ) ? gp_array_flatten( $value ) : array( $value ) );
|
|
}
|
|
return $res;
|
|
}
|
|
|
|
/**
|
|
* Passes the message set through the next redirect.
|
|
*
|
|
* Works best for edit requests, which want to pass error message or notice back to the listing page.
|
|
*
|
|
* @param string $message The message to be passed.
|
|
* @param string $key Optional. Key for the message. You can pass several messages under different keys.
|
|
* A key has one message. The default is 'notice'.
|
|
*/
|
|
function gp_notice_set( $message, $key = 'notice' ) {
|
|
$cookie_path = '/' . ltrim( gp_url_path(), '/' ); // Make sure that the cookie path is never empty.
|
|
gp_set_cookie( '_gp_notice_' . $key, $message, 0, $cookie_path );
|
|
}
|
|
|
|
/**
|
|
* Retrieves a notice message, set by {@link gp_notice()}
|
|
*
|
|
* @param string $key Optional. Message key. The default is 'notice'
|
|
*/
|
|
function gp_notice( $key = 'notice' ) {
|
|
// Sanitize fields
|
|
$allowed_tags = array(
|
|
'a' => array( 'href' => true ),
|
|
'abbr' => array(),
|
|
'acronym' => array(),
|
|
'b' => array(),
|
|
'br' => array(),
|
|
'button' => array(
|
|
'disabled' => true,
|
|
'name' => true,
|
|
'type' => true,
|
|
'value' => true,
|
|
),
|
|
'em' => array(),
|
|
'i' => array(),
|
|
'img' => array(
|
|
'src' => true,
|
|
'width' => true,
|
|
'height' => true,
|
|
),
|
|
'p' => array(),
|
|
'pre' => array(),
|
|
's' => array(),
|
|
'strike' => array(),
|
|
'strong' => array(),
|
|
'sub' => array(),
|
|
'sup' => array(),
|
|
'u' => array(),
|
|
);
|
|
|
|
// Adds class, id, style, title, role attributes to all of the above allowed tags.
|
|
$allowed_tags = array_map( '_wp_add_global_attributes', $allowed_tags );
|
|
|
|
return wp_kses( gp_array_get( GP::$redirect_notices, $key ), $allowed_tags );
|
|
}
|
|
|
|
function gp_populate_notices() {
|
|
GP::$redirect_notices = array();
|
|
$prefix = '_gp_notice_';
|
|
$cookie_path = '/' . ltrim( gp_url_path(), '/' ); // Make sure that the cookie path is never empty.
|
|
foreach ( $_COOKIE as $key => $value ) {
|
|
if ( gp_startswith( $key, $prefix ) && $suffix = substr( $key, strlen( $prefix ) ) ) {
|
|
GP::$redirect_notices[ $suffix ] = wp_unslash( $value );
|
|
gp_set_cookie( $key, '', 0, $cookie_path );
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns an array of arrays, where the i-th array contains the i-th element from
|
|
* each of the argument arrays. The returned array is truncated in length to the length
|
|
* of the shortest argument array.
|
|
*
|
|
* Previously this function was documented as:
|
|
*
|
|
* The function works only with numerical arrays.
|
|
*
|
|
* However this was incorrect, this function would only return an array of arrays with
|
|
* numeric basic indexes, but would process any array whether it was numeric or reference
|
|
* based, using the order in which the array was created as the index value to return.
|
|
*
|
|
* For example:
|
|
*
|
|
* $first_array[] = "First"
|
|
* $first_array[] = "Second"
|
|
* $first_array[] = "Third"
|
|
*
|
|
* $second_array[0] = "Fourth"
|
|
* $second_array[test] = "Fifth"
|
|
* $second_array[1] = "Sixth"
|
|
*
|
|
* $result = gp_array_zip( $first_array, $second_array );
|
|
*
|
|
* Would produce:
|
|
*
|
|
* $result[0][0] = "First"
|
|
* $result[0][1] = "Fourth"
|
|
* $result[1][0] = "Second"
|
|
* $result[1][1] = "Fifth"
|
|
* $result[2][0] = "Third"
|
|
* $result[2][1] = "Sixth"
|
|
*
|
|
* Instead of either failing (which is probably what should have happened) or something like:
|
|
*
|
|
* $result[0][0] = "First"
|
|
* $result[0][1] = "Fourth"
|
|
* $result[1][0] = "Second"
|
|
* $result[1][1] = "Sixth"
|
|
*
|
|
* Or some other random result.
|
|
*
|
|
* @param array ...$args Array arguments.
|
|
* @return array|false Array on success, false on failure.
|
|
*/
|
|
function gp_array_zip( ...$args ) {
|
|
if ( empty( $args ) ) {
|
|
return array();
|
|
}
|
|
|
|
$depth = 0;
|
|
|
|
foreach ( $args as &$array ) {
|
|
if ( ! is_array( $array ) ) {
|
|
return false;
|
|
}
|
|
|
|
$array_size = count( $array );
|
|
reset( $array );
|
|
|
|
if ( 0 === $depth || $depth > $array_size ) {
|
|
$depth = $array_size;
|
|
}
|
|
}
|
|
|
|
$res = array();
|
|
|
|
$array_count = 0;
|
|
|
|
foreach ( $args as &$array ) {
|
|
for ( $i = 0; $i < $depth; $i++ ) {
|
|
$res[ $i ][ $array_count ] = current( $array );
|
|
|
|
next( $array );
|
|
}
|
|
|
|
$array_count++;
|
|
}
|
|
|
|
return $res;
|
|
}
|
|
|
|
function gp_array_any( $callback, $array, $arg = null ) {
|
|
foreach ( $array as $item ) {
|
|
if ( is_array( $callback ) ) {
|
|
if ( $callback[0]->{$callback[1]}( $item, $arg ) ) {
|
|
return true;
|
|
}
|
|
} else {
|
|
if ( $callback( $item, $arg ) ) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
function gp_array_all( $callback, $array ) {
|
|
foreach ( $array as $item ) {
|
|
if ( ! $callback( $item ) ) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
function gp_error_log_dump( $value ) {
|
|
if ( is_array( $value ) || is_object( $value ) ) {
|
|
$value = print_r( $value, true );
|
|
}
|
|
error_log( $value );
|
|
}
|
|
|
|
function gp_object_has_var( $object, $var_name ) {
|
|
return in_array( $var_name, array_keys( get_object_vars( $object ) ), true );
|
|
}
|
|
|
|
/**
|
|
* Has this translation been updated since the passed timestamp?
|
|
*
|
|
* @param GP_Translation_Set $translation_set Translation to check
|
|
* @param int $timestamp Optional; unix timestamp to compare against. Defaults to HTTP_IF_MODIFIED_SINCE if set.
|
|
* @return bool
|
|
*/
|
|
function gp_has_translation_been_updated( $translation_set, $timestamp = 0 ) {
|
|
|
|
// If $timestamp isn't set, try to default to the HTTP_IF_MODIFIED_SINCE header.
|
|
if ( ! $timestamp && isset( $_SERVER['HTTP_IF_MODIFIED_SINCE'] ) ) {
|
|
$timestamp = gp_gmt_strtotime( wp_unslash( $_SERVER['HTTP_IF_MODIFIED_SINCE'] ) );
|
|
}
|
|
|
|
// If nothing to compare against, then always assume there's an update available
|
|
if ( ! $timestamp ) {
|
|
return true;
|
|
}
|
|
|
|
return gp_gmt_strtotime( GP::$translation->last_modified( $translation_set ) ) > $timestamp;
|
|
}
|
|
|
|
|
|
/**
|
|
* Delete translation set counts cache.
|
|
*
|
|
* @global bool $_wp_suspend_cache_invalidation
|
|
*
|
|
* @param int $id Translation set ID.
|
|
*/
|
|
function gp_clean_translation_set_cache( $id ) {
|
|
global $_wp_suspend_cache_invalidation;
|
|
|
|
if ( ! empty( $_wp_suspend_cache_invalidation ) ) {
|
|
return;
|
|
}
|
|
|
|
wp_cache_delete( $id, 'translation_set_status_breakdown' );
|
|
wp_cache_delete( $id, 'translation_set_last_modified' );
|
|
}
|
|
|
|
/**
|
|
* Delete counts cache for all translation sets of a project
|
|
*
|
|
* @param int $project_id project ID
|
|
*/
|
|
function gp_clean_translation_sets_cache( $project_id ) {
|
|
$translation_sets = GP::$translation_set->by_project_id( $project_id );
|
|
|
|
if ( ! $translation_sets ) {
|
|
return;
|
|
}
|
|
|
|
foreach ( $translation_sets as $set ) {
|
|
gp_clean_translation_set_cache( $set->id );
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Checks if the passed value is empty.
|
|
*
|
|
* @param string $value The value you want to check.
|
|
* @return bool
|
|
*/
|
|
function gp_is_empty( $value ) {
|
|
return empty( $value );
|
|
}
|
|
|
|
/**
|
|
* Checks if the passed value is an empty string.
|
|
*
|
|
* @param string $value The value you want to check.
|
|
* @return bool
|
|
*/
|
|
function gp_is_empty_string( $value ) {
|
|
return '' === $value;
|
|
}
|
|
|
|
/**
|
|
* Checks if the passed value isn't an empty string.
|
|
*
|
|
* @param string $value The value you want to check.
|
|
* @return bool
|
|
*/
|
|
function gp_is_not_empty_string( $value ) {
|
|
return '' !== $value;
|
|
}
|
|
|
|
/**
|
|
* Checks if the passed value is a positive integer.
|
|
*
|
|
* @param int $value The value you want to check.
|
|
* @return bool
|
|
*/
|
|
function gp_is_positive_int( $value ) {
|
|
return (int) $value > 0;
|
|
}
|
|
|
|
/**
|
|
* Checks if the passed value is an integer.
|
|
*
|
|
* @param int|string $value The value you want to check.
|
|
* @return bool
|
|
*/
|
|
function gp_is_int( $value ) {
|
|
return (bool) preg_match( '/^-?\d+$/', $value );
|
|
}
|
|
|
|
/**
|
|
* Checks if the passed value is null.
|
|
*
|
|
* @param string $value The value you want to check.
|
|
* @return bool
|
|
*/
|
|
function gp_is_null( $value ) {
|
|
return null === $value;
|
|
}
|
|
|
|
/**
|
|
* Checks if the passed value is not null.
|
|
*
|
|
* @param string $value The value you want to check.
|
|
* @return bool
|
|
*/
|
|
function gp_is_not_null( $value ) {
|
|
return null !== $value;
|
|
}
|
|
|
|
/**
|
|
* Checks if the passed value is between the start and end value or is the same.
|
|
*
|
|
* @param string $value The value you want to check.
|
|
* @param string $value The lower value you want to check against.
|
|
* @param string $value The upper value you want to check against.
|
|
* @return bool
|
|
*/
|
|
function gp_is_between( $value, $start, $end ) {
|
|
return $value >= $start && $value <= $end;
|
|
}
|
|
|
|
/**
|
|
* Checks if the passed value is between the start and end value.
|
|
*
|
|
* @param string $value The value you want to check.
|
|
* @return bool
|
|
*/
|
|
function gp_is_between_exclusive( $value, $start, $end ) {
|
|
return $value > $start && $value < $end;
|
|
}
|
|
|
|
/**
|
|
* Checks if the passed value is one of the values in the list.
|
|
*
|
|
* @since 3.0.0
|
|
*
|
|
* @param string $value The value you want to check.
|
|
* @param array $list The list of values you want to check against.
|
|
* @return bool
|
|
*/
|
|
function gp_is_one_of( $value, $list ) {
|
|
return in_array( $value, $list, true );
|
|
}
|
|
|
|
/**
|
|
* Checks if the passed value has only ASCII characters.
|
|
*
|
|
* @since 3.0.0
|
|
*
|
|
* @param string $value The value you want to check.
|
|
* @return bool
|
|
*/
|
|
function gp_is_ascii_string( $value ) {
|
|
return preg_replace( "/[^\x20-\x7E\p{L}]/", '', $value ) === $value;
|
|
}
|
|
|
|
/**
|
|
* Checks if the passed value starts and ends with a word character.
|
|
*
|
|
* @since 3.0.0
|
|
*
|
|
* @param string $value The value you want to check.
|
|
* @return bool
|
|
*/
|
|
function gp_is_starting_and_ending_with_a_word_character( $value ) {
|
|
return (bool) preg_match( '/\b' . preg_quote( $value, '/' ) . '\b/i', $value );
|
|
}
|
|
|
|
/**
|
|
* Acts the same as core PHP setcookie() but its arguments are run through the gp_set_cookie filter.
|
|
*
|
|
* If the filter returns false, setcookie() isn't called.
|
|
*
|
|
* @param string $name The name of the cookie.
|
|
* @param mixed ...$args Additional arguments to be passed to setcookie().
|
|
*/
|
|
function gp_set_cookie( $name, ...$args ) {
|
|
array_unshift( $args, $name );
|
|
|
|
/**
|
|
* Filter whether GlotPress should set a cookie.
|
|
*
|
|
* If the filter returns false, a cookie will not be set.
|
|
*
|
|
* @since 1.0.0
|
|
*
|
|
* @param array $args {
|
|
* The cookie that is about to be set.
|
|
*
|
|
* @type string $name The name of the cookie.
|
|
* @type string $value The value of the cookie.
|
|
* @type int $expires The time the cookie expires.
|
|
* @type string $path The path on the server in which the cookie will be available on.
|
|
* }
|
|
*/
|
|
$args = apply_filters( 'gp_set_cookie', $args );
|
|
if ( false === $args ) {
|
|
return;
|
|
}
|
|
|
|
setcookie( ...$args );
|
|
}
|
|
|
|
/**
|
|
* Converts a string represented time/date to a utime int, adding a GMT offset if not found.
|
|
*
|
|
* @since 1.0.0
|
|
*
|
|
* @param string $string The string representation of the time to convert.
|
|
* @return int
|
|
*/
|
|
function gp_gmt_strtotime( $string ) {
|
|
if ( is_numeric( $string ) ) {
|
|
return $string;
|
|
}
|
|
if ( ! is_string( $string ) ) {
|
|
return -1;
|
|
}
|
|
|
|
if ( stristr( $string, 'utc' ) || stristr( $string, 'gmt' ) || stristr( $string, '+0000' ) ) {
|
|
return strtotime( $string );
|
|
}
|
|
|
|
if ( -1 == $time = strtotime( $string . ' +0000' ) ) {
|
|
return strtotime( $string );
|
|
}
|
|
|
|
return $time;
|
|
}
|
|
|
|
/**
|
|
* Determines the format to use based on the selected format type or by auto detection based on the file name.
|
|
*
|
|
* Used during import of translations and originals.
|
|
*
|
|
* @param string $selected_format The format that the user selected on the import page.
|
|
* @param string $filename The filname that was uploaded by the user.
|
|
* @return object|null A GP_Format child object or null if not found.
|
|
*/
|
|
function gp_get_import_file_format( $selected_format, $filename ) {
|
|
$formats = GP::$formats;
|
|
unset( $formats['php'] ); // Remove PHP format from the list of formats until we have an import process.
|
|
|
|
$format = gp_array_get( $formats, $selected_format, null );
|
|
|
|
if ( ! $format ) {
|
|
$matched_ext_len = 0;
|
|
|
|
foreach ( $formats as $format_entry ) {
|
|
$format_extensions = $format_entry->get_file_extensions();
|
|
|
|
foreach ( $format_extensions as $extension ) {
|
|
$current_ext_len = strlen( $extension );
|
|
|
|
if ( gp_endswith( $filename, $extension ) && $current_ext_len > $matched_ext_len ) {
|
|
$format = $format_entry;
|
|
$matched_ext_len = $current_ext_len;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return $format;
|
|
}
|
|
|
|
/**
|
|
* Gets the list of format extensions prefixed with leading delimiters "." ( eg.: '.po' ).
|
|
*
|
|
* @since 4.0.0
|
|
*
|
|
* @return array Supported format file extensions.
|
|
*/
|
|
function gp_get_format_extensions() {
|
|
|
|
$format_extensions = array();
|
|
|
|
// Get all the supported format extensions.
|
|
foreach ( GP::$formats as $format ) {
|
|
$format_extensions = array_merge( $format_extensions, $format->get_file_extensions() );
|
|
}
|
|
|
|
// Remove any duplicates added by alternate extensions.
|
|
$format_extensions = array_unique( $format_extensions );
|
|
|
|
// Prefix with delimiter ".".
|
|
$format_extensions = preg_replace( '/^/', '.', $format_extensions );
|
|
|
|
return $format_extensions;
|
|
}
|
|
|
|
/**
|
|
* Displays the GlotPress administrator option in the user profile screen for WordPress administrators.
|
|
*
|
|
* @since 2.0.0
|
|
*
|
|
* @param WP_User $user The WP_User object to display the profile for.
|
|
*/
|
|
function gp_wp_profile_options( $user ) {
|
|
if ( ! current_user_can( 'manage_options' ) ) {
|
|
return;
|
|
}
|
|
|
|
?>
|
|
<h2 id="glotpress"><?php _e( 'GlotPress', 'glotpress' ); ?></h2>
|
|
|
|
<table class="form-table">
|
|
<tr id="gp-admin">
|
|
<th scope="row"><?php _e( 'Administrator', 'glotpress' ); ?></th>
|
|
<td>
|
|
<fieldset>
|
|
<legend class="screen-reader-text"><span><?php _e( 'GlotPress Administrator', 'glotpress' ); ?></span></legend>
|
|
<label for="gp_administrator">
|
|
<input name="gp_administrator" type="checkbox" id="gp_administrator" value="1"<?php checked( GP::$permission->user_can( $user, 'admin' ) ); ?> />
|
|
<?php _e( 'Grant this user administrative privileges in GlotPress.', 'glotpress' ); ?>
|
|
</label>
|
|
</fieldset>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
<?php
|
|
}
|
|
|
|
/**
|
|
* Saves the settings for the GlotPress administrator option in the user profile screen for WordPress administrators.
|
|
*
|
|
* @since 2.0.0
|
|
*
|
|
* @param int $user_id The WordPress user id to save the setting for.
|
|
*/
|
|
function gp_wp_profile_options_update( $user_id ) {
|
|
if ( ! current_user_can( 'manage_options' ) ) {
|
|
return;
|
|
}
|
|
|
|
$is_user_gp_admin = GP::$permission->user_can( $user_id, 'admin' );
|
|
|
|
// phpcs:ignore WordPress.Security.NonceVerification.Missing
|
|
if ( array_key_exists( 'gp_administrator', $_POST ) && ! $is_user_gp_admin ) {
|
|
GP::$administrator_permission->create(
|
|
array(
|
|
'user_id' => $user_id,
|
|
'action' => 'admin',
|
|
'object_type' => null,
|
|
)
|
|
);
|
|
}
|
|
|
|
// phpcs:ignore WordPress.Security.NonceVerification.Missing
|
|
if ( ! array_key_exists( 'gp_administrator', $_POST ) && $is_user_gp_admin ) {
|
|
$current_perm = GP::$administrator_permission->find_one(
|
|
array(
|
|
'user_id' => $user_id,
|
|
'action' => 'admin',
|
|
)
|
|
);
|
|
$current_perm->delete();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns a multi-dimensional array with the sort by types, descriptions and SQL query for each.
|
|
*
|
|
* @since 2.1.0
|
|
*
|
|
* @return array An array of sort by field types.
|
|
*/
|
|
function gp_get_sort_by_fields() {
|
|
$sort_fields = array(
|
|
'original_date_added' => array(
|
|
'title' => __( 'Date added (original)', 'glotpress' ),
|
|
'sql_sort_by' => 'o.date_added %s',
|
|
),
|
|
'translation_date_added' => array(
|
|
'title' => __( 'Date added (translation)', 'glotpress' ),
|
|
'sql_sort_by' => 't.date_added %s',
|
|
),
|
|
'translation_date_modified' => array(
|
|
'title' => __( 'Date modified (translation)', 'glotpress' ),
|
|
'sql_sort_by' => 't.date_modified %s',
|
|
),
|
|
'original' => array(
|
|
'title' => __( 'Original string', 'glotpress' ),
|
|
'sql_sort_by' => 'o.singular %s',
|
|
),
|
|
'translation' => array(
|
|
'title' => __( 'Translation', 'glotpress' ),
|
|
'sql_sort_by' => 't.translation_0 %s',
|
|
),
|
|
'priority' => array(
|
|
'title' => __( 'Priority', 'glotpress' ),
|
|
'sql_sort_by' => 'o.priority %s, o.date_added DESC',
|
|
),
|
|
'references' => array(
|
|
'title' => __( 'Filename in source', 'glotpress' ),
|
|
'sql_sort_by' => 'o.references',
|
|
),
|
|
'length' => array(
|
|
'title' => __( 'Original length', 'glotpress' ),
|
|
'sql_sort_by' => 'LENGTH(o.singular) %s',
|
|
),
|
|
'random' => array(
|
|
'title' => __( 'Random', 'glotpress' ),
|
|
'sql_sort_by' => 'o.priority DESC, RAND()',
|
|
),
|
|
);
|
|
|
|
/**
|
|
* Filter the sort by list to allow plugins to add or remove sort by types.
|
|
*
|
|
* Plugins can add, remove or resort the sort by types array which is used to create
|
|
* the sort by drop down in the translations page.
|
|
*
|
|
* @since 2.1.0
|
|
*
|
|
* @param array $sort_fields {
|
|
* A list of sort by types.
|
|
*
|
|
* @type array $sort_type An array with two keys, 'title' is a translated description of the key and 'sql_sort_by' which is a partial SQL SORT BY clause to use.
|
|
* }
|
|
*/
|
|
return apply_filters( 'gp_sort_by_fields', $sort_fields );
|
|
}
|
|
|
|
/**
|
|
* Sets the maximum memory limit available for translations imports.
|
|
*
|
|
* @since 3.0.0
|
|
*
|
|
* @return string The maximum memory limit.
|
|
*/
|
|
function gp_set_translations_import_max_memory_limit() {
|
|
return '256M';
|
|
}
|