genel rss ekleme uygulaması wordpress

Genel Forum
muratca61
Site Admin
Mesajlar: 35899
Kayıt: Cmt Ara 21, 2024 7:56 am

Re: genel rss ekleme uygulaması wordpress

Mesaj gönderen muratca61 »

bu her seferinde 2 kaynaktan çekecekmiş

Kod:Tümünü seç

$batch_size = 2; // Her istekte 2 kaynak işlenecek.

Kod:Tümünü seç

$batch_size = 1; // Her istekte 1 kaynak işlenecek.

Kod:Tümünü seç

<?php
/*
Plugin Name: Genel RSS Haber Scraper
Description: Excel benzeri tablo üzerinden RSS kaynaklarını ekleyip, RSS haberlerini çekmenize olanak tanır. Ayarlarda; RSS adresi, kategoriler, RSS haber etiket kodu, link eklenip eklenmeyeceği, resim HTML kodu ve bağlantı kontrolü yapabilirsiniz. Ayrıca, yazı içeriğinden cümle başları hariç büyük harfli olan ve en çok geçen kelimelerden otomatik 5 etiket oluşturur. Görsel URL’leri için <img src="..."> içindeki .jpg gibi URL’lerde, query string kısmı hariç çekilir.
Version: 1.1
Author: Örnek Geliştirici
License: GPL2
*/

if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

class Genel_RSS_Haber_Scraper {
    private $option_name = 'genel_rss_haber_scraper_sources';

    public function __construct() {
        add_action( 'admin_menu', array( $this, 'add_admin_menu' ) );
        add_action( 'admin_init', array( $this, 'register_settings' ) );
        add_action( 'wp_ajax_genel_rss_scrape', array( $this, 'handle_scrape_request' ) );
        add_action( 'wp_ajax_genel_rss_connection_check', array( $this, 'handle_connection_check' ) );
        add_action( 'wp_enqueue_scripts', array( $this, 'frontend_enqueue_scripts' ) );
        add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
    }

    public function add_admin_menu() {
        add_menu_page(
            'Genel RSS Haber Scraper',
            'RSS Haber Scraper',
            'manage_options',
            'genel-rss-haber-scraper',
            array( $this, 'admin_page' ),
            'dashicons-rss',
            20
        );
    }

    public function register_settings() {
        register_setting( 'genel_rss_haber_scraper_options', $this->option_name );
    }

    public function admin_enqueue_scripts( $hook ) {
        if ( $hook == 'toplevel_page_genel-rss-haber-scraper' ) {
            wp_enqueue_script(
                'genel-rss-admin',
                plugin_dir_url( __FILE__ ) . 'js/genel-rss-admin.js',
                array( 'jquery' ),
                '1.0',
                true
            );
            wp_localize_script( 'genel-rss-admin', 'genelRssAdmin', array(
                'ajax_url' => admin_url( 'admin-ajax.php' )
            ) );
        }
    }

    public function frontend_enqueue_scripts() {
        wp_enqueue_script(
            'genel-rss-frontend',
            plugin_dir_url( __FILE__ ) . 'js/genel-rss-frontend.js',
            array( 'jquery' ),
            '1.0',
            true
        );
        wp_localize_script( 'genel-rss-frontend', 'genelRssAjax', array(
            'ajax_url' => admin_url( 'admin-ajax.php' )
        ) );
    }

    public function admin_page() {
        // Kayıtlı RSS kaynaklarını alıyoruz
        $sources = get_option( $this->option_name, array() );
        ?>
        <div class="wrap">
            <h1>Genel RSS Haber Scraper</h1>
            <form method="post" action="options.php">
                <?php settings_fields( 'genel_rss_haber_scraper_options' ); ?>
                <table class="widefat" id="rss-sources-table">
                    <thead>
                        <tr>
                            <th>RSS Adresi</th>
                            <th>Kategoriler (virgülle ayrılmış)</th>
                            <th>RSS Haber Etiket</th>
                            <th>Link Eklensin mi?</th>
                            <th>Resim HTML Kodu</th>
                            <th>Bağlantı Kontrol</th>
                            <th>İşlem</th>
                        </tr>
                    </thead>
                    <tbody>
                        <?php 
                        if ( ! empty( $sources ) ) {
                            foreach ( $sources as $index => $source ) {
                                $rss_url    = isset( $source['rss_url'] ) ? $source['rss_url'] : '';
                                $categories = isset( $source['categories'] ) ? $source['categories'] : '';
                                $tag        = isset( $source['tag'] ) ? $source['tag'] : '';
                                $add_link   = isset( $source['add_link'] ) ? $source['add_link'] : '';
                                $image_html = isset( $source['image_html'] ) ? $source['image_html'] : '';
                                ?>
                                <tr>
                                    <td>
                                        <input type="text" name="<?php echo $this->option_name; ?>[<?php echo $index; ?>][rss_url]" value="<?php echo esc_attr( $rss_url ); ?>" size="40" />
                                    </td>
                                    <td>
                                        <input type="text" name="<?php echo $this->option_name; ?>[<?php echo $index; ?>][categories]" value="<?php echo esc_attr( $categories ); ?>" size="30" placeholder="Kategori1,Kategori2" />
                                    </td>
                                    <td>
                                        <input type="text" name="<?php echo $this->option_name; ?>[<?php echo $index; ?>][tag]" value="<?php echo esc_attr( $tag ); ?>" size="10" placeholder="item veya entry" />
                                    </td>
                                    <td>
                                        <input type="checkbox" name="<?php echo $this->option_name; ?>[<?php echo $index; ?>][add_link]" value="1" <?php checked( $add_link, 1 ); ?> />
                                    </td>
                                    <td>
                                        <input type="text" name="<?php echo $this->option_name; ?>[<?php echo $index; ?>][image_html]" value="<?php echo esc_attr( $image_html ); ?>" size="30" placeholder="<img src='...' />" />
                                    </td>
                                    <td>
                                        <button class="button connection-check" data-row-index="<?php echo $index; ?>">Bağlantıyı Kontrol Et</button>
                                        <span class="connection-result" id="conn-result-<?php echo $index; ?>"></span>
                                    </td>
                                    <td>
                                        <button class="button remove-row">Kaldır</button>
                                    </td>
                                </tr>
                                <?php
                            }
                        }
                        ?>
                    </tbody>
                </table>
                <p>
                    <button type="button" class="button" id="add-row">Yeni Satır Ekle</button>
                </p>
                <?php submit_button(); ?>
            </form>
            <hr>
            <h2>Manuel Haber Çekme (Batch Processing)</h2>
            <p>RSS haberlerini çekmek için aşağıdaki butona tıklayın. İşlem, kaynakları parça parça (batch) kontrol ederek yapılır.</p>
            <button id="fetch-rss-news" class="button button-primary">Haberleri Çek</button>
            <div id="rss-news-log" style="margin-top:20px;padding:10px;background:#f9f9f9;border:1px solid #ddd;max-height:300px;overflow-y:auto;"></div>
            <script>
            jQuery(document).ready(function($) {
                var log = $('#rss-news-log');
                $('#fetch-rss-news').on('click', function() {
                    log.html('<p>Haber çekme işlemi başlatıldı...</p>');
                    processBatch(0);
                });
                
                function processBatch(offset) {
                    $.ajax({
                        url: ajaxurl,
                        type: 'POST',
                        data: { action: 'genel_rss_scrape', offset: offset },
                        success: function(response) {
                            if(response.success) {
                                log.append('<p style="color:green;">' + response.data.message + '</p>');
                                if(response.data.next_offset !== null) {
                                    processBatch(response.data.next_offset);
                                } else {
                                    log.append('<p style="font-weight:bold;">Tüm kaynaklar işlendi.</p>');
                                }
                            } else {
                                log.append('<p style="color:red;">' + response.data.message + '</p>');
                            }
                        },
                        error: function() {
                            log.append('<p style="color:red;">Bağlantı hatası!</p>');
                        }
                    });
                }
            });
            </script>
        </div>
        <?php
    }

    // AJAX: Manuel haber çekme işlemi (batch processing)
    public function handle_scrape_request() {
        // Timeout ayarlarını optimize ediyoruz:
        @set_time_limit(30);
        ini_set('default_socket_timeout', 15);

        $offset = isset( $_POST['offset'] ) ? intval( $_POST['offset'] ) : 0;
        $batch_size = 2; // Her istekte 2 kaynak işlenecek.
        $result = $this->fetch_news_batch( $offset, $batch_size );
        
        if ( $result['new_posts'] > 0 ) {
            wp_send_json_success( array( 
                'message'     => $result['new_posts'] . ' yeni haber eklendi.',
                'next_offset' => $result['next_offset']
            ) );
        } else {
            wp_send_json_success( array( 
                'message'     => 'İşlenen ' . $result['processed'] . ' kaynaktan yeni haber bulunamadı.',
                'next_offset' => $result['next_offset']
            ) );
        }
    }

    // AJAX: Bağlantı kontrolü için RSS adresi ve etiket bilgisini kontrol eder
    public function handle_connection_check() {
        $rss_url = isset( $_POST['rss_url'] ) ? esc_url_raw( $_POST['rss_url'] ) : '';
        $tag     = isset( $_POST['tag'] ) ? sanitize_text_field( $_POST['tag'] ) : '';

        if ( empty( $rss_url ) || empty( $tag ) ) {
            wp_send_json_error( array( 'message' => 'RSS URL ve Etiket bilgisi gerekli.' ) );
        }

        $rss_feed = @simplexml_load_file( $rss_url );
        if ( ! $rss_feed ) {
            wp_send_json_error( array( 'message' => 'RSS beslemesi yüklenemedi.' ) );
        }

        if ( $tag === 'item' && isset( $rss_feed->channel->item ) ) {
            wp_send_json_success( array( 'message' => 'Bağlantı başarılı: <item> bulundu.' ) );
        } elseif ( $tag === 'entry' && isset( $rss_feed->entry ) ) {
            wp_send_json_success( array( 'message' => 'Bağlantı başarılı: <entry> bulundu.' ) );
        } else {
            wp_send_json_error( array( 'message' => 'Belirtilen etiket bulunamadı.' ) );
        }
    }

    /**
     * Belirtilen offset ve batch size'a göre RSS kaynaklarını kontrol eder.
     *
     * @param int $offset İşleme başlanacak kaynak indeksi.
     * @param int $batch_size Bir istekte işlenecek kaynak sayısı.
     * @return array İşlenen kaynak sayısı, eklenen yeni haber sayısı ve bir sonraki offset.
     */
    private function fetch_news_batch( $offset, $batch_size ) {
        $sources = get_option( $this->option_name, array() );
        $total = count( $sources );
        if ( $total === 0 ) {
            return array( 'processed' => 0, 'new_posts' => 0, 'next_offset' => null );
        }
        $processed = 0;
        $new_posts = 0;
        for ( $i = $offset; $i < min( $offset + $batch_size, $total ); $i++ ) {
            if ( $this->process_source( $sources[ $i ] ) ) {
                $new_posts++;
            }
            $processed++;
        }
        $next_offset = $offset + $batch_size;
        if ( $next_offset >= $total ) {
            $next_offset = null;
        }
        return array(
            'processed'  => $processed,
            'new_posts'  => $new_posts,
            'next_offset'=> $next_offset
        );
    }

    /**
     * Verilen bir RSS kaynağından (tek kaynak) haber çekmeye çalışır.
     *
     * @param array $source Kaynak bilgileri.
     * @return bool Yeni haber eklenmişse true, aksi halde false.
     */
    private function process_source( $source ) {
        require_once( ABSPATH . 'wp-admin/includes/post.php' );
        $rss_url        = isset( $source['rss_url'] ) ? trim( $source['rss_url'] ) : '';
        $categories_str = isset( $source['categories'] ) ? trim( $source['categories'] ) : '';
        $tag            = isset( $source['tag'] ) ? trim( $source['tag'] ) : '';
        $add_link       = isset( $source['add_link'] ) ? $source['add_link'] : 0;
        $image_html     = isset( $source['image_html'] ) ? trim( $source['image_html'] ) : '';

        if ( empty( $rss_url ) || empty( $tag ) ) {
            return false;
        }

        $rss_feed = @simplexml_load_file( $rss_url );
        if ( ! $rss_feed ) {
            error_log( 'RSS yüklenemedi: ' . $rss_url );
            return false;
        }

        // --- RSS item yapısı ---
        if ( $tag === 'item' && isset( $rss_feed->channel->item ) ) {
            foreach ( $rss_feed->channel->item as $item ) {
                $title = (string) $item->title;
                if ( post_exists( $title ) ) {
                    continue;
                }
                $link        = (string) $item->link;
                $description = (string) strip_tags( $item->description );
                $content     = isset( $item->children( 'content', true )->encoded ) ? (string) strip_tags( $item->children( 'content', true )->encoded ) : '';
                $image_url   = isset( $item->enclosure['url'] ) ? (string) $item->enclosure['url'] : '';

                // Eğer enclosure yoksa description veya content içinden resim URL'si arayalım.
                if ( empty( $image_url ) ) {
                    $combined_text = $description . ' ' . $content;
                    if ( preg_match( '/(https?:\/\/[^\s"\']+\.(?:png|jpg|wrp))(\?[^\s"\']*)?/i', $combined_text, $matches ) ) {
                        $image_url = $matches[1];
                    }
                }

                if ( empty( $title ) || ( empty( $content ) && empty( $description ) ) ) {
                    continue;
                }

                $post_content = '<p>' . esc_html( $description ) . '</p><p>' . esc_html( $content ) . '</p>';
                if ( $add_link ) {
                    $post_content .= '<p><a href="' . esc_url( $link ) . '" target="_blank" rel="noopener noreferrer">Kaynak</a></p>';
                }
                $category_ids = array();
                if ( ! empty( $categories_str ) ) {
                    $categories = array_map( 'trim', explode( ',', $categories_str ) );
                    foreach ( $categories as $cat_name ) {
                        $cat_id = get_cat_ID( $cat_name );
                        if ( ! $cat_id ) {
                            $cat_id = wp_create_category( $cat_name );
                        }
                        $category_ids[] = $cat_id;
                    }
                }
                $post_id = wp_insert_post( array(
                    'post_title'    => wp_strip_all_tags( $title ),
                    'post_content'  => $post_content,
                    'post_status'   => 'publish',
                    'post_author'   => 1,
                    'post_category' => $category_ids,
                    'post_type'     => 'post'
                ) );
                if ( ! is_wp_error( $post_id ) ) {
                    // Görsel ekleme işlemi
                    if ( ! empty( $image_url ) ) {
                        require_once( ABSPATH . 'wp-admin/includes/media.php' );
                        require_once( ABSPATH . 'wp-admin/includes/file.php' );
                        require_once( ABSPATH . 'wp-admin/includes/image.php' );
                        $attachment_id = media_sideload_image( $image_url, $post_id, $title, 'id' );
                        if ( ! is_wp_error( $attachment_id ) ) {
                            set_post_thumbnail( $post_id, $attachment_id );
                        }
                    }
                    // Ekstra resim HTML kodunu ekleme (varsa)
                    if ( ! empty( $image_html ) ) {
                        $post_content .= "\n" . $image_html;
                        wp_update_post( array(
                            'ID'           => $post_id,
                            'post_content' => $post_content
                        ) );
                    }
                    // Yazı içeriğinden otomatik etiket oluşturma (cümle başları hariç)
                    $tags = $this->extract_tags_from_content( $description . ' ' . $content );
                    if ( ! empty( $tags ) ) {
                        wp_set_post_tags( $post_id, $tags );
                    }
                    return true; // Bu kaynaktan bir haber eklendi.
                }
            }
        }
        // --- RSS entry yapısı ---
        elseif ( $tag === 'entry' && isset( $rss_feed->entry ) ) {
            foreach ( $rss_feed->entry as $entry ) {
                $title = (string) $entry->title;
                if ( post_exists( $title ) ) {
                    continue;
                }
                $link = '';
                if ( isset( $entry->link ) ) {
                    foreach ( $entry->link as $l ) {
                        $attributes = $l->attributes();
                        if ( isset( $attributes['rel'] ) && (string) $attributes['rel'] === 'alternate' ) {
                            $link = (string) $attributes['href'];
                            break;
                        }
                    }
                    if ( empty( $link ) ) {
                        $link = (string) $entry->link;
                    }
                }
                $description = isset( $entry->summary ) ? (string) strip_tags( $entry->summary ) : '';
                $content     = isset( $entry->content ) ? (string) strip_tags( $entry->content ) : '';
                $image_url   = '';

                if ( empty( $image_url ) ) {
                    $combined_text = $description . ' ' . $content;
                    if ( preg_match( '/(https?:\/\/[^\s"\']+\.(?:png|jpg|wrp))(\?[^\s"\']*)?/i', $combined_text, $matches ) ) {
                        $image_url = $matches[1];
                    }
                }

                if ( empty( $title ) || ( empty( $content ) && empty( $description ) ) ) {
                    continue;
                }

                $post_content = '<p>' . esc_html( $description ) . '</p><p>' . esc_html( $content ) . '</p>';
                if ( $add_link ) {
                    $post_content .= '<p><a href="' . esc_url( $link ) . '" target="_blank" rel="noopener noreferrer">Kaynak</a></p>';
                }
                $category_ids = array();
                if ( ! empty( $categories_str ) ) {
                    $categories = array_map( 'trim', explode( ',', $categories_str ) );
                    foreach ( $categories as $cat_name ) {
                        $cat_id = get_cat_ID( $cat_name );
                        if ( ! $cat_id ) {
                            $cat_id = wp_create_category( $cat_name );
                        }
                        $category_ids[] = $cat_id;
                    }
                }
                $post_id = wp_insert_post( array(
                    'post_title'    => wp_strip_all_tags( $title ),
                    'post_content'  => $post_content,
                    'post_status'   => 'publish',
                    'post_author'   => 1,
                    'post_category' => $category_ids,
                    'post_type'     => 'post'
                ) );
                if ( ! is_wp_error( $post_id ) ) {
                    if ( ! empty( $image_url ) ) {
                        require_once( ABSPATH . 'wp-admin/includes/media.php' );
                        require_once( ABSPATH . 'wp-admin/includes/file.php' );
                        require_once( ABSPATH . 'wp-admin/includes/image.php' );
                        $attachment_id = media_sideload_image( $image_url, $post_id, $title, 'id' );
                        if ( ! is_wp_error( $attachment_id ) ) {
                            set_post_thumbnail( $post_id, $attachment_id );
                        }
                    }
                    $tags = $this->extract_tags_from_content( $description . ' ' . $content );
                    if ( ! empty( $tags ) ) {
                        wp_set_post_tags( $post_id, $tags );
                    }
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * Yazı içeriğinden, cümle başları hariç, ilk kelimeyi atlayarak
     * büyük harfli (ilk harfi büyük) kelimelerin frekansını hesaplar ve
     * en çok geçen 5 kelimeyi etiket olarak döndürür.
     */
    private function extract_tags_from_content( $content ) {
        $sentences = preg_split( '/(?<=[.?!])\s+/', $content, -1, PREG_SPLIT_NO_EMPTY );
        $words = array();
        foreach ( $sentences as $sentence ) {
            $sentence_words = preg_split( '/\s+/', $sentence, -1, PREG_SPLIT_NO_EMPTY );
            if ( count( $sentence_words ) > 1 ) {
                for ( $i = 1; $i < count( $sentence_words ); $i++ ) {
                    $words[] = $sentence_words[$i];
                }
            }
        }
        $filtered = array();
        foreach ( $words as $word ) {
            $clean = trim( $word, ".,!?()[]{}\"'" );
            if ( strlen( $clean ) > 2 && ctype_upper( substr( $clean, 0, 1 ) ) ) {
                $filtered[] = $clean;
            }
        }
        $freq = array();
        foreach ( $filtered as $w ) {
            $key = strtolower( $w );
            if ( isset( $freq[ $key ] ) ) {
                $freq[ $key ]++;
            } else {
                $freq[ $key ] = 1;
            }
        }
        arsort( $freq );
        $top_tags = array_slice( array_keys( $freq ), 0, 5 );
        return $top_tags;
    }
}

new Genel_RSS_Haber_Scraper();
muratca61
Site Admin
Mesajlar: 35899
Kayıt: Cmt Ara 21, 2024 7:56 am

Re: genel rss ekleme uygulaması wordpress

Mesaj gönderen muratca61 »

250218-bundan devam
sanırım üstteki çekme işlemini yapmıyor bu hesapta düzeltilmiş hali. bakacağız

Kod:Tümünü seç

<?php
/*
Plugin Name: Genel RSS Haber Scraper
Description: Excel benzeri tablo üzerinden RSS kaynaklarını ekleyip, RSS haberlerini çekmenize olanak tanır. Ayarlarda; RSS adresi, kategoriler, RSS haber etiket kodu, link eklenip eklenmeyeceği, resim HTML kodu ve bağlantı kontrolü yapabilirsiniz. Ayrıca, yazı içeriğinden cümle başları hariç büyük harfli olan ve en çok geçen kelimelerden otomatik 5 etiket oluşturur. Görsel URL’leri için <img src="..."> içindeki .jpg gibi URL’lerde, query string kısmı hariç çekilir.
Version: 1.1
Author: Örnek Geliştirici
License: GPL2
*/

if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

class Genel_RSS_Haber_Scraper {
    private $option_name = 'genel_rss_haber_scraper_sources';

    public function __construct() {
        add_action( 'admin_menu', array( $this, 'add_admin_menu' ) );
        add_action( 'admin_init', array( $this, 'register_settings' ) );
        add_action( 'wp_ajax_genel_rss_scrape', array( $this, 'handle_scrape_request' ) );
        add_action( 'wp_ajax_genel_rss_connection_check', array( $this, 'handle_connection_check' ) );
        add_action( 'wp_enqueue_scripts', array( $this, 'frontend_enqueue_scripts' ) );
        add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
    }

    public function add_admin_menu() {
        add_menu_page(
            'Genel RSS Haber Scraper',
            'RSS Haber Scraper',
            'manage_options',
            'genel-rss-haber-scraper',
            array( $this, 'admin_page' ),
            'dashicons-rss',
            20
        );
    }

    public function register_settings() {
        register_setting( 'genel_rss_haber_scraper_options', $this->option_name );
    }

    public function admin_enqueue_scripts( $hook ) {
        if ( $hook == 'toplevel_page_genel-rss-haber-scraper' ) {
            wp_enqueue_script(
                'genel-rss-admin',
                plugin_dir_url( __FILE__ ) . 'js/genel-rss-admin.js',
                array( 'jquery' ),
                '1.0',
                true
            );
            wp_localize_script( 'genel-rss-admin', 'genelRssAdmin', array(
                'ajax_url' => admin_url( 'admin-ajax.php' )
            ) );
        }
    }

    public function frontend_enqueue_scripts() {
        wp_enqueue_script(
            'genel-rss-frontend',
            plugin_dir_url( __FILE__ ) . 'js/genel-rss-frontend.js',
            array( 'jquery' ),
            '1.0',
            true
        );
        wp_localize_script( 'genel-rss-frontend', 'genelRssAjax', array(
            'ajax_url' => admin_url( 'admin-ajax.php' )
        ) );
    }

    public function admin_page() {
        // Kayıtlı RSS kaynaklarını alıyoruz
        $sources = get_option( $this->option_name, array() );
        ?>
        <div class="wrap">
            <h1>Genel RSS Haber Scraper</h1>
            <form method="post" action="options.php">
                <?php settings_fields( 'genel_rss_haber_scraper_options' ); ?>
                <table class="widefat" id="rss-sources-table">
                    <thead>
                        <tr>
                            <th>RSS Adresi</th>
                            <th>Kategoriler (virgülle ayrılmış)</th>
                            <th>RSS Haber Etiket</th>
                            <th>Link Eklensin mi?</th>
                            <th>Resim HTML Kodu</th>
                            <th>Bağlantı Kontrol</th>
                            <th>İşlem</th>
                        </tr>
                    </thead>
                    <tbody>
                        <?php 
                        if ( ! empty( $sources ) ) {
                            foreach ( $sources as $index => $source ) {
                                $rss_url    = isset( $source['rss_url'] ) ? $source['rss_url'] : '';
                                $categories = isset( $source['categories'] ) ? $source['categories'] : '';
                                $tag        = isset( $source['tag'] ) ? $source['tag'] : '';
                                $add_link   = isset( $source['add_link'] ) ? $source['add_link'] : '';
                                $image_html = isset( $source['image_html'] ) ? $source['image_html'] : '';
                                ?>
                                <tr>
                                    <td>
                                        <input type="text" name="<?php echo $this->option_name; ?>[<?php echo $index; ?>][rss_url]" value="<?php echo esc_attr( $rss_url ); ?>" size="40" />
                                    </td>
                                    <td>
                                        <input type="text" name="<?php echo $this->option_name; ?>[<?php echo $index; ?>][categories]" value="<?php echo esc_attr( $categories ); ?>" size="30" placeholder="Kategori1,Kategori2" />
                                    </td>
                                    <td>
                                        <input type="text" name="<?php echo $this->option_name; ?>[<?php echo $index; ?>][tag]" value="<?php echo esc_attr( $tag ); ?>" size="10" placeholder="item veya entry" />
                                    </td>
                                    <td>
                                        <input type="checkbox" name="<?php echo $this->option_name; ?>[<?php echo $index; ?>][add_link]" value="1" <?php checked( $add_link, 1 ); ?> />
                                    </td>
                                    <td>
                                        <input type="text" name="<?php echo $this->option_name; ?>[<?php echo $index; ?>][image_html]" value="<?php echo esc_attr( $image_html ); ?>" size="30" placeholder="<img src='...' />" />
                                    </td>
                                    <td>
                                        <button class="button connection-check" data-row-index="<?php echo $index; ?>">Bağlantıyı Kontrol Et</button>
                                        <span class="connection-result" id="conn-result-<?php echo $index; ?>"></span>
                                    </td>
                                    <td>
                                        <button class="button remove-row">Kaldır</button>
                                    </td>
                                </tr>
                                <?php
                            }
                        }
                        ?>
                    </tbody>
                </table>
                <p>
                    <button type="button" class="button" id="add-row">Yeni Satır Ekle</button>
                </p>
                <?php submit_button(); ?>
            </form>
            <hr>
            <h2>Manuel Haber Çekme (Batch Processing)</h2>
            <p>RSS haberlerini çekmek için aşağıdaki butona tıklayın. İşlem, kaynakları parça parça (batch) kontrol ederek yapılır.</p>
            <button id="fetch-rss-news" class="button button-primary">Haberleri Çek</button>
            <div id="rss-news-log" style="margin-top:20px;padding:10px;background:#f9f9f9;border:1px solid #ddd;max-height:300px;overflow-y:auto;"></div>
            <script>
            jQuery(document).ready(function($) {
                var log = $('#rss-news-log');
                $('#fetch-rss-news').on('click', function() {
                    log.html('<p>Haber çekme işlemi başlatıldı...</p>');
                    processBatch(0);
                });
                
                function processBatch(offset) {
                    $.ajax({
                        url: ajaxurl,
                        type: 'POST',
                        data: { action: 'genel_rss_scrape', offset: offset },
                        success: function(response) {
                            console.log(response);
                            if(response.success) {
                                log.append('<p style="color:green;">' + response.data.message + '</p>');
                                if(response.data.next_offset !== null) {
                                    processBatch(response.data.next_offset);
                                } else {
                                    log.append('<p style="font-weight:bold;">Tüm kaynaklar işlendi.</p>');
                                }
                            } else {
                                log.append('<p style="color:red;">' + response.data.message + '</p>');
                            }
                        },
                        error: function() {
                            log.append('<p style="color:red;">Bağlantı hatası!</p>');
                        }
                    });
                }
            });
            </script>
        </div>
        <?php
    }

    // AJAX: Manuel haber çekme işlemi (batch processing)
    public function handle_scrape_request() {
        // Timeout ayarlarını optimize ediyoruz:
        @set_time_limit(30);
        ini_set('default_socket_timeout', 15);

        $offset = isset( $_POST['offset'] ) ? intval( $_POST['offset'] ) : 0;
        $batch_size = 2; // Her istekte 2 kaynak işlenecek.
        $result = $this->fetch_news_batch( $offset, $batch_size );
        
        if ( $result['new_posts'] > 0 ) {
            wp_send_json_success( array( 
                'message'     => $result['new_posts'] . ' yeni haber eklendi.',
                'next_offset' => $result['next_offset']
            ) );
        } else {
            wp_send_json_success( array( 
                'message'     => 'İşlenen ' . $result['processed'] . ' kaynaktan yeni haber bulunamadı.',
                'next_offset' => $result['next_offset']
            ) );
        }
    }

    // AJAX: Bağlantı kontrolü için RSS adresi ve etiket bilgisini kontrol eder
    public function handle_connection_check() {
        $rss_url = isset( $_POST['rss_url'] ) ? esc_url_raw( $_POST['rss_url'] ) : '';
        $tag     = isset( $_POST['tag'] ) ? sanitize_text_field( $_POST['tag'] ) : '';

        if ( empty( $rss_url ) || empty( $tag ) ) {
            wp_send_json_error( array( 'message' => 'RSS URL ve Etiket bilgisi gerekli.' ) );
        }

        $rss_feed = @simplexml_load_file( $rss_url );
        if ( ! $rss_feed ) {
            wp_send_json_error( array( 'message' => 'RSS beslemesi yüklenemedi.' ) );
        }

        if ( $tag === 'item' && isset( $rss_feed->channel->item ) ) {
            wp_send_json_success( array( 'message' => 'Bağlantı başarılı: <item> bulundu.' ) );
        } elseif ( $tag === 'entry' && isset( $rss_feed->entry ) ) {
            wp_send_json_success( array( 'message' => 'Bağlantı başarılı: <entry> bulundu.' ) );
        } else {
            wp_send_json_error( array( 'message' => 'Belirtilen etiket bulunamadı.' ) );
        }
    }

    /**
     * Belirtilen offset ve batch size'a göre RSS kaynaklarını kontrol eder.
     *
     * @param int $offset İşleme başlanacak kaynak indeksi.
     * @param int $batch_size Bir istekte işlenecek kaynak sayısı.
     * @return array İşlenen kaynak sayısı, eklenen yeni haber sayısı ve bir sonraki offset.
     */
    private function fetch_news_batch( $offset, $batch_size ) {
        $sources = get_option( $this->option_name, array() );
        $total = count( $sources );
        if ( $total === 0 ) {
            return array( 'processed' => 0, 'new_posts' => 0, 'next_offset' => null );
        }
        $processed = 0;
        $new_posts = 0;
        for ( $i = $offset; $i < min( $offset + $batch_size, $total ); $i++ ) {
            $inserted = $this->process_source( $sources[ $i ] );
            $new_posts += $inserted;
            $processed++;
        }
        $next_offset = $offset + $batch_size;
        if ( $next_offset >= $total ) {
            $next_offset = null;
        }
        return array(
            'processed'   => $processed,
            'new_posts'   => $new_posts,
            'next_offset' => $next_offset
        );
    }

    /**
     * Verilen bir RSS kaynağından (tek kaynak) haber çekmeye çalışır.
     *
     * @param array $source Kaynak bilgileri.
     * @return int Eklenen yeni haber sayısı.
     */
    private function process_source( $source ) {
        require_once( ABSPATH . 'wp-admin/includes/post.php' );
        $rss_url        = isset( $source['rss_url'] ) ? trim( $source['rss_url'] ) : '';
        $categories_str = isset( $source['categories'] ) ? trim( $source['categories'] ) : '';
        $tag            = isset( $source['tag'] ) ? trim( $source['tag'] ) : '';
        $add_link       = isset( $source['add_link'] ) ? $source['add_link'] : 0;
        $image_html     = isset( $source['image_html'] ) ? trim( $source['image_html'] ) : '';

        if ( empty( $rss_url ) || empty( $tag ) ) {
            return 0;
        }

        $rss_feed = @simplexml_load_file( $rss_url );
        if ( ! $rss_feed ) {
            error_log( 'RSS yüklenemedi: ' . $rss_url );
            return 0;
        }

        $inserted = 0;
        // --- RSS item yapısı ---
        if ( $tag === 'item' && isset( $rss_feed->channel->item ) ) {
            foreach ( $rss_feed->channel->item as $item ) {
                $title = (string) $item->title;
                if ( post_exists( $title ) ) {
                    continue;
                }
                $link        = (string) $item->link;
                $description = (string) strip_tags( $item->description );
                $content     = isset( $item->children( 'content', true )->encoded ) ? (string) strip_tags( $item->children( 'content', true )->encoded ) : '';
                $image_url   = isset( $item->enclosure['url'] ) ? (string) $item->enclosure['url'] : '';

                // Eğer enclosure yoksa description veya content içinden resim URL'si arayalım.
                if ( empty( $image_url ) ) {
                    $combined_text = $description . ' ' . $content;
                    if ( preg_match( '/(https?:\/\/[^\s"\']+\.(?:png|jpg|webp))(\?[^\s"\']*)?/i', $combined_text, $matches ) ) {
                        $image_url = $matches[1];
                    }
                }

                if ( empty( $title ) || ( empty( $content ) && empty( $description ) ) ) {
                    continue;
                }

                $post_content = '<p>' . esc_html( $description ) . '</p><p>' . esc_html( $content ) . '</p>';
                if ( $add_link ) {
                    $post_content .= '<p><a href="' . esc_url( $link ) . '" target="_blank" rel="noopener noreferrer">Kaynak</a></p>';
                }
                $category_ids = array();
                if ( ! empty( $categories_str ) ) {
                    $categories = array_map( 'trim', explode( ',', $categories_str ) );
                    foreach ( $categories as $cat_name ) {
                        $cat_id = get_cat_ID( $cat_name );
                        if ( ! $cat_id ) {
                            $cat_id = wp_create_category( $cat_name );
                        }
                        $category_ids[] = $cat_id;
                    }
                }
                $post_id = wp_insert_post( array(
                    'post_title'    => wp_strip_all_tags( $title ),
                    'post_content'  => $post_content,
                    'post_status'   => 'publish',
                    'post_author'   => 1,
                    'post_category' => $category_ids,
                    'post_type'     => 'post'
                ) );
                if ( ! is_wp_error( $post_id ) ) {
                    // Görsel ekleme işlemi
                    if ( ! empty( $image_url ) ) {
                        require_once( ABSPATH . 'wp-admin/includes/media.php' );
                        require_once( ABSPATH . 'wp-admin/includes/file.php' );
                        require_once( ABSPATH . 'wp-admin/includes/image.php' );
                        $attachment_id = media_sideload_image( $image_url, $post_id, $title, 'id' );
                        if ( ! is_wp_error( $attachment_id ) ) {
                            set_post_thumbnail( $post_id, $attachment_id );
                        }
                    }
                    // Ekstra resim HTML kodunu ekleme (varsa)
                    if ( ! empty( $image_html ) ) {
                        $post_content .= "\n" . $image_html;
                        wp_update_post( array(
                            'ID'           => $post_id,
                            'post_content' => $post_content
                        ) );
                    }
                    // Yazı içeriğinden otomatik etiket oluşturma (cümle başları hariç)
                    $tags = $this->extract_tags_from_content( $description . ' ' . $content );
                    if ( ! empty( $tags ) ) {
                        wp_set_post_tags( $post_id, $tags );
                    }
                    $inserted++;
                }
            }
        }
        // --- RSS entry yapısı ---
        elseif ( $tag === 'entry' && isset( $rss_feed->entry ) ) {
            foreach ( $rss_feed->entry as $entry ) {
                $title = (string) $entry->title;
                if ( post_exists( $title ) ) {
                    continue;
                }
                $link = '';
                if ( isset( $entry->link ) ) {
                    foreach ( $entry->link as $l ) {
                        $attributes = $l->attributes();
                        if ( isset( $attributes['rel'] ) && (string) $attributes['rel'] === 'alternate' ) {
                            $link = (string) $attributes['href'];
                            break;
                        }
                    }
                    if ( empty( $link ) ) {
                        $link = (string) $entry->link;
                    }
                }
                $description = isset( $entry->summary ) ? (string) strip_tags( $entry->summary ) : '';
                $content     = isset( $entry->content ) ? (string) strip_tags( $entry->content ) : '';
                $image_url   = '';

                if ( empty( $image_url ) ) {
                    $combined_text = $description . ' ' . $content;
                    if ( preg_match( '/(https?:\/\/[^\s"\']+\.(?:png|jpg|webp))(\?[^\s"\']*)?/i', $combined_text, $matches ) ) {
                        $image_url = $matches[1];
                    }
                }

                if ( empty( $title ) || ( empty( $content ) && empty( $description ) ) ) {
                    continue;
                }

                $post_content = '<p>' . esc_html( $description ) . '</p><p>' . esc_html( $content ) . '</p>';
                if ( $add_link ) {
                    $post_content .= '<p><a href="' . esc_url( $link ) . '" target="_blank" rel="noopener noreferrer">Kaynak</a></p>';
                }
                $category_ids = array();
                if ( ! empty( $categories_str ) ) {
                    $categories = array_map( 'trim', explode( ',', $categories_str ) );
                    foreach ( $categories as $cat_name ) {
                        $cat_id = get_cat_ID( $cat_name );
                        if ( ! $cat_id ) {
                            $cat_id = wp_create_category( $cat_name );
                        }
                        $category_ids[] = $cat_id;
                    }
                }
                $post_id = wp_insert_post( array(
                    'post_title'    => wp_strip_all_tags( $title ),
                    'post_content'  => $post_content,
                    'post_status'   => 'publish',
                    'post_author'   => 1,
                    'post_category' => $category_ids,
                    'post_type'     => 'post'
                ) );
                if ( ! is_wp_error( $post_id ) ) {
                    if ( ! empty( $image_url ) ) {
                        require_once( ABSPATH . 'wp-admin/includes/media.php' );
                        require_once( ABSPATH . 'wp-admin/includes/file.php' );
                        require_once( ABSPATH . 'wp-admin/includes/image.php' );
                        $attachment_id = media_sideload_image( $image_url, $post_id, $title, 'id' );
                        if ( ! is_wp_error( $attachment_id ) ) {
                            set_post_thumbnail( $post_id, $attachment_id );
                        }
                    }
                    $tags = $this->extract_tags_from_content( $description . ' ' . $content );
                    if ( ! empty( $tags ) ) {
                        wp_set_post_tags( $post_id, $tags );
                    }
                    $inserted++;
                }
            }
        }
        return $inserted;
    }

    /**
     * Yazı içeriğinden, cümle başları hariç, ilk kelimeyi atlayarak
     * büyük harfli (ilk harfi büyük) kelimelerin frekansını hesaplar ve
     * en çok geçen 5 kelimeyi etiket olarak döndürür.
     */
    private function extract_tags_from_content( $content ) {
        $sentences = preg_split( '/(?<=[.?!])\s+/', $content, -1, PREG_SPLIT_NO_EMPTY );
        $words = array();
        foreach ( $sentences as $sentence ) {
            $sentence_words = preg_split( '/\s+/', $sentence, -1, PREG_SPLIT_NO_EMPTY );
            if ( count( $sentence_words ) > 1 ) {
                for ( $i = 1; $i < count( $sentence_words ); $i++ ) {
                    $words[] = $sentence_words[$i];
                }
            }
        }
        $filtered = array();
        foreach ( $words as $word ) {
            $clean = trim( $word, ".,!?()[]{}\"'" );
            if ( strlen( $clean ) > 2 && ctype_upper( substr( $clean, 0, 1 ) ) ) {
                $filtered[] = $clean;
            }
        }
        $freq = array();
        foreach ( $filtered as $w ) {
            $key = strtolower( $w );
            if ( isset( $freq[ $key ] ) ) {
                $freq[ $key ]++;
            } else {
                $freq[ $key ] = 1;
            }
        }
        arsort( $freq );
        $top_tags = array_slice( array_keys( $freq ), 0, 5 );
        return $top_tags;
    }
}

new Genel_RSS_Haber_Scraper();
muratca61
Site Admin
Mesajlar: 35899
Kayıt: Cmt Ara 21, 2024 7:56 am

Re: genel rss ekleme uygulaması wordpress

Mesaj gönderen muratca61 »

bu da deepseek çözümü
aptal deepseek içine etmiş kodun

Kod:Tümünü seç

<?php
/*
Plugin Name: Genel RSS Haber Scraper
Description: Excel benzeri tablo üzerinden RSS kaynaklarını ekleyip, RSS haberlerini çekmenize olanak tanır.
Version: 1.2
Author: Örnek Geliştirici
License: GPL2
*/

if (!defined('ABSPATH')) {
    exit;
}

class Genel_RSS_Haber_Scraper {
    private $option_name = 'genel_rss_haber_scraper_sources';

    public function __construct() {
        add_action('admin_menu', array($this, 'add_admin_menu'));
        add_action('admin_init', array($this, 'register_settings'));
        add_action('wp_ajax_genel_rss_scrape', array($this, 'handle_scrape_request'));
        add_action('wp_ajax_genel_rss_connection_check', array($this, 'handle_connection_check'));
        add_action('admin_enqueue_scripts', array($this, 'admin_enqueue_scripts'));
    }

    public function add_admin_menu() {
        add_menu_page(
            'Genel RSS Haber Scraper',
            'RSS Haber Scraper',
            'manage_options',
            'genel-rss-haber-scraper',
            array($this, 'admin_page'),
            'dashicons-rss',
            20
        );
    }

    public function register_settings() {
        register_setting('genel_rss_haber_scraper_options', $this->option_name);
    }

    public function admin_enqueue_scripts($hook) {
        if ($hook == 'toplevel_page_genel-rss-haber-scraper') {
            wp_enqueue_script(
                'genel-rss-admin',
                plugin_dir_url(__FILE__) . 'js/genel-rss-admin.js',
                array('jquery'),
                '1.1',
                true
            );
            wp_localize_script('genel-rss-admin', 'genelRssAdmin', array(
                'ajax_url' => admin_url('admin-ajax.php'),
                'nonce' => wp_create_nonce('genel_rss_nonce')
            ));
        }
    }

    public function admin_page() {
        $sources = get_option($this->option_name, array());
        ?>
        <div class="wrap">
            <h1>Genel RSS Haber Scraper</h1>
            <form method="post" action="options.php">
                <?php settings_fields('genel_rss_haber_scraper_options'); ?>
                <table class="widefat" id="rss-sources-table">
                    <!-- Tablo yapısı önceki ile aynı -->
                </table>
                <p>
                    <button type="button" class="button" id="add-row">Yeni Satır Ekle</button>
                </p>
                <?php submit_button(); ?>
            </form>
            <hr>
            <h2>Manuel Haber Çekme</h2>
            <div id="rss-news-log"></div>
            <script>
            jQuery(document).ready(function($) {
                // Güncellenmiş AJAX çağrısı nonce ile
                function processBatch(offset) {
                    $.ajax({
                        url: ajaxurl,
                        type: 'POST',
                        data: { 
                            action: 'genel_rss_scrape', 
                            offset: offset,
                            nonce: genelRssAdmin.nonce
                        },
                        // Diğer ayarlar...
                    });
                }
            });
            </script>
        </div>
        <?php
    }

    public function handle_scrape_request() {
        check_ajax_referer('genel_rss_nonce', 'nonce');
        if (!current_user_can('manage_options')) {
            wp_send_json_error('Yetkiniz yok!');
        }

        @set_time_limit(60);
        ini_set('memory_limit', '256M');
        
        $offset = isset($_POST['offset']) ? intval($_POST['offset']) : 0;
        $batch_size = 3;
        $result = $this->fetch_news_batch($offset, $batch_size);
        
        wp_send_json_success($result);
    }

    public function handle_connection_check() {
        check_ajax_referer('genel_rss_nonce', 'nonce');
        if (!current_user_can('manage_options')) {
            wp_send_json_error('Yetkiniz yok!');
        }

        // Bağlantı kontrol mantığı...
    }

    private function fetch_news_batch($offset, $batch_size) {
        // Güncellenmiş batch işleme...
    }

    private function process_source($source) {
        libxml_use_internal_errors(true);
        $rss_feed = simplexml_load_file($source['rss_url']);
        
        if (!$rss_feed) {
            $errors = libxml_get_errors();
            error_log('RSS Hatası: ' . print_r($errors, true));
            return false;
        }

        // Güncellenmiş post kontrolü ve kategori işleme
        foreach ($rss_feed->channel->item as $item) {
            $guid = (string)$item->guid;
            if (post_exists($item->title, '', '', 'post', $guid)) {
                continue;
            }

            // Kategori işleme (case-insensitive)
            $categories = array_map('strtolower', explode(',', $source['categories']));
            $category_ids = array();
            foreach ($categories as $cat_name) {
                $cat_name = trim($cat_name);
                // Kategori oluşturma...
            }

            // Görsel işleme (güncellenmiş regex)
            if (preg_match('/https?:\/\/[^\s"\'<>]+\.(jpg|jpeg|png|gif)(?:\?[^\s"\'<>]*)?/i', $content, $matches)) {
                $image_url = $matches[0];
            }

            // Post oluşturma ve etiket işleme...
        }
    }

    private function extract_tags_from_content($content) {
        // Güncellenmiş etiket çıkarma mantığı...
    }
}

new Genel_RSS_Haber_Scraper();
muratca61
Site Admin
Mesajlar: 35899
Kayıt: Cmt Ara 21, 2024 7:56 am

Re: genel rss ekleme uygulaması wordpress

Mesaj gönderen muratca61 »

selam. şu kodu şu şekilde güncelleyebilir miyiz. sayfada tıklama görünce her seferinde farklı rss sorgulacak. sorgulanan rss de başlık sistemimdeki başlığı kontrol edecek. mevcut değilse haberi çekecek.
şimdilik iyi görünüyor
kontrol ettiğimde aynı haberleri tekrar çekebiliyor yani başlık kontrolü yapmıyor şu an

Kod:Tümünü seç

<?php
/*
Plugin Name: Genel RSS Haber Scraper
Description: Excel benzeri tablo üzerinden RSS kaynaklarını ekleyip, RSS haberlerini çekmenize olanak tanır. Ayarlarda; RSS adresi, kategoriler, RSS haber etiket kodu, link eklenip eklenmeyeceği, resim HTML kodu ve bağlantı kontrolü yapabilirsiniz. Ayrıca, yazı içeriğinden cümle başları hariç büyük harfli olan ve en çok geçen kelimelerden otomatik 5 etiket oluşturur. Görsel URL’leri için <img src="..."> içindeki .jpg gibi URL’lerde, query string kısmı hariç çekilir.
Version: 1.3
Author: Örnek Geliştirici
License: GPL2
*/

if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

class Genel_RSS_Haber_Scraper {
    private $option_name = 'genel_rss_haber_scraper_sources';

    public function __construct() {
        add_action( 'admin_menu', array( $this, 'add_admin_menu' ) );
        add_action( 'admin_init', array( $this, 'register_settings' ) );
        add_action( 'wp_ajax_genel_rss_scrape', array( $this, 'handle_scrape_request' ) );
        add_action( 'wp_ajax_genel_rss_connection_check', array( $this, 'handle_connection_check' ) );
        add_action( 'wp_enqueue_scripts', array( $this, 'frontend_enqueue_scripts' ) );
        add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
    }

    public function add_admin_menu() {
        add_menu_page(
            'Genel RSS Haber Scraper',
            'RSS Haber Scraper',
            'manage_options',
            'genel-rss-haber-scraper',
            array( $this, 'admin_page' ),
            'dashicons-rss',
            20
        );
    }

    public function register_settings() {
        register_setting( 'genel_rss_haber_scraper_options', $this->option_name );
    }

    public function admin_enqueue_scripts( $hook ) {
        if ( $hook == 'toplevel_page_genel-rss-haber-scraper' ) {
            wp_enqueue_script(
                'genel-rss-admin',
                plugin_dir_url( __FILE__ ) . 'js/genel-rss-admin.js',
                array( 'jquery' ),
                '1.0',
                true
            );
            wp_localize_script( 'genel-rss-admin', 'genelRssAdmin', array(
                'ajax_url' => admin_url( 'admin-ajax.php' )
            ) );
        }
    }

    public function frontend_enqueue_scripts() {
        wp_enqueue_script(
            'genel-rss-frontend',
            plugin_dir_url( __FILE__ ) . 'js/genel-rss-frontend.js',
            array( 'jquery' ),
            '1.0',
            true
        );
        wp_localize_script( 'genel-rss-frontend', 'genelRssAjax', array(
            'ajax_url' => admin_url( 'admin-ajax.php' )
        ) );
    }

    public function admin_page() {
        $sources = get_option( $this->option_name, array() );
        ?>
        <div class="wrap">
            <h1>Genel RSS Haber Scraper</h1>
            <form method="post" action="options.php">
                <?php settings_fields( 'genel_rss_haber_scraper_options' ); ?>
                <table class="widefat" id="rss-sources-table">
                    <thead>
                        <tr>
                            <th>RSS Adresi</th>
                            <th>Kategoriler (virgülle ayrılmış)</th>
                            <th>RSS Haber Etiket</th>
                            <th>Link Eklensin mi?</th>
                            <th>Resim HTML Kodu</th>
                            <th>Bağlantı Kontrol</th>
                            <th>İşlem</th>
                        </tr>
                    </thead>
                    <tbody>
                        <?php 
                        if ( ! empty( $sources ) ) {
                            foreach ( $sources as $index => $source ) {
                                $rss_url    = isset( $source['rss_url'] ) ? $source['rss_url'] : '';
                                $categories = isset( $source['categories'] ) ? $source['categories'] : '';
                                $tag        = isset( $source['tag'] ) ? $source['tag'] : '';
                                $add_link   = isset( $source['add_link'] ) ? $source['add_link'] : '';
                                $image_html = isset( $source['image_html'] ) ? $source['image_html'] : '';
                                ?>
                                <tr>
                                    <td>
                                        <input type="text" name="<?php echo $this->option_name; ?>[<?php echo $index; ?>][rss_url]" value="<?php echo esc_attr( $rss_url ); ?>" size="40" />
                                    </td>
                                    <td>
                                        <input type="text" name="<?php echo $this->option_name; ?>[<?php echo $index; ?>][categories]" value="<?php echo esc_attr( $categories ); ?>" size="30" placeholder="Kategori1,Kategori2" />
                                    </td>
                                    <td>
                                        <input type="text" name="<?php echo $this->option_name; ?>[<?php echo $index; ?>][tag]" value="<?php echo esc_attr( $tag ); ?>" size="10" placeholder="item veya entry" />
                                    </td>
                                    <td>
                                        <input type="checkbox" name="<?php echo $this->option_name; ?>[<?php echo $index; ?>][add_link]" value="1" <?php checked( $add_link, 1 ); ?> />
                                    </td>
                                    <td>
                                        <input type="text" name="<?php echo $this->option_name; ?>[<?php echo $index; ?>][image_html]" value="<?php echo esc_attr( $image_html ); ?>" size="30" placeholder="<img src='...' />" />
                                    </td>
                                    <td>
                                        <button class="button connection-check" data-row-index="<?php echo $index; ?>">Bağlantıyı Kontrol Et</button>
                                        <span class="connection-result" id="conn-result-<?php echo $index; ?>"></span>
                                    </td>
                                    <td>
                                        <button class="button remove-row">Kaldır</button>
                                    </td>
                                </tr>
                                <?php
                            }
                        }
                        ?>
                    </tbody>
                </table>
                <p>
                    <button type="button" class="button" id="add-row">Yeni Satır Ekle</button>
                </p>
                <?php submit_button(); ?>
            </form>
            <hr>
            <h2>Manuel Haber Çekme</h2>
            <p>Her tıklamada, listede sıradaki RSS kaynağı sorgulanır ve henüz eklenmemiş (sistemde aynı guid veya başlık yoksa) haberlerden belirlenen adette (örnekte <code>$news_limit</code> ile ayarlanıyor) haber çekilir.</p>
            <button id="fetch-rss-news" class="button button-primary">Haberleri Çek</button>
            <div id="rss-news-log" style="margin-top:20px;padding:10px;background:#f9f9f9;border:1px solid #ddd;max-height:300px;overflow-y:auto;"></div>
            <script>
            jQuery(document).ready(function($) {
                var currentSourceIndex = 0;
                var log = $('#rss-news-log');
                $('#fetch-rss-news').on('click', function() {
                    log.append('<p>RSS kaynağı sorgulanıyor (index: ' + currentSourceIndex + ')...</p>');
                    $.ajax({
                        url: ajaxurl,
                        type: 'POST',
                        data: { action: 'genel_rss_scrape', source_index: currentSourceIndex },
                        success: function(response) {
                            console.log(response);
                            if(response.success) {
                                currentSourceIndex = response.data.next_source_index;
                                log.append('<p style="color:green;">' + response.data.message + '</p>');
                            } else {
                                log.append('<p style="color:red;">' + response.data.message + '</p>');
                            }
                        },
                        error: function() {
                            log.append('<p style="color:red;">Bağlantı hatası!</p>');
                        }
                    });
                });
            });
            </script>
        </div>
        <?php
    }

    public function handle_scrape_request() {
        @set_time_limit(30);
        ini_set('default_socket_timeout', 15);

        $source_index = isset( $_POST['source_index'] ) ? intval( $_POST['source_index'] ) : 0;
        $sources = get_option( $this->option_name, array() );
        $total = count( $sources );
        if ( $total === 0 ) {
            wp_send_json_error( array( 'message' => 'RSS kaynakları bulunamadı.' ) );
        }
        if ( $source_index >= $total ) {
            $source_index = 0;
        }
        $news_limit = 1; // Her sorguda çekilecek haber adedi
        $inserted = $this->process_source( $sources[ $source_index ], $news_limit );
        
        $message = $inserted > 0 ? $inserted . ' yeni haber eklendi.' : 'Yeni haber bulunamadı.';
        $next_source_index = ($source_index + 1) % $total;
        
        wp_send_json_success( array( 
            'message' => $message,
            'next_source_index' => $next_source_index
        ) );
    }

    public function handle_connection_check() {
        $rss_url = isset( $_POST['rss_url'] ) ? esc_url_raw( $_POST['rss_url'] ) : '';
        $tag     = isset( $_POST['tag'] ) ? sanitize_text_field( $_POST['tag'] ) : '';

        if ( empty( $rss_url ) || empty( $tag ) ) {
            wp_send_json_error( array( 'message' => 'RSS URL ve Etiket bilgisi gerekli.' ) );
        }

        $rss_feed = @simplexml_load_file( $rss_url );
        if ( ! $rss_feed ) {
            wp_send_json_error( array( 'message' => 'RSS beslemesi yüklenemedi.' ) );
        }

        if ( $tag === 'item' && isset( $rss_feed->channel->item ) ) {
            wp_send_json_success( array( 'message' => 'Bağlantı başarılı: <item> bulundu.' ) );
        } elseif ( $tag === 'entry' && isset( $rss_feed->entry ) ) {
            wp_send_json_success( array( 'message' => 'Bağlantı başarılı: <entry> bulundu.' ) );
        } else {
            wp_send_json_error( array( 'message' => 'Belirtilen etiket bulunamadı.' ) );
        }
    }

    private function process_source( $source, $limit = 1 ) {
        require_once( ABSPATH . 'wp-admin/includes/post.php' );
        $rss_url        = isset( $source['rss_url'] ) ? trim( $source['rss_url'] ) : '';
        $categories_str = isset( $source['categories'] ) ? trim( $source['categories'] ) : '';
        $tag            = isset( $source['tag'] ) ? trim( $source['tag'] ) : '';
        $add_link       = isset( $source['add_link'] ) ? $source['add_link'] : 0;
        $image_html     = isset( $source['image_html'] ) ? trim( $source['image_html'] ) : '';

        if ( empty( $rss_url ) || empty( $tag ) ) {
            return 0;
        }

        $rss_feed = @simplexml_load_file( $rss_url );
        if ( ! $rss_feed ) {
            error_log( 'RSS yüklenemedi: ' . $rss_url );
            return 0;
        }

        $inserted = 0;
        // --- RSS item yapısı ---
        if ( $tag === 'item' && isset( $rss_feed->channel->item ) ) {
            foreach ( $rss_feed->channel->item as $item ) {
                if ( $inserted >= $limit ) break;
                $title = trim( (string) $item->title );
                
                // Guid kontrolü (varsa)
                $guid = isset( $item->guid ) ? trim( (string) $item->guid ) : '';
                if ( ! empty( $guid ) ) {
                    $existing = new WP_Query( array(
                        'post_type'  => 'post',
                        'meta_key'   => '_rss_guid',
                        'meta_value' => $guid,
                        'fields'     => 'ids'
                    ) );
                    if ( $existing->have_posts() ) {
                        continue;
                    }
                } else {
                    if ( post_exists( $title ) ) {
                        continue;
                    }
                }

                $link        = (string) $item->link;
                $description = (string) strip_tags( $item->description );
                $content     = isset( $item->children( 'content', true )->encoded ) ? (string) strip_tags( $item->children( 'content', true )->encoded ) : '';
                $image_url   = isset( $item->enclosure['url'] ) ? (string) $item->enclosure['url'] : '';

                if ( empty( $image_url ) ) {
                    $combined_text = $description . ' ' . $content;
                    if ( preg_match( '/(https?:\/\/[^\s"\']+\.(?:png|jpg|webp))(\?[^\s"\']*)?/i', $combined_text, $matches ) ) {
                        $image_url = $matches[1];
                    }
                }

                if ( empty( $title ) || ( empty( $content ) && empty( $description ) ) ) {
                    continue;
                }

                $post_content = '<p>' . esc_html( $description ) . '</p><p>' . esc_html( $content ) . '</p>';
                if ( $add_link ) {
                    $post_content .= '<p><a href="' . esc_url( $link ) . '" target="_blank" rel="noopener noreferrer">Kaynak</a></p>';
                }
                $category_ids = array();
                if ( ! empty( $categories_str ) ) {
                    $categories = array_map( 'trim', explode( ',', $categories_str ) );
                    foreach ( $categories as $cat_name ) {
                        $cat_id = get_cat_ID( $cat_name );
                        if ( ! $cat_id ) {
                            $cat_id = wp_create_category( $cat_name );
                        }
                        $category_ids[] = $cat_id;
                    }
                }
                $post_id = wp_insert_post( array(
                    'post_title'    => wp_strip_all_tags( $title ),
                    'post_content'  => $post_content,
                    'post_status'   => 'publish',
                    'post_author'   => 1,
                    'post_category' => $category_ids,
                    'post_type'     => 'post'
                ) );
                if ( ! is_wp_error( $post_id ) ) {
                    if ( ! empty( $image_url ) ) {
                        require_once( ABSPATH . 'wp-admin/includes/media.php' );
                        require_once( ABSPATH . 'wp-admin/includes/file.php' );
                        require_once( ABSPATH . 'wp-admin/includes/image.php' );
                        $attachment_id = media_sideload_image( $image_url, $post_id, $title, 'id' );
                        if ( ! is_wp_error( $attachment_id ) ) {
                            set_post_thumbnail( $post_id, $attachment_id );
                        }
                    }
                    if ( ! empty( $image_html ) ) {
                        $post_content .= "\n" . $image_html;
                        wp_update_post( array(
                            'ID'           => $post_id,
                            'post_content' => $post_content
                        ) );
                    }
                    $tags = $this->extract_tags_from_content( $description . ' ' . $content );
                    if ( ! empty( $tags ) ) {
                        wp_set_post_tags( $post_id, $tags );
                    }
                    if ( ! empty( $guid ) ) {
                        update_post_meta( $post_id, '_rss_guid', $guid );
                    }
                    $inserted++;
                }
            }
        }
        // --- RSS entry yapısı ---
        elseif ( $tag === 'entry' && isset( $rss_feed->entry ) ) {
            foreach ( $rss_feed->entry as $entry ) {
                if ( $inserted >= $limit ) break;
                $title = trim( (string) $entry->title );
                
                // Guid veya ID kontrolü (varsa)
                $guid = isset( $entry->id ) ? trim( (string) $entry->id ) : '';
                if ( ! empty( $guid ) ) {
                    $existing = new WP_Query( array(
                        'post_type'  => 'post',
                        'meta_key'   => '_rss_guid',
                        'meta_value' => $guid,
                        'fields'     => 'ids'
                    ) );
                    if ( $existing->have_posts() ) {
                        continue;
                    }
                } else {
                    if ( post_exists( $title ) ) {
                        continue;
                    }
                }

                $link = '';
                if ( isset( $entry->link ) ) {
                    foreach ( $entry->link as $l ) {
                        $attributes = $l->attributes();
                        if ( isset( $attributes['rel'] ) && (string) $attributes['rel'] === 'alternate' ) {
                            $link = (string) $attributes['href'];
                            break;
                        }
                    }
                    if ( empty( $link ) ) {
                        $link = (string) $entry->link;
                    }
                }
                $description = isset( $entry->summary ) ? (string) strip_tags( $entry->summary ) : '';
                $content     = isset( $entry->content ) ? (string) strip_tags( $entry->content ) : '';
                $image_url   = '';

                if ( empty( $image_url ) ) {
                    $combined_text = $description . ' ' . $content;
                    if ( preg_match( '/(https?:\/\/[^\s"\']+\.(?:png|jpg|webp))(\?[^\s"\']*)?/i', $combined_text, $matches ) ) {
                        $image_url = $matches[1];
                    }
                }

                if ( empty( $title ) || ( empty( $content ) && empty( $description ) ) ) {
                    continue;
                }

                $post_content = '<p>' . esc_html( $description ) . '</p><p>' . esc_html( $content ) . '</p>';
                if ( $add_link ) {
                    $post_content .= '<p><a href="' . esc_url( $link ) . '" target="_blank" rel="noopener noreferrer">Kaynak</a></p>';
                }
                $category_ids = array();
                if ( ! empty( $categories_str ) ) {
                    $categories = array_map( 'trim', explode( ',', $categories_str ) );
                    foreach ( $categories as $cat_name ) {
                        $cat_id = get_cat_ID( $cat_name );
                        if ( ! $cat_id ) {
                            $cat_id = wp_create_category( $cat_name );
                        }
                        $category_ids[] = $cat_id;
                    }
                }
                $post_id = wp_insert_post( array(
                    'post_title'    => wp_strip_all_tags( $title ),
                    'post_content'  => $post_content,
                    'post_status'   => 'publish',
                    'post_author'   => 1,
                    'post_category' => $category_ids,
                    'post_type'     => 'post'
                ) );
                if ( ! is_wp_error( $post_id ) ) {
                    if ( ! empty( $image_url ) ) {
                        require_once( ABSPATH . 'wp-admin/includes/media.php' );
                        require_once( ABSPATH . 'wp-admin/includes/file.php' );
                        require_once( ABSPATH . 'wp-admin/includes/image.php' );
                        $attachment_id = media_sideload_image( $image_url, $post_id, $title, 'id' );
                        if ( ! is_wp_error( $attachment_id ) ) {
                            set_post_thumbnail( $post_id, $attachment_id );
                        }
                    }
                    $tags = $this->extract_tags_from_content( $description . ' ' . $content );
                    if ( ! empty( $tags ) ) {
                        wp_set_post_tags( $post_id, $tags );
                    }
                    if ( ! empty( $guid ) ) {
                        update_post_meta( $post_id, '_rss_guid', $guid );
                    }
                    $inserted++;
                }
            }
        }
        return $inserted;
    }

    private function extract_tags_from_content( $content ) {
        $sentences = preg_split( '/(?<=[.?!])\s+/', $content, -1, PREG_SPLIT_NO_EMPTY );
        $words = array();
        foreach ( $sentences as $sentence ) {
            $sentence_words = preg_split( '/\s+/', $sentence, -1, PREG_SPLIT_NO_EMPTY );
            if ( count( $sentence_words ) > 1 ) {
                for ( $i = 1; $i < count( $sentence_words ); $i++ ) {
                    $words[] = $sentence_words[$i];
                }
            }
        }
        $filtered = array();
        foreach ( $words as $word ) {
            $clean = trim( $word, ".,!?()[]{}\"'" );
            if ( strlen( $clean ) > 2 && ctype_upper( substr( $clean, 0, 1 ) ) ) {
                $filtered[] = $clean;
            }
        }
        $freq = array();
        foreach ( $filtered as $w ) {
            $key = strtolower( $w );
            if ( isset( $freq[ $key ] ) ) {
                $freq[ $key ]++;
            } else {
                $freq[ $key ] = 1;
            }
        }
        arsort( $freq );
        $top_tags = array_slice( array_keys( $freq ), 0, 5 );
        return $top_tags;
    }
}

new Genel_RSS_Haber_Scraper();
muratca61
Site Admin
Mesajlar: 35899
Kayıt: Cmt Ara 21, 2024 7:56 am

Re: genel rss ekleme uygulaması wordpress

Mesaj gönderen muratca61 »

olmadı
aynı başlık kontrolü yaptığını söylüyor

Kod:Tümünü seç

<?php
/*
Plugin Name: Genel RSS Haber Scraper
Description: Excel benzeri tablo üzerinden RSS kaynaklarını ekleyip, RSS haberlerini çekmenize olanak tanır. Ayarlarda; RSS adresi, kategoriler, RSS haber etiket kodu, link eklenip eklenmeyeceği, resim HTML kodu ve bağlantı kontrolü yapabilirsiniz. Ayrıca, yazı içeriğinden cümle başları hariç büyük harfli olan ve en çok geçen kelimelerden otomatik 5 etiket oluşturur. Görsel URL’leri için <img src="..."> içindeki .jpg gibi URL’lerde, query string kısmı hariç çekilir.
Version: 1.4
Author: Örnek Geliştirici
License: GPL2
*/

if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

class Genel_RSS_Haber_Scraper {
    private $option_name = 'genel_rss_haber_scraper_sources';

    public function __construct() {
        add_action( 'admin_menu', array( $this, 'add_admin_menu' ) );
        add_action( 'admin_init', array( $this, 'register_settings' ) );
        add_action( 'wp_ajax_genel_rss_scrape', array( $this, 'handle_scrape_request' ) );
        add_action( 'wp_ajax_genel_rss_connection_check', array( $this, 'handle_connection_check' ) );
        add_action( 'wp_enqueue_scripts', array( $this, 'frontend_enqueue_scripts' ) );
        add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
    }

    public function add_admin_menu() {
        add_menu_page(
            'Genel RSS Haber Scraper',
            'RSS Haber Scraper',
            'manage_options',
            'genel-rss-haber-scraper',
            array( $this, 'admin_page' ),
            'dashicons-rss',
            20
        );
    }

    public function register_settings() {
        register_setting( 'genel_rss_haber_scraper_options', $this->option_name );
    }

    public function admin_enqueue_scripts( $hook ) {
        if ( $hook == 'toplevel_page_genel-rss-haber-scraper' ) {
            wp_enqueue_script(
                'genel-rss-admin',
                plugin_dir_url( __FILE__ ) . 'js/genel-rss-admin.js',
                array( 'jquery' ),
                '1.0',
                true
            );
            wp_localize_script( 'genel-rss-admin', 'genelRssAdmin', array(
                'ajax_url' => admin_url( 'admin-ajax.php' )
            ) );
        }
    }

    public function frontend_enqueue_scripts() {
        wp_enqueue_script(
            'genel-rss-frontend',
            plugin_dir_url( __FILE__ ) . 'js/genel-rss-frontend.js',
            array( 'jquery' ),
            '1.0',
            true
        );
        wp_localize_script( 'genel-rss-frontend', 'genelRssAjax', array(
            'ajax_url' => admin_url( 'admin-ajax.php' )
        ) );
    }

    public function admin_page() {
        $sources = get_option( $this->option_name, array() );
        ?>
        <div class="wrap">
            <h1>Genel RSS Haber Scraper</h1>
            <form method="post" action="options.php">
                <?php settings_fields( 'genel_rss_haber_scraper_options' ); ?>
                <table class="widefat" id="rss-sources-table">
                    <thead>
                        <tr>
                            <th>RSS Adresi</th>
                            <th>Kategoriler (virgülle ayrılmış)</th>
                            <th>RSS Haber Etiket</th>
                            <th>Link Eklensin mi?</th>
                            <th>Resim HTML Kodu</th>
                            <th>Bağlantı Kontrol</th>
                            <th>İşlem</th>
                        </tr>
                    </thead>
                    <tbody>
                        <?php 
                        if ( ! empty( $sources ) ) {
                            foreach ( $sources as $index => $source ) {
                                $rss_url    = isset( $source['rss_url'] ) ? $source['rss_url'] : '';
                                $categories = isset( $source['categories'] ) ? $source['categories'] : '';
                                $tag        = isset( $source['tag'] ) ? $source['tag'] : '';
                                $add_link   = isset( $source['add_link'] ) ? $source['add_link'] : '';
                                $image_html = isset( $source['image_html'] ) ? $source['image_html'] : '';
                                ?>
                                <tr>
                                    <td>
                                        <input type="text" name="<?php echo $this->option_name; ?>[<?php echo $index; ?>][rss_url]" value="<?php echo esc_attr( $rss_url ); ?>" size="40" />
                                    </td>
                                    <td>
                                        <input type="text" name="<?php echo $this->option_name; ?>[<?php echo $index; ?>][categories]" value="<?php echo esc_attr( $categories ); ?>" size="30" placeholder="Kategori1,Kategori2" />
                                    </td>
                                    <td>
                                        <input type="text" name="<?php echo $this->option_name; ?>[<?php echo $index; ?>][tag]" value="<?php echo esc_attr( $tag ); ?>" size="10" placeholder="item veya entry" />
                                    </td>
                                    <td>
                                        <input type="checkbox" name="<?php echo $this->option_name; ?>[<?php echo $index; ?>][add_link]" value="1" <?php checked( $add_link, 1 ); ?> />
                                    </td>
                                    <td>
                                        <input type="text" name="<?php echo $this->option_name; ?>[<?php echo $index; ?>][image_html]" value="<?php echo esc_attr( $image_html ); ?>" size="30" placeholder="<img src='...' />" />
                                    </td>
                                    <td>
                                        <button class="button connection-check" data-row-index="<?php echo $index; ?>">Bağlantıyı Kontrol Et</button>
                                        <span class="connection-result" id="conn-result-<?php echo $index; ?>"></span>
                                    </td>
                                    <td>
                                        <button class="button remove-row">Kaldır</button>
                                    </td>
                                </tr>
                                <?php
                            }
                        }
                        ?>
                    </tbody>
                </table>
                <p>
                    <button type="button" class="button" id="add-row">Yeni Satır Ekle</button>
                </p>
                <?php submit_button(); ?>
            </form>
            <hr>
            <h2>Manuel Haber Çekme</h2>
            <p>Her tıklamada, listede sıradaki RSS kaynağı sorgulanır ve henüz eklenmemiş (sistemde aynı guid veya başlık yoksa) haberlerden belirlenen adette (örnekte <code>$news_limit</code> ile ayarlanıyor) haber çekilir.</p>
            <button id="fetch-rss-news" class="button button-primary">Haberleri Çek</button>
            <div id="rss-news-log" style="margin-top:20px;padding:10px;background:#f9f9f9;border:1px solid #ddd;max-height:300px;overflow-y:auto;"></div>
            <script>
            jQuery(document).ready(function($) {
                var currentSourceIndex = 0;
                var log = $('#rss-news-log');
                $('#fetch-rss-news').on('click', function() {
                    log.append('<p>RSS kaynağı sorgulanıyor (index: ' + currentSourceIndex + ')...</p>');
                    $.ajax({
                        url: ajaxurl,
                        type: 'POST',
                        data: { action: 'genel_rss_scrape', source_index: currentSourceIndex },
                        success: function(response) {
                            console.log(response);
                            if(response.success) {
                                currentSourceIndex = response.data.next_source_index;
                                log.append('<p style="color:green;">' + response.data.message + '</p>');
                            } else {
                                log.append('<p style="color:red;">' + response.data.message + '</p>');
                            }
                        },
                        error: function() {
                            log.append('<p style="color:red;">Bağlantı hatası!</p>');
                        }
                    });
                });
            });
            </script>
        </div>
        <?php
    }

    public function handle_scrape_request() {
        @set_time_limit(30);
        ini_set('default_socket_timeout', 15);

        $source_index = isset( $_POST['source_index'] ) ? intval( $_POST['source_index'] ) : 0;
        $sources = get_option( $this->option_name, array() );
        $total = count( $sources );
        if ( $total === 0 ) {
            wp_send_json_error( array( 'message' => 'RSS kaynakları bulunamadı.' ) );
        }
        if ( $source_index >= $total ) {
            $source_index = 0;
        }
        $news_limit = 1; // Her sorguda çekilecek haber adedi
        $inserted = $this->process_source( $sources[ $source_index ], $news_limit );
        
        $message = $inserted > 0 ? $inserted . ' yeni haber eklendi.' : 'Yeni haber bulunamadı.';
        $next_source_index = ($source_index + 1) % $total;
        
        wp_send_json_success( array( 
            'message' => $message,
            'next_source_index' => $next_source_index
        ) );
    }

    public function handle_connection_check() {
        $rss_url = isset( $_POST['rss_url'] ) ? esc_url_raw( $_POST['rss_url'] ) : '';
        $tag     = isset( $_POST['tag'] ) ? sanitize_text_field( $_POST['tag'] ) : '';

        if ( empty( $rss_url ) || empty( $tag ) ) {
            wp_send_json_error( array( 'message' => 'RSS URL ve Etiket bilgisi gerekli.' ) );
        }

        $rss_feed = @simplexml_load_file( $rss_url );
        if ( ! $rss_feed ) {
            wp_send_json_error( array( 'message' => 'RSS beslemesi yüklenemedi.' ) );
        }

        if ( $tag === 'item' && isset( $rss_feed->channel->item ) ) {
            wp_send_json_success( array( 'message' => 'Bağlantı başarılı: <item> bulundu.' ) );
        } elseif ( $tag === 'entry' && isset( $rss_feed->entry ) ) {
            wp_send_json_success( array( 'message' => 'Bağlantı başarılı: <entry> bulundu.' ) );
        } else {
            wp_send_json_error( array( 'message' => 'Belirtilen etiket bulunamadı.' ) );
        }
    }

    private function process_source( $source, $limit = 1 ) {
        require_once( ABSPATH . 'wp-admin/includes/post.php' );
        $rss_url        = isset( $source['rss_url'] ) ? trim( $source['rss_url'] ) : '';
        $categories_str = isset( $source['categories'] ) ? trim( $source['categories'] ) : '';
        $tag            = isset( $source['tag'] ) ? trim( $source['tag'] ) : '';
        $add_link       = isset( $source['add_link'] ) ? $source['add_link'] : 0;
        $image_html     = isset( $source['image_html'] ) ? trim( $source['image_html'] ) : '';

        if ( empty( $rss_url ) || empty( $tag ) ) {
            return 0;
        }

        $rss_feed = @simplexml_load_file( $rss_url );
        if ( ! $rss_feed ) {
            error_log( 'RSS yüklenemedi: ' . $rss_url );
            return 0;
        }

        $inserted = 0;
        // --- RSS item yapısı ---
        if ( $tag === 'item' && isset( $rss_feed->channel->item ) ) {
            foreach ( $rss_feed->channel->item as $item ) {
                if ( $inserted >= $limit ) break;
                $title = trim( (string) $item->title );
                $normalized_title = wp_strip_all_tags( $title );
                
                // Guid kontrolü (varsa)
                $guid = isset( $item->guid ) ? trim( (string) $item->guid ) : '';
                if ( ! empty( $guid ) ) {
                    $existing = new WP_Query( array(
                        'post_type'  => 'post',
                        'meta_key'   => '_rss_guid',
                        'meta_value' => $guid,
                        'fields'     => 'ids'
                    ) );
                    if ( $existing->have_posts() ) {
                        continue;
                    }
                } else {
                    // Guid yoksa başlığa göre kontrol (normalize edilmiş başlık)
                    if ( get_page_by_title( $normalized_title, OBJECT, 'post' ) ) {
                        continue;
                    }
                }

                $link        = (string) $item->link;
                $description = (string) strip_tags( $item->description );
                $content     = isset( $item->children( 'content', true )->encoded ) ? (string) strip_tags( $item->children( 'content', true )->encoded ) : '';
                $image_url   = isset( $item->enclosure['url'] ) ? (string) $item->enclosure['url'] : '';

                if ( empty( $image_url ) ) {
                    $combined_text = $description . ' ' . $content;
                    if ( preg_match( '/(https?:\/\/[^\s"\']+\.(?:png|jpg|webp))(\?[^\s"\']*)?/i', $combined_text, $matches ) ) {
                        $image_url = $matches[1];
                    }
                }

                if ( empty( $title ) || ( empty( $content ) && empty( $description ) ) ) {
                    continue;
                }

                $post_content = '<p>' . esc_html( $description ) . '</p><p>' . esc_html( $content ) . '</p>';
                if ( $add_link ) {
                    $post_content .= '<p><a href="' . esc_url( $link ) . '" target="_blank" rel="noopener noreferrer">Kaynak</a></p>';
                }
                $category_ids = array();
                if ( ! empty( $categories_str ) ) {
                    $categories = array_map( 'trim', explode( ',', $categories_str ) );
                    foreach ( $categories as $cat_name ) {
                        $cat_id = get_cat_ID( $cat_name );
                        if ( ! $cat_id ) {
                            $cat_id = wp_create_category( $cat_name );
                        }
                        $category_ids[] = $cat_id;
                    }
                }
                $post_id = wp_insert_post( array(
                    'post_title'    => $normalized_title,
                    'post_content'  => $post_content,
                    'post_status'   => 'publish',
                    'post_author'   => 1,
                    'post_category' => $category_ids,
                    'post_type'     => 'post'
                ) );
                if ( ! is_wp_error( $post_id ) ) {
                    if ( ! empty( $image_url ) ) {
                        require_once( ABSPATH . 'wp-admin/includes/media.php' );
                        require_once( ABSPATH . 'wp-admin/includes/file.php' );
                        require_once( ABSPATH . 'wp-admin/includes/image.php' );
                        $attachment_id = media_sideload_image( $image_url, $post_id, $title, 'id' );
                        if ( ! is_wp_error( $attachment_id ) ) {
                            set_post_thumbnail( $post_id, $attachment_id );
                        }
                    }
                    if ( ! empty( $image_html ) ) {
                        $post_content .= "\n" . $image_html;
                        wp_update_post( array(
                            'ID'           => $post_id,
                            'post_content' => $post_content
                        ) );
                    }
                    $tags = $this->extract_tags_from_content( $description . ' ' . $content );
                    if ( ! empty( $tags ) ) {
                        wp_set_post_tags( $post_id, $tags );
                    }
                    if ( ! empty( $guid ) ) {
                        update_post_meta( $post_id, '_rss_guid', $guid );
                    }
                    $inserted++;
                }
            }
        }
        // --- RSS entry yapısı ---
        elseif ( $tag === 'entry' && isset( $rss_feed->entry ) ) {
            foreach ( $rss_feed->entry as $entry ) {
                if ( $inserted >= $limit ) break;
                $title = trim( (string) $entry->title );
                $normalized_title = wp_strip_all_tags( $title );
                
                // Guid veya ID kontrolü (varsa)
                $guid = isset( $entry->id ) ? trim( (string) $entry->id ) : '';
                if ( ! empty( $guid ) ) {
                    $existing = new WP_Query( array(
                        'post_type'  => 'post',
                        'meta_key'   => '_rss_guid',
                        'meta_value' => $guid,
                        'fields'     => 'ids'
                    ) );
                    if ( $existing->have_posts() ) {
                        continue;
                    }
                } else {
                    if ( get_page_by_title( $normalized_title, OBJECT, 'post' ) ) {
                        continue;
                    }
                }

                $link = '';
                if ( isset( $entry->link ) ) {
                    foreach ( $entry->link as $l ) {
                        $attributes = $l->attributes();
                        if ( isset( $attributes['rel'] ) && (string) $attributes['rel'] === 'alternate' ) {
                            $link = (string) $attributes['href'];
                            break;
                        }
                    }
                    if ( empty( $link ) ) {
                        $link = (string) $entry->link;
                    }
                }
                $description = isset( $entry->summary ) ? (string) strip_tags( $entry->summary ) : '';
                $content     = isset( $entry->content ) ? (string) strip_tags( $entry->content ) : '';
                $image_url   = '';

                if ( empty( $image_url ) ) {
                    $combined_text = $description . ' ' . $content;
                    if ( preg_match( '/(https?:\/\/[^\s"\']+\.(?:png|jpg|webp))(\?[^\s"\']*)?/i', $combined_text, $matches ) ) {
                        $image_url = $matches[1];
                    }
                }

                if ( empty( $title ) || ( empty( $content ) && empty( $description ) ) ) {
                    continue;
                }

                $post_content = '<p>' . esc_html( $description ) . '</p><p>' . esc_html( $content ) . '</p>';
                if ( $add_link ) {
                    $post_content .= '<p><a href="' . esc_url( $link ) . '" target="_blank" rel="noopener noreferrer">Kaynak</a></p>';
                }
                $category_ids = array();
                if ( ! empty( $categories_str ) ) {
                    $categories = array_map( 'trim', explode( ',', $categories_str ) );
                    foreach ( $categories as $cat_name ) {
                        $cat_id = get_cat_ID( $cat_name );
                        if ( ! $cat_id ) {
                            $cat_id = wp_create_category( $cat_name );
                        }
                        $category_ids[] = $cat_id;
                    }
                }
                $post_id = wp_insert_post( array(
                    'post_title'    => $normalized_title,
                    'post_content'  => $post_content,
                    'post_status'   => 'publish',
                    'post_author'   => 1,
                    'post_category' => $category_ids,
                    'post_type'     => 'post'
                ) );
                if ( ! is_wp_error( $post_id ) ) {
                    if ( ! empty( $image_url ) ) {
                        require_once( ABSPATH . 'wp-admin/includes/media.php' );
                        require_once( ABSPATH . 'wp-admin/includes/file.php' );
                        require_once( ABSPATH . 'wp-admin/includes/image.php' );
                        $attachment_id = media_sideload_image( $image_url, $post_id, $title, 'id' );
                        if ( ! is_wp_error( $attachment_id ) ) {
                            set_post_thumbnail( $post_id, $attachment_id );
                        }
                    }
                    $tags = $this->extract_tags_from_content( $description . ' ' . $content );
                    if ( ! empty( $tags ) ) {
                        wp_set_post_tags( $post_id, $tags );
                    }
                    if ( ! empty( $guid ) ) {
                        update_post_meta( $post_id, '_rss_guid', $guid );
                    }
                    $inserted++;
                }
            }
        }
        return $inserted;
    }

    private function extract_tags_from_content( $content ) {
        $sentences = preg_split( '/(?<=[.?!])\s+/', $content, -1, PREG_SPLIT_NO_EMPTY );
        $words = array();
        foreach ( $sentences as $sentence ) {
            $sentence_words = preg_split( '/\s+/', $sentence, -1, PREG_SPLIT_NO_EMPTY );
            if ( count( $sentence_words ) > 1 ) {
                for ( $i = 1; $i < count( $sentence_words ); $i++ ) {
                    $words[] = $sentence_words[$i];
                }
            }
        }
        $filtered = array();
        foreach ( $words as $word ) {
            $clean = trim( $word, ".,!?()[]{}\"'" );
            if ( strlen( $clean ) > 2 && ctype_upper( substr( $clean, 0, 1 ) ) ) {
                $filtered[] = $clean;
            }
        }
        $freq = array();
        foreach ( $filtered as $w ) {
            $key = strtolower( $w );
            if ( isset( $freq[ $key ] ) ) {
                $freq[ $key ]++;
            } else {
                $freq[ $key ] = 1;
            }
        }
        arsort( $freq );
        $top_tags = array_slice( array_keys( $freq ), 0, 5 );
        return $top_tags;
    }
}

new Genel_RSS_Haber_Scraper();
muratca61
Site Admin
Mesajlar: 35899
Kayıt: Cmt Ara 21, 2024 7:56 am

Re: genel rss ekleme uygulaması wordpress

Mesaj gönderen muratca61 »

olmadı
aynı başlık kontrolü yaptığını söylüyor

Kod:Tümünü seç

<?php
/*
Plugin Name: Genel RSS Haber Scraper
Description: Excel benzeri tablo üzerinden RSS kaynaklarını ekleyip, RSS haberlerini çekmenize olanak tanır. Ayarlarda; RSS adresi, kategoriler, RSS haber etiket kodu, link eklenip eklenmeyeceği, resim HTML kodu ve bağlantı kontrolü yapabilirsiniz. Ayrıca, yazı içeriğinden cümle başları hariç büyük harfli olan ve en çok geçen kelimelerden otomatik 5 etiket oluşturur. Görsel URL’leri için <img src="..."> içindeki .jpg gibi URL’lerde, query string kısmı hariç çekilir.
Version: 1.5
Author: Örnek Geliştirici
License: GPL2
*/

if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

class Genel_RSS_Haber_Scraper {
    private $option_name = 'genel_rss_haber_scraper_sources';

    public function __construct() {
        add_action( 'admin_menu', array( $this, 'add_admin_menu' ) );
        add_action( 'admin_init', array( $this, 'register_settings' ) );
        add_action( 'wp_ajax_genel_rss_scrape', array( $this, 'handle_scrape_request' ) );
        add_action( 'wp_ajax_genel_rss_connection_check', array( $this, 'handle_connection_check' ) );
        add_action( 'wp_enqueue_scripts', array( $this, 'frontend_enqueue_scripts' ) );
        add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
    }

    public function add_admin_menu() {
        add_menu_page(
            'Genel RSS Haber Scraper',
            'RSS Haber Scraper',
            'manage_options',
            'genel-rss-haber-scraper',
            array( $this, 'admin_page' ),
            'dashicons-rss',
            20
        );
    }

    public function register_settings() {
        register_setting( 'genel_rss_haber_scraper_options', $this->option_name );
    }

    public function admin_enqueue_scripts( $hook ) {
        if ( $hook == 'toplevel_page_genel-rss-haber-scraper' ) {
            wp_enqueue_script(
                'genel-rss-admin',
                plugin_dir_url( __FILE__ ) . 'js/genel-rss-admin.js',
                array( 'jquery' ),
                '1.0',
                true
            );
            wp_localize_script( 'genel-rss-admin', 'genelRssAdmin', array(
                'ajax_url' => admin_url( 'admin-ajax.php' )
            ) );
        }
    }

    public function frontend_enqueue_scripts() {
        wp_enqueue_script(
            'genel-rss-frontend',
            plugin_dir_url( __FILE__ ) . 'js/genel-rss-frontend.js',
            array( 'jquery' ),
            '1.0',
            true
        );
        wp_localize_script( 'genel-rss-frontend', 'genelRssAjax', array(
            'ajax_url' => admin_url( 'admin-ajax.php' )
        ) );
    }

    public function admin_page() {
        $sources = get_option( $this->option_name, array() );
        ?>
        <div class="wrap">
            <h1>Genel RSS Haber Scraper</h1>
            <form method="post" action="options.php">
                <?php settings_fields( 'genel_rss_haber_scraper_options' ); ?>
                <table class="widefat" id="rss-sources-table">
                    <thead>
                        <tr>
                            <th>RSS Adresi</th>
                            <th>Kategoriler (virgülle ayrılmış)</th>
                            <th>RSS Haber Etiket</th>
                            <th>Link Eklensin mi?</th>
                            <th>Resim HTML Kodu</th>
                            <th>Bağlantı Kontrol</th>
                            <th>İşlem</th>
                        </tr>
                    </thead>
                    <tbody>
                        <?php 
                        if ( ! empty( $sources ) ) {
                            foreach ( $sources as $index => $source ) {
                                $rss_url    = isset( $source['rss_url'] ) ? $source['rss_url'] : '';
                                $categories = isset( $source['categories'] ) ? $source['categories'] : '';
                                $tag        = isset( $source['tag'] ) ? $source['tag'] : '';
                                $add_link   = isset( $source['add_link'] ) ? $source['add_link'] : '';
                                $image_html = isset( $source['image_html'] ) ? $source['image_html'] : '';
                                ?>
                                <tr>
                                    <td>
                                        <input type="text" name="<?php echo $this->option_name; ?>[<?php echo $index; ?>][rss_url]" value="<?php echo esc_attr( $rss_url ); ?>" size="40" />
                                    </td>
                                    <td>
                                        <input type="text" name="<?php echo $this->option_name; ?>[<?php echo $index; ?>][categories]" value="<?php echo esc_attr( $categories ); ?>" size="30" placeholder="Kategori1,Kategori2" />
                                    </td>
                                    <td>
                                        <input type="text" name="<?php echo $this->option_name; ?>[<?php echo $index; ?>][tag]" value="<?php echo esc_attr( $tag ); ?>" size="10" placeholder="item veya entry" />
                                    </td>
                                    <td>
                                        <input type="checkbox" name="<?php echo $this->option_name; ?>[<?php echo $index; ?>][add_link]" value="1" <?php checked( $add_link, 1 ); ?> />
                                    </td>
                                    <td>
                                        <input type="text" name="<?php echo $this->option_name; ?>[<?php echo $index; ?>][image_html]" value="<?php echo esc_attr( $image_html ); ?>" size="30" placeholder="<img src='...' />" />
                                    </td>
                                    <td>
                                        <button class="button connection-check" data-row-index="<?php echo $index; ?>">Bağlantıyı Kontrol Et</button>
                                        <span class="connection-result" id="conn-result-<?php echo $index; ?>"></span>
                                    </td>
                                    <td>
                                        <button class="button remove-row">Kaldır</button>
                                    </td>
                                </tr>
                                <?php
                            }
                        }
                        ?>
                    </tbody>
                </table>
                <p>
                    <button type="button" class="button" id="add-row">Yeni Satır Ekle</button>
                </p>
                <?php submit_button(); ?>
            </form>
            <hr>
            <h2>Manuel Haber Çekme</h2>
            <p>Her tıklamada, listede sıradaki RSS kaynağı sorgulanır ve henüz eklenmemiş (sistemde aynı guid veya başlık yoksa) haberlerden belirlenen adette (örnekte <code>$news_limit</code> ile ayarlanıyor) haber çekilir.</p>
            <button id="fetch-rss-news" class="button button-primary">Haberleri Çek</button>
            <div id="rss-news-log" style="margin-top:20px;padding:10px;background:#f9f9f9;border:1px solid #ddd;max-height:300px;overflow-y:auto;"></div>
            <script>
            jQuery(document).ready(function($) {
                var currentSourceIndex = 0;
                var log = $('#rss-news-log');
                $('#fetch-rss-news').on('click', function() {
                    log.append('<p>RSS kaynağı sorgulanıyor (index: ' + currentSourceIndex + ')...</p>');
                    $.ajax({
                        url: ajaxurl,
                        type: 'POST',
                        data: { action: 'genel_rss_scrape', source_index: currentSourceIndex },
                        success: function(response) {
                            console.log(response);
                            if(response.success) {
                                currentSourceIndex = response.data.next_source_index;
                                log.append('<p style="color:green;">' + response.data.message + '</p>');
                            } else {
                                log.append('<p style="color:red;">' + response.data.message + '</p>');
                            }
                        },
                        error: function() {
                            log.append('<p style="color:red;">Bağlantı hatası!</p>');
                        }
                    });
                });
            });
            </script>
        </div>
        <?php
    }

    public function handle_scrape_request() {
        @set_time_limit(30);
        ini_set('default_socket_timeout', 15);

        $source_index = isset( $_POST['source_index'] ) ? intval( $_POST['source_index'] ) : 0;
        $sources = get_option( $this->option_name, array() );
        $total = count( $sources );
        if ( $total === 0 ) {
            wp_send_json_error( array( 'message' => 'RSS kaynakları bulunamadı.' ) );
        }
        if ( $source_index >= $total ) {
            $source_index = 0;
        }
        $news_limit = 1; // Her sorguda çekilecek haber adedi
        $inserted = $this->process_source( $sources[ $source_index ], $news_limit );
        
        $message = $inserted > 0 ? $inserted . ' yeni haber eklendi.' : 'Yeni haber bulunamadı.';
        $next_source_index = ($source_index + 1) % $total;
        
        wp_send_json_success( array( 
            'message' => $message,
            'next_source_index' => $next_source_index
        ) );
    }

    public function handle_connection_check() {
        $rss_url = isset( $_POST['rss_url'] ) ? esc_url_raw( $_POST['rss_url'] ) : '';
        $tag     = isset( $_POST['tag'] ) ? sanitize_text_field( $_POST['tag'] ) : '';

        if ( empty( $rss_url ) || empty( $tag ) ) {
            wp_send_json_error( array( 'message' => 'RSS URL ve Etiket bilgisi gerekli.' ) );
        }

        $rss_feed = @simplexml_load_file( $rss_url );
        if ( ! $rss_feed ) {
            wp_send_json_error( array( 'message' => 'RSS beslemesi yüklenemedi.' ) );
        }

        if ( $tag === 'item' && isset( $rss_feed->channel->item ) ) {
            wp_send_json_success( array( 'message' => 'Bağlantı başarılı: <item> bulundu.' ) );
        } elseif ( $tag === 'entry' && isset( $rss_feed->entry ) ) {
            wp_send_json_success( array( 'message' => 'Bağlantı başarılı: <entry> bulundu.' ) );
        } else {
            wp_send_json_error( array( 'message' => 'Belirtilen etiket bulunamadı.' ) );
        }
    }

    /**
     * RSS kaynağındaki haberleri, duplicate kontrolüyle birlikte ekler.
     * Duplicate kontrolü için:
     * - Eğer guid (veya entry için id) varsa, bu değere göre kontrol yapılır.
     * - Guid yoksa, başlık normalize edilerek ($title; küçük harf, trim, HTML temizleme)
     *   veritabanındaki post_title ile karşılaştırılır (CASE-INSENSITIVE).
     */
    private function process_source( $source, $limit = 1 ) {
        require_once( ABSPATH . 'wp-admin/includes/post.php' );
        $rss_url        = isset( $source['rss_url'] ) ? trim( $source['rss_url'] ) : '';
        $categories_str = isset( $source['categories'] ) ? trim( $source['categories'] ) : '';
        $tag            = isset( $source['tag'] ) ? trim( $source['tag'] ) : '';
        $add_link       = isset( $source['add_link'] ) ? $source['add_link'] : 0;
        $image_html     = isset( $source['image_html'] ) ? trim( $source['image_html'] ) : '';

        if ( empty( $rss_url ) || empty( $tag ) ) {
            return 0;
        }

        $rss_feed = @simplexml_load_file( $rss_url );
        if ( ! $rss_feed ) {
            error_log( 'RSS yüklenemedi: ' . $rss_url );
            return 0;
        }

        $inserted = 0;
        global $wpdb;

        // --- RSS item yapısı ---
        if ( $tag === 'item' && isset( $rss_feed->channel->item ) ) {
            foreach ( $rss_feed->channel->item as $item ) {
                if ( $inserted >= $limit ) break;
                $title = trim( (string) $item->title );
                $normalized_title = strtolower( trim( wp_strip_all_tags( $title ) ) );
                
                // Guid kontrolü (varsa)
                $guid = isset( $item->guid ) ? trim( (string) $item->guid ) : '';
                if ( ! empty( $guid ) ) {
                    $existing = new WP_Query( array(
                        'post_type'  => 'post',
                        'meta_key'   => '_rss_guid',
                        'meta_value' => $guid,
                        'fields'     => 'ids'
                    ) );
                    if ( $existing->have_posts() ) {
                        continue;
                    }
                } else {
                    // Guid yoksa, başlığı veritabanında doğrudan kontrol edelim (CASE-INSENSITIVE)
                    $existing = $wpdb->get_var( $wpdb->prepare(
                        "SELECT ID FROM $wpdb->posts WHERE post_type = 'post' AND LOWER(post_title) = %s",
                        $normalized_title
                    ) );
                    if ( ! empty( $existing ) ) {
                        continue;
                    }
                }

                $link        = (string) $item->link;
                $description = (string) strip_tags( $item->description );
                $content     = isset( $item->children( 'content', true )->encoded ) ? (string) strip_tags( $item->children( 'content', true )->encoded ) : '';
                $image_url   = isset( $item->enclosure['url'] ) ? (string) $item->enclosure['url'] : '';

                if ( empty( $image_url ) ) {
                    $combined_text = $description . ' ' . $content;
                    if ( preg_match( '/(https?:\/\/[^\s"\']+\.(?:png|jpg|webp))(\?[^\s"\']*)?/i', $combined_text, $matches ) ) {
                        $image_url = $matches[1];
                    }
                }

                if ( empty( $title ) || ( empty( $content ) && empty( $description ) ) ) {
                    continue;
                }

                $post_content = '<p>' . esc_html( $description ) . '</p><p>' . esc_html( $content ) . '</p>';
                if ( $add_link ) {
                    $post_content .= '<p><a href="' . esc_url( $link ) . '" target="_blank" rel="noopener noreferrer">Kaynak</a></p>';
                }
                $category_ids = array();
                if ( ! empty( $categories_str ) ) {
                    $categories = array_map( 'trim', explode( ',', $categories_str ) );
                    foreach ( $categories as $cat_name ) {
                        $cat_id = get_cat_ID( $cat_name );
                        if ( ! $cat_id ) {
                            $cat_id = wp_create_category( $cat_name );
                        }
                        $category_ids[] = $cat_id;
                    }
                }
                $post_id = wp_insert_post( array(
                    'post_title'    => $normalized_title,
                    'post_content'  => $post_content,
                    'post_status'   => 'publish',
                    'post_author'   => 1,
                    'post_category' => $category_ids,
                    'post_type'     => 'post'
                ) );
                if ( ! is_wp_error( $post_id ) ) {
                    if ( ! empty( $image_url ) ) {
                        require_once( ABSPATH . 'wp-admin/includes/media.php' );
                        require_once( ABSPATH . 'wp-admin/includes/file.php' );
                        require_once( ABSPATH . 'wp-admin/includes/image.php' );
                        $attachment_id = media_sideload_image( $image_url, $post_id, $title, 'id' );
                        if ( ! is_wp_error( $attachment_id ) ) {
                            set_post_thumbnail( $post_id, $attachment_id );
                        }
                    }
                    if ( ! empty( $image_html ) ) {
                        $post_content .= "\n" . $image_html;
                        wp_update_post( array(
                            'ID'           => $post_id,
                            'post_content' => $post_content
                        ) );
                    }
                    $tags = $this->extract_tags_from_content( $description . ' ' . $content );
                    if ( ! empty( $tags ) ) {
                        wp_set_post_tags( $post_id, $tags );
                    }
                    if ( ! empty( $guid ) ) {
                        update_post_meta( $post_id, '_rss_guid', $guid );
                    }
                    $inserted++;
                }
            }
        }
        // --- RSS entry yapısı ---
        elseif ( $tag === 'entry' && isset( $rss_feed->entry ) ) {
            foreach ( $rss_feed->entry as $entry ) {
                if ( $inserted >= $limit ) break;
                $title = trim( (string) $entry->title );
                $normalized_title = strtolower( trim( wp_strip_all_tags( $title ) ) );
                
                // Guid veya ID kontrolü (varsa)
                $guid = isset( $entry->id ) ? trim( (string) $entry->id ) : '';
                if ( ! empty( $guid ) ) {
                    $existing = new WP_Query( array(
                        'post_type'  => 'post',
                        'meta_key'   => '_rss_guid',
                        'meta_value' => $guid,
                        'fields'     => 'ids'
                    ) );
                    if ( $existing->have_posts() ) {
                        continue;
                    }
                } else {
                    $existing = $wpdb->get_var( $wpdb->prepare(
                        "SELECT ID FROM $wpdb->posts WHERE post_type = 'post' AND LOWER(post_title) = %s",
                        $normalized_title
                    ) );
                    if ( ! empty( $existing ) ) {
                        continue;
                    }
                }

                $link = '';
                if ( isset( $entry->link ) ) {
                    foreach ( $entry->link as $l ) {
                        $attributes = $l->attributes();
                        if ( isset( $attributes['rel'] ) && (string) $attributes['rel'] === 'alternate' ) {
                            $link = (string) $attributes['href'];
                            break;
                        }
                    }
                    if ( empty( $link ) ) {
                        $link = (string) $entry->link;
                    }
                }
                $description = isset( $entry->summary ) ? (string) strip_tags( $entry->summary ) : '';
                $content     = isset( $entry->content ) ? (string) strip_tags( $entry->content ) : '';
                $image_url   = '';

                if ( empty( $image_url ) ) {
                    $combined_text = $description . ' ' . $content;
                    if ( preg_match( '/(https?:\/\/[^\s"\']+\.(?:png|jpg|webp))(\?[^\s"\']*)?/i', $combined_text, $matches ) ) {
                        $image_url = $matches[1];
                    }
                }

                if ( empty( $title ) || ( empty( $content ) && empty( $description ) ) ) {
                    continue;
                }

                $post_content = '<p>' . esc_html( $description ) . '</p><p>' . esc_html( $content ) . '</p>';
                if ( $add_link ) {
                    $post_content .= '<p><a href="' . esc_url( $link ) . '" target="_blank" rel="noopener noreferrer">Kaynak</a></p>';
                }
                $category_ids = array();
                if ( ! empty( $categories_str ) ) {
                    $categories = array_map( 'trim', explode( ',', $categories_str ) );
                    foreach ( $categories as $cat_name ) {
                        $cat_id = get_cat_ID( $cat_name );
                        if ( ! $cat_id ) {
                            $cat_id = wp_create_category( $cat_name );
                        }
                        $category_ids[] = $cat_id;
                    }
                }
                $post_id = wp_insert_post( array(
                    'post_title'    => $normalized_title,
                    'post_content'  => $post_content,
                    'post_status'   => 'publish',
                    'post_author'   => 1,
                    'post_category' => $category_ids,
                    'post_type'     => 'post'
                ) );
                if ( ! is_wp_error( $post_id ) ) {
                    if ( ! empty( $image_url ) ) {
                        require_once( ABSPATH . 'wp-admin/includes/media.php' );
                        require_once( ABSPATH . 'wp-admin/includes/file.php' );
                        require_once( ABSPATH . 'wp-admin/includes/image.php' );
                        $attachment_id = media_sideload_image( $image_url, $post_id, $title, 'id' );
                        if ( ! is_wp_error( $attachment_id ) ) {
                            set_post_thumbnail( $post_id, $attachment_id );
                        }
                    }
                    $tags = $this->extract_tags_from_content( $description . ' ' . $content );
                    if ( ! empty( $tags ) ) {
                        wp_set_post_tags( $post_id, $tags );
                    }
                    if ( ! empty( $guid ) ) {
                        update_post_meta( $post_id, '_rss_guid', $guid );
                    }
                    $inserted++;
                }
            }
        }
        return $inserted;
    }

    private function extract_tags_from_content( $content ) {
        $sentences = preg_split( '/(?<=[.?!])\s+/', $content, -1, PREG_SPLIT_NO_EMPTY );
        $words = array();
        foreach ( $sentences as $sentence ) {
            $sentence_words = preg_split( '/\s+/', $sentence, -1, PREG_SPLIT_NO_EMPTY );
            if ( count( $sentence_words ) > 1 ) {
                for ( $i = 1; $i < count( $sentence_words ); $i++ ) {
                    $words[] = $sentence_words[$i];
                }
            }
        }
        $filtered = array();
        foreach ( $words as $word ) {
            $clean = trim( $word, ".,!?()[]{}\"'" );
            if ( strlen( $clean ) > 2 && ctype_upper( substr( $clean, 0, 1 ) ) ) {
                $filtered[] = $clean;
            }
        }
        $freq = array();
        foreach ( $filtered as $w ) {
            $key = strtolower( $w );
            if ( isset( $freq[ $key ] ) ) {
                $freq[ $key ]++;
            } else {
                $freq[ $key ] = 1;
            }
        }
        arsort( $freq );
        $top_tags = array_slice( array_keys( $freq ), 0, 5 );
        return $top_tags;
    }
}

new Genel_RSS_Haber_Scraper();
muratca61
Site Admin
Mesajlar: 35899
Kayıt: Cmt Ara 21, 2024 7:56 am

Re: genel rss ekleme uygulaması wordpress

Mesaj gönderen muratca61 »

bundan devam
muratca61 yazdı: Pzt Şub 17, 2025 4:07 pm
250218-bundan devam
sanırım üstteki çekme işlemini yapmıyor bu hesapta düzeltilmiş hali. bakacağız

Kod:Tümünü seç

<?php
/*
Plugin Name: Genel RSS Haber Scraper
Description: Excel benzeri tablo üzerinden RSS kaynaklarını ekleyip, RSS haberlerini çekmenize olanak tanır. Ayarlarda; RSS adresi, kategoriler, RSS haber etiket kodu, link eklenip eklenmeyeceği, resim HTML kodu ve bağlantı kontrolü yapabilirsiniz. Ayrıca, yazı içeriğinden cümle başları hariç büyük harfli olan ve en çok geçen kelimelerden otomatik 5 etiket oluşturur. Görsel URL’leri için <img src="..."> içindeki .jpg gibi URL’lerde, query string kısmı hariç çekilir.
Version: 1.1
Author: Örnek Geliştirici
License: GPL2
*/

if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

class Genel_RSS_Haber_Scraper {
    private $option_name = 'genel_rss_haber_scraper_sources';

    public function __construct() {
        add_action( 'admin_menu', array( $this, 'add_admin_menu' ) );
        add_action( 'admin_init', array( $this, 'register_settings' ) );
        add_action( 'wp_ajax_genel_rss_scrape', array( $this, 'handle_scrape_request' ) );
        add_action( 'wp_ajax_genel_rss_connection_check', array( $this, 'handle_connection_check' ) );
        add_action( 'wp_enqueue_scripts', array( $this, 'frontend_enqueue_scripts' ) );
        add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
    }

    public function add_admin_menu() {
        add_menu_page(
            'Genel RSS Haber Scraper',
            'RSS Haber Scraper',
            'manage_options',
            'genel-rss-haber-scraper',
            array( $this, 'admin_page' ),
            'dashicons-rss',
            20
        );
    }

    public function register_settings() {
        register_setting( 'genel_rss_haber_scraper_options', $this->option_name );
    }

    public function admin_enqueue_scripts( $hook ) {
        if ( $hook == 'toplevel_page_genel-rss-haber-scraper' ) {
            wp_enqueue_script(
                'genel-rss-admin',
                plugin_dir_url( __FILE__ ) . 'js/genel-rss-admin.js',
                array( 'jquery' ),
                '1.0',
                true
            );
            wp_localize_script( 'genel-rss-admin', 'genelRssAdmin', array(
                'ajax_url' => admin_url( 'admin-ajax.php' )
            ) );
        }
    }

    public function frontend_enqueue_scripts() {
        wp_enqueue_script(
            'genel-rss-frontend',
            plugin_dir_url( __FILE__ ) . 'js/genel-rss-frontend.js',
            array( 'jquery' ),
            '1.0',
            true
        );
        wp_localize_script( 'genel-rss-frontend', 'genelRssAjax', array(
            'ajax_url' => admin_url( 'admin-ajax.php' )
        ) );
    }

    public function admin_page() {
        // Kayıtlı RSS kaynaklarını alıyoruz
        $sources = get_option( $this->option_name, array() );
        ?>
        <div class="wrap">
            <h1>Genel RSS Haber Scraper</h1>
            <form method="post" action="options.php">
                <?php settings_fields( 'genel_rss_haber_scraper_options' ); ?>
                <table class="widefat" id="rss-sources-table">
                    <thead>
                        <tr>
                            <th>RSS Adresi</th>
                            <th>Kategoriler (virgülle ayrılmış)</th>
                            <th>RSS Haber Etiket</th>
                            <th>Link Eklensin mi?</th>
                            <th>Resim HTML Kodu</th>
                            <th>Bağlantı Kontrol</th>
                            <th>İşlem</th>
                        </tr>
                    </thead>
                    <tbody>
                        <?php 
                        if ( ! empty( $sources ) ) {
                            foreach ( $sources as $index => $source ) {
                                $rss_url    = isset( $source['rss_url'] ) ? $source['rss_url'] : '';
                                $categories = isset( $source['categories'] ) ? $source['categories'] : '';
                                $tag        = isset( $source['tag'] ) ? $source['tag'] : '';
                                $add_link   = isset( $source['add_link'] ) ? $source['add_link'] : '';
                                $image_html = isset( $source['image_html'] ) ? $source['image_html'] : '';
                                ?>
                                <tr>
                                    <td>
                                        <input type="text" name="<?php echo $this->option_name; ?>[<?php echo $index; ?>][rss_url]" value="<?php echo esc_attr( $rss_url ); ?>" size="40" />
                                    </td>
                                    <td>
                                        <input type="text" name="<?php echo $this->option_name; ?>[<?php echo $index; ?>][categories]" value="<?php echo esc_attr( $categories ); ?>" size="30" placeholder="Kategori1,Kategori2" />
                                    </td>
                                    <td>
                                        <input type="text" name="<?php echo $this->option_name; ?>[<?php echo $index; ?>][tag]" value="<?php echo esc_attr( $tag ); ?>" size="10" placeholder="item veya entry" />
                                    </td>
                                    <td>
                                        <input type="checkbox" name="<?php echo $this->option_name; ?>[<?php echo $index; ?>][add_link]" value="1" <?php checked( $add_link, 1 ); ?> />
                                    </td>
                                    <td>
                                        <input type="text" name="<?php echo $this->option_name; ?>[<?php echo $index; ?>][image_html]" value="<?php echo esc_attr( $image_html ); ?>" size="30" placeholder="<img src='...' />" />
                                    </td>
                                    <td>
                                        <button class="button connection-check" data-row-index="<?php echo $index; ?>">Bağlantıyı Kontrol Et</button>
                                        <span class="connection-result" id="conn-result-<?php echo $index; ?>"></span>
                                    </td>
                                    <td>
                                        <button class="button remove-row">Kaldır</button>
                                    </td>
                                </tr>
                                <?php
                            }
                        }
                        ?>
                    </tbody>
                </table>
                <p>
                    <button type="button" class="button" id="add-row">Yeni Satır Ekle</button>
                </p>
                <?php submit_button(); ?>
            </form>
            <hr>
            <h2>Manuel Haber Çekme (Batch Processing)</h2>
            <p>RSS haberlerini çekmek için aşağıdaki butona tıklayın. İşlem, kaynakları parça parça (batch) kontrol ederek yapılır.</p>
            <button id="fetch-rss-news" class="button button-primary">Haberleri Çek</button>
            <div id="rss-news-log" style="margin-top:20px;padding:10px;background:#f9f9f9;border:1px solid #ddd;max-height:300px;overflow-y:auto;"></div>
            <script>
            jQuery(document).ready(function($) {
                var log = $('#rss-news-log');
                $('#fetch-rss-news').on('click', function() {
                    log.html('<p>Haber çekme işlemi başlatıldı...</p>');
                    processBatch(0);
                });
                
                function processBatch(offset) {
                    $.ajax({
                        url: ajaxurl,
                        type: 'POST',
                        data: { action: 'genel_rss_scrape', offset: offset },
                        success: function(response) {
                            console.log(response);
                            if(response.success) {
                                log.append('<p style="color:green;">' + response.data.message + '</p>');
                                if(response.data.next_offset !== null) {
                                    processBatch(response.data.next_offset);
                                } else {
                                    log.append('<p style="font-weight:bold;">Tüm kaynaklar işlendi.</p>');
                                }
                            } else {
                                log.append('<p style="color:red;">' + response.data.message + '</p>');
                            }
                        },
                        error: function() {
                            log.append('<p style="color:red;">Bağlantı hatası!</p>');
                        }
                    });
                }
            });
            </script>
        </div>
        <?php
    }

    // AJAX: Manuel haber çekme işlemi (batch processing)
    public function handle_scrape_request() {
        // Timeout ayarlarını optimize ediyoruz:
        @set_time_limit(30);
        ini_set('default_socket_timeout', 15);

        $offset = isset( $_POST['offset'] ) ? intval( $_POST['offset'] ) : 0;
        $batch_size = 2; // Her istekte 2 kaynak işlenecek.
        $result = $this->fetch_news_batch( $offset, $batch_size );
        
        if ( $result['new_posts'] > 0 ) {
            wp_send_json_success( array( 
                'message'     => $result['new_posts'] . ' yeni haber eklendi.',
                'next_offset' => $result['next_offset']
            ) );
        } else {
            wp_send_json_success( array( 
                'message'     => 'İşlenen ' . $result['processed'] . ' kaynaktan yeni haber bulunamadı.',
                'next_offset' => $result['next_offset']
            ) );
        }
    }

    // AJAX: Bağlantı kontrolü için RSS adresi ve etiket bilgisini kontrol eder
    public function handle_connection_check() {
        $rss_url = isset( $_POST['rss_url'] ) ? esc_url_raw( $_POST['rss_url'] ) : '';
        $tag     = isset( $_POST['tag'] ) ? sanitize_text_field( $_POST['tag'] ) : '';

        if ( empty( $rss_url ) || empty( $tag ) ) {
            wp_send_json_error( array( 'message' => 'RSS URL ve Etiket bilgisi gerekli.' ) );
        }

        $rss_feed = @simplexml_load_file( $rss_url );
        if ( ! $rss_feed ) {
            wp_send_json_error( array( 'message' => 'RSS beslemesi yüklenemedi.' ) );
        }

        if ( $tag === 'item' && isset( $rss_feed->channel->item ) ) {
            wp_send_json_success( array( 'message' => 'Bağlantı başarılı: <item> bulundu.' ) );
        } elseif ( $tag === 'entry' && isset( $rss_feed->entry ) ) {
            wp_send_json_success( array( 'message' => 'Bağlantı başarılı: <entry> bulundu.' ) );
        } else {
            wp_send_json_error( array( 'message' => 'Belirtilen etiket bulunamadı.' ) );
        }
    }

    /**
     * Belirtilen offset ve batch size'a göre RSS kaynaklarını kontrol eder.
     *
     * @param int $offset İşleme başlanacak kaynak indeksi.
     * @param int $batch_size Bir istekte işlenecek kaynak sayısı.
     * @return array İşlenen kaynak sayısı, eklenen yeni haber sayısı ve bir sonraki offset.
     */
    private function fetch_news_batch( $offset, $batch_size ) {
        $sources = get_option( $this->option_name, array() );
        $total = count( $sources );
        if ( $total === 0 ) {
            return array( 'processed' => 0, 'new_posts' => 0, 'next_offset' => null );
        }
        $processed = 0;
        $new_posts = 0;
        for ( $i = $offset; $i < min( $offset + $batch_size, $total ); $i++ ) {
            $inserted = $this->process_source( $sources[ $i ] );
            $new_posts += $inserted;
            $processed++;
        }
        $next_offset = $offset + $batch_size;
        if ( $next_offset >= $total ) {
            $next_offset = null;
        }
        return array(
            'processed'   => $processed,
            'new_posts'   => $new_posts,
            'next_offset' => $next_offset
        );
    }

    /**
     * Verilen bir RSS kaynağından (tek kaynak) haber çekmeye çalışır.
     *
     * @param array $source Kaynak bilgileri.
     * @return int Eklenen yeni haber sayısı.
     */
    private function process_source( $source ) {
        require_once( ABSPATH . 'wp-admin/includes/post.php' );
        $rss_url        = isset( $source['rss_url'] ) ? trim( $source['rss_url'] ) : '';
        $categories_str = isset( $source['categories'] ) ? trim( $source['categories'] ) : '';
        $tag            = isset( $source['tag'] ) ? trim( $source['tag'] ) : '';
        $add_link       = isset( $source['add_link'] ) ? $source['add_link'] : 0;
        $image_html     = isset( $source['image_html'] ) ? trim( $source['image_html'] ) : '';

        if ( empty( $rss_url ) || empty( $tag ) ) {
            return 0;
        }

        $rss_feed = @simplexml_load_file( $rss_url );
        if ( ! $rss_feed ) {
            error_log( 'RSS yüklenemedi: ' . $rss_url );
            return 0;
        }

        $inserted = 0;
        // --- RSS item yapısı ---
        if ( $tag === 'item' && isset( $rss_feed->channel->item ) ) {
            foreach ( $rss_feed->channel->item as $item ) {
                $title = (string) $item->title;
                if ( post_exists( $title ) ) {
                    continue;
                }
                $link        = (string) $item->link;
                $description = (string) strip_tags( $item->description );
                $content     = isset( $item->children( 'content', true )->encoded ) ? (string) strip_tags( $item->children( 'content', true )->encoded ) : '';
                $image_url   = isset( $item->enclosure['url'] ) ? (string) $item->enclosure['url'] : '';

                // Eğer enclosure yoksa description veya content içinden resim URL'si arayalım.
                if ( empty( $image_url ) ) {
                    $combined_text = $description . ' ' . $content;
                    if ( preg_match( '/(https?:\/\/[^\s"\']+\.(?:png|jpg|webp))(\?[^\s"\']*)?/i', $combined_text, $matches ) ) {
                        $image_url = $matches[1];
                    }
                }

                if ( empty( $title ) || ( empty( $content ) && empty( $description ) ) ) {
                    continue;
                }

                $post_content = '<p>' . esc_html( $description ) . '</p><p>' . esc_html( $content ) . '</p>';
                if ( $add_link ) {
                    $post_content .= '<p><a href="' . esc_url( $link ) . '" target="_blank" rel="noopener noreferrer">Kaynak</a></p>';
                }
                $category_ids = array();
                if ( ! empty( $categories_str ) ) {
                    $categories = array_map( 'trim', explode( ',', $categories_str ) );
                    foreach ( $categories as $cat_name ) {
                        $cat_id = get_cat_ID( $cat_name );
                        if ( ! $cat_id ) {
                            $cat_id = wp_create_category( $cat_name );
                        }
                        $category_ids[] = $cat_id;
                    }
                }
                $post_id = wp_insert_post( array(
                    'post_title'    => wp_strip_all_tags( $title ),
                    'post_content'  => $post_content,
                    'post_status'   => 'publish',
                    'post_author'   => 1,
                    'post_category' => $category_ids,
                    'post_type'     => 'post'
                ) );
                if ( ! is_wp_error( $post_id ) ) {
                    // Görsel ekleme işlemi
                    if ( ! empty( $image_url ) ) {
                        require_once( ABSPATH . 'wp-admin/includes/media.php' );
                        require_once( ABSPATH . 'wp-admin/includes/file.php' );
                        require_once( ABSPATH . 'wp-admin/includes/image.php' );
                        $attachment_id = media_sideload_image( $image_url, $post_id, $title, 'id' );
                        if ( ! is_wp_error( $attachment_id ) ) {
                            set_post_thumbnail( $post_id, $attachment_id );
                        }
                    }
                    // Ekstra resim HTML kodunu ekleme (varsa)
                    if ( ! empty( $image_html ) ) {
                        $post_content .= "\n" . $image_html;
                        wp_update_post( array(
                            'ID'           => $post_id,
                            'post_content' => $post_content
                        ) );
                    }
                    // Yazı içeriğinden otomatik etiket oluşturma (cümle başları hariç)
                    $tags = $this->extract_tags_from_content( $description . ' ' . $content );
                    if ( ! empty( $tags ) ) {
                        wp_set_post_tags( $post_id, $tags );
                    }
                    $inserted++;
                }
            }
        }
        // --- RSS entry yapısı ---
        elseif ( $tag === 'entry' && isset( $rss_feed->entry ) ) {
            foreach ( $rss_feed->entry as $entry ) {
                $title = (string) $entry->title;
                if ( post_exists( $title ) ) {
                    continue;
                }
                $link = '';
                if ( isset( $entry->link ) ) {
                    foreach ( $entry->link as $l ) {
                        $attributes = $l->attributes();
                        if ( isset( $attributes['rel'] ) && (string) $attributes['rel'] === 'alternate' ) {
                            $link = (string) $attributes['href'];
                            break;
                        }
                    }
                    if ( empty( $link ) ) {
                        $link = (string) $entry->link;
                    }
                }
                $description = isset( $entry->summary ) ? (string) strip_tags( $entry->summary ) : '';
                $content     = isset( $entry->content ) ? (string) strip_tags( $entry->content ) : '';
                $image_url   = '';

                if ( empty( $image_url ) ) {
                    $combined_text = $description . ' ' . $content;
                    if ( preg_match( '/(https?:\/\/[^\s"\']+\.(?:png|jpg|webp))(\?[^\s"\']*)?/i', $combined_text, $matches ) ) {
                        $image_url = $matches[1];
                    }
                }

                if ( empty( $title ) || ( empty( $content ) && empty( $description ) ) ) {
                    continue;
                }

                $post_content = '<p>' . esc_html( $description ) . '</p><p>' . esc_html( $content ) . '</p>';
                if ( $add_link ) {
                    $post_content .= '<p><a href="' . esc_url( $link ) . '" target="_blank" rel="noopener noreferrer">Kaynak</a></p>';
                }
                $category_ids = array();
                if ( ! empty( $categories_str ) ) {
                    $categories = array_map( 'trim', explode( ',', $categories_str ) );
                    foreach ( $categories as $cat_name ) {
                        $cat_id = get_cat_ID( $cat_name );
                        if ( ! $cat_id ) {
                            $cat_id = wp_create_category( $cat_name );
                        }
                        $category_ids[] = $cat_id;
                    }
                }
                $post_id = wp_insert_post( array(
                    'post_title'    => wp_strip_all_tags( $title ),
                    'post_content'  => $post_content,
                    'post_status'   => 'publish',
                    'post_author'   => 1,
                    'post_category' => $category_ids,
                    'post_type'     => 'post'
                ) );
                if ( ! is_wp_error( $post_id ) ) {
                    if ( ! empty( $image_url ) ) {
                        require_once( ABSPATH . 'wp-admin/includes/media.php' );
                        require_once( ABSPATH . 'wp-admin/includes/file.php' );
                        require_once( ABSPATH . 'wp-admin/includes/image.php' );
                        $attachment_id = media_sideload_image( $image_url, $post_id, $title, 'id' );
                        if ( ! is_wp_error( $attachment_id ) ) {
                            set_post_thumbnail( $post_id, $attachment_id );
                        }
                    }
                    $tags = $this->extract_tags_from_content( $description . ' ' . $content );
                    if ( ! empty( $tags ) ) {
                        wp_set_post_tags( $post_id, $tags );
                    }
                    $inserted++;
                }
            }
        }
        return $inserted;
    }

    /**
     * Yazı içeriğinden, cümle başları hariç, ilk kelimeyi atlayarak
     * büyük harfli (ilk harfi büyük) kelimelerin frekansını hesaplar ve
     * en çok geçen 5 kelimeyi etiket olarak döndürür.
     */
    private function extract_tags_from_content( $content ) {
        $sentences = preg_split( '/(?<=[.?!])\s+/', $content, -1, PREG_SPLIT_NO_EMPTY );
        $words = array();
        foreach ( $sentences as $sentence ) {
            $sentence_words = preg_split( '/\s+/', $sentence, -1, PREG_SPLIT_NO_EMPTY );
            if ( count( $sentence_words ) > 1 ) {
                for ( $i = 1; $i < count( $sentence_words ); $i++ ) {
                    $words[] = $sentence_words[$i];
                }
            }
        }
        $filtered = array();
        foreach ( $words as $word ) {
            $clean = trim( $word, ".,!?()[]{}\"'" );
            if ( strlen( $clean ) > 2 && ctype_upper( substr( $clean, 0, 1 ) ) ) {
                $filtered[] = $clean;
            }
        }
        $freq = array();
        foreach ( $filtered as $w ) {
            $key = strtolower( $w );
            if ( isset( $freq[ $key ] ) ) {
                $freq[ $key ]++;
            } else {
                $freq[ $key ] = 1;
            }
        }
        arsort( $freq );
        $top_tags = array_slice( array_keys( $freq ), 0, 5 );
        return $top_tags;
    }
}

new Genel_RSS_Haber_Scraper();
muratca61
Site Admin
Mesajlar: 35899
Kayıt: Cmt Ara 21, 2024 7:56 am

Re: genel rss ekleme uygulaması wordpress

Mesaj gönderen muratca61 »

bu çalışan son ama düzenli çekip çekmediğini bilmiyorum ama bunu kullanıyorum

Kod:Tümünü seç

<?php
/*
Plugin Name: Genel RSS Haber Scraper
Description: Excel benzeri tablo üzerinden RSS kaynaklarını ekleyip, RSS haberlerini çekmenize olanak tanır. Ayarlarda; RSS adresi, kategoriler, RSS haber etiket kodu, link eklenip eklenmeyeceği, resim HTML kodu ve bağlantı kontrolü yapabilirsiniz. Ayrıca, yazı içeriğinden cümle başları hariç büyük harfli olan ve en çok geçen kelimelerden otomatik 5 etiket oluşturur. Görsel URL’leri için <img src="..."> içindeki .jpg gibi URL’lerde, query string kısmı hariç çekilir.
Version: 1.1
Author: Örnek Geliştirici
License: GPL2
*/

if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

class Genel_RSS_Haber_Scraper {
    private $option_name = 'genel_rss_haber_scraper_sources';

    public function __construct() {
        add_action( 'admin_menu', array( $this, 'add_admin_menu' ) );
        add_action( 'admin_init', array( $this, 'register_settings' ) );
        add_action( 'wp_ajax_genel_rss_scrape', array( $this, 'handle_scrape_request' ) );
        add_action( 'wp_ajax_genel_rss_connection_check', array( $this, 'handle_connection_check' ) );
        add_action( 'wp_enqueue_scripts', array( $this, 'frontend_enqueue_scripts' ) );
        add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
    }

    public function add_admin_menu() {
        add_menu_page(
            'Genel RSS Haber Scraper',
            'RSS Haber Scraper',
            'manage_options',
            'genel-rss-haber-scraper',
            array( $this, 'admin_page' ),
            'dashicons-rss',
            20
        );
    }

    public function register_settings() {
        register_setting( 'genel_rss_haber_scraper_options', $this->option_name );
    }

    public function admin_enqueue_scripts( $hook ) {
        if ( $hook == 'toplevel_page_genel-rss-haber-scraper' ) {
            wp_enqueue_script(
                'genel-rss-admin',
                plugin_dir_url( __FILE__ ) . 'js/genel-rss-admin.js',
                array( 'jquery' ),
                '1.0',
                true
            );
            wp_localize_script( 'genel-rss-admin', 'genelRssAdmin', array(
                'ajax_url' => admin_url( 'admin-ajax.php' )
            ) );
        }
    }

    public function frontend_enqueue_scripts() {
        wp_enqueue_script(
            'genel-rss-frontend',
            plugin_dir_url( __FILE__ ) . 'js/genel-rss-frontend.js',
            array( 'jquery' ),
            '1.0',
            true
        );
        wp_localize_script( 'genel-rss-frontend', 'genelRssAjax', array(
            'ajax_url' => admin_url( 'admin-ajax.php' )
        ) );
    }

    public function admin_page() {
        // Kayıtlı RSS kaynaklarını alıyoruz
        $sources = get_option( $this->option_name, array() );
        ?>
        <div class="wrap">
            <h1>Genel RSS Haber Scraper</h1>
            <form method="post" action="options.php">
                <?php settings_fields( 'genel_rss_haber_scraper_options' ); ?>
                <table class="widefat" id="rss-sources-table">
                    <thead>
                        <tr>
                            <th>RSS Adresi</th>
                            <th>Kategoriler (virgülle ayrılmış)</th>
                            <th>RSS Haber Etiket</th>
                            <th>Link Eklensin mi?</th>
                            <th>Resim HTML Kodu</th>
                            <th>Bağlantı Kontrol</th>
                            <th>İşlem</th>
                        </tr>
                    </thead>
                    <tbody>
                        <?php 
                        if ( ! empty( $sources ) ) {
                            foreach ( $sources as $index => $source ) {
                                $rss_url    = isset( $source['rss_url'] ) ? $source['rss_url'] : '';
                                $categories = isset( $source['categories'] ) ? $source['categories'] : '';
                                $tag        = isset( $source['tag'] ) ? $source['tag'] : '';
                                $add_link   = isset( $source['add_link'] ) ? $source['add_link'] : '';
                                $image_html = isset( $source['image_html'] ) ? $source['image_html'] : '';
                                ?>
                                <tr>
                                    <td>
                                        <input type="text" name="<?php echo $this->option_name; ?>[<?php echo $index; ?>][rss_url]" value="<?php echo esc_attr( $rss_url ); ?>" size="40" />
                                    </td>
                                    <td>
                                        <input type="text" name="<?php echo $this->option_name; ?>[<?php echo $index; ?>][categories]" value="<?php echo esc_attr( $categories ); ?>" size="30" placeholder="Kategori1,Kategori2" />
                                    </td>
                                    <td>
                                        <input type="text" name="<?php echo $this->option_name; ?>[<?php echo $index; ?>][tag]" value="<?php echo esc_attr( $tag ); ?>" size="10" placeholder="item veya entry" />
                                    </td>
                                    <td>
                                        <input type="checkbox" name="<?php echo $this->option_name; ?>[<?php echo $index; ?>][add_link]" value="1" <?php checked( $add_link, 1 ); ?> />
                                    </td>
                                    <td>
                                        <input type="text" name="<?php echo $this->option_name; ?>[<?php echo $index; ?>][image_html]" value="<?php echo esc_attr( $image_html ); ?>" size="30" placeholder="<img src='...' />" />
                                    </td>
                                    <td>
                                        <button class="button connection-check" data-row-index="<?php echo $index; ?>">Bağlantıyı Kontrol Et</button>
                                        <span class="connection-result" id="conn-result-<?php echo $index; ?>"></span>
                                    </td>
                                    <td>
                                        <button class="button remove-row">Kaldır</button>
                                    </td>
                                </tr>
                                <?php
                            }
                        }
                        ?>
                    </tbody>
                </table>
                <p>
                    <button type="button" class="button" id="add-row">Yeni Satır Ekle</button>
                </p>
                <?php submit_button(); ?>
            </form>
            <hr>
            <h2>Manuel Haber Çekme (Batch Processing)</h2>
            <p>RSS haberlerini çekmek için aşağıdaki butona tıklayın. İşlem, kaynakları parça parça (batch) kontrol ederek yapılır.</p>
            <button id="fetch-rss-news" class="button button-primary">Haberleri Çek</button>
            <div id="rss-news-log" style="margin-top:20px;padding:10px;background:#f9f9f9;border:1px solid #ddd;max-height:300px;overflow-y:auto;"></div>
            <script>
            jQuery(document).ready(function($) {
                var log = $('#rss-news-log');
                $('#fetch-rss-news').on('click', function() {
                    log.html('<p>Haber çekme işlemi başlatıldı...</p>');
                    processBatch(0);
                });
                
                function processBatch(offset) {
                    $.ajax({
                        url: ajaxurl,
                        type: 'POST',
                        data: { action: 'genel_rss_scrape', offset: offset },
                        success: function(response) {
                            console.log(response);
                            if(response.success) {
                                log.append('<p style="color:green;">' + response.data.message + '</p>');
                                if(response.data.next_offset !== null) {
                                    processBatch(response.data.next_offset);
                                } else {
                                    log.append('<p style="font-weight:bold;">Tüm kaynaklar işlendi.</p>');
                                }
                            } else {
                                log.append('<p style="color:red;">' + response.data.message + '</p>');
                            }
                        },
                        error: function() {
                            log.append('<p style="color:red;">Bağlantı hatası!</p>');
                        }
                    });
                }
            });
            </script>
        </div>
        <?php
    }

    // AJAX: Manuel haber çekme işlemi (batch processing)
    public function handle_scrape_request() {
        // Timeout ayarlarını optimize ediyoruz:
        @set_time_limit(30);
        ini_set('default_socket_timeout', 15);

        $offset = isset( $_POST['offset'] ) ? intval( $_POST['offset'] ) : 0;
        $batch_size = 2; // Her istekte 2 kaynak işlenecek.
        $result = $this->fetch_news_batch( $offset, $batch_size );
        
        if ( $result['new_posts'] > 0 ) {
            wp_send_json_success( array( 
                'message'     => $result['new_posts'] . ' yeni haber eklendi.',
                'next_offset' => $result['next_offset']
            ) );
        } else {
            wp_send_json_success( array( 
                'message'     => 'İşlenen ' . $result['processed'] . ' kaynaktan yeni haber bulunamadı.',
                'next_offset' => $result['next_offset']
            ) );
        }
    }

    // AJAX: Bağlantı kontrolü için RSS adresi ve etiket bilgisini kontrol eder
    public function handle_connection_check() {
        $rss_url = isset( $_POST['rss_url'] ) ? esc_url_raw( $_POST['rss_url'] ) : '';
        $tag     = isset( $_POST['tag'] ) ? sanitize_text_field( $_POST['tag'] ) : '';

        if ( empty( $rss_url ) || empty( $tag ) ) {
            wp_send_json_error( array( 'message' => 'RSS URL ve Etiket bilgisi gerekli.' ) );
        }

        $rss_feed = @simplexml_load_file( $rss_url );
        if ( ! $rss_feed ) {
            wp_send_json_error( array( 'message' => 'RSS beslemesi yüklenemedi.' ) );
        }

        if ( $tag === 'item' && isset( $rss_feed->channel->item ) ) {
            wp_send_json_success( array( 'message' => 'Bağlantı başarılı: <item> bulundu.' ) );
        } elseif ( $tag === 'entry' && isset( $rss_feed->entry ) ) {
            wp_send_json_success( array( 'message' => 'Bağlantı başarılı: <entry> bulundu.' ) );
        } else {
            wp_send_json_error( array( 'message' => 'Belirtilen etiket bulunamadı.' ) );
        }
    }

    /**
     * Belirtilen offset ve batch size'a göre RSS kaynaklarını kontrol eder.
     *
     * @param int $offset İşleme başlanacak kaynak indeksi.
     * @param int $batch_size Bir istekte işlenecek kaynak sayısı.
     * @return array İşlenen kaynak sayısı, eklenen yeni haber sayısı ve bir sonraki offset.
     */
    private function fetch_news_batch( $offset, $batch_size ) {
        $sources = get_option( $this->option_name, array() );
        $total = count( $sources );
        if ( $total === 0 ) {
            return array( 'processed' => 0, 'new_posts' => 0, 'next_offset' => null );
        }
        $processed = 0;
        $new_posts = 0;
        for ( $i = $offset; $i < min( $offset + $batch_size, $total ); $i++ ) {
            $inserted = $this->process_source( $sources[ $i ] );
            $new_posts += $inserted;
            $processed++;
        }
        $next_offset = $offset + $batch_size;
        if ( $next_offset >= $total ) {
            $next_offset = null;
        }
        return array(
            'processed'   => $processed,
            'new_posts'   => $new_posts,
            'next_offset' => $next_offset
        );
    }

    /**
     * Verilen bir RSS kaynağından (tek kaynak) haber çekmeye çalışır.
     *
     * @param array $source Kaynak bilgileri.
     * @return int Eklenen yeni haber sayısı.
     */
    private function process_source( $source ) {
        require_once( ABSPATH . 'wp-admin/includes/post.php' );
        $rss_url        = isset( $source['rss_url'] ) ? trim( $source['rss_url'] ) : '';
        $categories_str = isset( $source['categories'] ) ? trim( $source['categories'] ) : '';
        $tag            = isset( $source['tag'] ) ? trim( $source['tag'] ) : '';
        $add_link       = isset( $source['add_link'] ) ? $source['add_link'] : 0;
        $image_html     = isset( $source['image_html'] ) ? trim( $source['image_html'] ) : '';

        if ( empty( $rss_url ) || empty( $tag ) ) {
            return 0;
        }

        $rss_feed = @simplexml_load_file( $rss_url );
        if ( ! $rss_feed ) {
            error_log( 'RSS yüklenemedi: ' . $rss_url );
            return 0;
        }

        $inserted = 0;
        // --- RSS item yapısı ---
        if ( $tag === 'item' && isset( $rss_feed->channel->item ) ) {
            foreach ( $rss_feed->channel->item as $item ) {
                $title = (string) $item->title;
                if ( post_exists( $title ) ) {
                    continue;
                }
                $link        = (string) $item->link;
                $description = (string) strip_tags( $item->description );
                $content     = isset( $item->children( 'content', true )->encoded ) ? (string) strip_tags( $item->children( 'content', true )->encoded ) : '';
                $image_url   = isset( $item->enclosure['url'] ) ? (string) $item->enclosure['url'] : '';

                // Eğer enclosure yoksa description veya content içinden resim URL'si arayalım.
                if ( empty( $image_url ) ) {
                    $combined_text = $description . ' ' . $content;
                    if ( preg_match( '/(https?:\/\/[^\s"\']+\.(?:png|jpg|webp))(\?[^\s"\']*)?/i', $combined_text, $matches ) ) {
                        $image_url = $matches[1];
                    }
                }

                if ( empty( $title ) || ( empty( $content ) && empty( $description ) ) ) {
                    continue;
                }

                $post_content = '<p>' . esc_html( $description ) . '</p><p>' . esc_html( $content ) . '</p>';
                if ( $add_link ) {
                    $post_content .= '<p><a href="' . esc_url( $link ) . '" target="_blank" rel="noopener noreferrer">Kaynak</a></p>';
                }
                $category_ids = array();
                if ( ! empty( $categories_str ) ) {
                    $categories = array_map( 'trim', explode( ',', $categories_str ) );
                    foreach ( $categories as $cat_name ) {
                        $cat_id = get_cat_ID( $cat_name );
                        if ( ! $cat_id ) {
                            $cat_id = wp_create_category( $cat_name );
                        }
                        $category_ids[] = $cat_id;
                    }
                }
                $post_id = wp_insert_post( array(
                    'post_title'    => wp_strip_all_tags( $title ),
                    'post_content'  => $post_content,
                    'post_status'   => 'publish',
                    'post_author'   => 1,
                    'post_category' => $category_ids,
                    'post_type'     => 'post'
                ) );
                if ( ! is_wp_error( $post_id ) ) {
                    // Görsel ekleme işlemi
                    if ( ! empty( $image_url ) ) {
                        require_once( ABSPATH . 'wp-admin/includes/media.php' );
                        require_once( ABSPATH . 'wp-admin/includes/file.php' );
                        require_once( ABSPATH . 'wp-admin/includes/image.php' );
                        $attachment_id = media_sideload_image( $image_url, $post_id, $title, 'id' );
                        if ( ! is_wp_error( $attachment_id ) ) {
                            set_post_thumbnail( $post_id, $attachment_id );
                        }
                    }
                    // Ekstra resim HTML kodunu ekleme (varsa)
                    if ( ! empty( $image_html ) ) {
                        $post_content .= "\n" . $image_html;
                        wp_update_post( array(
                            'ID'           => $post_id,
                            'post_content' => $post_content
                        ) );
                    }
                    // Yazı içeriğinden otomatik etiket oluşturma (cümle başları hariç)
                    $tags = $this->extract_tags_from_content( $description . ' ' . $content );
                    if ( ! empty( $tags ) ) {
                        wp_set_post_tags( $post_id, $tags );
                    }
                    $inserted++;
                }
            }
        }
        // --- RSS entry yapısı ---
        elseif ( $tag === 'entry' && isset( $rss_feed->entry ) ) {
            foreach ( $rss_feed->entry as $entry ) {
                $title = (string) $entry->title;
                if ( post_exists( $title ) ) {
                    continue;
                }
                $link = '';
                if ( isset( $entry->link ) ) {
                    foreach ( $entry->link as $l ) {
                        $attributes = $l->attributes();
                        if ( isset( $attributes['rel'] ) && (string) $attributes['rel'] === 'alternate' ) {
                            $link = (string) $attributes['href'];
                            break;
                        }
                    }
                    if ( empty( $link ) ) {
                        $link = (string) $entry->link;
                    }
                }
                $description = isset( $entry->summary ) ? (string) strip_tags( $entry->summary ) : '';
                $content     = isset( $entry->content ) ? (string) strip_tags( $entry->content ) : '';
                $image_url   = '';

                if ( empty( $image_url ) ) {
                    $combined_text = $description . ' ' . $content;
                    if ( preg_match( '/(https?:\/\/[^\s"\']+\.(?:png|jpg|webp))(\?[^\s"\']*)?/i', $combined_text, $matches ) ) {
                        $image_url = $matches[1];
                    }
                }

                if ( empty( $title ) || ( empty( $content ) && empty( $description ) ) ) {
                    continue;
                }

                $post_content = '<p>' . esc_html( $description ) . '</p><p>' . esc_html( $content ) . '</p>';
                if ( $add_link ) {
                    $post_content .= '<p><a href="' . esc_url( $link ) . '" target="_blank" rel="noopener noreferrer">Kaynak</a></p>';
                }
                $category_ids = array();
                if ( ! empty( $categories_str ) ) {
                    $categories = array_map( 'trim', explode( ',', $categories_str ) );
                    foreach ( $categories as $cat_name ) {
                        $cat_id = get_cat_ID( $cat_name );
                        if ( ! $cat_id ) {
                            $cat_id = wp_create_category( $cat_name );
                        }
                        $category_ids[] = $cat_id;
                    }
                }
                $post_id = wp_insert_post( array(
                    'post_title'    => wp_strip_all_tags( $title ),
                    'post_content'  => $post_content,
                    'post_status'   => 'publish',
                    'post_author'   => 1,
                    'post_category' => $category_ids,
                    'post_type'     => 'post'
                ) );
                if ( ! is_wp_error( $post_id ) ) {
                    if ( ! empty( $image_url ) ) {
                        require_once( ABSPATH . 'wp-admin/includes/media.php' );
                        require_once( ABSPATH . 'wp-admin/includes/file.php' );
                        require_once( ABSPATH . 'wp-admin/includes/image.php' );
                        $attachment_id = media_sideload_image( $image_url, $post_id, $title, 'id' );
                        if ( ! is_wp_error( $attachment_id ) ) {
                            set_post_thumbnail( $post_id, $attachment_id );
                        }
                    }
                    $tags = $this->extract_tags_from_content( $description . ' ' . $content );
                    if ( ! empty( $tags ) ) {
                        wp_set_post_tags( $post_id, $tags );
                    }
                    $inserted++;
                }
            }
        }
        return $inserted;
    }

    /**
     * Yazı içeriğinden, cümle başları hariç, ilk kelimeyi atlayarak
     * büyük harfli (ilk harfi büyük) kelimelerin frekansını hesaplar ve
     * en çok geçen 5 kelimeyi etiket olarak döndürür.
     */
    private function extract_tags_from_content( $content ) {
        $sentences = preg_split( '/(?<=[.?!])\s+/', $content, -1, PREG_SPLIT_NO_EMPTY );
        $words = array();
        foreach ( $sentences as $sentence ) {
            $sentence_words = preg_split( '/\s+/', $sentence, -1, PREG_SPLIT_NO_EMPTY );
            if ( count( $sentence_words ) > 1 ) {
                for ( $i = 1; $i < count( $sentence_words ); $i++ ) {
                    $words[] = $sentence_words[$i];
                }
            }
        }
        $filtered = array();
        foreach ( $words as $word ) {
            $clean = trim( $word, ".,!?()[]{}\"'" );
            if ( strlen( $clean ) > 2 && ctype_upper( substr( $clean, 0, 1 ) ) ) {
                $filtered[] = $clean;
            }
        }
        $freq = array();
        foreach ( $filtered as $w ) {
            $key = strtolower( $w );
            if ( isset( $freq[ $key ] ) ) {
                $freq[ $key ]++;
            } else {
                $freq[ $key ] = 1;
            }
        }
        arsort( $freq );
        $top_tags = array_slice( array_keys( $freq ), 0, 5 );
        return $top_tags;
    }
}

new Genel_RSS_Haber_Scraper();
muratca61
Site Admin
Mesajlar: 35899
Kayıt: Cmt Ara 21, 2024 7:56 am

Re: genel rss ekleme uygulaması wordpress

Mesaj gönderen muratca61 »

etkin devre dışı ayarı eklemesini istedim
Aşağıdaki örnekte, her RSS kaynağı için "Etkin mi?" (aktif/devre dışı) seçeneğini ekledik. Hem yönetici panelindeki tabloya bir sütun ekledik hem de haber çekme işlemi sırasında devre dışı bırakılan kaynakları atladık.

Aşağıdaki kodu inceleyebilirsiniz:

Kod:Tümünü seç

<?php
/*
Plugin Name: Genel RSS Haber Scraper
Description: Excel benzeri tablo üzerinden RSS kaynaklarını ekleyip, RSS haberlerini çekmenize olanak tanır. Ayarlarda; RSS adresi, kategoriler, RSS haber etiket kodu, link eklenip eklenmeyeceği, resim HTML kodu ve bağlantı kontrolü yapabilirsiniz. Ayrıca, yazı içeriğinden cümle başları hariç büyük harfli olan ve en çok geçen kelimelerden otomatik 5 etiket oluşturur. Görsel URL’leri için <img src="..."> içindeki .jpg gibi URL’lerde, query string kısmı hariç çekilir.
Version: 1.1
Author: Örnek Geliştirici
License: GPL2
*/

if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

class Genel_RSS_Haber_Scraper {
    private $option_name = 'genel_rss_haber_scraper_sources';

    public function __construct() {
        add_action( 'admin_menu', array( $this, 'add_admin_menu' ) );
        add_action( 'admin_init', array( $this, 'register_settings' ) );
        add_action( 'wp_ajax_genel_rss_scrape', array( $this, 'handle_scrape_request' ) );
        add_action( 'wp_ajax_genel_rss_connection_check', array( $this, 'handle_connection_check' ) );
        add_action( 'wp_enqueue_scripts', array( $this, 'frontend_enqueue_scripts' ) );
        add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
    }

    public function add_admin_menu() {
        add_menu_page(
            'Genel RSS Haber Scraper',
            'RSS Haber Scraper',
            'manage_options',
            'genel-rss-haber-scraper',
            array( $this, 'admin_page' ),
            'dashicons-rss',
            20
        );
    }

    public function register_settings() {
        register_setting( 'genel_rss_haber_scraper_options', $this->option_name );
    }

    public function admin_enqueue_scripts( $hook ) {
        if ( $hook == 'toplevel_page_genel-rss-haber-scraper' ) {
            wp_enqueue_script(
                'genel-rss-admin',
                plugin_dir_url( __FILE__ ) . 'js/genel-rss-admin.js',
                array( 'jquery' ),
                '1.0',
                true
            );
            wp_localize_script( 'genel-rss-admin', 'genelRssAdmin', array(
                'ajax_url' => admin_url( 'admin-ajax.php' )
            ) );
        }
    }

    public function frontend_enqueue_scripts() {
        wp_enqueue_script(
            'genel-rss-frontend',
            plugin_dir_url( __FILE__ ) . 'js/genel-rss-frontend.js',
            array( 'jquery' ),
            '1.0',
            true
        );
        wp_localize_script( 'genel-rss-frontend', 'genelRssAjax', array(
            'ajax_url' => admin_url( 'admin-ajax.php' )
        ) );
    }

    public function admin_page() {
        // Kayıtlı RSS kaynaklarını alıyoruz
        $sources = get_option( $this->option_name, array() );
        ?>
        <div class="wrap">
            <h1>Genel RSS Haber Scraper</h1>
            <form method="post" action="options.php">
                <?php settings_fields( 'genel_rss_haber_scraper_options' ); ?>
                <table class="widefat" id="rss-sources-table">
                    <thead>
                        <tr>
                            <th>RSS Adresi</th>
                            <th>Kategoriler (virgülle ayrılmış)</th>
                            <th>RSS Haber Etiket</th>
                            <th>Etkin mi?</th>
                            <th>Link Eklensin mi?</th>
                            <th>Resim HTML Kodu</th>
                            <th>Bağlantı Kontrol</th>
                            <th>İşlem</th>
                        </tr>
                    </thead>
                    <tbody>
                        <?php 
                        if ( ! empty( $sources ) ) {
                            foreach ( $sources as $index => $source ) {
                                $rss_url    = isset( $source['rss_url'] ) ? $source['rss_url'] : '';
                                $categories = isset( $source['categories'] ) ? $source['categories'] : '';
                                $tag        = isset( $source['tag'] ) ? $source['tag'] : '';
                                $active     = isset( $source['active'] ) ? $source['active'] : 1; // Varsayılan aktif
                                $add_link   = isset( $source['add_link'] ) ? $source['add_link'] : '';
                                $image_html = isset( $source['image_html'] ) ? $source['image_html'] : '';
                                ?>
                                <tr>
                                    <td>
                                        <input type="text" name="<?php echo $this->option_name; ?>[<?php echo $index; ?>][rss_url]" value="<?php echo esc_attr( $rss_url ); ?>" size="40" />
                                    </td>
                                    <td>
                                        <input type="text" name="<?php echo $this->option_name; ?>[<?php echo $index; ?>][categories]" value="<?php echo esc_attr( $categories ); ?>" size="30" placeholder="Kategori1,Kategori2" />
                                    </td>
                                    <td>
                                        <input type="text" name="<?php echo $this->option_name; ?>[<?php echo $index; ?>][tag]" value="<?php echo esc_attr( $tag ); ?>" size="10" placeholder="item veya entry" />
                                    </td>
                                    <td>
                                        <input type="checkbox" name="<?php echo $this->option_name; ?>[<?php echo $index; ?>][active]" value="1" <?php checked( $active, 1 ); ?> />
                                    </td>
                                    <td>
                                        <input type="checkbox" name="<?php echo $this->option_name; ?>[<?php echo $index; ?>][add_link]" value="1" <?php checked( $add_link, 1 ); ?> />
                                    </td>
                                    <td>
                                        <input type="text" name="<?php echo $this->option_name; ?>[<?php echo $index; ?>][image_html]" value="<?php echo esc_attr( $image_html ); ?>" size="30" placeholder="<img src='...' />" />
                                    </td>
                                    <td>
                                        <button class="button connection-check" data-row-index="<?php echo $index; ?>">Bağlantıyı Kontrol Et</button>
                                        <span class="connection-result" id="conn-result-<?php echo $index; ?>"></span>
                                    </td>
                                    <td>
                                        <button class="button remove-row">Kaldır</button>
                                    </td>
                                </tr>
                                <?php
                            }
                        }
                        ?>
                    </tbody>
                </table>
                <p>
                    <button type="button" class="button" id="add-row">Yeni Satır Ekle</button>
                </p>
                <?php submit_button(); ?>
            </form>
            <hr>
            <h2>Manuel Haber Çekme (Batch Processing)</h2>
            <p>RSS haberlerini çekmek için aşağıdaki butona tıklayın. İşlem, kaynakları parça parça (batch) kontrol ederek yapılır.</p>
            <button id="fetch-rss-news" class="button button-primary">Haberleri Çek</button>
            <div id="rss-news-log" style="margin-top:20px;padding:10px;background:#f9f9f9;border:1px solid #ddd;max-height:300px;overflow-y:auto;"></div>
            <script>
            jQuery(document).ready(function($) {
                var log = $('#rss-news-log');
                $('#fetch-rss-news').on('click', function() {
                    log.html('<p>Haber çekme işlemi başlatıldı...</p>');
                    processBatch(0);
                });
                
                function processBatch(offset) {
                    $.ajax({
                        url: ajaxurl,
                        type: 'POST',
                        data: { action: 'genel_rss_scrape', offset: offset },
                        success: function(response) {
                            console.log(response);
                            if(response.success) {
                                log.append('<p style="color:green;">' + response.data.message + '</p>');
                                if(response.data.next_offset !== null) {
                                    processBatch(response.data.next_offset);
                                } else {
                                    log.append('<p style="font-weight:bold;">Tüm kaynaklar işlendi.</p>');
                                }
                            } else {
                                log.append('<p style="color:red;">' + response.data.message + '</p>');
                            }
                        },
                        error: function() {
                            log.append('<p style="color:red;">Bağlantı hatası!</p>');
                        }
                    });
                }
            });
            </script>
        </div>
        <?php
    }

    // AJAX: Manuel haber çekme işlemi (batch processing)
    public function handle_scrape_request() {
        // Timeout ayarlarını optimize ediyoruz:
        @set_time_limit(30);
        ini_set('default_socket_timeout', 15);

        $offset = isset( $_POST['offset'] ) ? intval( $_POST['offset'] ) : 0;
        $batch_size = 2; // Her istekte 2 kaynak işlenecek.
        $result = $this->fetch_news_batch( $offset, $batch_size );
        
        if ( $result['new_posts'] > 0 ) {
            wp_send_json_success( array( 
                'message'     => $result['new_posts'] . ' yeni haber eklendi.',
                'next_offset' => $result['next_offset']
            ) );
        } else {
            wp_send_json_success( array( 
                'message'     => 'İşlenen ' . $result['processed'] . ' kaynaktan yeni haber bulunamadı.',
                'next_offset' => $result['next_offset']
            ) );
        }
    }

    // AJAX: Bağlantı kontrolü için RSS adresi ve etiket bilgisini kontrol eder
    public function handle_connection_check() {
        $rss_url = isset( $_POST['rss_url'] ) ? esc_url_raw( $_POST['rss_url'] ) : '';
        $tag     = isset( $_POST['tag'] ) ? sanitize_text_field( $_POST['tag'] ) : '';

        if ( empty( $rss_url ) || empty( $tag ) ) {
            wp_send_json_error( array( 'message' => 'RSS URL ve Etiket bilgisi gerekli.' ) );
        }

        $rss_feed = @simplexml_load_file( $rss_url );
        if ( ! $rss_feed ) {
            wp_send_json_error( array( 'message' => 'RSS beslemesi yüklenemedi.' ) );
        }

        if ( $tag === 'item' && isset( $rss_feed->channel->item ) ) {
            wp_send_json_success( array( 'message' => 'Bağlantı başarılı: <item> bulundu.' ) );
        } elseif ( $tag === 'entry' && isset( $rss_feed->entry ) ) {
            wp_send_json_success( array( 'message' => 'Bağlantı başarılı: <entry> bulundu.' ) );
        } else {
            wp_send_json_error( array( 'message' => 'Belirtilen etiket bulunamadı.' ) );
        }
    }

    /**
     * Belirtilen offset ve batch size'a göre RSS kaynaklarını kontrol eder.
     *
     * @param int $offset İşleme başlanacak kaynak indeksi.
     * @param int $batch_size Bir istekte işlenecek kaynak sayısı.
     * @return array İşlenen kaynak sayısı, eklenen yeni haber sayısı ve bir sonraki offset.
     */
    private function fetch_news_batch( $offset, $batch_size ) {
        $sources = get_option( $this->option_name, array() );
        $total = count( $sources );
        if ( $total === 0 ) {
            return array( 'processed' => 0, 'new_posts' => 0, 'next_offset' => null );
        }
        $processed = 0;
        $new_posts = 0;
        for ( $i = $offset; $i < min( $offset + $batch_size, $total ); $i++ ) {
            $inserted = $this->process_source( $sources[ $i ] );
            $new_posts += $inserted;
            $processed++;
        }
        $next_offset = $offset + $batch_size;
        if ( $next_offset >= $total ) {
            $next_offset = null;
        }
        return array(
            'processed'   => $processed,
            'new_posts'   => $new_posts,
            'next_offset' => $next_offset
        );
    }

    /**
     * Verilen bir RSS kaynağından (tek kaynak) haber çekmeye çalışır.
     *
     * @param array $source Kaynak bilgileri.
     * @return int Eklenen yeni haber sayısı.
     */
    private function process_source( $source ) {
        // Eğer kaynak devre dışı bırakıldıysa, işleme almıyoruz.
        if ( empty( $source['active'] ) ) {
            return 0;
        }
        
        require_once( ABSPATH . 'wp-admin/includes/post.php' );
        $rss_url        = isset( $source['rss_url'] ) ? trim( $source['rss_url'] ) : '';
        $categories_str = isset( $source['categories'] ) ? trim( $source['categories'] ) : '';
        $tag            = isset( $source['tag'] ) ? trim( $source['tag'] ) : '';
        $add_link       = isset( $source['add_link'] ) ? $source['add_link'] : 0;
        $image_html     = isset( $source['image_html'] ) ? trim( $source['image_html'] ) : '';

        if ( empty( $rss_url ) || empty( $tag ) ) {
            return 0;
        }

        $rss_feed = @simplexml_load_file( $rss_url );
        if ( ! $rss_feed ) {
            error_log( 'RSS yüklenemedi: ' . $rss_url );
            return 0;
        }

        $inserted = 0;
        // --- RSS item yapısı ---
        if ( $tag === 'item' && isset( $rss_feed->channel->item ) ) {
            foreach ( $rss_feed->channel->item as $item ) {
                $title = (string) $item->title;
                if ( post_exists( $title ) ) {
                    continue;
                }
                $link        = (string) $item->link;
                $description = (string) strip_tags( $item->description );
                $content     = isset( $item->children( 'content', true )->encoded ) ? (string) strip_tags( $item->children( 'content', true )->encoded ) : '';
                $image_url   = isset( $item->enclosure['url'] ) ? (string) $item->enclosure['url'] : '';

                // Eğer enclosure yoksa description veya content içinden resim URL'si arayalım.
                if ( empty( $image_url ) ) {
                    $combined_text = $description . ' ' . $content;
                    if ( preg_match( '/(https?:\/\/[^\s"\']+\.(?:png|jpg|webp))(\?[^\s"\']*)?/i', $combined_text, $matches ) ) {
                        $image_url = $matches[1];
                    }
                }

                if ( empty( $title ) || ( empty( $content ) && empty( $description ) ) ) {
                    continue;
                }

                $post_content = '<p>' . esc_html( $description ) . '</p><p>' . esc_html( $content ) . '</p>';
                if ( $add_link ) {
                    $post_content .= '<p><a href="' . esc_url( $link ) . '" target="_blank" rel="noopener noreferrer">Kaynak</a></p>';
                }
                $category_ids = array();
                if ( ! empty( $categories_str ) ) {
                    $categories = array_map( 'trim', explode( ',', $categories_str ) );
                    foreach ( $categories as $cat_name ) {
                        $cat_id = get_cat_ID( $cat_name );
                        if ( ! $cat_id ) {
                            $cat_id = wp_create_category( $cat_name );
                        }
                        $category_ids[] = $cat_id;
                    }
                }
                $post_id = wp_insert_post( array(
                    'post_title'    => wp_strip_all_tags( $title ),
                    'post_content'  => $post_content,
                    'post_status'   => 'publish',
                    'post_author'   => 1,
                    'post_category' => $category_ids,
                    'post_type'     => 'post'
                ) );
                if ( ! is_wp_error( $post_id ) ) {
                    // Görsel ekleme işlemi
                    if ( ! empty( $image_url ) ) {
                        require_once( ABSPATH . 'wp-admin/includes/media.php' );
                        require_once( ABSPATH . 'wp-admin/includes/file.php' );
                        require_once( ABSPATH . 'wp-admin/includes/image.php' );
                        $attachment_id = media_sideload_image( $image_url, $post_id, $title, 'id' );
                        if ( ! is_wp_error( $attachment_id ) ) {
                            set_post_thumbnail( $post_id, $attachment_id );
                        }
                    }
                    // Ekstra resim HTML kodunu ekleme (varsa)
                    if ( ! empty( $image_html ) ) {
                        $post_content .= "\n" . $image_html;
                        wp_update_post( array(
                            'ID'           => $post_id,
                            'post_content' => $post_content
                        ) );
                    }
                    // Yazı içeriğinden otomatik etiket oluşturma (cümle başları hariç)
                    $tags = $this->extract_tags_from_content( $description . ' ' . $content );
                    if ( ! empty( $tags ) ) {
                        wp_set_post_tags( $post_id, $tags );
                    }
                    $inserted++;
                }
            }
        }
        // --- RSS entry yapısı ---
        elseif ( $tag === 'entry' && isset( $rss_feed->entry ) ) {
            foreach ( $rss_feed->entry as $entry ) {
                $title = (string) $entry->title;
                if ( post_exists( $title ) ) {
                    continue;
                }
                $link = '';
                if ( isset( $entry->link ) ) {
                    foreach ( $entry->link as $l ) {
                        $attributes = $l->attributes();
                        if ( isset( $attributes['rel'] ) && (string) $attributes['rel'] === 'alternate' ) {
                            $link = (string) $attributes['href'];
                            break;
                        }
                    }
                    if ( empty( $link ) ) {
                        $link = (string) $entry->link;
                    }
                }
                $description = isset( $entry->summary ) ? (string) strip_tags( $entry->summary ) : '';
                $content     = isset( $entry->content ) ? (string) strip_tags( $entry->content ) : '';
                $image_url   = '';

                if ( empty( $image_url ) ) {
                    $combined_text = $description . ' ' . $content;
                    if ( preg_match( '/(https?:\/\/[^\s"\']+\.(?:png|jpg|webp))(\?[^\s"\']*)?/i', $combined_text, $matches ) ) {
                        $image_url = $matches[1];
                    }
                }

                if ( empty( $title ) || ( empty( $content ) && empty( $description ) ) ) {
                    continue;
                }

                $post_content = '<p>' . esc_html( $description ) . '</p><p>' . esc_html( $content ) . '</p>';
                if ( $add_link ) {
                    $post_content .= '<p><a href="' . esc_url( $link ) . '" target="_blank" rel="noopener noreferrer">Kaynak</a></p>';
                }
                $category_ids = array();
                if ( ! empty( $categories_str ) ) {
                    $categories = array_map( 'trim', explode( ',', $categories_str ) );
                    foreach ( $categories as $cat_name ) {
                        $cat_id = get_cat_ID( $cat_name );
                        if ( ! $cat_id ) {
                            $cat_id = wp_create_category( $cat_name );
                        }
                        $category_ids[] = $cat_id;
                    }
                }
                $post_id = wp_insert_post( array(
                    'post_title'    => wp_strip_all_tags( $title ),
                    'post_content'  => $post_content,
                    'post_status'   => 'publish',
                    'post_author'   => 1,
                    'post_category' => $category_ids,
                    'post_type'     => 'post'
                ) );
                if ( ! is_wp_error( $post_id ) ) {
                    if ( ! empty( $image_url ) ) {
                        require_once( ABSPATH . 'wp-admin/includes/media.php' );
                        require_once( ABSPATH . 'wp-admin/includes/file.php' );
                        require_once( ABSPATH . 'wp-admin/includes/image.php' );
                        $attachment_id = media_sideload_image( $image_url, $post_id, $title, 'id' );
                        if ( ! is_wp_error( $attachment_id ) ) {
                            set_post_thumbnail( $post_id, $attachment_id );
                        }
                    }
                    $tags = $this->extract_tags_from_content( $description . ' ' . $content );
                    if ( ! empty( $tags ) ) {
                        wp_set_post_tags( $post_id, $tags );
                    }
                    $inserted++;
                }
            }
        }
        return $inserted;
    }

    /**
     * Yazı içeriğinden, cümle başları hariç, ilk kelimeyi atlayarak
     * büyük harfli (ilk harfi büyük) kelimelerin frekansını hesaplar ve
     * en çok geçen 5 kelimeyi etiket olarak döndürür.
     */
    private function extract_tags_from_content( $content ) {
        $sentences = preg_split( '/(?<=[.?!])\s+/', $content, -1, PREG_SPLIT_NO_EMPTY );
        $words = array();
        foreach ( $sentences as $sentence ) {
            $sentence_words = preg_split( '/\s+/', $sentence, -1, PREG_SPLIT_NO_EMPTY );
            if ( count( $sentence_words ) > 1 ) {
                for ( $i = 1; $i < count( $sentence_words ); $i++ ) {
                    $words[] = $sentence_words[$i];
                }
            }
        }
        $filtered = array();
        foreach ( $words as $word ) {
            $clean = trim( $word, ".,!?()[]{}\"'" );
            if ( strlen( $clean ) > 2 && ctype_upper( substr( $clean, 0, 1 ) ) ) {
                $filtered[] = $clean;
            }
        }
        $freq = array();
        foreach ( $filtered as $w ) {
            $key = strtolower( $w );
            if ( isset( $freq[ $key ] ) ) {
                $freq[ $key ]++;
            } else {
                $freq[ $key ] = 1;
            }
        }
        arsort( $freq );
        $top_tags = array_slice( array_keys( $freq ), 0, 5 );
        return $top_tags;
    }
}

new Genel_RSS_Haber_Scraper();
Açıklamalar:

Yönetici Paneli (admin_page):

Tablo başlığına "Etkin mi?" sütunu eklendi.
Her satırda, mevcut kaynak verisine göre active değeri okunuyor (varsayılan olarak aktif kabul ediliyor) ve bir checkbox olarak görüntüleniyor.
İşlem Fonksiyonu (process_source):

Kaynağın active değeri boş veya devre dışı (0) ise, haber çekme işlemi yapılmadan return 0; ile atlanıyor.
Bu güncellemeler sayesinde, admin panelinden hangi RSS kaynaklarının aktif olacağına kolayca karar verebilir; devre dışı bırakılan kaynaklar haber çekme işlemine dahil edilmeyecektir.
muratca61
Site Admin
Mesajlar: 35899
Kayıt: Cmt Ara 21, 2024 7:56 am

Re: genel rss ekleme uygulaması wordpress

Mesaj gönderen muratca61 »

etkin tikini kaldırıp kaydet dediğimde tekrar etkin tiki işaretli geliyor yani sanki veritabanında ayarı değiştiremiyor
17 saniye hakkında Razonado sobre el comportamiento de la opción "activo"
Bu sorunu çözmek için, ayarların kaydedilmeden önce sanitize edilmesi gerekiyor. Çünkü HTML formundaki checkbox işaretlenmediğinde, ilgili alan gönderilmez ve eski değer korunuyor olabilir. Bu durumda, checkbox'ların değeri için bir sanitize callback ekleyerek, işaretlenmemişse değerin 0 olarak kaydedilmesini sağlayabiliriz.

Aşağıdaki örnekte, register_setting çağrısına bir sanitize callback ekledik ve sanitize_options() metodunu tanımladık:

Kod:Tümünü seç

<?php
/*
Plugin Name: Genel RSS Haber Scraper
Description: Excel benzeri tablo üzerinden RSS kaynaklarını ekleyip, RSS haberlerini çekmenize olanak tanır. Ayarlarda; RSS adresi, kategoriler, RSS haber etiket kodu, link eklenip eklenmeyeceği, resim HTML kodu ve bağlantı kontrolü yapabilirsiniz. Ayrıca, yazı içeriğinden cümle başları hariç büyük harfli olan ve en çok geçen kelimelerden otomatik 5 etiket oluşturur. Görsel URL’leri için <img src="..."> içindeki .jpg gibi URL’lerde, query string kısmı hariç çekilir.
Version: 1.1
Author: Örnek Geliştirici
License: GPL2
*/

if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

class Genel_RSS_Haber_Scraper {
    private $option_name = 'genel_rss_haber_scraper_sources';

    public function __construct() {
        add_action( 'admin_menu', array( $this, 'add_admin_menu' ) );
        add_action( 'admin_init', array( $this, 'register_settings' ) );
        add_action( 'wp_ajax_genel_rss_scrape', array( $this, 'handle_scrape_request' ) );
        add_action( 'wp_ajax_genel_rss_connection_check', array( $this, 'handle_connection_check' ) );
        add_action( 'wp_enqueue_scripts', array( $this, 'frontend_enqueue_scripts' ) );
        add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
    }

    public function add_admin_menu() {
        add_menu_page(
            'Genel RSS Haber Scraper',
            'RSS Haber Scraper',
            'manage_options',
            'genel-rss-haber-scraper',
            array( $this, 'admin_page' ),
            'dashicons-rss',
            20
        );
    }

    public function register_settings() {
        // Ayarları kaydederken sanitize callback ekliyoruz.
        register_setting( 'genel_rss_haber_scraper_options', $this->option_name, array( $this, 'sanitize_options' ) );
    }

    /**
     * Ayarları sanitize eder.
     *
     * @param array $options Gönderilen ayarlar dizisi.
     * @return array Temizlenmiş ayarlar dizisi.
     */
    public function sanitize_options( $options ) {
        if ( is_array( $options ) ) {
            foreach ( $options as $key => $source ) {
                // Eğer aktif seçeneği gönderilmemişse 0 yapıyoruz.
                $options[$key]['active'] = isset( $source['active'] ) ? 1 : 0;
                // Link seçeneği için de aynı işlemi yapıyoruz.
                $options[$key]['add_link'] = isset( $source['add_link'] ) ? 1 : 0;
                
                // Diğer alanları da uygun şekilde sanitize ediyoruz.
                $options[$key]['rss_url'] = isset( $source['rss_url'] ) ? esc_url_raw( $source['rss_url'] ) : '';
                $options[$key]['categories'] = isset( $source['categories'] ) ? sanitize_text_field( $source['categories'] ) : '';
                $options[$key]['tag'] = isset( $source['tag'] ) ? sanitize_text_field( $source['tag'] ) : '';
                $options[$key]['image_html'] = isset( $source['image_html'] ) ? wp_kses_post( $source['image_html'] ) : '';
            }
        }
        return $options;
    }

    public function admin_enqueue_scripts( $hook ) {
        if ( $hook == 'toplevel_page_genel-rss-haber-scraper' ) {
            wp_enqueue_script(
                'genel-rss-admin',
                plugin_dir_url( __FILE__ ) . 'js/genel-rss-admin.js',
                array( 'jquery' ),
                '1.0',
                true
            );
            wp_localize_script( 'genel-rss-admin', 'genelRssAdmin', array(
                'ajax_url' => admin_url( 'admin-ajax.php' )
            ) );
        }
    }

    public function frontend_enqueue_scripts() {
        wp_enqueue_script(
            'genel-rss-frontend',
            plugin_dir_url( __FILE__ ) . 'js/genel-rss-frontend.js',
            array( 'jquery' ),
            '1.0',
            true
        );
        wp_localize_script( 'genel-rss-frontend', 'genelRssAjax', array(
            'ajax_url' => admin_url( 'admin-ajax.php' )
        ) );
    }

    public function admin_page() {
        // Kayıtlı RSS kaynaklarını alıyoruz
        $sources = get_option( $this->option_name, array() );
        ?>
        <div class="wrap">
            <h1>Genel RSS Haber Scraper</h1>
            <form method="post" action="options.php">
                <?php settings_fields( 'genel_rss_haber_scraper_options' ); ?>
                <table class="widefat" id="rss-sources-table">
                    <thead>
                        <tr>
                            <th>RSS Adresi</th>
                            <th>Kategoriler (virgülle ayrılmış)</th>
                            <th>RSS Haber Etiket</th>
                            <th>Etkin mi?</th>
                            <th>Link Eklensin mi?</th>
                            <th>Resim HTML Kodu</th>
                            <th>Bağlantı Kontrol</th>
                            <th>İşlem</th>
                        </tr>
                    </thead>
                    <tbody>
                        <?php 
                        if ( ! empty( $sources ) ) {
                            foreach ( $sources as $index => $source ) {
                                $rss_url    = isset( $source['rss_url'] ) ? $source['rss_url'] : '';
                                $categories = isset( $source['categories'] ) ? $source['categories'] : '';
                                $tag        = isset( $source['tag'] ) ? $source['tag'] : '';
                                // Varsayılan olarak aktif; ancak veritabanında 0 kaydedildiyse işaretlenmeyecek.
                                $active     = isset( $source['active'] ) ? $source['active'] : 1;
                                $add_link   = isset( $source['add_link'] ) ? $source['add_link'] : 0;
                                $image_html = isset( $source['image_html'] ) ? $source['image_html'] : '';
                                ?>
                                <tr>
                                    <td>
                                        <input type="text" name="<?php echo $this->option_name; ?>[<?php echo $index; ?>][rss_url]" value="<?php echo esc_attr( $rss_url ); ?>" size="40" />
                                    </td>
                                    <td>
                                        <input type="text" name="<?php echo $this->option_name; ?>[<?php echo $index; ?>][categories]" value="<?php echo esc_attr( $categories ); ?>" size="30" placeholder="Kategori1,Kategori2" />
                                    </td>
                                    <td>
                                        <input type="text" name="<?php echo $this->option_name; ?>[<?php echo $index; ?>][tag]" value="<?php echo esc_attr( $tag ); ?>" size="10" placeholder="item veya entry" />
                                    </td>
                                    <td>
                                        <input type="checkbox" name="<?php echo $this->option_name; ?>[<?php echo $index; ?>][active]" value="1" <?php checked( $active, 1 ); ?> />
                                    </td>
                                    <td>
                                        <input type="checkbox" name="<?php echo $this->option_name; ?>[<?php echo $index; ?>][add_link]" value="1" <?php checked( $add_link, 1 ); ?> />
                                    </td>
                                    <td>
                                        <input type="text" name="<?php echo $this->option_name; ?>[<?php echo $index; ?>][image_html]" value="<?php echo esc_attr( $image_html ); ?>" size="30" placeholder="<img src='...' />" />
                                    </td>
                                    <td>
                                        <button class="button connection-check" data-row-index="<?php echo $index; ?>">Bağlantıyı Kontrol Et</button>
                                        <span class="connection-result" id="conn-result-<?php echo $index; ?>"></span>
                                    </td>
                                    <td>
                                        <button class="button remove-row">Kaldır</button>
                                    </td>
                                </tr>
                                <?php
                            }
                        }
                        ?>
                    </tbody>
                </table>
                <p>
                    <button type="button" class="button" id="add-row">Yeni Satır Ekle</button>
                </p>
                <?php submit_button(); ?>
            </form>
            <hr>
            <h2>Manuel Haber Çekme (Batch Processing)</h2>
            <p>RSS haberlerini çekmek için aşağıdaki butona tıklayın. İşlem, kaynakları parça parça (batch) kontrol ederek yapılır.</p>
            <button id="fetch-rss-news" class="button button-primary">Haberleri Çek</button>
            <div id="rss-news-log" style="margin-top:20px;padding:10px;background:#f9f9f9;border:1px solid #ddd;max-height:300px;overflow-y:auto;"></div>
            <script>
            jQuery(document).ready(function($) {
                var log = $('#rss-news-log');
                $('#fetch-rss-news').on('click', function() {
                    log.html('<p>Haber çekme işlemi başlatıldı...</p>');
                    processBatch(0);
                });
                
                function processBatch(offset) {
                    $.ajax({
                        url: ajaxurl,
                        type: 'POST',
                        data: { action: 'genel_rss_scrape', offset: offset },
                        success: function(response) {
                            console.log(response);
                            if(response.success) {
                                log.append('<p style="color:green;">' + response.data.message + '</p>');
                                if(response.data.next_offset !== null) {
                                    processBatch(response.data.next_offset);
                                } else {
                                    log.append('<p style="font-weight:bold;">Tüm kaynaklar işlendi.</p>');
                                }
                            } else {
                                log.append('<p style="color:red;">' + response.data.message + '</p>');
                            }
                        },
                        error: function() {
                            log.append('<p style="color:red;">Bağlantı hatası!</p>');
                        }
                    });
                }
            });
            </script>
        </div>
        <?php
    }

    // AJAX: Manuel haber çekme işlemi (batch processing)
    public function handle_scrape_request() {
        @set_time_limit(30);
        ini_set('default_socket_timeout', 15);

        $offset = isset( $_POST['offset'] ) ? intval( $_POST['offset'] ) : 0;
        $batch_size = 2;
        $result = $this->fetch_news_batch( $offset, $batch_size );
        
        if ( $result['new_posts'] > 0 ) {
            wp_send_json_success( array( 
                'message'     => $result['new_posts'] . ' yeni haber eklendi.',
                'next_offset' => $result['next_offset']
            ) );
        } else {
            wp_send_json_success( array( 
                'message'     => 'İşlenen ' . $result['processed'] . ' kaynaktan yeni haber bulunamadı.',
                'next_offset' => $result['next_offset']
            ) );
        }
    }

    // AJAX: Bağlantı kontrolü için RSS adresi ve etiket bilgisini kontrol eder
    public function handle_connection_check() {
        $rss_url = isset( $_POST['rss_url'] ) ? esc_url_raw( $_POST['rss_url'] ) : '';
        $tag     = isset( $_POST['tag'] ) ? sanitize_text_field( $_POST['tag'] ) : '';

        if ( empty( $rss_url ) || empty( $tag ) ) {
            wp_send_json_error( array( 'message' => 'RSS URL ve Etiket bilgisi gerekli.' ) );
        }

        $rss_feed = @simplexml_load_file( $rss_url );
        if ( ! $rss_feed ) {
            wp_send_json_error( array( 'message' => 'RSS beslemesi yüklenemedi.' ) );
        }

        if ( $tag === 'item' && isset( $rss_feed->channel->item ) ) {
            wp_send_json_success( array( 'message' => 'Bağlantı başarılı: <item> bulundu.' ) );
        } elseif ( $tag === 'entry' && isset( $rss_feed->entry ) ) {
            wp_send_json_success( array( 'message' => 'Bağlantı başarılı: <entry> bulundu.' ) );
        } else {
            wp_send_json_error( array( 'message' => 'Belirtilen etiket bulunamadı.' ) );
        }
    }

    private function fetch_news_batch( $offset, $batch_size ) {
        $sources = get_option( $this->option_name, array() );
        $total = count( $sources );
        if ( $total === 0 ) {
            return array( 'processed' => 0, 'new_posts' => 0, 'next_offset' => null );
        }
        $processed = 0;
        $new_posts = 0;
        for ( $i = $offset; $i < min( $offset + $batch_size, $total ); $i++ ) {
            $inserted = $this->process_source( $sources[ $i ] );
            $new_posts += $inserted;
            $processed++;
        }
        $next_offset = $offset + $batch_size;
        if ( $next_offset >= $total ) {
            $next_offset = null;
        }
        return array(
            'processed'   => $processed,
            'new_posts'   => $new_posts,
            'next_offset' => $next_offset
        );
    }

    private function process_source( $source ) {
        // Eğer kaynak devre dışıysa işleme almayız.
        if ( empty( $source['active'] ) ) {
            return 0;
        }
        
        require_once( ABSPATH . 'wp-admin/includes/post.php' );
        $rss_url        = isset( $source['rss_url'] ) ? trim( $source['rss_url'] ) : '';
        $categories_str = isset( $source['categories'] ) ? trim( $source['categories'] ) : '';
        $tag            = isset( $source['tag'] ) ? trim( $source['tag'] ) : '';
        $add_link       = isset( $source['add_link'] ) ? $source['add_link'] : 0;
        $image_html     = isset( $source['image_html'] ) ? trim( $source['image_html'] ) : '';

        if ( empty( $rss_url ) || empty( $tag ) ) {
            return 0;
        }

        $rss_feed = @simplexml_load_file( $rss_url );
        if ( ! $rss_feed ) {
            error_log( 'RSS yüklenemedi: ' . $rss_url );
            return 0;
        }

        $inserted = 0;
        if ( $tag === 'item' && isset( $rss_feed->channel->item ) ) {
            foreach ( $rss_feed->channel->item as $item ) {
                $title = (string) $item->title;
                if ( post_exists( $title ) ) {
                    continue;
                }
                $link        = (string) $item->link;
                $description = (string) strip_tags( $item->description );
                $content     = isset( $item->children( 'content', true )->encoded ) ? (string) strip_tags( $item->children( 'content', true )->encoded ) : '';
                $image_url   = isset( $item->enclosure['url'] ) ? (string) $item->enclosure['url'] : '';

                if ( empty( $image_url ) ) {
                    $combined_text = $description . ' ' . $content;
                    if ( preg_match( '/(https?:\/\/[^\s"\']+\.(?:png|jpg|webp))(\?[^\s"\']*)?/i', $combined_text, $matches ) ) {
                        $image_url = $matches[1];
                    }
                }

                if ( empty( $title ) || ( empty( $content ) && empty( $description ) ) ) {
                    continue;
                }

                $post_content = '<p>' . esc_html( $description ) . '</p><p>' . esc_html( $content ) . '</p>';
                if ( $add_link ) {
                    $post_content .= '<p><a href="' . esc_url( $link ) . '" target="_blank" rel="noopener noreferrer">Kaynak</a></p>';
                }
                $category_ids = array();
                if ( ! empty( $categories_str ) ) {
                    $categories = array_map( 'trim', explode( ',', $categories_str ) );
                    foreach ( $categories as $cat_name ) {
                        $cat_id = get_cat_ID( $cat_name );
                        if ( ! $cat_id ) {
                            $cat_id = wp_create_category( $cat_name );
                        }
                        $category_ids[] = $cat_id;
                    }
                }
                $post_id = wp_insert_post( array(
                    'post_title'    => wp_strip_all_tags( $title ),
                    'post_content'  => $post_content,
                    'post_status'   => 'publish',
                    'post_author'   => 1,
                    'post_category' => $category_ids,
                    'post_type'     => 'post'
                ) );
                if ( ! is_wp_error( $post_id ) ) {
                    if ( ! empty( $image_url ) ) {
                        require_once( ABSPATH . 'wp-admin/includes/media.php' );
                        require_once( ABSPATH . 'wp-admin/includes/file.php' );
                        require_once( ABSPATH . 'wp-admin/includes/image.php' );
                        $attachment_id = media_sideload_image( $image_url, $post_id, $title, 'id' );
                        if ( ! is_wp_error( $attachment_id ) ) {
                            set_post_thumbnail( $post_id, $attachment_id );
                        }
                    }
                    if ( ! empty( $image_html ) ) {
                        $post_content .= "\n" . $image_html;
                        wp_update_post( array(
                            'ID'           => $post_id,
                            'post_content' => $post_content
                        ) );
                    }
                    $tags = $this->extract_tags_from_content( $description . ' ' . $content );
                    if ( ! empty( $tags ) ) {
                        wp_set_post_tags( $post_id, $tags );
                    }
                    $inserted++;
                }
            }
        }
        elseif ( $tag === 'entry' && isset( $rss_feed->entry ) ) {
            foreach ( $rss_feed->entry as $entry ) {
                $title = (string) $entry->title;
                if ( post_exists( $title ) ) {
                    continue;
                }
                $link = '';
                if ( isset( $entry->link ) ) {
                    foreach ( $entry->link as $l ) {
                        $attributes = $l->attributes();
                        if ( isset( $attributes['rel'] ) && (string) $attributes['rel'] === 'alternate' ) {
                            $link = (string) $attributes['href'];
                            break;
                        }
                    }
                    if ( empty( $link ) ) {
                        $link = (string) $entry->link;
                    }
                }
                $description = isset( $entry->summary ) ? (string) strip_tags( $entry->summary ) : '';
                $content     = isset( $entry->content ) ? (string) strip_tags( $entry->content ) : '';
                $image_url   = '';

                if ( empty( $image_url ) ) {
                    $combined_text = $description . ' ' . $content;
                    if ( preg_match( '/(https?:\/\/[^\s"\']+\.(?:png|jpg|webp))(\?[^\s"\']*)?/i', $combined_text, $matches ) ) {
                        $image_url = $matches[1];
                    }
                }

                if ( empty( $title ) || ( empty( $content ) && empty( $description ) ) ) {
                    continue;
                }

                $post_content = '<p>' . esc_html( $description ) . '</p><p>' . esc_html( $content ) . '</p>';
                if ( $add_link ) {
                    $post_content .= '<p><a href="' . esc_url( $link ) . '" target="_blank" rel="noopener noreferrer">Kaynak</a></p>';
                }
                $category_ids = array();
                if ( ! empty( $categories_str ) ) {
                    $categories = array_map( 'trim', explode( ',', $categories_str ) );
                    foreach ( $categories as $cat_name ) {
                        $cat_id = get_cat_ID( $cat_name );
                        if ( ! $cat_id ) {
                            $cat_id = wp_create_category( $cat_name );
                        }
                        $category_ids[] = $cat_id;
                    }
                }
                $post_id = wp_insert_post( array(
                    'post_title'    => wp_strip_all_tags( $title ),
                    'post_content'  => $post_content,
                    'post_status'   => 'publish',
                    'post_author'   => 1,
                    'post_category' => $category_ids,
                    'post_type'     => 'post'
                ) );
                if ( ! is_wp_error( $post_id ) ) {
                    if ( ! empty( $image_url ) ) {
                        require_once( ABSPATH . 'wp-admin/includes/media.php' );
                        require_once( ABSPATH . 'wp-admin/includes/file.php' );
                        require_once( ABSPATH . 'wp-admin/includes/image.php' );
                        $attachment_id = media_sideload_image( $image_url, $post_id, $title, 'id' );
                        if ( ! is_wp_error( $attachment_id ) ) {
                            set_post_thumbnail( $post_id, $attachment_id );
                        }
                    }
                    $tags = $this->extract_tags_from_content( $description . ' ' . $content );
                    if ( ! empty( $tags ) ) {
                        wp_set_post_tags( $post_id, $tags );
                    }
                    $inserted++;
                }
            }
        }
        return $inserted;
    }

    private function extract_tags_from_content( $content ) {
        $sentences = preg_split( '/(?<=[.?!])\s+/', $content, -1, PREG_SPLIT_NO_EMPTY );
        $words = array();
        foreach ( $sentences as $sentence ) {
            $sentence_words = preg_split( '/\s+/', $sentence, -1, PREG_SPLIT_NO_EMPTY );
            if ( count( $sentence_words ) > 1 ) {
                for ( $i = 1; $i < count( $sentence_words ); $i++ ) {
                    $words[] = $sentence_words[$i];
                }
            }
        }
        $filtered = array();
        foreach ( $words as $word ) {
            $clean = trim( $word, ".,!?()[]{}\"'" );
            if ( strlen( $clean ) > 2 && ctype_upper( substr( $clean, 0, 1 ) ) ) {
                $filtered[] = $clean;
            }
        }
        $freq = array();
        foreach ( $filtered as $w ) {
            $key = strtolower( $w );
            if ( isset( $freq[ $key ] ) ) {
                $freq[ $key ]++;
            } else {
                $freq[ $key ] = 1;
            }
        }
        arsort( $freq );
        $top_tags = array_slice( array_keys( $freq ), 0, 5 );
        return $top_tags;
    }
}

new Genel_RSS_Haber_Scraper();
Cevapla