Plugin Directory

Changeset 3450163


Ignore:
Timestamp:
01/30/2026 06:16:37 AM (2 months ago)
Author:
santechidea
Message:

version 1.1.6

Location:
sti-rss-feed-reader/trunk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • sti-rss-feed-reader/trunk/admin/admin-page.php

    r3449452 r3450163  
    588588                                                <label>Feed Position</label>
    589589                                                <select name="profile_position[<?php echo esc_attr($i); ?>]">
    590                                                     <option value="after_header" <?php selected($p['position'] ?? '', 'after_header'); ?>>Before Header</option>
    591                                                     <option value="after_nav" <?php selected($p['position'] ?? '', 'after_nav'); ?>>After Navigation</option>
     590                                                    <option value="after_header" <?php selected($p['position'] ?? '', 'after_header'); ?>>After Header</option>
     591                                                    <option value="before_header" <?php selected($p['position'] ?? '', 'before_header'); ?>>Before Header</option>
    592592                                                    <option value="before_content" <?php selected($p['position'] ?? 'before_content', 'before_content'); ?>>Before Post</option>
    593593                                                    <option value="after_content" <?php selected($p['position'] ?? '', 'after_content'); ?>>After Post</option>
  • sti-rss-feed-reader/trunk/assets/css/frontend.css

    r3449452 r3450163  
    4646    grid-template-columns: repeat(var(--stirfr-cols, 2), minmax(0, 1fr));
    4747    gap: 14px;
    48     padding: 0% 3% 3% 0%;
     48    padding-bottom: 3%;
    4949}
    5050
     
    301301    color: var(--stirfr-text-color, inherit);
    302302}
     303
     304
     305/* =========================================
     306   FULL FIX: Remove left gap from grid feeds
     307   ========================================= */
     308
     309.stirfr-feed.stirfr-grid {
     310    padding-left: 0;
     311    padding-right: 0;
     312    margin-left: calc(-1 * var(--wp--style--root--padding-left, 16px));
     313    margin-right: calc(-1 * var(--wp--style--root--padding-right, 16px));
     314}
  • sti-rss-feed-reader/trunk/includes/shortcode.php

    r3449452 r3450163  
    1414    });
    1515   
    16     function stirfr_render_profile_by_position( string $position ) {
    17 
    18         if ( ! is_category() ) return;
    19 
    20         $cat = get_queried_object();
    21         if ( ! $cat || empty( $cat->term_id ) ) return;
    22 
    23         $profiles = get_option( 'stirfr_profiles', [] );
    24         if ( ! is_array( $profiles ) ) return;
    25 
    26         foreach ( $profiles as $id => $profile ) {
    27 
    28             if ( empty( $profile['active'] ) ) continue;
    29             if ( empty( $profile['category'] ) ) continue;
    30             if ( (int) $profile['category'] !== (int) $cat->term_id ) continue;
    31             if ( ($profile['position'] ?? 'before_content') !== $position ) continue;
    32 
    33             echo do_shortcode( '[stirfr_rss_feed id="' . (int) $id . '"]' );
    34             break; // one feed per position
    35         }
    36     }
    37     add_action( 'wp_body_open', function () {
    38         stirfr_render_profile_by_position( 'after_header' );
    39     }, 20 );
    40     add_action( 'get_header', function () {
    41         stirfr_render_profile_by_position( 'after_nav' );
    42     }, 30 );
    43     add_action( 'loop_start', function ( $query ) {
    44         if ( ! is_main_query() ) return;
    45         stirfr_render_profile_by_position( 'before_content' );
    46     }, 5 );
    47     add_action( 'loop_end', function ( $query ) {
    48         if ( ! is_main_query() ) return;
    49         stirfr_render_profile_by_position( 'after_content' );
    50     }, 20 );
    51     add_action( 'get_footer', function () {
    52         stirfr_render_profile_by_position( 'before_footer' );
    53     }, 5 );
    54     add_action( 'wp_footer', function () {
    55         stirfr_render_profile_by_position( 'after_footer' );
    56     }, 20 );
    57 
    58 
     16/**
     17 * ======================================================
     18 * AUTO HEADER / FOOTER POSITION LOGIC (JS ONLY)
     19 * Safe for all PHP versions
     20 * ======================================================
     21 */
     22function stirfr_auto_positions_js() {
     23
     24    if ( ! is_category() ) {
     25        return;
     26    }
     27
     28    $cat = get_queried_object();
     29    if ( ! $cat || empty( $cat->term_id ) ) {
     30        return;
     31    }
     32
     33    $profiles = get_option( 'stirfr_profiles', [] );
     34    if ( ! is_array( $profiles ) ) {
     35        return;
     36    }
     37
     38    $before_header = '';
     39    $after_header  = '';
     40    $before_footer = '';
     41
     42    foreach ( $profiles as $id => $profile ) {
     43
     44        if ( empty( $profile['active'] ) ) continue;
     45        if ( empty( $profile['category'] ) ) continue;
     46        if ( (int) $profile['category'] !== (int) $cat->term_id ) continue;
     47
     48        $pos = $profile['position'] ?? '';
     49
     50        if ( $pos === 'before_header' && ! $before_header ) {
     51            $before_header = do_shortcode( '[stirfr_rss_feed id="' . (int) $id . '"]' );
     52        }
     53
     54        if ( $pos === 'after_header' && ! $after_header ) {
     55            $after_header = do_shortcode( '[stirfr_rss_feed id="' . (int) $id . '"]' );
     56        }
     57
     58        if ( $pos === 'before_footer' && ! $before_footer ) {
     59            $before_footer = do_shortcode( '[stirfr_rss_feed id="' . (int) $id . '"]' );
     60        }
     61    }
     62
     63    if ( ! $before_header && ! $after_header && ! $before_footer ) {
     64        return;
     65    }
     66    ?>
     67    <script>
     68    document.addEventListener("DOMContentLoaded", function () {
     69
     70        function findHeader() {
     71            return (
     72                document.querySelector("header.site-header") ||
     73                document.querySelector("#masthead") ||
     74                document.querySelector("header") ||
     75                document.querySelector(".site-header")
     76            );
     77        }
     78
     79        function findFooter() {
     80            return (
     81                document.querySelector("footer.site-footer") ||
     82                document.querySelector("#colophon") ||
     83                document.querySelector("footer") ||
     84                document.querySelector(".site-footer")
     85            );
     86        }
     87
     88        var beforeHeaderHTML = <?php echo wp_json_encode( $before_header ); ?>;
     89        var afterHeaderHTML  = <?php echo wp_json_encode( $after_header ); ?>;
     90        var beforeFooterHTML = <?php echo wp_json_encode(
     91            '<div class="stirfr-before-footer">' . $before_footer . '</div>'
     92        ); ?>;
     93
     94        var header = findHeader();
     95        var footer = findFooter();
     96
     97        if (header) {
     98            if (beforeHeaderHTML) {
     99                header.insertAdjacentHTML("beforebegin", beforeHeaderHTML);
     100                console.log("STIRFR auto: before header");
     101            }
     102            if (afterHeaderHTML) {
     103                header.insertAdjacentHTML("afterend", afterHeaderHTML);
     104                console.log("STIRFR auto: after header");
     105            }
     106        }
     107
     108        if (footer && beforeFooterHTML) {
     109            footer.insertAdjacentHTML("beforebegin", beforeFooterHTML);
     110            console.log("STIRFR auto: before footer");
     111        }
     112
     113    });
     114    </script>
     115    <?php
     116}
     117add_action( 'wp_head', 'stirfr_auto_positions_js', 99 );
     118
     119
     120/**
     121 * ======================================================
     122 * RENDER PROFILE BY POSITION
     123 * ======================================================
     124 */
     125function stirfr_render_profile_by_position( string $position ) {
     126
     127    if ( ! is_category() ) return;
     128
     129    $cat = get_queried_object();
     130    if ( ! $cat || empty( $cat->term_id ) ) return;
     131
     132    $profiles = get_option( 'stirfr_profiles', [] );
     133    if ( ! is_array( $profiles ) ) return;
     134
     135    foreach ( $profiles as $id => $profile ) {
     136
     137        if ( empty( $profile['active'] ) ) continue;
     138        if ( empty( $profile['category'] ) ) continue;
     139        if ( (int) $profile['category'] !== (int) $cat->term_id ) continue;
     140
     141        if ( ( $profile['position'] ?? 'before_content' ) !== $position ) continue;
     142
     143        echo do_shortcode( '[stirfr_rss_feed id="' . (int) $id . '"]' );
     144        break;
     145    }
     146}
     147
     148/**
     149 * ======================================================
     150 * HEADER POSITIONS (JS)
     151 * ======================================================
     152 */
     153function stirfr_header_positions_js() {
     154
     155    if ( ! is_category() ) return;
     156
     157    $cat = get_queried_object();
     158    if ( ! $cat || empty( $cat->term_id ) ) return;
     159
     160    $profiles = get_option( 'stirfr_profiles', [] );
     161    if ( ! is_array( $profiles ) ) return;
     162
     163    $before_header_html = '';
     164    $after_header_html  = '';
     165
     166    foreach ( $profiles as $id => $profile ) {
     167
     168        if ( empty( $profile['active'] ) ) continue;
     169        if ( empty( $profile['category'] ) ) continue;
     170        if ( (int) $profile['category'] !== (int) $cat->term_id ) continue;
     171
     172        $pos = $profile['position'] ?? '';
     173
     174        if ( $pos === 'before_header' && empty( $before_header_html ) ) {
     175            $before_header_html = do_shortcode( '[stirfr_rss_feed id="' . (int) $id . '"]' );
     176        }
     177
     178        if ( $pos === 'after_header' && empty( $after_header_html ) ) {
     179            $after_header_html = do_shortcode( '[stirfr_rss_feed id="' . (int) $id . '"]' );
     180        }
     181    }
     182
     183    if ( ! $before_header_html && ! $after_header_html ) return;
     184    ?>
     185    <script>
     186    document.addEventListener("DOMContentLoaded", function () {
     187
     188        var beforeHeaderHTML = <?php echo wp_json_encode( $before_header_html ); ?>;
     189        var afterHeaderHTML  = <?php echo wp_json_encode( $after_header_html ); ?>;
     190
     191        var header =
     192            document.querySelector("header") ||
     193            document.querySelector("#masthead") ||
     194            document.querySelector(".site-header") ||
     195            document.querySelector(".header");
     196
     197        if (!header) return;
     198
     199        if (beforeHeaderHTML) {
     200            header.insertAdjacentHTML("beforebegin", beforeHeaderHTML);
     201        }
     202
     203        if (afterHeaderHTML) {
     204            header.insertAdjacentHTML("afterend", afterHeaderHTML);
     205        }
     206
     207    });
     208    </script>
     209    <?php
     210}
     211add_action( 'wp_head', 'stirfr_header_positions_js', 99 );
     212
     213/**
     214 * ======================================================
     215 * BEFORE CONTENT
     216 * ======================================================
     217 */
     218add_action( 'loop_start', function ( $query ) {
     219    if ( ! $query->is_main_query() ) return;
     220    stirfr_render_profile_by_position( 'before_content' );
     221}, 5 );
     222
     223/**
     224 * ======================================================
     225 * AFTER CONTENT
     226 * ======================================================
     227 */
     228add_action( 'loop_end', function ( $query ) {
     229    if ( ! $query->is_main_query() ) return;
     230    stirfr_render_profile_by_position( 'after_content' );
     231}, 20 );
     232
     233/**
     234 * ======================================================
     235 * FOOTER ZONE (HONEST & STABLE)
     236 * ======================================================
     237 */
     238
     239
     240
     241/* After footer scripts */
     242add_action( 'wp_footer', function () {
     243    stirfr_render_profile_by_position( 'after_footer' );
     244}, 50 );
     245
     246function stirfr_visual_before_footer_js() {
     247
     248    if ( ! is_category() ) return;
     249
     250    $cat = get_queried_object();
     251    if ( ! $cat || empty( $cat->term_id ) ) return;
     252
     253    $profiles = get_option( 'stirfr_profiles', [] );
     254    if ( ! is_array( $profiles ) ) return;
     255
     256    $html = '';
     257
     258    foreach ( $profiles as $id => $profile ) {
     259
     260        if ( empty( $profile['active'] ) ) continue;
     261        if ( empty( $profile['category'] ) ) continue;
     262        if ( (int) $profile['category'] !== (int) $cat->term_id ) continue;
     263        if ( ( $profile['position'] ?? '' ) !== 'before_footer' ) continue;
     264
     265        $html = do_shortcode( '[stirfr_rss_feed id="' . (int) $id . '"]' );
     266        break;
     267    }
     268
     269    if ( ! $html ) return;
     270    ?>
     271    <script>
     272    document.addEventListener("DOMContentLoaded", function () {
     273
     274        var html = <?php echo wp_json_encode(
     275            '<div class="stirfr-before-footer">' . $html . '</div>'
     276        ); ?>;
     277
     278        /* 🔒 SITE FOOTER ONLY (NO BLOCK FOOTERS) */
     279        var siteFooter =
     280            document.querySelector("footer.site-footer") ||
     281            document.querySelector("#colophon") ||
     282            document.querySelector("footer#footer") ||
     283            document.querySelector(".site-footer");
     284
     285        if (!siteFooter) {
     286            console.warn("STIRFR: Site footer not found");
     287            return;
     288        }
     289
     290        siteFooter.insertAdjacentHTML("beforebegin", html);
     291
     292        console.log("STIRFR: Injected before SITE footer");
     293
     294    });
     295    </script>
     296    <?php
     297}
     298add_action( 'wp_head', 'stirfr_visual_before_footer_js', 99 );
     299
     300   
    59301    add_action( 'stirfr_bg_fetch_image', 'stirfr_bg_fetch_image_handler', 10, 1 );
    60302
     
    344586        if (!$candidates) return '';
    345587
    346         usort($candidates, fn($a,$b) => $b['score'] <=> $a['score']);
     588        usort($candidates, function ($a, $b) {
     589            return $b['score'] <=> $a['score'];
     590        });
     591
    347592        $best = $candidates[0]['node'];
    348593
     
    599844
    600845            $ok = @imagewebp($image_resource, $dest_path, 82);
    601             if ( $image_resource instanceof GdImage ) {
     846            if ( is_object( $image_resource ) ) {
    602847                unset( $image_resource );
    603848            } elseif ( is_resource( $image_resource ) ) {
     
    709954     * Create a WP post from a feed item (deduped, with expiry meta).
    710955     */
    711     function stirfr_store_feed_item_as_post(array $args): ?int {
     956    function stirfr_store_feed_item_as_post(array $args) {
     957
    712958        // --- Normalize inputs ---
    713959        $title   = isset($args['title'])  ? wp_strip_all_tags((string)$args['title']) : '';
  • sti-rss-feed-reader/trunk/readme.txt

    r3449452 r3450163  
    55Tested up to: 6.9
    66Requires PHP: 7.4
    7 Stable tag: 1.1.5
     7Stable tag: 1.1.6
    88License: GPLv2 or later
    99License URI: https://www.gnu.org/licenses/gpl-2.0.html
     
    5353
    5454== Changelog ==
     55
     56
     57= 1.1.6 =
     58
     59* Improved the Structure of Feed.
     60* Fixed the Positioning of Feed.
     61
    5562
    5663= 1.1.5 =
  • sti-rss-feed-reader/trunk/sti-rss-feed-reader.php

    r3449452 r3450163  
    33Plugin Name: STI RSS Feed Reader
    44Description: A simple RSS feed reader with image fallback, layout options, and optional feed source display.
    5 Version: 1.1.5
     5Version: 1.1.6
    66Author: Santechidea
    77Text Domain: sti-rss-feed-reader
     
    1818if (!defined('STIRFR_PLUGIN_URL'))  define('STIRFR_PLUGIN_URL', plugin_dir_url(__FILE__));
    1919if (!defined('STIRFR_PLUGIN_PATH')) define('STIRFR_PLUGIN_PATH', plugin_dir_path(__FILE__));
    20 if (!defined('STIRFR_PLUGIN_VER'))  define('STIRFR_PLUGIN_VER', '1.1.5');
     20if (!defined('STIRFR_PLUGIN_VER'))  define('STIRFR_PLUGIN_VER', '1.1.6');
    2121
    2222// Load admin page
Note: See TracChangeset for help on using the changeset viewer.