function sfput_extra_permastructs($rules)
{
    global $wp_rewrite, $polylang;
    if (empty($rules)) {
        // Uh? oO
        return $rules;
    }
    $languages = $polylang->model->get_languages_list(array('fields' => 'slug'));
    // If Polylang doesn't add the /{default_lang}/ in the URL, no need to modify the rules for this lang, sfput_registered_post_type() took care of it earlier.
    if ($polylang->options['hide_default']) {
        $languages = array_diff($languages, array($polylang->options['default_lang']));
    }
    if (empty($languages)) {
        return $rules;
    }
    // The way Polylang built its regex.
    $imploded_langs = '(' . implode('|', $languages) . ')/';
    $poly_slug = $wp_rewrite->root . ($polylang->options['rewrite'] ? '' : 'language/') . $imploded_langs;
    // So, why are we here?
    $filter = str_replace('_rewrite_rules', '', current_filter());
    $post_types = sfput_get_post_types();
    $taxonomies = sfput_get_taxonomies();
    // Post type, single
    if (!empty($post_types[$filter])) {
        $slugs = sfput_get_option('post_types.single');
        $slug = sfput_get_post_type_singular_slug($filter);
        if (empty($slugs[$filter]) || empty($slug)) {
            // Uh? oO
            return $rules;
        }
    } elseif (!empty($taxonomies[$filter])) {
        $slugs = sfput_get_option('taxonomies');
        $slug = sfput_get_taxonomy_slug($filter);
        if (empty($slugs[$filter]) || empty($slug)) {
            // Uh? oO
            return $rules;
        }
    } else {
        // Uh? oO
        return $rules;
    }
    // Replacements
    $new_rules = array();
    $slugs = $slugs[$filter];
    foreach ($rules as $regex => $rule) {
        if (strpos($regex, $poly_slug) !== 0) {
            $new_rules[$regex] = $rule;
            continue;
        }
        foreach ($languages as $language) {
            $new_regex = str_replace_once($imploded_langs, '(' . $language . ')/', $regex);
            $new_regex = str_replace_once('/' . $slug . '/', '/' . $slugs[$language] . '/', '/' . $new_regex);
            $new_regex = ltrim($new_regex, '/');
            $new_rules[$new_regex] = $rule;
        }
    }
    return $new_rules;
}
function sfput_registered_post_type($post_type, $args)
{
    global $wp_post_types, $wp_rewrite, $polylang;
    add_filter('sfput_options_clear_post_types_cache', '__return_true');
    $post_types = sfput_get_post_types();
    if (empty($post_types[$post_type])) {
        return;
    }
    $mode = sfput_get_polylang_mode();
    // Language
    if ($mode === 1) {
        $lang = $polylang->options['default_lang'];
    } else {
        $lang = pll_current_language();
    }
    // Save the original slugs somewhere safe, it could be usefull later (like in the settings page).
    $original_slugs = array('singular' => sfput_get_post_type_singular_slug($post_type), 'archive' => sfput_get_post_type_archive_slug($post_type));
    if (!sf_cache_data('sfput_original_slugs-pt-' . $post_type)) {
        sf_cache_data('sfput_original_slugs-pt-' . $post_type, $original_slugs);
    }
    // Settings
    $single_slugs = sfput_get_option('post_types.single');
    $archive_slugs = sfput_get_option('post_types.archive');
    $single_slug = !empty($single_slugs[$post_type][$lang]) ? $single_slugs[$post_type][$lang] : $original_slugs['singular'];
    $archive_slug = !empty($archive_slugs[$post_type][$lang]) ? $archive_slugs[$post_type][$lang] : $original_slugs['archive'];
    if (!$single_slug && !$archive_slug) {
        return;
    }
    // Change the singular slug.
    if ($single_slug && $original_slugs['singular'] && $original_slugs['singular'] !== $single_slug) {
        if (!empty($wp_rewrite->extra_permastructs[$post_type]['struct'])) {
            // This is me being paranoïd: I want to make sure to replace "/my-slug/", and not "FOOmy-slugBAR".
            $has_slash = strpos($wp_rewrite->extra_permastructs[$post_type]['struct'], '/') === 0;
            $wp_rewrite->extra_permastructs[$post_type]['struct'] = str_replace('/' . $original_slugs['singular'] . '/', '/' . $single_slug . '/', '/' . $wp_rewrite->extra_permastructs[$post_type]['struct']);
            $wp_rewrite->extra_permastructs[$post_type]['struct'] = ($has_slash ? '/' : '') . ltrim($wp_rewrite->extra_permastructs[$post_type]['struct'], '/');
        }
        $wp_post_types[$post_type]->rewrite['slug'] = $single_slug;
    }
    // Change the archive slug.
    if ($archive_slug && $original_slugs['archive'] && $original_slugs['archive'] !== $archive_slug) {
        if (!empty($wp_rewrite->extra_rules_top)) {
            $new_rules = array();
            foreach ($wp_rewrite->extra_rules_top as $regex => $rule) {
                if (preg_match('@[?|&]post_type=' . $post_type . '(?:&.*)?$@', $rule)) {
                    // This is me being paranoïd again: I want to make sure to replace "/my-slug/", and not "FOOmy-slugBAR".
                    $has_slash = strpos($regex, '/') === 0;
                    $new_regex = str_replace('/' . $original_slugs['archive'] . '/', '/' . $archive_slug . '/', '/' . $regex);
                    $new_regex = ($has_slash ? '/' : '') . ltrim($new_regex, '/');
                    $new_rules[$new_regex] = $rule;
                } else {
                    $new_rules[$regex] = $rule;
                }
            }
            $wp_rewrite->extra_rules_top = $new_rules;
        }
        $wp_post_types[$post_type]->has_archive = $archive_slug;
    }
    if (is_admin() && !(defined('DOING_AJAX') && DOING_AJAX) && $mode === 1) {
        remove_filter($post_type . '_rewrite_rules', 'sfput_extra_permastructs', 1000);
        add_filter($post_type . '_rewrite_rules', 'sfput_extra_permastructs', 1000);
    }
}