plugin_dir = plugin_dir_path( __FILE__ ); $this->plugin_url = plugin_dir_url( __FILE__ ); $this->define_constants(); $this->init_hooks(); } /** * Prevent cloning */ private function __clone() {} /** * Prevent unserializing */ public function __wakeup() { throw new Exception( 'Cannot unserialize singleton' ); } /** * Define plugin constants */ private function define_constants() { define( 'MYOP_VERSION', self::VERSION ); define( 'MYOP_PLUGIN_DIR', $this->plugin_dir ); define( 'MYOP_PLUGIN_URL', $this->plugin_url ); define( 'MYOP_PLUGIN_BASENAME', plugin_basename( __FILE__ ) ); } /** * Initialize WordPress hooks */ private function init_hooks() { // Core hooks add_action( 'init', array( $this, 'init' ) ); add_action( 'admin_menu', array( $this, 'add_admin_menu' ) ); add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) ); add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ) ); // AJAX hooks add_action( 'wp_ajax_myop_action', array( $this, 'ajax_handler' ) ); add_action( 'wp_ajax_nopriv_myop_action', array( $this, 'ajax_handler_nopriv' ) ); // REST API hooks add_action( 'rest_api_init', array( $this, 'register_rest_routes' ) ); // Activation/Deactivation register_activation_hook( __FILE__, array( $this, 'activate' ) ); register_deactivation_hook( __FILE__, array( $this, 'deactivate' ) ); } /** * Initialize plugin functionality */ public function init() { // Load text domain load_plugin_textdomain( 'my-oop-plugin', false, dirname( MYOP_PLUGIN_BASENAME ) . '/languages' ); // Register custom post type $this->register_post_types(); // Register taxonomies $this->register_taxonomies(); } /** * Register custom post types */ private function register_post_types() { $labels = array( 'name' => _x( 'Books', 'post type general name', 'my-oop-plugin' ), 'singular_name' => _x( 'Book', 'post type singular name', 'my-oop-plugin' ), 'menu_name' => _x( 'Books', 'admin menu', 'my-oop-plugin' ), 'add_new' => _x( 'Add New', 'book', 'my-oop-plugin' ), 'add_new_item' => __( 'Add New Book', 'my-oop-plugin' ), 'edit_item' => __( 'Edit Book', 'my-oop-plugin' ), 'new_item' => __( 'New Book', 'my-oop-plugin' ), 'view_item' => __( 'View Book', 'my-oop-plugin' ), 'search_items' => __( 'Search Books', 'my-oop-plugin' ), 'not_found' => __( 'No books found', 'my-oop-plugin' ), 'not_found_in_trash' => __( 'No books found in Trash', 'my-oop-plugin' ), ); $args = array( 'labels' => $labels, 'public' => true, 'publicly_queryable' => true, 'show_ui' => true, 'show_in_menu' => true, 'query_var' => true, 'rewrite' => array( 'slug' => 'books' ), 'capability_type' => 'post', 'has_archive' => true, 'hierarchical' => false, 'menu_position' => 5, 'menu_icon' => 'dashicons-book', 'show_in_rest' => true, 'supports' => array( 'title', 'editor', 'thumbnail', 'excerpt' ), ); register_post_type( 'book', $args ); } /** * Register taxonomies */ private function register_taxonomies() { $labels = array( 'name' => _x( 'Genres', 'taxonomy general name', 'my-oop-plugin' ), 'singular_name' => _x( 'Genre', 'taxonomy singular name', 'my-oop-plugin' ), 'search_items' => __( 'Search Genres', 'my-oop-plugin' ), 'all_items' => __( 'All Genres', 'my-oop-plugin' ), 'parent_item' => __( 'Parent Genre', 'my-oop-plugin' ), 'parent_item_colon' => __( 'Parent Genre:', 'my-oop-plugin' ), 'edit_item' => __( 'Edit Genre', 'my-oop-plugin' ), 'update_item' => __( 'Update Genre', 'my-oop-plugin' ), 'add_new_item' => __( 'Add New Genre', 'my-oop-plugin' ), 'new_item_name' => __( 'New Genre Name', 'my-oop-plugin' ), 'menu_name' => __( 'Genres', 'my-oop-plugin' ), ); $args = array( 'hierarchical' => true, 'labels' => $labels, 'show_ui' => true, 'show_admin_column' => true, 'query_var' => true, 'rewrite' => array( 'slug' => 'genre' ), 'show_in_rest' => true, ); register_taxonomy( 'genre', array( 'book' ), $args ); } /** * Add admin menu pages */ public function add_admin_menu() { add_options_page( __( 'My OOP Plugin Settings', 'my-oop-plugin' ), __( 'OOP Plugin', 'my-oop-plugin' ), 'manage_options', 'my-oop-plugin', array( $this, 'render_settings_page' ) ); } /** * Render settings page */ public function render_settings_page() { // Check user capabilities if ( ! current_user_can( 'manage_options' ) ) { return; } // Handle form submission if ( isset( $_POST['myop_settings_submit'] ) ) { $this->save_settings(); } // Get current settings $settings = $this->get_settings(); // Render page include $this->plugin_dir . 'views/admin-settings.php'; } /** * Save plugin settings */ private function save_settings() { // Verify nonce if ( ! isset( $_POST['myop_settings_nonce'] ) || ! wp_verify_nonce( $_POST['myop_settings_nonce'], 'myop_settings_action' ) ) { wp_die( __( 'Security check failed', 'my-oop-plugin' ) ); } // Sanitize and save settings $settings = array( 'option1' => isset( $_POST['myop_option1'] ) ? sanitize_text_field( $_POST['myop_option1'] ) : '', 'option2' => isset( $_POST['myop_option2'] ) ? absint( $_POST['myop_option2'] ) : 0, 'option3' => isset( $_POST['myop_option3'] ) ? (bool) $_POST['myop_option3'] : false, ); update_option( 'myop_settings', $settings ); add_settings_error( 'myop_messages', 'myop_message', __( 'Settings Saved', 'my-oop-plugin' ), 'updated' ); } /** * Get plugin settings * * @return array */ private function get_settings() { $defaults = array( 'option1' => '', 'option2' => 0, 'option3' => false, ); $settings = get_option( 'myop_settings', $defaults ); return wp_parse_args( $settings, $defaults ); } /** * Enqueue admin scripts and styles * * @param string $hook Current admin page hook */ public function admin_enqueue_scripts( $hook ) { // Only load on specific pages if ( 'edit.php' !== $hook && 'post.php' !== $hook && 'post-new.php' !== $hook ) { return; } $screen = get_current_screen(); if ( $screen && 'book' === $screen->post_type ) { wp_enqueue_style( 'myop-admin-style', $this->plugin_url . 'assets/css/admin-style.css', array(), self::VERSION ); wp_enqueue_script( 'myop-admin-script', $this->plugin_url . 'assets/js/admin-script.js', array( 'jquery' ), self::VERSION, true ); wp_localize_script( 'myop-admin-script', 'myopData', array( 'ajax_url' => admin_url( 'admin-ajax.php' ), 'nonce' => wp_create_nonce( 'myop_ajax_nonce' ), ) ); } } /** * Enqueue frontend scripts and styles */ public function enqueue_scripts() { if ( is_singular( 'book' ) ) { wp_enqueue_style( 'myop-style', $this->plugin_url . 'assets/css/style.css', array(), self::VERSION ); wp_enqueue_script( 'myop-script', $this->plugin_url . 'assets/js/script.js', array( 'jquery' ), self::VERSION, true ); } } /** * AJAX handler (for logged-in users) */ public function ajax_handler() { // Verify nonce check_ajax_referer( 'myop_ajax_nonce', 'nonce' ); // Check capability if ( ! current_user_can( 'edit_posts' ) ) { wp_send_json_error( array( 'message' => __( 'Permission denied', 'my-oop-plugin' ) ) ); } // Get and sanitize input $input = isset( $_POST['data'] ) ? sanitize_text_field( $_POST['data'] ) : ''; // Process data $result = $this->process_ajax_data( $input ); // Return response wp_send_json_success( array( 'message' => __( 'Success!', 'my-oop-plugin' ), 'data' => $result, ) ); } /** * AJAX handler (for non-logged-in users) */ public function ajax_handler_nopriv() { // For public AJAX requests wp_send_json_error( array( 'message' => __( 'Login required', 'my-oop-plugin' ) ) ); } /** * Process AJAX data * * @param string $data Input data * @return mixed */ private function process_ajax_data( $data ) { // Process your data here return $data; } /** * Register REST API routes */ public function register_rest_routes() { register_rest_route( 'myop/v1', '/books', array( 'methods' => 'GET', 'callback' => array( $this, 'rest_get_books' ), 'permission_callback' => array( $this, 'rest_permission_check' ), ) ); register_rest_route( 'myop/v1', '/books/(?P\d+)', array( 'methods' => 'GET', 'callback' => array( $this, 'rest_get_book' ), 'permission_callback' => '__return_true', 'args' => array( 'id' => array( 'required' => true, 'validate_callback' => function( $param ) { return is_numeric( $param ); }, 'sanitize_callback' => 'absint', ), ), ) ); } /** * REST API permission check * * @return bool */ public function rest_permission_check() { return current_user_can( 'edit_posts' ); } /** * REST API endpoint: Get books * * @param WP_REST_Request $request Request object * @return WP_REST_Response|WP_Error */ public function rest_get_books( $request ) { $args = array( 'post_type' => 'book', 'posts_per_page' => 10, 'post_status' => 'publish', ); $books = get_posts( $args ); $data = array(); foreach ( $books as $book ) { $data[] = array( 'id' => $book->ID, 'title' => $book->post_title, 'content' => $book->post_content, 'excerpt' => $book->post_excerpt, ); } return rest_ensure_response( $data ); } /** * REST API endpoint: Get single book * * @param WP_REST_Request $request Request object * @return WP_REST_Response|WP_Error */ public function rest_get_book( $request ) { $book_id = $request->get_param( 'id' ); $book = get_post( $book_id ); if ( ! $book || 'book' !== $book->post_type ) { return new WP_Error( 'not_found', __( 'Book not found', 'my-oop-plugin' ), array( 'status' => 404 ) ); } $data = array( 'id' => $book->ID, 'title' => $book->post_title, 'content' => $book->post_content, 'excerpt' => $book->post_excerpt, ); return rest_ensure_response( $data ); } /** * Plugin activation */ public function activate() { // Register post types and taxonomies $this->register_post_types(); $this->register_taxonomies(); // Flush rewrite rules flush_rewrite_rules(); // Set default settings if ( false === get_option( 'myop_settings' ) ) { add_option( 'myop_settings', array( 'option1' => '', 'option2' => 0, 'option3' => false, ) ); } // Set activation timestamp if ( false === get_option( 'myop_activated_time' ) ) { add_option( 'myop_activated_time', current_time( 'timestamp' ) ); } } /** * Plugin deactivation */ public function deactivate() { // Flush rewrite rules flush_rewrite_rules(); // Clear scheduled events wp_clear_scheduled_hook( 'myop_cron_event' ); } } // Initialize plugin My_OOP_Plugin::get_instance();