Plugin Directory

Changeset 3444917


Ignore:
Timestamp:
01/22/2026 02:44:26 PM (2 months ago)
Author:
mharisart
Message:

Update WLCP: use CoinGecko /coins/markets API, dynamic icons/names/symbols, add 24h price change & symbol columns, refactor get_coin_markets(), fix missing icons/symbols

Location:
live-crypto-prices
Files:
16 added
8 edited

Legend:

Unmodified
Added
Removed
  • live-crypto-prices/trunk/admin/wlcp-admin-settings.php

    r3443883 r3444917  
    7272            <li><code>[wlcp_tabs]</code> – Multi-Currency Tabs</li>
    7373        </ul>
     74
     75    <hr>
     76
     77    <h2><?php esc_html_e( 'Display Mode', 'live-crypto-prices' ); ?></h2>
     78
     79    <p>
     80    <?php esc_html_e(
     81        'You can control the color theme (Light or Dark) using the mode attribute in shortcodes.',
     82        'live-crypto-prices'
     83    ); ?>
     84    </p>
     85
     86    <ul>
     87    <li>
     88        <code>[wlcp_ticker mode="light"]</code> – <?php esc_html_e( 'Light mode (default)', 'live-crypto-prices' ); ?>
     89    </li>
     90    <li>
     91        <code>[wlcp_ticker mode="dark"]</code> – <?php esc_html_e( 'Dark mode', 'live-crypto-prices' ); ?>
     92    </li>
     93    </ul>
     94
     95    <p class="description">
     96    <?php esc_html_e(
     97        'The mode attribute works with all available shortcodes.',
     98        'live-crypto-prices'
     99    ); ?>
     100    </p>
     101   
     102
    74103    </div>
    75104    <?php
  • live-crypto-prices/trunk/assets/css/wlcp-style.css

    r3443883 r3444917  
    3939    color: #ffffff;
    4040}
     41
     42/* Tabs Styling */
     43
     44/* Wrapper */
     45.wlcp-tabs-wrapper {
     46  border-radius: 10px;
     47  padding: 14px;
     48}
     49
     50/* Tabs */
     51.wlcp-tab-buttons {
     52  display: flex;
     53  gap: 10px;
     54  margin-bottom: 14px;
     55}
     56
     57.wlcp-tab-buttons button {
     58  flex: 1;
     59  padding: 8px 0;
     60  border: none;
     61  cursor: pointer;
     62  font-weight: 600;
     63  border-radius: 6px;
     64  background: #e2e8f0;
     65  transition: 0.3s;
     66}
     67
     68.wlcp-dark-mode .wlcp-tab-buttons button {
     69  background: #1e293b;
     70  color: #fff;
     71}
     72
     73.wlcp-tab-buttons button.active {
     74  background: #38bdf8;
     75  color: #020617;
     76}
     77
     78/* Rows */
     79.wlcp-tabs-wrapper .wlcp-row {
     80  display: flex;
     81  justify-content: space-between;
     82  padding: 10px 0;
     83  border-bottom: 1px solid #cbd5f5;
     84}
     85
     86.wlcp-dark-mode .wlcp-row {
     87  border-color: #1e293b;
     88}
     89
     90.wlcp-tabs-wrapper .wlcp-row strong {
     91  font-weight: 600;
     92}
  • live-crypto-prices/trunk/assets/js/wlcp-script.js

    r3443883 r3444917  
    11console.log('WLCP plugin JS loaded');
     2
     3document.addEventListener('DOMContentLoaded', function() {
     4    const buttons = document.querySelectorAll('.wlcp-tab-button');
     5    const contents = document.querySelectorAll('.wlcp-tab-content');
     6   
     7    buttons.forEach(button => {
     8        button.addEventListener('click', function() {
     9            const currency = this.getAttribute('data-currency');
     10           
     11            // Remove active class from all buttons
     12            buttons.forEach(btn => btn.classList.remove('active'));
     13            // Add active class to clicked button
     14            this.classList.add('active');
     15           
     16            // Hide all content
     17            contents.forEach(content => content.style.display = 'none');
     18            // Show selected content
     19            document.querySelector('.wlcp-tab-content[data-currency="' + currency + '"]').style.display = 'block';
     20        });
     21    });
     22});
  • live-crypto-prices/trunk/includes/class-wlcp-api.php

    r3443883 r3444917  
    11<?php
    22class WLCP_API {
    3     public static function fetch_data( $endpoint ) {
    4         $url = 'https://api.coingecko.com/api/v3/' . $endpoint .'&include_24hr_change=true';
     3    public static function fetch_data( $url ) {
    54        $response = wp_remote_get( $url );
    65
     
    109    }
    1110
     11    /**
     12     * Get coin price using simple/price endpoint (lightweight, no images/symbols)
     13     */
    1214    public static function get_coin_price( $ids = 'bitcoin,ethereum', $vs_currencies = 'usd' ) {
    13         return self::fetch_data( "simple/price?ids={$ids}&vs_currencies={$vs_currencies}" );
     15        $url = 'https://api.coingecko.com/api/v3/simple/price?ids=' . $ids . '&vs_currencies=' . $vs_currencies . '&include_24hr_change=true';
     16        return self::fetch_data( $url );
     17    }
     18
     19    /**
     20     * Get coin data with symbols and images using coins/markets endpoint
     21     * This is the recommended method for ticker displays
     22     */
     23    public static function get_coin_markets( $ids = 'bitcoin,ethereum', $vs_currency = 'usd' ) {
     24        $url = 'https://api.coingecko.com/api/v3/coins/markets?vs_currency=' . $vs_currency . '&ids=' . $ids . '&order=market_cap_desc&sparkline=false&price_change_percentage=24h';
     25       
     26        $data = self::fetch_data( $url );
     27       
     28        if ( ! $data ) return false;
     29
     30        // Reformat data to match the structure expected by the ticker
     31        $formatted_data = [];
     32       
     33        foreach ( $data as $coin ) {
     34            $coin_id = $coin['id'];
     35           
     36            $formatted_data[ $coin_id ] = [
     37                'usd'             => $coin['current_price'],
     38                'usd_24h_change'  => $coin['price_change_percentage_24h'] ?? 0,
     39                'symbol'          => strtoupper( $coin['symbol'] ),
     40                'image'           => $coin['image'],
     41                'name'            => $coin['name'],
     42            ];
     43        }
     44       
     45        return $formatted_data;
     46    }
     47
     48    /**
     49     * Get detailed coin data including symbol and image (alternative method)
     50     * Use this if you need more detailed information for each coin
     51     */
     52    public static function get_coins_list( $ids = 'bitcoin,ethereum' ) {
     53        $ids_array = explode( ',', $ids );
     54        $all_data = [];
     55
     56        foreach ( $ids_array as $coin_id ) {
     57            $coin_id = trim( $coin_id );
     58            $url = 'https://api.coingecko.com/api/v3/coins/' . $coin_id . '?localization=false&tickers=false&community_data=false&developer_data=false';
     59           
     60            $coin_data = self::fetch_data( $url );
     61           
     62            if ( $coin_data ) {
     63                $all_data[ $coin_id ] = [
     64                    'usd'            => $coin_data['market_data']['current_price']['usd'] ?? 0,
     65                    'usd_24h_change' => $coin_data['market_data']['price_change_percentage_24h'] ?? 0,
     66                    'symbol'         => strtoupper( $coin_data['symbol'] ?? '' ),
     67                    'image'          => $coin_data['image']['small'] ?? '',
     68                    'name'           => $coin_data['name'] ?? '',
     69                ];
     70            }
     71        }
     72
     73        return $all_data;
    1474    }
    1575}
  • live-crypto-prices/trunk/includes/class-wlcp-shortcodes.php

    r3443883 r3444917  
    1616    }
    1717
     18    public static function wlcp_format_price( $number, $decimals = 8 ) {
     19        if ( ! is_numeric( $number ) ) {
     20            return $number;
     21        }
     22        $float = (float) $number;
     23        return rtrim(
     24            rtrim( number_format( $float, $decimals, '.', '' ), '0' ),
     25            '.'
     26        );
     27    }
     28
    1829    public static function ticker( $atts ) {
    1930        $coin_ids = get_option('wlcp_custom_coins', 'bitcoin,ethereum');
    2031        $coin_ids_array = explode(',', $coin_ids);
    21         $data = WLCP_API::get_coin_price($coin_ids, 'usd');
     32       
     33        // Use the new API method that includes symbol, image, and name
     34        $data = WLCP_API::get_coin_markets($coin_ids, 'usd');
    2235
    2336        $atts = shortcode_atts([
     
    3144
    3245    public static function price_list( $atts ) {
    33         $data = WLCP_API::get_coin_price(self::get_user_coins());
     46        // Use the new API method
     47        $data = WLCP_API::get_coin_markets(self::get_user_coins(), 'usd');
    3448
    3549        ob_start();
    3650        echo '<ul class="wlcp-price-list">';
    3751
    38         foreach ( $data as $coin => $prices ) {
    39             foreach ( $prices as $currency => $value ) {
    40                 echo '<li>'
    41                     . esc_html( ucfirst($coin) )
    42                     . ': '
    43                     . esc_html($value)
    44                     . ' '
    45                     . esc_html( strtoupper($currency) )
    46                     . '</li>';
    47             }
     52        foreach ( $data as $coin_id => $coin_data ) {
     53            $name = isset($coin_data['name']) ? $coin_data['name'] : ucfirst($coin_id);
     54            $symbol = isset($coin_data['symbol']) ? $coin_data['symbol'] : strtoupper(substr($coin_id, 0, 3));
     55            $price = isset($coin_data['usd']) ? $coin_data['usd'] : 'N/A';
     56           
     57            echo '<li>'
     58                . esc_html( $name )
     59                . ' (' . esc_html( $symbol ) . '): '
     60                . esc_html( self::wlcp_format_price($price) )
     61                . ' USD</li>';
    4862        }
    4963
     
    5367
    5468    public static function price_table( $atts ) {
    55         $data = WLCP_API::get_coin_price(self::get_user_coins());
     69        // Use the new API method
     70        $data = WLCP_API::get_coin_markets(self::get_user_coins(), 'usd');
    5671
    5772        ob_start();
    58         echo '<table class="wlcp-price-table"><thead><tr><th>Coin</th><th>Price (USD)</th></tr></thead><tbody>';
     73        echo '<table class="wlcp-price-table">';
     74        echo '<thead><tr><th>Coin</th><th>Symbol</th><th>Price (USD)</th><th>24h Change</th></tr></thead>';
     75        echo '<tbody>';
    5976
    60         foreach ( $data as $coin => $prices ) {
    61             $usd = isset($prices['usd']) ? $prices['usd'] : '';
     77        foreach ( $data as $coin_id => $coin_data ) {
     78            $name = isset($coin_data['name']) ? $coin_data['name'] : ucfirst($coin_id);
     79            $symbol = isset($coin_data['symbol']) ? $coin_data['symbol'] : '';
     80            $price = isset($coin_data['usd']) ? $coin_data['usd'] : 'N/A';
     81            $change = isset($coin_data['usd_24h_change']) ? round($coin_data['usd_24h_change'], 2) : 0;
     82            $change_class = $change >= 0 ? 'positive' : 'negative';
     83           
    6284            echo '<tr>'
    63                 . '<td>' . esc_html( ucfirst($coin) ) . '</td>'
    64                 . '<td>' . esc_html( $usd ) . '</td>'
     85                . '<td>' . esc_html( $name ) . '</td>'
     86                . '<td>' . esc_html( $symbol ) . '</td>'
     87                . '<td>$' . esc_html( self::wlcp_format_price($price) ) . '</td>'
     88                . '<td class="' . esc_attr($change_class) . '">' . esc_html( $change ) . '%</td>'
    6589                . '</tr>';
    6690        }
     
    7195
    7296    public static function multi_currency_tabs( $atts ) {
     97
     98        $atts = shortcode_atts(
     99            array(
     100                'mode' => 'light',
     101            ),
     102            $atts,
     103            'wlcp_tabs'
     104        );
     105
     106        $wlcp_mode_class = ( $atts['mode'] === 'dark' )
     107            ? 'wlcp-dark-mode'
     108            : 'wlcp-light-mode';
     109
    73110        $coins = self::get_user_coins();
    74         $data = WLCP_API::get_coin_price($coins, 'usd,eur,gbp');
     111       
     112        // NOTE: The current get_coin_markets() only supports single currency
     113        // You'll need to make separate API calls for each currency
     114        // or modify the API class to support multiple currencies
     115       
     116        $data_usd = WLCP_API::get_coin_markets( $coins, 'usd' );
     117        $data_eur = WLCP_API::get_coin_markets( $coins, 'eur' );
     118        $data_gbp = WLCP_API::get_coin_markets( $coins, 'gbp' );
    75119
    76120        ob_start();
    77         echo '<div class="wlcp-tabs">';
    78 
    79         foreach ( $data as $coin => $prices ) {
    80             echo '<div><strong>' . esc_html( ucfirst($coin) ) . ':</strong> ';
    81 
    82             foreach ( $prices as $currency => $value ) {
    83                 echo esc_html($value) . ' ' . esc_html( strtoupper($currency) ) . ' | ';
    84             }
    85 
    86             echo '</div>';
    87         }
    88 
    89         echo '</div>';
     121        include plugin_dir_path(__FILE__) . 'template-multi-currency-tab-ui.php';
    90122        return ob_get_clean();
    91123    }
     124
    92125}
    93126
  • live-crypto-prices/trunk/includes/template-ticker-ui.php

    r3443883 r3444917  
    22if ( ! defined( 'ABSPATH' ) ) {
    33    exit;
     4}
     5if ( ! function_exists( 'wlcp_format_price' ) ) {
     6    function wlcp_format_price( $number, $decimals = 8 ) {
     7        if ( ! is_numeric( $number ) ) {
     8            return $number;
     9        }
     10        $float = (float) $number;
     11        return rtrim(
     12            rtrim( number_format( $float, $decimals, '.', '' ), '0' ),
     13            '.'
     14        );
     15    }
    416}
    517$wlcp_mode_class = ( isset( $atts['mode'] ) && $atts['mode'] === 'dark' )
     
    820?>
    921
    10 <div class="wlcp-ticker-outer <?php echo esc_attr( $wlcp_mode_class ); ?>" style="overflow:hidden; white-space:nowrap; position:relative;">
     22<div class="wlcp-ticker-outer <?php echo esc_attr( $wlcp_mode_class ); ?>" style="overflow:hidden; white-space:nowrap; position:relative; max-width: 100%">
    1123    <div class="wlcp-ticker-wrap" style="display:inline-flex; animation: wlcp-marquee 30s linear infinite; will-change:transform;">
    1224
     
    4860            $wlcp_arrow_svg = $wlcp_is_up ? $wlcp_up_svg : $wlcp_down_svg;
    4961
    50             // Coin symbol map
    51             $wlcp_coin_map = [
    52                 'bitcoin'  => 'btc',
    53                 'ethereum' => 'eth',
    54                 'solana'   => 'sol',
    55                 'doge'     => 'doge',
    56                 'ripple'   => 'xrp',
    57                 'cardano'  => 'ada',
    58                 'polygon'  => 'matic',
    59                 'litecoin' => 'ltc',
    60             ];
    61 
    62             $wlcp_symbol   = $wlcp_coin_map[ $wlcp_coin_id ] ?? substr( $wlcp_coin_id, 0, 3 );
    63             $wlcp_logo_url = 'https://static.coincap.io/assets/icons/' . $wlcp_symbol . '@2x.png';
     62            // Get symbol dynamically from API data
     63            $wlcp_symbol = isset( $data[ $wlcp_coin_id ]['symbol'] )
     64                ? strtoupper( $data[ $wlcp_coin_id ]['symbol'] )
     65                : strtoupper( substr( $wlcp_coin_id, 0, 3 ) );
     66           
     67            // Get icon URL from CoinGecko API data
     68            $wlcp_logo_url = $data[ $wlcp_coin_id ]['image'] ?? '';
     69           
     70            // Fallback: If image not in data, try to construct CoinGecko URL
     71            if ( empty( $wlcp_logo_url ) ) {
     72                $wlcp_logo_url = 'https://assets.coingecko.com/coins/images/1/small/' . $wlcp_coin_id . '.png';
     73            }
    6474        ?>
    6575
     
    8292
    8393                <span class="wlcp-price" style="margin-left:10px;">
    84                     $<?php echo esc_html( number_format( (float) $wlcp_price, 2 ) ); ?>
     94                    $<?php echo esc_html( wlcp_format_price( $wlcp_price ) ); ?>
    8595                </span>
    8696
  • live-crypto-prices/trunk/live-crypto-prices.php

    r3443883 r3444917  
    33 * Plugin Name: Live Crypto Prices
    44 * Description: Live crypto prices using CoinGecko API with ticker, price tables, and shortcode generator.
    5  * Version: 1.0.3
     5 * Version: 1.0.4
    66 * Author: mharisart
    77 * License: GPLv2 or later
     
    1111if ( ! defined( 'ABSPATH' ) ) exit;
    1212
    13 define( 'WLCP_VERSION', '1.0.3' );
     13define( 'WLCP_VERSION', '1.0.4' );
    1414define( 'WLCP_PATH', plugin_dir_path( __FILE__ ) );
    1515define( 'WLCP_URL', plugin_dir_url( __FILE__ ) );
  • live-crypto-prices/trunk/readme.txt

    r3443883 r3444917  
    11=== Live Crypto Prices ===
    22Contributors: mharisart
    3 Tags: cryptocurrency, crypto prices, price ticker, crypto table
     3Tags: cryptocurrency, crypto prices, price ticker, crypto table, CoinGecko
    44Requires at least: 5.8
    55Tested up to: 6.9
    6 Stable tag: 1.0.3
     6Stable tag: 1.0.4
    77License: GPLv2 or later
    88License URI: https://www.gnu.org/licenses/gpl-2.0.html
     
    8787== Changelog ==
    8888
     89= 1.0.4 =
     90*Switched to CoinGecko /coins/markets API
     91*Dynamic coin icons, names, and symbols (no manual mapping)
     92*Added 24h price change & symbol columns to price table
     93*Refactored WLCP_API with get_coin_markets()
     94*Fixed missing icons & symbol issues for new coins
     95
    8996= 1.0.3 =
    9097Initial public release
Note: See TracChangeset for help on using the changeset viewer.