Changeset 2313464
- Timestamp:
- 05/28/2020 02:30:43 AM (6 years ago)
- Location:
- show-repos/trunk
- Files:
-
- 5 added
- 2 edited
-
changelog.txt (added)
-
languages (added)
-
languages/show-repos-zh_CN.mo (added)
-
languages/show-repos-zh_CN.po (added)
-
languages/show-repos.pot (added)
-
readme.txt (modified) (7 diffs)
-
show-repos.php (modified) (16 diffs)
Legend:
- Unmodified
- Added
- Removed
-
show-repos/trunk/readme.txt
r2305634 r2313464 4 4 Requires at least: 5.0 5 5 Tested up to: 5.4 6 Stable tag: 1. 06 Stable tag: 1.1 7 7 Requires PHP: 5.4 8 8 License: GPLv2 … … 26 26 = Upgrade Notice = 27 27 28 The `./mod/`directory needs to be backed up before updating, it will be overwritten through the system update mechanism.28 The './mod/' directory needs to be backed up before updating, it will be overwritten through the system update mechanism. 29 29 30 30 = Steps to Upgrade = … … 32 32 1. Back up the plugin directory, deactive the plugin, and then delete the plugin directory before upgrade to new version. 33 33 2. Upload and unzip the new version to its original location, active plugins, plugin configuration sits to automatically inherit. 34 35 = Contribute = 36 37 Welcome 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~ 34 38 35 39 == Installation == … … 45 49 1. Create a php file in './mod/' directory, and name it to the plant name (format: {{plant name}}.php). 46 50 2. Write the php file content as the following template: 47 ``` 48 <?php 51 `<?php 49 52 class SHOW_REPOS_MOD_{{PLANT_NAME}} { 50 53 public $api_url = '{{url}}'; //Plant api url that point to repo, usual it is such: https://{{url}}/{:user}/{:repo} … … 70 73 return $data; 71 74 } 72 } 73 ``` 75 }` 74 76 3. 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 77 78 {{description}} => Repo's description 78 79 {{url}} => Repo's url … … 87 88 {{ctime}} => Repo's created time 88 89 {{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` 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) 92 92 93 93 = I had added the shortcode, but it still does not display or it display the error message. = … … 101 101 == Screenshots == 102 102 103 1. Final screen in wider screen104 2. Final screen in narrow screen105 3. Example shortcode103 1. In PC. 104 2. In mobile. 105 3. Shortcode. 106 106 107 107 == Changelog == 108 108 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. 111 112 112 113 == Upgrade Notice == 113 114 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 2 2 /** 3 3 * @package Show_Repos 4 * @version 1. 0.04 * @version 1.1.2 5 5 */ 6 6 /** 7 7 * Plugin Name: Show Repos 8 8 * Description: Show your repo(s) on the wordpress through a simple shortcode. 9 * Version: 1. 0.09 * Version: 1.1.2 10 10 * Requires at least: 5.0 11 11 * Requires PHP: 5.4 … … 15 15 * License URI: https://www.gnu.org/licenses/gpl-2.0.html 16 16 * Text Domain: show-repos 17 * Domain Path: /languages 17 18 * 18 19 * Show Repos is free software: you can redistribute it and/or modify … … 42 43 defined( 'SHOW_REPOS_VERSION' ) or define( 'SHOW_REPOS_VERSION', '1.0.0' ); 43 44 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 45 49 /** 46 50 * Define the some uri of directory that running in this plugin. … … 62 66 class SHOW_REPOS { 63 67 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 64 81 /** 65 82 * Storage the instance of repo class. … … 84 101 */ 85 102 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 86 144 $dir = SHOW_REPOS_MOD_DIR; 87 145 //Check if exists the mod directory … … 91 149 esc_attr( 'settings_error' ), 92 150 sprintf( 93 self::$errorMessage[ 'missing_requisite_file' ],151 __( self::$errorMessage[ 'missing_requisite_file' ] ), 94 152 SHOW_REPOS_NAME, 95 153 $dir … … 105 163 esc_attr( 'settings_error' ), 106 164 sprintf( 107 self::$errorMessage[ 'missing_requisite_file' ],165 __( self::$errorMessage[ 'missing_requisite_file' ] ), 108 166 SHOW_REPOS_NAME, 109 167 $dir … … 135 193 esc_attr( 'settings_error' ), 136 194 sprintf( 137 self::$errorMessage[ 'class_not_exists' ],195 __( self::$errorMessage[ 'class_not_exists' ] ), 138 196 SHOW_REPOS_NAME, 139 197 $class, … … 146 204 closedir( $dh ); 147 205 } 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 ); 148 257 } 149 258 … … 169 278 if( empty( $v ) ) { 170 279 return sprintf( 171 self::$errorMessage[ 'empty_param_in_shortcode' ],280 __( self::$errorMessage[ 'empty_param_in_shortcode' ] ), 172 281 $k 173 282 ); … … 178 287 $user = $atts[ 'user' ]; 179 288 $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. 181 290 $class = self::$instances[ SHOW_REPOS_MOD_PREFIX . $classname ]; 182 291 $api_url = str_replace( array( '{:user}', '{:repo}' ), array( $user, $repo ), $class->api_url ); … … 188 297 'Content-Type' => 'application/json;charset=UTF-8', 189 298 ), 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 ), 202 313 ); 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 ) ); 210 340 } 211 341 … … 247 377 if( is_array( $css ) ) { 248 378 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 ); 250 380 self::debug( __LINE__ ); 251 381 } 252 382 } 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 ); 254 384 self::debug( __LINE__ ); 255 385 } … … 262 392 if( is_array( $js ) ) { 263 393 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 ); 265 395 self::debug( __LINE__ ); 266 396 } 267 397 } 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 ); 269 399 self::debug( __LINE__ ); 270 400 } … … 273 403 } 274 404 } 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"> *</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 } 275 537 276 538 private static function debug( $line ) { … … 291 553 } 292 554 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' ) ); 293 558 add_action( 'plugins_loaded', array( 'SHOW_REPOS', 'init' ) ); 294 559 add_action( 'wp_head', array( 'SHOW_REPOS', 'load_static_file' ) ); 295 560 add_shortcode( 'show-repo', array( 'SHOW_REPOS', 'render_shortcode' ) ); 296 561 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.