| Server IP : 213.186.33.2 / Your IP : 216.73.216.39 Web Server : Apache System : Linux webm005.cluster102.gra.hosting.ovh.net 6.18.42-ovh-vps-grsec-zfs+ #1 SMP PREEMPT_DYNAMIC Wed Aug 5 15:59:48 CEST 2026 x86_64 User : symetry ( 21728) PHP Version : 8.2.31 Disable Function : _dyuweyrj4,_dyuweyrj4r,dl MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : OFF | Pkexec : OFF Directory : /home/s/y/m/symetry/www/wp-content/themes/symetry-theme/ |
Upload File : |
<?php
// Images à la une
add_theme_support( 'post-thumbnails' );
// Enable support for Post Formats
add_theme_support( 'post-formats', array(
'aside', 'image', 'video', 'audio', 'quote', 'link', 'gallery',
) );
// Menus
function register_my_menus() {
register_nav_menus(
array(
'menu-principal' => __( 'Menu Principal' )
)
);
}
// Custom Post Types
add_action('init', 'my_custom_init');
function my_custom_init()
{
register_post_type('projets', array(
'labels' => array(
'name' => __('Projets'),
'singular_name' => __('Projet'),
'add_new' => __('Ajouter un projet'),
'add_new_item' => __('Ajouter un nouveau projet'),
'edit_item' => __('Modifier le projet'),
'new_item' => __('Nouveau projet'),
'view_item' => __('Voir le projet'),
'search_items' => __('Rechercher des projets'),
'not_found' => __('Aucun projet trouvé'),
'not_found_in_trash' => __('Aucun projet dans la corbeille'),
'all_items' => __('Tous les projets'),
'menu_name' => __('Projets')
),
'public' => true,
'show_ui' => true,
'capability_type' => 'post',
'hierarchical' => false,
'supports' => array('title', 'thumbnail'),
'has_archive' => true,
'menu_icon' => 'dashicons-portfolio',
));
register_taxonomy( 'types', 'projets', array(
'hierarchical' => true,
'label' => 'Types de projets',
'query_var' => true,
'rewrite' => true,
));
}
add_action( 'init', 'register_my_menus' );
/**
* Enqueue scripts and styles.
*/
function my_scripts() {
wp_enqueue_style( '_s-style', get_stylesheet_uri() );
wp_register_script('jquery', "http" . ($_SERVER['SERVER_PORT'] == 443 ? "s" : "") . "://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js", false, null);
wp_enqueue_script('jquery');
wp_enqueue_script( 'menu', get_template_directory_uri() . '/js/menu.js', array(), '1', true );
}
add_action( 'wp_enqueue_scripts', 'my_scripts' );
// Remove core HTML width & height
function remove_img_attr ($html) {
return preg_replace('/(width|height)="\d+"\s/', "", $html);
}
add_filter( 'post_thumbnail_html', 'remove_img_attr' );
// Add new image sizes
if ( function_exists( 'add_image_size' ) ) {
add_image_size( 'grande-image', 850, 550, true );
add_image_size( 'image-carree-moyenne', 200, 200, true );
add_image_size( 'image-carree-petite', 100, 100, true );
add_image_size( 'image-rect-portrait-moyenne', 200, 280, true );
add_image_size( 'image-rect-paysage-moyenne', 280, 200, true );
add_image_size( 'image-profil', 380, 650, true ); // on vérifie que la fonction existe, puis on crée la nouvelle taille d'image. Le dernier paramètre à true indique qu'il faut rogner l'image pour qu'elle s'adapte aux dimensions
}
add_filter('image_size_names_choose', 'my_image_sizes'); // le filtre qui permet d'ajouter la nouvelle taille au gestionnaire de médias
function my_image_sizes($sizes) {
$addsizes = array(
"grande-image" => __( "Grande image de projet"),
"image-carree-moyenne" => __( "Image carrée moyenne"),
"image-carree-petite" => __( "Image carrée petite"),
"image-rect-portrait-moyenne" => __( "Image portrait moyenne"),
"image-rect-paysage-moyenne" => __( "Image paysage moyenne") // on indique ici le nom de la nouvelle image (défini dans add_image_size), et le texte qui doit apparaître pour la sélection
);
$newsizes = array_merge($sizes, $addsizes);
return $newsizes;
}
/* Ajout de la boite pour crédits dans la page Personnaliser */
function symetry_customize($wp_customize) {
$wp_customize->add_section( 'symetry_settings', array(
'title' => 'Crédits photos',
'priority' => 35,
) );
$wp_customize->add_setting( 'credits_footer', array(
'default' => 'Entrez ici les noms des photographes séparés par des virgules',
'capability' => 'edit_theme_options',
'type' => 'option',
'transport' => 'postMessage'
) );
$wp_customize->add_control( 'credits_footer_control', array(
'label' => 'Crédits photos pied de page',
'section' => 'symetry_settings',
'settings' => 'credits_footer',
) );
}
add_action( 'customize_register', 'symetry_customize' );
/* live preview de la page Personnaliser */
function symetry_customize_preview_js() {
wp_enqueue_script( 'symetry-customize', get_template_directory_uri() . '/js/theme-customizer.js', array( 'jquery', 'customize-preview' ), '20130301', true );
}
add_action( 'customize_preview_init', 'symetry_customize_preview_js' );
function my_acf_init() {
acf_update_setting('google_api_key', 'AIzaSyDI5DBy0FzJ5dQQLc0UFQyG8dsyfZ6QBxY');
}
add_action('acf/init', 'my_acf_init');
// ============================================
// SYMETRY THEME OPTIONS - Remplacement plugins
// ============================================
/**
* Force SSL/HTTPS Redirect
* Remplace: jsm-force-ssl
*/
function symetry_force_ssl() {
if (!is_ssl() && !is_admin()) {
wp_redirect('https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'], 301);
exit();
}
}
add_action('template_redirect', 'symetry_force_ssl');
/**
* Gestion des liens externes
* Remplace: wp-external-links
*/
function symetry_external_links($content) {
if (get_option('symetry_external_links_enabled', true)) {
$target = get_option('symetry_external_links_target', '_blank');
$nofollow = get_option('symetry_external_links_nofollow', false);
$noopener = get_option('symetry_external_links_noopener', true);
$rel_parts = array();
if ($nofollow) $rel_parts[] = 'nofollow';
if ($noopener) $rel_parts[] = 'noopener noreferrer';
$rel = !empty($rel_parts) ? ' rel="' . implode(' ', $rel_parts) . '"' : '';
$pattern = '/<a(.*?)href=["\']https?:\/\/(?!' . preg_quote($_SERVER['HTTP_HOST'], '/') . ')(.*?)["\'](.*?)>/i';
$replacement = '<a$1href="http$2"' . ($target ? ' target="' . $target . '"' : '') . $rel . '$3>';
$content = preg_replace($pattern, $replacement, $content);
}
return $content;
}
add_filter('the_content', 'symetry_external_links');
/**
* Ordre personnalisé des posts avec Drag & Drop
* Remplace: post-types-order / simple-custom-post-order
*/
function symetry_custom_post_order_init() {
$post_types = get_option('symetry_sortable_post_types', array('post', 'page', 'projets'));
foreach ($post_types as $post_type) {
add_post_type_support($post_type, 'page-attributes');
}
}
add_action('init', 'symetry_custom_post_order_init');
function symetry_custom_post_order_query($query) {
if (is_admin()) {
return $query;
}
$post_types = get_option('symetry_sortable_post_types', array('post', 'page', 'projets'));
if (in_array($query->get('post_type'), $post_types) || (is_home() && $query->is_main_query())) {
$query->set('orderby', 'menu_order');
$query->set('order', 'ASC');
}
return $query;
}
add_filter('pre_get_posts', 'symetry_custom_post_order_query');
/**
* Ajouter les sous-menus Drag & Drop pour chaque post type
*/
function symetry_post_order_menu() {
$post_types = get_option('symetry_sortable_post_types', array('post', 'page', 'projets'));
foreach ($post_types as $post_type) {
$post_type_obj = get_post_type_object($post_type);
if ($post_type_obj) {
add_submenu_page(
'edit.php' . ($post_type !== 'post' ? '?post_type=' . $post_type : ''),
'Réorganiser l\'ordre',
'Réorganiser',
'edit_posts',
'symetry-order-' . $post_type,
'symetry_post_order_page'
);
}
}
}
add_action('admin_menu', 'symetry_post_order_menu');
/**
* Page d'administration Drag & Drop
*/
function symetry_post_order_page() {
$post_type = isset($_GET['post_type']) ? sanitize_text_field($_GET['post_type']) : 'post';
if (strpos($_GET['page'], 'symetry-order-') === 0) {
$post_type = str_replace('symetry-order-', '', $_GET['page']);
}
$post_type_obj = get_post_type_object($post_type);
$args = array(
'post_type' => $post_type,
'posts_per_page' => -1,
'orderby' => 'menu_order',
'order' => 'ASC',
'post_status' => 'publish,draft,pending,future,private'
);
$posts = get_posts($args);
?>
<div class="wrap symetry-order-wrap">
<div class="symetry-order-header">
<h1>🔀 Réorganiser : <?php echo esc_html($post_type_obj->labels->name); ?></h1>
<div class="symetry-header-actions">
<?php if (!empty($posts)) : ?>
<span class="symetry-count"><?php echo count($posts); ?> élément<?php echo count($posts) > 1 ? 's' : ''; ?></span>
<?php endif; ?>
<button type="button" id="symetry-undo-btn" class="button" disabled title="Annuler (Cmd+Z)">
<span class="dashicons dashicons-undo"></span> Annuler
</button>
</div>
</div>
<div id="symetry-order-message" style="display:none;" class="notice notice-success is-dismissible">
<p><span class="dashicons dashicons-yes-alt"></span> Ordre enregistré !</p>
</div>
<ul id="symetry-sortable-list" class="symetry-sortable-list">
<?php foreach ($posts as $post) :
$status_class = 'status-' . $post->post_status;
$status_label = $post->post_status === 'publish' ? 'Publié' : ucfirst($post->post_status);
?>
<li data-id="<?php echo esc_attr($post->ID); ?>" class="symetry-sortable-item <?php echo esc_attr($status_class); ?>">
<span class="drag-handle">
<span class="dashicons dashicons-menu"></span>
</span>
<span class="item-title"><?php echo esc_html($post->post_title ?: '(Sans titre)'); ?></span>
<span class="item-status"><?php echo esc_html($status_label); ?></span>
<span class="item-order"><?php echo esc_html($post->menu_order); ?></span>
<span class="item-arrows">
<button type="button" class="arrow-up" title="Monter">
<span class="dashicons dashicons-arrow-up-alt2"></span>
</button>
<button type="button" class="arrow-down" title="Descendre">
<span class="dashicons dashicons-arrow-down-alt2"></span>
</button>
</span>
</li>
<?php endforeach; ?>
</ul>
<?php if (empty($posts)) : ?>
<div class="notice notice-info">
<p>Aucun élément à réorganiser pour le moment.</p>
</div>
<?php endif; ?>
</div>
<style>
.symetry-order-wrap {
max-width: 1000px;
}
.symetry-order-header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 12px;
padding-bottom: 8px;
border-bottom: 1px solid #dcdcde;
}
.symetry-order-header h1 {
margin: 0;
font-size: 20px;
line-height: 1.2;
}
.symetry-header-actions {
display: flex;
align-items: center;
gap: 12px;
}
.symetry-count {
background: #f0f6fc;
color: #0c5d9d;
padding: 4px 12px;
border-radius: 12px;
font-size: 13px;
font-weight: 600;
}
#symetry-undo-btn {
display: inline-flex;
align-items: center;
gap: 6px;
padding: 6px 12px;
font-size: 13px;
height: auto;
line-height: 1;
border-radius: 4px;
transition: all 0.2s ease;
}
#symetry-undo-btn .dashicons {
font-size: 16px;
width: 16px;
height: 16px;
}
#symetry-undo-btn:not(:disabled) {
background: linear-gradient(135deg, #0366d6 0%, #0969da 100%);
border-color: #0366d6;
color: #ffffff;
box-shadow: 0 1px 3px rgba(3, 102, 214, 0.3);
}
#symetry-undo-btn:not(:disabled):hover {
background: linear-gradient(135deg, #0550ae 0%, #0860ca 100%);
transform: translateY(-1px);
box-shadow: 0 2px 6px rgba(3, 102, 214, 0.4);
}
#symetry-undo-btn:not(:disabled):active {
transform: translateY(0);
}
#symetry-undo-btn:disabled {
opacity: 0.5;
cursor: not-allowed;
}
#symetry-order-message {
border-left-width: 4px;
position: fixed;
top: 32px;
right: 20px;
margin: 0 !important;
z-index: 100000;
min-width: 250px;
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
}
#symetry-order-message p {
display: flex;
align-items: center;
gap: 6px;
margin: 0.5em 0;
font-size: 13px;
}
.symetry-sortable-list {
list-style: none;
padding: 0;
margin: 10px 0;
}
.symetry-sortable-item {
background: linear-gradient(to right, #ffffff 0%, #fafbfc 100%);
border: 1px solid #e1e4e8;
border-radius: 4px;
padding: 0;
margin-bottom: 4px;
display: flex;
align-items: center;
transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
overflow: hidden;
min-height: 36px;
position: relative;
}
.symetry-sortable-item::before {
content: '';
position: absolute;
left: 0;
top: 0;
bottom: 0;
width: 3px;
background: transparent;
transition: background 0.2s ease;
}
.symetry-sortable-item:hover {
border-color: #0366d6;
box-shadow: 0 2px 8px rgba(3, 102, 214, 0.15);
transform: translateX(2px);
}
.symetry-sortable-item:hover::before {
background: linear-gradient(to bottom, #0366d6, #0969da);
}
.symetry-sortable-item.ui-sortable-helper {
box-shadow: 0 8px 24px rgba(0,0,0,0.15);
transform: scale(1.02) rotate(0.5deg);
border-color: #0366d6;
background: #ffffff;
}
.symetry-sortable-item .drag-handle {
background: linear-gradient(135deg, #f6f8fa 0%, #eef1f4 100%);
border-right: 1px solid #e1e4e8;
padding: 8px 7px;
cursor: grab;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.2s ease;
}
.symetry-sortable-item .drag-handle:active {
cursor: grabbing;
}
.symetry-sortable-item:hover .drag-handle {
background: linear-gradient(135deg, #e1e8f0 0%, #d0dae6 100%);
}
.symetry-sortable-item .drag-handle .dashicons {
color: #6a737d;
font-size: 16px;
transition: color 0.2s ease;
}
.symetry-sortable-item:hover .drag-handle .dashicons {
color: #0366d6;
}
.symetry-sortable-item .item-title {
flex: 1;
padding: 8px 10px;
font-weight: 500;
font-size: 13px;
color: #1d2327;
line-height: 1.2;
}
.symetry-sortable-item .item-status {
padding: 4px 10px;
font-size: 10px;
font-weight: 600;
color: #646970;
background: linear-gradient(135deg, #f6f8fa 0%, #eef1f4 100%);
border-radius: 12px;
margin-right: 8px;
white-space: nowrap;
border: 1px solid #e1e4e8;
transition: all 0.2s ease;
}
.symetry-sortable-item.status-publish .item-status {
background: linear-gradient(135deg, #dcfce7 0%, #bbf7d0 100%);
color: #166534;
border-color: #86efac;
}
.symetry-sortable-item.status-draft .item-status {
background: linear-gradient(135deg, #fef3c7 0%, #fde68a 100%);
color: #92400e;
border-color: #fcd34d;
}
.symetry-sortable-item .item-order {
padding: 8px 12px;
font-size: 12px;
color: #0366d6;
font-weight: 700;
min-width: 40px;
text-align: center;
background: linear-gradient(135deg, #e6f2ff 0%, #d0e7ff 100%);
border-left: 1px solid #e1e4e8;
transition: all 0.2s ease;
}
.symetry-sortable-item:hover .item-order {
background: linear-gradient(135deg, #cfe5ff 0%, #b8daff 100%);
color: #0550ae;
}
.symetry-sortable-item .item-arrows {
display: flex;
gap: 3px;
padding: 0 8px;
background: linear-gradient(135deg, #f6f8fa 0%, #eef1f4 100%);
border-left: 1px solid #e1e4e8;
}
.symetry-sortable-item .item-arrows button {
background: #ffffff;
border: 1px solid #d0d7de;
padding: 5px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
border-radius: 4px;
transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
box-shadow: 0 1px 2px rgba(0,0,0,0.05);
}
.symetry-sortable-item .item-arrows button:hover:not(:disabled) {
background: linear-gradient(135deg, #0366d6 0%, #0969da 100%);
border-color: #0366d6;
transform: translateY(-1px);
box-shadow: 0 2px 4px rgba(3, 102, 214, 0.3);
}
.symetry-sortable-item .item-arrows button:active:not(:disabled) {
transform: translateY(0);
box-shadow: 0 1px 2px rgba(3, 102, 214, 0.2);
}
.symetry-sortable-item .item-arrows button .dashicons {
font-size: 16px;
width: 16px;
height: 16px;
color: #6a737d;
transition: color 0.2s ease;
}
.symetry-sortable-item .item-arrows button:hover:not(:disabled) .dashicons {
color: #ffffff;
}
.symetry-sortable-item:first-child .arrow-up {
opacity: 0.4;
cursor: not-allowed;
pointer-events: none;
}
.symetry-sortable-item:last-child .arrow-down {
opacity: 0.4;
cursor: not-allowed;
pointer-events: none;
}
.ui-sortable-placeholder {
background: linear-gradient(135deg, #e6f2ff 0%, #d0e7ff 100%);
border: 2px dashed #0366d6;
border-radius: 4px;
visibility: visible !important;
height: 36px;
margin-bottom: 4px;
animation: pulse 1.5s ease-in-out infinite;
}
@keyframes pulse {
0%, 100% { opacity: 0.6; }
50% { opacity: 1; }
}
@media screen and (max-width: 782px) {
.symetry-sortable-item .item-title {
font-size: 12px;
}
.symetry-sortable-item .item-status {
font-size: 10px;
padding: 3px 6px;
}
}
</style>
<script>
jQuery(document).ready(function($) {
// Historique pour annuler
var undoStack = [];
var maxUndoSteps = 20;
// Fonction pour mettre à jour les numéros d'ordre
function updateOrderNumbers() {
$('#symetry-sortable-list li').each(function(index) {
$(this).find('.item-order').text(index);
});
}
// Fonction pour obtenir l'ordre actuel
function getCurrentOrder() {
var order = [];
$('#symetry-sortable-list li').each(function() {
order.push($(this).data('id'));
});
return order;
}
// Fonction pour sauvegarder dans l'historique
function saveToHistory() {
var currentOrder = getCurrentOrder();
undoStack.push(currentOrder);
if (undoStack.length > maxUndoSteps) {
undoStack.shift();
}
updateUndoButton();
}
// Fonction pour mettre à jour le bouton annuler
function updateUndoButton() {
if (undoStack.length > 0) {
$('#symetry-undo-btn').prop('disabled', false);
} else {
$('#symetry-undo-btn').prop('disabled', true);
}
}
// Fonction pour annuler
function undo() {
if (undoStack.length === 0) return;
var previousOrder = undoStack.pop();
var $list = $('#symetry-sortable-list');
// Réorganiser les éléments selon l'ordre précédent
previousOrder.forEach(function(id) {
var $item = $list.find('li[data-id="' + id + '"]');
$list.append($item);
});
updateOrderNumbers();
updateUndoButton();
// Sauvegarder en base de données sans ajouter à l'historique
saveOrderToServer(false);
}
// Fonction pour sauvegarder l'ordre
function saveOrder() {
saveOrderToServer(true);
}
// Fonction pour sauvegarder sur le serveur
function saveOrderToServer(showMessage) {
var order = [];
$('#symetry-sortable-list li').each(function(index) {
order.push({
id: $(this).data('id'),
position: index
});
});
updateOrderNumbers();
$.ajax({
url: ajaxurl,
type: 'POST',
data: {
action: 'symetry_update_post_order',
order: order,
nonce: '<?php echo wp_create_nonce('symetry_post_order_nonce'); ?>'
},
success: function(response) {
if (showMessage) {
$('#symetry-order-message').fadeIn().delay(2000).fadeOut();
}
}
});
}
// Initialiser les numéros
updateOrderNumbers();
// Drag & Drop
$('#symetry-sortable-list').sortable({
placeholder: 'ui-sortable-placeholder',
cursor: 'move',
opacity: 0.8,
handle: '.drag-handle',
tolerance: 'pointer',
start: function(event, ui) {
// Sauvegarder l'état AVANT le drag
saveToHistory();
},
update: function(event, ui) {
saveOrder();
}
});
// Boutons flèches
$(document).on('click', '.arrow-up', function(e) {
e.preventDefault();
var $item = $(this).closest('li');
var $prev = $item.prev();
if ($prev.length) {
// Sauvegarder l'état AVANT le déplacement
saveToHistory();
$item.insertBefore($prev);
saveOrder();
}
});
$(document).on('click', '.arrow-down', function(e) {
e.preventDefault();
var $item = $(this).closest('li');
var $next = $item.next();
if ($next.length) {
// Sauvegarder l'état AVANT le déplacement
saveToHistory();
$item.insertAfter($next);
saveOrder();
}
});
// Bouton Annuler
$('#symetry-undo-btn').on('click', function(e) {
e.preventDefault();
undo();
});
// Support Cmd+Z / Ctrl+Z
$(document).on('keydown', function(e) {
if ((e.metaKey || e.ctrlKey) && e.key === 'z') {
e.preventDefault();
undo();
}
});
});
</script>
<?php
}
/**
* AJAX handler pour mettre à jour l'ordre
*/
function symetry_update_post_order_ajax() {
check_ajax_referer('symetry_post_order_nonce', 'nonce');
if (!current_user_can('edit_posts')) {
wp_die('Unauthorized');
}
$order = isset($_POST['order']) ? $_POST['order'] : array();
foreach ($order as $item) {
wp_update_post(array(
'ID' => intval($item['id']),
'menu_order' => intval($item['position'])
));
}
wp_send_json_success();
}
add_action('wp_ajax_symetry_update_post_order', 'symetry_update_post_order_ajax');
/**
* Charger jQuery UI Sortable dans l'admin
*/
function symetry_enqueue_sortable_scripts($hook) {
if (strpos($hook, 'symetry-order-') !== false) {
wp_enqueue_script('jquery-ui-sortable');
}
}
add_action('admin_enqueue_scripts', 'symetry_enqueue_sortable_scripts');
/**
* Masquer les articles/blog dans l'admin
* Remplace: adminimize (pour cette fonctionnalité spécifique)
*/
function symetry_hide_blog_menu() {
if (get_option('symetry_hide_blog', false)) {
remove_menu_page('edit.php');
remove_menu_page('edit-comments.php');
}
}
add_action('admin_menu', 'symetry_hide_blog_menu', 999);
function symetry_hide_blog_admin_bar($wp_admin_bar) {
if (get_option('symetry_hide_blog', false)) {
$wp_admin_bar->remove_node('new-post');
$wp_admin_bar->remove_node('comments');
}
}
add_action('admin_bar_menu', 'symetry_hide_blog_admin_bar', 999);
/**
* Désactiver complètement les commentaires WordPress
*/
function symetry_disable_comments() {
if (get_option('symetry_hide_blog', false)) {
// Fermer les commentaires sur tous les posts
add_filter('comments_open', '__return_false', 20, 2);
add_filter('pings_open', '__return_false', 20, 2);
// Masquer les commentaires existants
add_filter('comments_array', '__return_empty_array', 10, 2);
// Désactiver le support des commentaires pour tous les post types
add_action('init', function() {
$post_types = get_post_types();
foreach ($post_types as $post_type) {
if (post_type_supports($post_type, 'comments')) {
remove_post_type_support($post_type, 'comments');
remove_post_type_support($post_type, 'trackbacks');
}
}
});
// Désactiver les widgets de commentaires
add_filter('widget_types_to_hide_from_legacy_widget_block', function($widget_types) {
$widget_types[] = 'recent-comments';
return $widget_types;
});
}
}
add_action('plugins_loaded', 'symetry_disable_comments');
/**
* Rediriger du tableau de bord vers les projets
*/
function symetry_redirect_dashboard() {
if (get_option('symetry_redirect_dashboard', false)) {
global $pagenow;
if ($pagenow === 'index.php') {
wp_redirect(admin_url('edit.php?post_type=projets'));
exit;
}
}
}
add_action('admin_init', 'symetry_redirect_dashboard');
/**
* Masquer le menu Tableau de bord quand la redirection est activée
*/
function symetry_hide_dashboard_menu() {
if (get_option('symetry_redirect_dashboard', false)) {
remove_menu_page('index.php');
}
}
add_action('admin_menu', 'symetry_hide_dashboard_menu', 999);
/**
* Réorganiser l'ordre des menus dans l'admin
*/
function symetry_reorder_admin_menu() {
global $menu;
// Créer un tableau pour stocker les positions
$new_order = array();
$position = 5;
// Ordre souhaité : Projets, Pages, Médias
$priority_items = array(
'edit.php?post_type=projets' => 'Projets',
'edit.php?post_type=page' => 'Pages',
'upload.php' => 'Médias'
);
// Ajouter d'abord les éléments prioritaires
foreach ($priority_items as $slug => $name) {
foreach ($menu as $key => $item) {
if (isset($item[2]) && $item[2] === $slug) {
$new_order[$position] = $item;
unset($menu[$key]);
$position += 5;
break;
}
}
}
// Ajouter un séparateur
$new_order[$position] = array(
'',
'read',
'separator-symetry',
'',
'wp-menu-separator'
);
$position += 5;
// Ajouter le reste des menus
foreach ($menu as $key => $item) {
if (!empty($item[2])) {
$new_order[$position] = $item;
$position += 5;
}
}
// Remplacer le menu global
$menu = $new_order;
}
add_action('admin_menu', 'symetry_reorder_admin_menu', 9999);
/**
* Ajouter du CSS pour améliorer le séparateur et masquer "voir les articles"
*/
function symetry_admin_custom_css() {
echo '<style>
/* Séparateur plus marqué avec plus d\'espace */
#adminmenu li.wp-menu-separator.separator-symetry {
height: 20px !important;
margin: 10px 0 !important;
background: linear-gradient(to right, transparent, #dcdcde 20%, #dcdcde 80%, transparent) !important;
}
/* Masquer le bouton "voir les articles" dans les projets */
.post-type-projets a.page-title-action[href*="edit.php"] {
display: none !important;
}
/* Masquer le bouton "Voir les articles" dans la barre d\'admin en haut */
body.post-type-projets #wp-admin-bar-archive a[href*="post_type=projets"] {
display: none !important;
}
body.post-type-projets #wp-admin-bar-archive {
display: none !important;
}
</style>';
}
add_action('admin_head', 'symetry_admin_custom_css');
/**
* Page d'options du thème Symetry
*/
function symetry_options_page() {
add_theme_page(
'Options Symetry',
'Options Symetry',
'manage_options',
'symetry-options',
'symetry_options_page_html'
);
}
add_action('admin_menu', 'symetry_options_page');
function symetry_options_page_html() {
if (!current_user_can('manage_options')) {
return;
}
if (isset($_POST['symetry_options_submit'])) {
check_admin_referer('symetry_options_save');
update_option('symetry_external_links_enabled', isset($_POST['external_links_enabled']));
update_option('symetry_external_links_target', sanitize_text_field($_POST['external_links_target']));
update_option('symetry_external_links_nofollow', isset($_POST['external_links_nofollow']));
update_option('symetry_external_links_noopener', isset($_POST['external_links_noopener']));
$sortable_types = isset($_POST['sortable_post_types']) ? array_map('sanitize_text_field', $_POST['sortable_post_types']) : array();
update_option('symetry_sortable_post_types', $sortable_types);
update_option('symetry_hide_blog', isset($_POST['hide_blog']));
$projects_per_page = isset($_POST['projects_per_page']) ? intval($_POST['projects_per_page']) : 12;
update_option('symetry_projects_per_page', $projects_per_page);
update_option('symetry_redirect_dashboard', isset($_POST['redirect_dashboard']));
echo '<div class="notice notice-success"><p>Options enregistrées avec succès.</p></div>';
}
$external_enabled = get_option('symetry_external_links_enabled', true);
$external_target = get_option('symetry_external_links_target', '_blank');
$external_nofollow = get_option('symetry_external_links_nofollow', false);
$external_noopener = get_option('symetry_external_links_noopener', true);
$sortable_types = get_option('symetry_sortable_post_types', array('post', 'page', 'projets'));
$hide_blog = get_option('symetry_hide_blog', false);
$projects_per_page = get_option('symetry_projects_per_page', 12);
$redirect_dashboard = get_option('symetry_redirect_dashboard', false);
?>
<div class="wrap">
<h1><?php echo esc_html(get_admin_page_title()); ?></h1>
<form method="post" action="">
<?php wp_nonce_field('symetry_options_save'); ?>
<h2>🔒 Force SSL/HTTPS</h2>
<p>La redirection HTTPS est activée automatiquement. Aucune configuration nécessaire.</p>
<hr>
<h2>🎨 Interface d'administration</h2>
<table class="form-table">
<tr>
<th scope="row">Masquer le blog</th>
<td>
<label>
<input type="checkbox" name="hide_blog" value="1" <?php checked($hide_blog); ?>>
Masquer les Articles et Commentaires dans l'admin
</label>
<p class="description">Utile pour un site vitrine sans blog. Cache les menus "Articles" et "Commentaires".</p>
</td>
</tr>
<tr>
<th scope="row">Redirection automatique</th>
<td>
<label>
<input type="checkbox" name="redirect_dashboard" value="1" <?php checked($redirect_dashboard); ?>>
Rediriger du tableau de bord vers les Projets
</label>
<p class="description">Redirige automatiquement vers la page des Projets au lieu d'afficher le tableau de bord.</p>
</td>
</tr>
</table>
<hr>
<h2>🔗 Liens externes</h2>
<table class="form-table">
<tr>
<th scope="row">Activer la gestion des liens externes</th>
<td>
<label>
<input type="checkbox" name="external_links_enabled" value="1" <?php checked($external_enabled); ?>>
Modifier automatiquement les liens externes
</label>
</td>
</tr>
<tr>
<th scope="row">Ouvrir dans</th>
<td>
<select name="external_links_target">
<option value="_blank" <?php selected($external_target, '_blank'); ?>>Nouvel onglet (_blank)</option>
<option value="_self" <?php selected($external_target, '_self'); ?>>Même fenêtre (_self)</option>
<option value="" <?php selected($external_target, ''); ?>>Par défaut</option>
</select>
</td>
</tr>
<tr>
<th scope="row">Attributs SEO</th>
<td>
<label>
<input type="checkbox" name="external_links_nofollow" value="1" <?php checked($external_nofollow); ?>>
Ajouter rel="nofollow"
</label><br>
<label>
<input type="checkbox" name="external_links_noopener" value="1" <?php checked($external_noopener); ?>>
Ajouter rel="noopener noreferrer" (recommandé pour la sécurité)
</label>
</td>
</tr>
</table>
<hr>
<h2>🔀 Ordre personnalisé des posts</h2>
<table class="form-table">
<tr>
<th scope="row">Types de contenu triables</th>
<td>
<label>
<input type="checkbox" name="sortable_post_types[]" value="post" <?php checked(in_array('post', $sortable_types)); ?>>
Articles
</label><br>
<label>
<input type="checkbox" name="sortable_post_types[]" value="page" <?php checked(in_array('page', $sortable_types)); ?>>
Pages
</label><br>
<label>
<input type="checkbox" name="sortable_post_types[]" value="projets" <?php checked(in_array('projets', $sortable_types)); ?>>
Projets
</label>
<p class="description">Vous pourrez modifier l'ordre dans l'éditeur via le champ "Ordre"</p>
</td>
</tr>
</table>
<hr>
<h2>🎨 Affichage des projets</h2>
<table class="form-table">
<tr>
<th scope="row">Nombre de projets sur la page d'accueil</th>
<td>
<select name="projects_per_page">
<option value="12" <?php selected($projects_per_page, 12); ?>>12 projets</option>
<option value="24" <?php selected($projects_per_page, 24); ?>>24 projets</option>
<option value="36" <?php selected($projects_per_page, 36); ?>>36 projets</option>
<option value="48" <?php selected($projects_per_page, 48); ?>>48 projets</option>
<option value="60" <?php selected($projects_per_page, 60); ?>>60 projets</option>
</select>
<p class="description">Valeurs compatibles avec un affichage responsive (4, 3, 2 ou 1 colonne)</p>
</td>
</tr>
</table>
<?php submit_button('Enregistrer les options', 'primary', 'symetry_options_submit'); ?>
</form>
</div>
<?php
}
?>