['appels-a-contribution', 8], 'THALIM_NL_CAT_COLLOQUES' => ['colloques-et-journees-detudes', 10], 'THALIM_NL_CAT_SEMINAIRES' => ['seminaires', 11], 'THALIM_NL_CAT_COMMS' => ['communications', 13], 'THALIM_NL_CAT_SOUTENANCES' => ['soutenances', 14], 'THALIM_NL_CAT_OUVRAGES' => ['ouvrages', 15], 'THALIM_NL_CAT_ARTICLES' => ['articles', 16], 'THALIM_NL_CAT_NEWSLETTER' => ['newsletter', 20], ]; $by_slug = get_transient('thalim_nl_cat_ids'); if (!is_array($by_slug)) { global $wpdb; $slugs = array_column($cats, 0); $placeholders = implode(',', array_fill(0, count($slugs), '%s')); $rows = $wpdb->get_results($wpdb->prepare( "SELECT t.slug, t.term_id FROM {$wpdb->terms} t JOIN {$wpdb->term_taxonomy} tt ON tt.term_id = t.term_id WHERE tt.taxonomy = 'category' AND t.slug IN ($placeholders)", $slugs )); $by_slug = []; foreach ((array) $rows as $row) { $by_slug[$row->slug] = (int) $row->term_id; } set_transient('thalim_nl_cat_ids', $by_slug, DAY_IN_SECONDS); } foreach ($cats as $const => [$slug, $fallback]) { define($const, $by_slug[$slug] ?? $fallback); } })(); /** * Main plugin class — singleton */ class Thalim_Newsletter { private static $instance = null; public static function get_instance() { if (self::$instance === null) { self::$instance = new self(); } return self::$instance; } private function __construct() { $this->load_dependencies(); $this->init_hooks(); } private function load_dependencies() { require_once THALIM_NL_PLUGIN_DIR . 'includes/class-post-query.php'; require_once THALIM_NL_PLUGIN_DIR . 'includes/class-html-exporter.php'; require_once THALIM_NL_PLUGIN_DIR . 'includes/class-admin-page.php'; } private function init_hooks() { add_action('admin_menu', [$this, 'add_admin_menu']); add_action('admin_enqueue_scripts', [$this, 'enqueue_assets']); add_action('wp_ajax_thalim_nl_load_month', [new Thalim_NL_Admin_Page(), 'handle_ajax_load_month']); add_action('wp_ajax_thalim_nl_export_html', [new Thalim_NL_Admin_Page(), 'handle_ajax_export_html']); } public function add_admin_menu() { add_management_page( 'Newsletter', 'Newsletter', 'edit_others_posts', 'thalim-newsletter', [$this, 'render_admin_page'] ); } public function enqueue_assets($hook) { if ($hook !== 'tools_page_thalim-newsletter') { return; } wp_enqueue_style( 'thalim-newsletter-admin', THALIM_NL_PLUGIN_URL . 'assets/admin.css', [], THALIM_NL_VERSION ); wp_enqueue_script( 'thalim-newsletter-admin', THALIM_NL_PLUGIN_URL . 'assets/admin.js', ['jquery', 'jquery-ui-sortable'], THALIM_NL_VERSION, true ); wp_localize_script('thalim-newsletter-admin', 'thalimNL', [ 'ajaxUrl' => admin_url('admin-ajax.php'), 'nonce' => wp_create_nonce('thalim_newsletter_ajax'), ]); } public function render_admin_page() { $page = new Thalim_NL_Admin_Page(); $page->render(); } } // Activation hook register_activation_hook(__FILE__, function () { add_option('thalim_nl_version', THALIM_NL_VERSION); }); // Initialize plugin add_action('plugins_loaded', function () { Thalim_Newsletter::get_instance(); });