Plugin Directory

Changeset 2313464


Ignore:
Timestamp:
05/28/2020 02:30:43 AM (6 years ago)
Author:
joytou
Message:

Update to version 1.1.2.

Location:
show-repos/trunk
Files:
5 added
2 edited

Legend:

Unmodified
Added
Removed
  • show-repos/trunk/readme.txt

    r2305634 r2313464  
    44Requires at least: 5.0
    55Tested up to: 5.4
    6 Stable tag: 1.0
     6Stable tag: 1.1
    77Requires PHP: 5.4
    88License: GPLv2
     
    2626= Upgrade Notice =
    2727
    28 The `./mod/` directory needs to be backed up before updating, it will be overwritten through the system update mechanism.
     28The './mod/' directory needs to be backed up before updating, it will be overwritten through the system update mechanism.
    2929
    3030= Steps to Upgrade =
     
    32321. Back up the plugin directory, deactive the plugin, and then delete the plugin directory before upgrade to new version.
    33332. Upload and unzip the new version to its original location, active plugins, plugin configuration sits to automatically inherit.
     34
     35= Contribute =
     36
     37Welcome to help to improve the plugin if you have any idea or you had caught any bug. Please email me <joytou.wu@qq.com>. Thanks~
    3438
    3539== Installation ==
     
    45491. Create a php file in './mod/' directory, and name it to the plant name (format: {{plant name}}.php).
    46502. Write the php file content as the following template:
    47 ```
    48 <?php
     51`<?php
    4952class SHOW_REPOS_MOD_{{PLANT_NAME}} {
    5053    public $api_url         = '{{url}}'; //Plant api url that point to repo, usual it is such: https://{{url}}/{:user}/{:repo}
     
    7073        return $data;
    7174    }
    72 }
    73 ```
     75}`
    74763. Add and write the html template file in the directory './mod/template/', which want to display in the shortcode, and add such label where want to display the specified infomation:
    75 ```
    76     {{name}} => Repo's name
     77`   {{name}} => Repo's name
    7778    {{description}} => Repo's description
    7879    {{url}} => Repo's url
     
    8788    {{ctime}} => Repo's created time
    8889    {{mtime}} => Repo's last updated time
    89     {{ptime}} => Repo's last pushed time
    90 ```
    91 4. Add the css/js file to the directory `./mod/template/css/` / `./mod/template/js/` as if needed, and name it(s) to the plant name (format: {{plant name}}.js / {{plant name}}.css)
     90    {{ptime}} => Repo's last pushed time`
     914. Add the css/js file to the directory './mod/template/css/' / './mod/template/js/' as if needed, and name it(s) to the plant name (format: {{plant name}}.js / {{plant name}}.css)
    9292
    9393= I had added the shortcode, but it still does not display or it display the error message. =
     
    101101== Screenshots ==
    102102
    103 1. Final screen in wider screen
    104 2. Final screen in narrow screen
    105 3. Example shortcode
     1031. In PC.
     1042. In mobile.
     1053. Shortcode.
    106106
    107107== Changelog ==
    108108
    109 = 1.0.0 =
    110 * The first version.
     109= 1.1.2 =
     110* Add translation supportted, for locale.
     111* Add api data cache function, and can clear the cache(in the setting screen: General Settings -> Show Repos). Of course, it is optional.
    111112
    112113== Upgrade Notice ==
    113114
    114 - The `./mod/` directory needs to be backed up before updating, it will be overwritten through the system update mechanism.
     115- The ./mod/ directory needs to be backed up before updating, it will be overwritten through the system update mechanism.
  • show-repos/trunk/show-repos.php

    r2305634 r2313464  
    22/**
    33 * @package Show_Repos
    4  * @version 1.0.0
     4 * @version 1.1.2
    55 */
    66/**
    77 * Plugin Name: Show Repos
    88 * Description: Show your repo(s) on the wordpress through a simple shortcode.
    9  * Version: 1.0.0
     9 * Version: 1.1.2
    1010 * Requires at least: 5.0
    1111 * Requires PHP: 5.4
     
    1515 * License URI: https://www.gnu.org/licenses/gpl-2.0.html
    1616 * Text Domain: show-repos
     17 * Domain Path: /languages
    1718 *
    1819 * Show Repos is free software: you can redistribute it and/or modify
     
    4243 defined( 'SHOW_REPOS_VERSION' ) or define( 'SHOW_REPOS_VERSION', '1.0.0' );
    4344 defined( 'SHOW_REPOS_MOD_PREFIX' ) or define( 'SHOW_REPOS_MOD_PREFIX', 'SHOW_REPOS_MOD_' );
    44  
     45 defined( 'SHOW_REPOS_SLUG' ) or define( 'SHOW_REPOS_SLUG', 'show-repos' );
     46 defined( 'SHOW_REPOS_SLUG_' ) or define( 'SHOW_REPOS_SLUG_', 'show_repos' );
     47 defined( 'SHOW_REPOS_OPTION_NAME' ) or define( 'SHOW_REPOS_OPTION_NAME', SHOW_REPOS_SLUG_ . '_options' );
     48
    4549 /**
    4650  * Define the some uri of directory that running in this plugin.
     
    6266 class SHOW_REPOS {
    6367   
     68    const OPTION_FIELDS = [
     69        [
     70            'id' => 'expire_time',
     71            'name' => 'Expire Time',
     72            'default_value' => '600',
     73            'type' => 'number',
     74            'desc' => 'The time of the cache data of the repo api to live. Set to 0 to keep it always be the latest.',
     75            'required' => true,
     76            'attrs' => [
     77            ],
     78        ],
     79    ];
     80   
    6481    /**
    6582     * Storage the instance of repo class.
     
    84101     */
    85102    static function init() {
     103        //Initialize the option datas.
     104        foreach(self::OPTION_FIELDS as $option ) {
     105           
     106            //Set to the default value if not exist.
     107            if( !isset( get_option( SHOW_REPOS_OPTION_NAME )[$option['id']] ) ) {
     108                $default = get_option( SHOW_REPOS_OPTION_NAME );
     109                $default[$option['id']] = $option['default_value'];
     110                update_option( SHOW_REPOS_OPTION_NAME, $default );
     111            }
     112        }
     113        if( !isset( get_option( SHOW_REPOS_OPTION_NAME )['list'] ) ) {
     114            $default = get_option( SHOW_REPOS_OPTION_NAME );
     115            $default['list'] = array();
     116            update_option( SHOW_REPOS_OPTION_NAME, $default );
     117        }
     118       
     119        //Deal the form submit action.
     120        if( isset( $_POST[SHOW_REPOS_OPTION_NAME] ) && isset( $_POST['action'] ) ){
     121             $options = get_option( SHOW_REPOS_OPTION_NAME );
     122            switch( $_POST['action'] ){
     123                case 'submit':
     124                    foreach( self::OPTION_FIELDS as $v ) {
     125                        $options[$v['id']] = sanitize_text_field( $_POST[SHOW_REPOS_OPTION_NAME][$v['id']] );
     126                    }
     127                case 'clear_transient':
     128                    foreach( $options['list'] as $k=>$v ) {
     129                        delete_transient( $v );
     130                    }
     131                    $options['list'] = array();
     132                    break;
     133            }
     134            update_option( SHOW_REPOS_OPTION_NAME, $options );
     135        }
     136       
     137        //Load i18n translations.
     138        load_plugin_textdomain(
     139            SHOW_REPOS_SLUG,
     140            false,
     141            dirname( plugin_basename( __FILE__ ) ) . '/languages/'
     142        );
     143       
    86144        $dir = SHOW_REPOS_MOD_DIR;
    87145        //Check if exists the mod directory
     
    91149                esc_attr( 'settings_error' ),
    92150                sprintf(
    93                     self::$errorMessage[ 'missing_requisite_file' ],
     151                    __( self::$errorMessage[ 'missing_requisite_file' ] ),
    94152                    SHOW_REPOS_NAME,
    95153                    $dir
     
    105163                esc_attr( 'settings_error' ),
    106164                sprintf(
    107                     self::$errorMessage[ 'missing_requisite_file' ],
     165                    __( self::$errorMessage[ 'missing_requisite_file' ] ),
    108166                    SHOW_REPOS_NAME,
    109167                    $dir
     
    135193                        esc_attr( 'settings_error' ),
    136194                        sprintf(
    137                             self::$errorMessage[ 'class_not_exists' ],
     195                            __( self::$errorMessage[ 'class_not_exists' ] ),
    138196                            SHOW_REPOS_NAME,
    139197                            $class,
     
    146204            closedir( $dh );
    147205        }
     206    }
     207   
     208    /**
     209     * Handler for activing the plugin.
     210     * @static
     211     * @author Joytou Wu <joytou.wu@qq.com>
     212     * @since 1.1.1
     213     */
     214    static function active() {
     215        if( !current_user_can( 'activate_plugins' ) ) {
     216            return;
     217        }
     218        $options = get_option( SHOW_REPOS_OPTION_NAME );
     219        if( empty( $options ) ) {
     220            $options = array();
     221            $options['expire_time'] = '3600';
     222            $options['list'] = array();
     223            update_option( SHOW_REPOS_OPTION_NAME, $options );
     224        }
     225    }
     226
     227    /**
     228     * Handler for deactiving the plugin.
     229     * @static
     230     * @author Joytou Wu <joytou.wu@qq.com>
     231     * @since 1.1.1
     232     */
     233    static function deactive() {
     234        if( !current_user_can( 'activate_plugins' ) ) {
     235            return;
     236        }
     237        $options = get_option( SHOW_REPOS_OPTION_NAME );
     238        foreach( $options['list'] as $k=>$v ) {
     239            delete_transient( $v );
     240        }
     241        $options['list'] = array();
     242        update_option( SHOW_REPOS_OPTION_NAME, $options );
     243    }
     244
     245    /**
     246     * Handler for uninstalling the plugin.
     247     * @static
     248     * @author Joytou Wu <joytou.wu@qq.com>
     249     * @since 1.1.1
     250     */
     251    static function uninstall() {
     252        if( !current_user_can( 'activate_plugins' ) || !defined( 'WP_UNINSTALL_PLUGIN' ) ) {
     253            return;
     254        }
     255        delete_option( SHOW_REPOS_OPTION_NAME );
     256        delete_site_option( SHOW_REPOS_OPTION_NAME );
    148257    }
    149258   
     
    169278            if( empty( $v ) ) {
    170279                return sprintf(
    171                     self::$errorMessage[ 'empty_param_in_shortcode' ],
     280                    __( self::$errorMessage[ 'empty_param_in_shortcode' ] ),
    172281                    $k
    173282                );
     
    178287        $user = $atts[ 'user' ];
    179288        $repo = $atts[ 'repo' ];
    180         //Get the current shortcode's class, and get the api data from the url that defined by repo class.
     289        /*//Get the current shortcode's class, and get the api data from the url that defined by repo class.
    181290        $class = self::$instances[ SHOW_REPOS_MOD_PREFIX . $classname ];
    182291        $api_url = str_replace( array( '{:user}', '{:repo}' ), array( $user, $repo ), $class->api_url );
     
    188297                'Content-Type' => 'application/json;charset=UTF-8',
    189298            ),
    190         );
    191         $response = wp_remote_get( $api_url, $response_header );
    192         //Check can get api data, or return error message.
    193         if( wp_remote_retrieve_response_code( $response ) === 200 ) {
    194             $api = json_decode( wp_remote_retrieve_body( $response ), true );
    195             return self::tmpl_render( $class->template_html, $class->data_format( $api ) );
    196         } else {
    197             $api = array(
    198                 'error_code' => wp_remote_retrieve_response_code( $response ),
    199                 'error_msg' => wp_remote_retrieve_body( $response ),
    200                 'error' => 'Not found the repo <strong>'. $user . '/' . $repo . '</strong> from <strong>' . $classname . '</strong>, please ensure there has datas in ' . $api_url,
    201                
     299        );*/
     300       
     301        $repo_data = get_transient( SHOW_REPOS_SLUG_ . "_{$classname}_{$user}_{$repo}" );
     302        if( $repo_data === false ){
     303            //Get the current shortcode's class, and get the api data from the url that defined by repo class.
     304            $class = self::$instances[ SHOW_REPOS_MOD_PREFIX . $classname ];
     305            $api_url = str_replace( array( '{:user}', '{:repo}' ), array( $user, $repo ), $class->api_url );
     306            //Simulating user normally access the site, some will return 403 forbidden with no header.
     307            $response_header = array(
     308                'method' => 'GET',
     309                'user-agent' => $_SERVER['HTTP_USER_AGENT'],
     310                'header' => array(
     311                    'Content-Type' => 'application/json;charset=UTF-8',
     312                ),
    202313            );
    203             return sprintf(
    204                 self::$errorMessage[ 'not_found_repo' ],
    205                 $api[ 'error' ],
    206                 $api[ 'error_code' ],
    207                 $api[ 'error_msg' ]
    208             );
    209         }
     314            $response = wp_remote_get( $api_url, $response_header );
     315            //Check can get api data, or return error message.
     316            if( wp_remote_retrieve_response_code( $response ) === 200 ) {
     317                $api = json_decode( wp_remote_retrieve_body( $response ), true );
     318                $options = get_option( SHOW_REPOS_OPTION_NAME );
     319                $current_transient_name = SHOW_REPOS_SLUG_ . "_{$classname}_{$user}_{$repo}";
     320                set_transient( $current_transient_name, $api, $options['expire_time'] );
     321                if( !in_array( $current_transient_name, $options['list'] ) ){
     322                    array_push( $options['list'], $current_transient_name );
     323                }
     324                update_option( SHOW_REPOS_OPTION_NAME, $options );
     325            } else {
     326                $api = array(
     327                    'error_code' => wp_remote_retrieve_response_code( $response ),
     328                    'error_msg' => wp_remote_retrieve_body( $response ),
     329                    'error' => 'Not found the repo <strong>'. $user . '/' . $repo . '</strong> from <strong>' . $classname . '</strong>, please ensure there has datas in ' . $api_url,
     330                );
     331                return sprintf(
     332                    __( self::$errorMessage[ 'not_found_repo' ] ),
     333                    $api[ 'error' ],
     334                    $api[ 'error_code' ],
     335                    $api[ 'error_msg' ]
     336                );
     337            }
     338        }
     339        return self::tmpl_render( $class->template_html, $class->data_format( $repo_data ) );
    210340    }
    211341   
     
    247377                if( is_array( $css ) ) {
    248378                    foreach( $css as $v ) {
    249                         wp_enqueue_style( 'show-repos' . $v, SHOW_REPOS_TEMPLATE_URL . $v );
     379                        wp_enqueue_style( SHOW_REPOS_SLUG . $v, SHOW_REPOS_TEMPLATE_URL . $v );
    250380                        self::debug( __LINE__ );
    251381                    }
    252382                } else {
    253                     wp_enqueue_style( 'show-repos' . $css, SHOW_REPOS_TEMPLATE_URL . $css );
     383                    wp_enqueue_style( SHOW_REPOS_SLUG . $css, SHOW_REPOS_TEMPLATE_URL . $css );
    254384                    self::debug( __LINE__ );
    255385                }
     
    262392                if( is_array( $js ) ) {
    263393                    foreach( $js as $v ) {
    264                         wp_enqueue_script( 'show-repos' . $v, SHOW_REPOS_TEMPLATE_URL . $v );
     394                        wp_enqueue_script( SHOW_REPOS_SLUG . $v, SHOW_REPOS_TEMPLATE_URL . $v );
    265395                        self::debug( __LINE__ );
    266396                    }
    267397                } else {
    268                     wp_enqueue_script( 'show-repos' . $js, SHOW_REPOS_TEMPLATE_URL . $js );
     398                    wp_enqueue_script( SHOW_REPOS_SLUG . $js, SHOW_REPOS_TEMPLATE_URL . $js );
    269399                    self::debug( __LINE__ );
    270400                }
     
    273403        }
    274404    }
     405   
     406    /**
     407     * Handler for adding setting page.
     408     * @static
     409     * @author Joytou Wu <joytou.wu@qq.com>
     410     * @since 1.0.0
     411     */
     412    static function add_setting_page(){
     413        add_options_page(
     414            esc_html__( SHOW_REPOS_NAME . ' Setting', SHOW_REPOS_SLUG ),
     415            esc_html__( SHOW_REPOS_NAME, SHOW_REPOS_SLUG ),
     416            'manage_options',
     417            SHOW_REPOS_SLUG,
     418            array( SHOW_REPOS_SLUG_, 'render_setting_page' )
     419        );
     420    }
     421   
     422    /**
     423     * Handler for rendering setting page.
     424     * @static
     425     * @author Joytou Wu <joytou.wu@qq.com>
     426     * @since 1.0.0
     427     */
     428    static function render_setting_page(){
     429        ?>
     430        <h2><?php esc_html_e( SHOW_REPOS_NAME, SHOW_REPOS_SLUG );?></h2>
     431        <form action="?page=<?php echo SHOW_REPOS_SLUG;?>&action=submit" method="post">
     432            <?php
     433                settings_fields( SHOW_REPOS_OPTION_NAME );
     434                do_settings_sections( SHOW_REPOS_SLUG_ );
     435            ?>
     436            <input name="submit" class="button button-primary" type="submit" value="<?php esc_attr_e( 'Save', SHOW_REPOS_SLUG ); ?>" />
     437        </form>
     438        <form action="?page=<?php echo SHOW_REPOS_SLUG;?>&action=clear_transient" method="post">
     439            <input name="submit" class="button button-secondly" type="submit" value="<?php esc_attr_e( 'Clear Cache', SHOW_REPOS_SLUG ); ?>" />
     440        </form>
     441        <?php
     442    }
     443   
     444    /**
     445     * Handler for registing settings and adding settings fields.
     446     * @static
     447     * @author Joytou Wu <joytou.wu@qq.com>
     448     * @since 1.0.0
     449     */
     450    static function register_settings(){
     451       
     452        $required_field_html = '<span class="required">&nbsp;*</span>';
     453       
     454        register_setting(
     455            SHOW_REPOS_SLUG_,
     456            SHOW_REPOS_OPTION_NAME,
     457            array( SHOW_REPOS_SLUG_, 'options_validate' )
     458        );
     459       
     460        add_settings_section(
     461            'api_settings',
     462            esc_html__( SHOW_REPOS_NAME . ' Setting', SHOW_REPOS_SLUG ),
     463            array( SHOW_REPOS_SLUG_, 'setting_section_text' ),
     464            SHOW_REPOS_SLUG_
     465        );
     466
     467        foreach ( self::OPTION_FIELDS as $item ) {
     468            add_settings_field(
     469                SHOW_REPOS_SLUG_ . '_' . $item['id'],
     470                esc_html__( $item['name'] , SHOW_REPOS_SLUG ) . ( $item['required'] ? $required_field_html : '' ),
     471                array(SHOW_REPOS_SLUG_, 'settings_field' ),
     472                SHOW_REPOS_SLUG_,
     473                'api_settings',
     474                $item
     475            );
     476        }       
     477    }
     478   
     479    /**
     480     * Handler for validating post options' data.
     481     * @static
     482     * @param Array $input Array for filtering and valitading.
     483     * @return Array
     484     * @author Joytou Wu <joytou.wu@qq.com>
     485     * @since 1.0.0
     486     */
     487    static function options_validate( $input ){
     488        //Valitaded the fields.
     489        $output = array();
     490        foreach ( $input as $k => $v ) {
     491            //Protect the input datas.
     492            $output[$k] = sanitize_text_field( $v );
     493        }
     494       
     495        return $output;
     496    }
     497   
     498    /**
     499     * Handler for rendering subtitle for setting page.
     500     * @static
     501     * @author Joytou Wu <joytou.wu@qq.com>
     502     * @since 1.0.0
     503     */
     504    static function setting_section_text(){
     505        //Form second title.
     506        esc_html_e( SHOW_REPOS_NAME, SHOW_REPOS_SLUG );
     507    }
     508   
     509    /**
     510     * Handler for rendering setting field.
     511     * @static
     512     * @param Array $args Array for rendering the setting fields.
     513     * @author Joytou Wu <joytou.wu@qq.com>
     514     * @since 1.0.0
     515     */
     516    static function settings_field( $args ) {
     517        $key_value_binding = '';
     518        foreach($args['attrs'] as $k=>$v){
     519            $key_value_binding .= " " . esc_attr( $k ) . "=\"" . esc_attr( $v ) . "\"";
     520        }
     521       
     522        $options = get_option( SHOW_REPOS_OPTION_NAME );
     523        echo "<input id=\"" . SHOW_REPOS_SLUG_ . "_" . esc_attr( $args['id'] ) ."\" name=\"" . esc_attr( SHOW_REPOS_OPTION_NAME ) . "[". esc_attr( $args['id'] ) ."]\" type=\"". ( $args['type'] ? esc_attr( $args['type'] ) : 'text' ) ."\" value=\"" . ( isset( $options[$args['id']] ) ? esc_attr( $options[$args['id']] ) : esc_attr( $args['default_value'] ) ) . "\" aria-describedby=\"" . esc_attr( $args['id'] ) . "-description\"" . $key_value_binding . "/>";
     524       
     525        if(isset( $args['type'] ) && esc_attr( $args['type'] ) === 'range' ){
     526            echo "<span id=\"" . SHOW_REPOS_SLUG_ . "_" . esc_attr( $args['id'] ) ."-value\">" . ( isset( $options[$args['id']] ) ? esc_html( $options[$args['id']] ) : esc_html( $args['default_value'] ) ) . "</span>";
     527        }
     528        /**
     529         * It will not run as expect unless use several echo() for outputing.
     530         * Expect: <p class="description" id="{$id}-description">{$desc}</p>
     531         * The fact if use only one echo(): {$desc}<p class="description" id="{$id}-description"></p>
     532         */
     533        echo "<p class=\"description\" id=\"" . esc_attr( $args['id'] ) . "-description\">";
     534        echo ( $args['desc'] ? esc_html__( $args['desc'], SHOW_REPOS_SLUG ) : '' );
     535        echo "</p>";
     536    }
    275537   
    276538    private static function debug( $line ) {
     
    291553 }
    292554 
     555 register_activation_hook( __FILE__, array( 'SHOW_REPOS', 'activate' ) );
     556 register_deactivation_hook( __FILE__, array( 'SHOW_REPOS', 'deactivate' ) );
     557 register_uninstall_hook( __FILE__, array( 'SHOW_REPOS', 'uninstall' ) );
    293558 add_action( 'plugins_loaded', array( 'SHOW_REPOS', 'init' ) );
    294559 add_action( 'wp_head', array( 'SHOW_REPOS', 'load_static_file' ) );
    295560 add_shortcode( 'show-repo', array( 'SHOW_REPOS', 'render_shortcode' ) );
    296561 add_shortcode( 'show-repos', array( 'SHOW_REPOS', 'render_shortcode' ) );
     562 if ( is_admin() ) {
     563    add_action( 'admin_menu', array( 'SHOW_REPOS', 'add_setting_page' ) );
     564    add_action( 'admin_init', array( 'SHOW_REPOS', 'register_settings' ) );
     565 }
Note: See TracChangeset for help on using the changeset viewer.