vergiği cevap cgpt
bu iyi fena değilKod: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 eklensin mi, 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, array( $this, 'sanitize_options' ) ); } public function sanitize_options( $options ) { if ( is_array( $options ) ) { foreach ( $options as $key => $source ) { $options[$key]['active'] = isset( $source['active'] ) ? 1 : 0; $options[$key]['add_link'] = isset( $source['add_link'] ) ? 1 : 0; $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() { $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; $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ı sırayla kontrol eder.</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'); // Global offset; başlangıçta 0 var currentOffset = 0; // Kayıtlı RSS sayısı (toplam kaynak sayısı) var totalSources = <?php echo count($sources); ?>; $('#fetch-rss-news').on('click', function() { log.html('<p>Haber çekme işlemi başlatıldı...</p>'); processBatch(currentOffset); }); function processBatch(offset) { $.ajax({ url: genelRssAdmin.ajax_url, 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>'); // İşlem sonrası güncellenen offset değerini alıyoruz currentOffset = response.data.next_offset; // Eğer tüm kaynaklar işlendi ise if ( currentOffset >= totalSources ) { 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); // Eğer offset POST ile gönderilmişse onu kullan, yoksa veritabanından al (varsayılan 0) $offset = isset($_POST['offset']) ? intval($_POST['offset']) : intval(get_option('genel_rss_last_offset', 0)); $batch_size = 2; $result = $this->fetch_news_batch( $offset, $batch_size ); // Güncel offset değerini veritabanına kaydediyoruz update_option('genel_rss_last_offset', $result['next_offset']); $sources = get_option( $this->option_name, array() ); $totalSources = count($sources); if ( $result['processed'] === 0 && $offset >= $totalSources ) { wp_send_json_success( array( 'message' => 'Tüm kaynaklar işlendi.', 'new_posts' => 0, 'next_offset' => $result['next_offset'], 'total' => $totalSources ) ); } if ( $result['new_posts'] > 0 ) { wp_send_json_success( array( 'message' => $result['new_posts'] . ' yeni haber eklendi.', 'new_posts' => $result['new_posts'], 'next_offset' => $result['next_offset'], 'total' => $totalSources ) ); } else { wp_send_json_success( array( 'message' => 'İşlenen ' . $result['processed'] . ' kaynaktan yeni haber bulunamadı.', 'new_posts' => 0, 'next_offset' => $result['next_offset'], 'total' => $totalSources ) ); } } /** * Belirtilen offset ve batch size’a göre RSS kaynaklarını kontrol eder. * Eğer offset kaynak sayısını aştıysa hiçbir işlem yapılmaz. */ private function fetch_news_batch( $offset, $batch_size ) { $sources = get_option( $this->option_name, array() ); $total = count( $sources ); if ( $offset >= $total ) { return array( 'processed' => 0, 'new_posts' => 0, 'next_offset' => $offset ); } $processed = 0; $new_posts = 0; $end = min( $offset + $batch_size, $total ); for ( $i = $offset; $i < $end; $i++ ) { $inserted = $this->process_source( $sources[ $i ] ); $new_posts += $inserted; $processed++; } // İşlenen kaynakların ardından offset’i artırıyoruz. $next_offset = $offset + $batch_size; return array( 'processed' => $processed, 'new_posts' => $new_posts, 'next_offset' => $next_offset ); } /** * Verilen bir RSS kaynağından haber çekmeye çalışır. */ private function process_source( $source ) { 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; } /** * Yazı içeriğinden cümle başları hariç büyük harfli 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(); ?>
genel rss ekleme uygulaması wordpress
Re: genel rss ekleme uygulaması wordpress
Re: genel rss ekleme uygulaması wordpress
sistemi ağırlaştırmasın bunun için sorgulama adedi her tıklamada tek rss her seferinde bir sonraki rss den tek sorgu yapsın yeni veri varsa çeksin yoksa diğer rss ye geçsin.Aşağıdaki kod, her sayfa tıklamasında (butona basıldığında) yalnızca 1 RSS kaynağını sorgulayacak şekilde güncellendi. Yani:
Her Tıklamada: Sadece tek bir RSS kaynağı kontrol edilir.
Eğer Yeni Haber Varsa: Haberler eklenir.
Eğer Yeni Haber Yoksa: Sorgu sonuçlanır ve sonraki tıklamada listede bir sonraki RSS kaynağı kontrol edilir.
Offset Yönetimi: İşlenen RSS kaynağının indeksi global olarak (ve/veya veritabanında) güncellenir. Listenin sonuna gelindiğinde sıfırlanır (döngüsel).
Aşağıda dosyanın tamamı ve işleyiş mantığı özetlenmiştir: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 eklensin mi, 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, array( $this, 'sanitize_options' ) ); } public function sanitize_options( $options ) { if ( is_array( $options ) ) { foreach ( $options as $key => $source ) { $options[$key]['active'] = isset( $source['active'] ) ? 1 : 0; $options[$key]['add_link'] = isset( $source['add_link'] ) ? 1 : 0; $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() { $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; $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 (Tek RSS Sorgusu)</h2> <p>Her tıklamada listedeki bir sonraki RSS kaynağından tek sorgu yapılır. Eğer yeni veri varsa çekilir, yoksa diğer RSS’e geçilir.</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'); // Global offset başlangıç değeri var currentOffset = 0; // Kayıtlı RSS sayısı var totalSources = <?php echo count($sources); ?>; $('#fetch-rss-news').on('click', function() { log.html('<p>Haber çekme işlemi başlatıldı...</p>'); processSingle(currentOffset); }); function processSingle(offset) { $.ajax({ url: genelRssAdmin.ajax_url, 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>'); // Yeni offset’i alıyoruz currentOffset = response.data.next_offset; // Döngüsel kontrol: Eğer offset tüm kaynaklara ulaştıysa yeniden 0’dan başlatıyoruz if ( currentOffset >= totalSources ) { currentOffset = 0; log.append('<p style="font-weight:bold;">Tüm RSS kaynakları kontrol edildi.</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: Her tıklamada tek bir RSS kaynağı üzerinden haber çekme işlemi public function handle_scrape_request() { @set_time_limit(30); ini_set('default_socket_timeout', 15); // POST ile gelen offset veya veritabanında saklı offset kullanılıyor (varsayılan 0) $offset = isset($_POST['offset']) ? intval($_POST['offset']) : intval(get_option('genel_rss_last_offset', 0)); // Sorgulama adedi her tıklamada 1 RSS için $batch_size = 1; $result = $this->fetch_news_batch( $offset, $batch_size ); // Güncel offset’i veritabanına kaydediyoruz update_option('genel_rss_last_offset', $result['next_offset']); $sources = get_option( $this->option_name, array() ); $totalSources = count($sources); if ( $result['processed'] === 0 ) { wp_send_json_success( array( 'message' => 'Hiçbir RSS kaynağı işlenemedi.', 'new_posts' => 0, 'next_offset' => $result['next_offset'], 'total' => $totalSources ) ); } if ( $result['new_posts'] > 0 ) { wp_send_json_success( array( 'message' => $result['new_posts'] . ' yeni haber eklendi.', 'new_posts' => $result['new_posts'], 'next_offset' => $result['next_offset'], 'total' => $totalSources ) ); } else { wp_send_json_success( array( 'message' => 'İşlenen RSS için yeni haber bulunamadı.', 'new_posts' => 0, 'next_offset' => $result['next_offset'], 'total' => $totalSources ) ); } } /** * Belirtilen offset’ten başlayarak tek RSS kaynağını kontrol eder. * Offset, döngüsel olarak (modulo) güncellenir. */ 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' => 0 ); } // Offset’in listenin boyutuna göre modunu alıyoruz (döngüsel sorgu) $offset = $offset % $total; $processed = 0; $new_posts = 0; // Sadece tek RSS kaynağı işlenecek $source = $sources[$offset]; $inserted = $this->process_source( $source ); $new_posts += $inserted; $processed++; // Sonraki offset’i modulo ile belirleyelim $next_offset = ($offset + 1) % $total; return array( 'processed' => $processed, 'new_posts' => $new_posts, 'next_offset' => $next_offset ); } /** * Verilen bir RSS kaynağından haber çekmeye çalışır. */ private function process_source( $source ) { 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; } /** * Yazı içeriğinden cümle başları hariç, büyük harfle başlayan 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(); ?>
Re: genel rss ekleme uygulaması wordpress
son güncellemede rss den tek yeni haber alıp sonraki rss ye geçecek
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 eklensin mi, 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, array( $this, 'sanitize_options' ) ); } public function sanitize_options( $options ) { if ( is_array( $options ) ) { foreach ( $options as $key => $source ) { $options[$key]['active'] = isset( $source['active'] ) ? 1 : 0; $options[$key]['add_link'] = isset( $source['add_link'] ) ? 1 : 0; $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() { $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; $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 (Tek RSS Sorgusu)</h2> <p>Her tıklamada listede sıradaki RSS kaynağından, daha önce çekilmemiş tek haber sorgulanı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'); // Global offset başlangıç değeri var currentOffset = 0; // Kayıtlı RSS sayısı var totalSources = <?php echo count($sources); ?>; $('#fetch-rss-news').on('click', function() { log.html('<p>Haber çekme işlemi başlatıldı...</p>'); processSingle(currentOffset); }); function processSingle(offset) { $.ajax({ url: genelRssAdmin.ajax_url, 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>'); // Yeni offset’i alıyoruz currentOffset = response.data.next_offset; // Döngüsel kontrol: Eğer offset tüm kaynaklara ulaştıysa yeniden 0’dan başlatıyoruz if ( currentOffset >= totalSources ) { currentOffset = 0; log.append('<p style="font-weight:bold;">Tüm RSS kaynakları kontrol edildi.</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: Her tıklamada tek bir RSS kaynağından, daha önce çekilmemiş tek haber sorgulama işlemi public function handle_scrape_request() { @set_time_limit(30); ini_set('default_socket_timeout', 15); // POST ile gelen offset veya veritabanında saklı offset kullanılıyor (varsayılan 0) $offset = isset($_POST['offset']) ? intval($_POST['offset']) : intval(get_option('genel_rss_last_offset', 0)); // Her tıklamada 1 RSS için sorgu yapılacak $batch_size = 1; $result = $this->fetch_news_batch( $offset, $batch_size ); // Güncel offset’i veritabanına kaydediyoruz update_option('genel_rss_last_offset', $result['next_offset']); $sources = get_option( $this->option_name, array() ); $totalSources = count($sources); if ( $result['processed'] === 0 ) { wp_send_json_success( array( 'message' => 'Hiçbir RSS kaynağı işlenemedi.', 'new_posts' => 0, 'next_offset' => $result['next_offset'], 'total' => $totalSources ) ); } if ( $result['new_posts'] > 0 ) { wp_send_json_success( array( 'message' => $result['new_posts'] . ' yeni haber eklendi.', 'new_posts' => $result['new_posts'], 'next_offset' => $result['next_offset'], 'total' => $totalSources ) ); } else { wp_send_json_success( array( 'message' => 'İşlenen RSS için yeni haber bulunamadı.', 'new_posts' => 0, 'next_offset' => $result['next_offset'], 'total' => $totalSources ) ); } } /** * Belirtilen offset’ten başlayarak tek RSS kaynağını kontrol eder. * Offset, döngüsel olarak (modulo) güncellenir. */ 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' => 0 ); } // Offset’in listenin boyutuna göre modunu alıyoruz (döngüsel sorgu) $offset = $offset % $total; $processed = 0; $new_posts = 0; // Sadece tek RSS kaynağı işlenecek $source = $sources[$offset]; $inserted = $this->process_source( $source ); $new_posts += $inserted; $processed++; // Sonraki offset’i modulo ile belirleyelim $next_offset = ($offset + 1) % $total; return array( 'processed' => $processed, 'new_posts' => $new_posts, 'next_offset' => $next_offset ); } /** * Verilen bir RSS kaynağından, daha önce çekilmemiş **tek haber** çekmeye çalışır. */ private function process_source( $source ) { 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++; // Tek haber çekildi, döngüyü sonlandır break; } } } 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++; // Tek haber çekildi, döngüyü sonlandır break; } } } return $inserted; } /** * Yazı içeriğinden cümle başları hariç, büyük harfle başlayan 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(); ?>
Re: genel rss ekleme uygulaması wordpress
döngüsel sorun ve bağlantı hatası sorunlarKod: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 eklensin mi, 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, array( $this, 'sanitize_options' ) ); } public function sanitize_options( $options ) { if ( is_array( $options ) ) { foreach ( $options as $key => $source ) { $options[$key]['active'] = isset( $source['active'] ) ? 1 : 0; $options[$key]['add_link'] = isset( $source['add_link'] ) ? 1 : 0; $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() { $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; $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 (Tek RSS Sorgusu)</h2> <p>Her tıklamada listede sıradaki RSS kaynağından, daha önce çekilmemiş tek haber sorgulanı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'); // Global offset başlangıç değeri var currentOffset = 0; // Kayıtlı RSS sayısı var totalSources = <?php echo count($sources); ?>; $('#fetch-rss-news').on('click', function() { log.html('<p>Haber çekme işlemi başlatıldı...</p>'); processSingle(currentOffset); }); function processSingle(offset) { $.ajax({ url: genelRssAdmin.ajax_url, 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>'); // Yeni offset’i alıyoruz currentOffset = response.data.next_offset; // Döngüsel kontrol: Eğer offset tüm kaynaklara ulaştıysa yeniden 0’dan başlatıyoruz if ( currentOffset >= totalSources ) { currentOffset = 0; log.append('<p style="font-weight:bold;">Tüm RSS kaynakları kontrol edildi.</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: Her tıklamada tek bir RSS kaynağından, daha önce çekilmemiş tek haber sorgulama işlemi public function handle_scrape_request() { @set_time_limit(30); ini_set('default_socket_timeout', 15); // POST ile gelen offset veya veritabanında saklı offset kullanılıyor (varsayılan 0) $offset = isset($_POST['offset']) ? intval($_POST['offset']) : intval(get_option('genel_rss_last_offset', 0)); // Her tıklamada 1 RSS için sorgu yapılacak $batch_size = 1; $result = $this->fetch_news_batch( $offset, $batch_size ); // Güncel offset’i veritabanına kaydediyoruz update_option('genel_rss_last_offset', $result['next_offset']); $sources = get_option( $this->option_name, array() ); $totalSources = count($sources); if ( $result['processed'] === 0 ) { wp_send_json_success( array( 'message' => 'Hiçbir RSS kaynağı işlenemedi.', 'new_posts' => 0, 'next_offset' => $result['next_offset'], 'total' => $totalSources ) ); } if ( $result['new_posts'] > 0 ) { wp_send_json_success( array( 'message' => $result['new_posts'] . ' yeni haber eklendi.', 'new_posts' => $result['new_posts'], 'next_offset' => $result['next_offset'], 'total' => $totalSources ) ); } else { wp_send_json_success( array( 'message' => 'İşlenen RSS için yeni haber bulunamadı.', 'new_posts' => 0, 'next_offset' => $result['next_offset'], 'total' => $totalSources ) ); } } /** * Belirtilen offset’ten başlayarak tek RSS kaynağını kontrol eder. * Offset, döngüsel olarak (modulo) güncellenir. */ 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' => 0 ); } // Offset’i listenin boyutuna göre döngüsel hale getiriyoruz. $offset = $offset % $total; $processed = 0; $new_posts = 0; // Sadece tek RSS kaynağı işlenecek $source = $sources[$offset]; $inserted = $this->process_source( $source ); $new_posts += $inserted; $processed++; // Sonraki offset’i döngüsel olarak hesaplıyoruz. $next_offset = ($offset + 1) % $total; return array( 'processed' => $processed, 'new_posts' => $new_posts, 'next_offset' => $next_offset ); } /** * Verilen bir RSS kaynağından, daha önce çekilmemiş **tek haber** çekmeye çalışır. * Bağlantı sorunlarını gidermek için wp_remote_get ile veriyi çekip, simplexml_load_string ile parse ediyoruz. */ private function process_source( $source ) { 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; } // wp_remote_get kullanarak RSS verisini çekiyoruz. $response = wp_remote_get( $rss_url, array( 'timeout' => 15 ) ); if ( is_wp_error( $response ) ) { error_log( 'RSS çekilemedi: ' . $rss_url . ' Hata: ' . $response->get_error_message() ); return 0; } $body = wp_remote_retrieve_body( $response ); if ( empty( $body ) ) { error_log( 'RSS içeriği boş: ' . $rss_url ); return 0; } $rss_feed = @simplexml_load_string( $body ); if ( ! $rss_feed ) { error_log( 'RSS XML parse edilemedi: ' . $rss_url ); return 0; } $inserted = 0; // Hem <item> hem de <entry> etiketleri için kontrol 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++; // Tek haber çekildi, döngüden çıkıyoruz. break; } } } 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++; // Tek haber çekildi, döngüden çıkıyoruz. break; } } } return $inserted; } /** * Yazı içeriğinden cümle başları hariç, büyük harfle başlayan 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(); ?>