├── .gitignore ├── assets ├── images │ ├── logo.png │ └── logo@2x.png ├── js │ ├── hermit-load.min.js │ ├── lib │ │ ├── jquery.mxloader.js │ │ ├── jquery.mxpage.js │ │ ├── jquery.mxlayer.js │ │ ├── hermit-load.js │ │ └── watch.js │ ├── hermit-load.js │ ├── blocks.build.js │ ├── hermit-post.js │ └── hermit-library.js └── css │ ├── hermit-post.css │ └── APlayer.min.css ├── README.md ├── include ├── cookies-pointer.php ├── template.php ├── library.php └── setting.php ├── LICENSE ├── hermit.php ├── hermit.functions.php ├── class.update.php ├── class.json.php └── class.hermit.php /.gitignore: -------------------------------------------------------------------------------- 1 | .history 2 | .vscode -------------------------------------------------------------------------------- /assets/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MoePlayer/Hermit-X/HEAD/assets/images/logo.png -------------------------------------------------------------------------------- /assets/images/logo@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MoePlayer/Hermit-X/HEAD/assets/images/logo@2x.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Hermit-X 2 | 在 WordPress 中使用 APlayer 播放音乐吧~ 3 | 详细信息请访问[插件发布页](https://blog.lwl12.com/read/hermit-x.html)~ 4 | -------------------------------------------------------------------------------- /include/cookies-pointer.php: -------------------------------------------------------------------------------- 1 | Meting Wiki。'; 5 | ?> 6 | jQuery( function() { 7 | var pointer = jQuery( "#toplevel_page_hermit" ).pointer( { 8 | content: '
', 9 | pointerWidth: 300, 10 | 11 | position: { 12 | edge: "left", 13 | align: "center" 14 | }, 15 | 16 | close: function() { 17 | jQuery( window ).off( "scroll", reposition ); 18 | jQuery.get( "" ); 19 | } 20 | } ).pointer( "open" ), 21 | 22 | reposition = function() { 23 | pointer.pointer( "reposition" ); 24 | }; 25 | 26 | jQuery( window ).on( "scroll", reposition ); 27 | } ); 28 | prefix . 'hermit'; 40 | $hermit_cat_name = $wpdb->prefix . 'hermit_cat'; 41 | 42 | /** 43 | * 加载函数 44 | */ 45 | require HERMIT_PATH . '/hermit.functions.php'; 46 | 47 | /** 48 | * 插件激活,新建数据库 49 | */ 50 | register_activation_hook(__FILE__, 'hermit_install'); 51 | 52 | /** 53 | * 插件停用, 删除数据库 54 | */ 55 | //register_deactivation_hook(__FILE__, 'hermit_uninstall'); 56 | -------------------------------------------------------------------------------- /assets/js/hermit-load.min.js: -------------------------------------------------------------------------------- 1 | "use strict";var _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(a){return typeof a}:function(a){return a&&"function"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a};function cloneObject(a){if(null==a||"object"!=("undefined"==typeof a?"undefined":_typeof(a)))return a;if(a instanceof Date){var b=new Date(a.getDate());return b}if(a instanceof Array){for(var b=[],c=0,d=a.length;c| 40 | 41 | 42 | | 43 |封面 | 44 |歌曲名称 | 45 |作者 | 46 |分类 | 47 |地址 | 48 |歌词 | 49 |操作 | 50 |
|---|---|---|---|---|---|---|---|
| 57 | 58 | 59 | | 60 |封面 | 61 |歌曲名称 | 62 |作者 | 63 |分类 | 64 |地址 | 65 |歌词 | 66 |操作 | 67 |
设置已保存。
' . $text . '
126 |
| |||||||||||||||||||||||||||||
没有封面图
' 80 | 81 | return html; 82 | }); 83 | 84 | Handlebars.registerHelper('catLrc', function (index) { 85 | var html; 86 | 87 | html = '显示歌词'; 88 | 89 | return html; 90 | }); 91 | 92 | Handlebars.registerHelper('catAction', function (id) { 93 | var html = ''; 94 | 95 | if (id !== '1') { 96 | html = '编辑 | 删除'; 97 | } else { 98 | html = '默认分类禁止编辑/删除
' 99 | } 100 | 101 | return html; 102 | }); 103 | 104 | //上传mp3 105 | $('body').on('click', '#hermit-form-song_url-upload', function(){ 106 | /** 107 | * 采用 3.5之后的新上传图片方法 108 | * 不再支持3.5以下 Wordpress 版本 109 | */ 110 | 111 | // Create the media frame. 112 | var file_frame = wp.media.frames.file_frame = wp.media({ 113 | title: '上传本地音乐(推荐 mp3 格式,尽量用英文名称)', 114 | multiple: false // Set to true to allow multiple files to be selected 115 | }); 116 | 117 | // When an image is selected, run a callback. 118 | file_frame.on( 'select', function() { 119 | var attachment = file_frame.state().get('selection').first().toJSON(); 120 | $('#hermit-form-song_url').val(attachment.url); 121 | }); 122 | 123 | // Finally, open the modal 124 | file_frame.open(); 125 | }); 126 | 127 | //上传封面图片 128 | $('body').on('click', '#hermit-form-song_cover-upload', function(){ 129 | /** 130 | * 采用 3.5之后的新上传图片方法 131 | * 不再支持3.5以下 Wordpress 版本 132 | */ 133 | 134 | // Create the media frame. 135 | var file_frame = wp.media.frames.file_frame = wp.media({ 136 | title: '上传本地图片(尽量用英文名称)', 137 | multiple: false // Set to true to allow multiple files to be selected 138 | }); 139 | 140 | // When an image is selected, run a callback. 141 | file_frame.on( 'select', function() { 142 | var attachment = file_frame.state().get('selection').first().toJSON(); 143 | $('#hermit-form-song_cover').val(attachment.url); 144 | }); 145 | 146 | // Finally, open the modal 147 | file_frame.open(); 148 | }); 149 | 150 | //新建音乐 151 | $('.add-new-h2').click(function () { 152 | var sobj = { 153 | id: 0, 154 | catList: hermit.catList 155 | }; 156 | 157 | form(sobj) 158 | }); 159 | 160 | //显示歌词 161 | $('.hermit-list-table').on('click', '.hermit-show-lrc', function () { 162 | var $this = $(this), 163 | index = $this.attr('data-index'), 164 | sobj = hermit.data[index], 165 | main_html = lrcTmpl(sobj); 166 | 167 | $.mxlayer({ 168 | title: sobj["song_name"], 169 | main: main_html, 170 | button: "关闭", 171 | width: 720, 172 | height: 720, 173 | confirm: function (that) { 174 | that.fireEvent(); 175 | } 176 | }) 177 | }); 178 | 179 | //编辑 180 | $('.hermit-list-table').on('click', '.hermit-edit', function () { 181 | var $this = $(this), 182 | index = $this.attr('data-index'), 183 | sobj = hermit.data[index]; 184 | 185 | sobj.catList = hermit.catList; 186 | 187 | form(sobj) 188 | }); 189 | 190 | //单个删除 191 | $('.hermit-list-table').on('click', '.hermit-delete', function () { 192 | var $this = $(this), 193 | ids = $this.attr('data-id'); 194 | 195 | dele(ids) 196 | }); 197 | 198 | //选中删除 199 | $('.hermit-selector-button').click(function() { 200 | if ($(this).prev('.hermit-action-selector').val() == 'trash') { 201 | var arr = []; 202 | 203 | $('.cb-select-th').each(function () { 204 | var $this = $(this); 205 | 206 | if ($this.prop("checked")) { 207 | arr.push($this.val()) 208 | } 209 | }); 210 | 211 | arr = arr.join(','); 212 | dele(arr) 213 | } 214 | else if ($(this).prev('.hermit-action-selector').val() == 'movecat') { 215 | var arr = []; 216 | 217 | $('.cb-select-th').each(function () { 218 | var $this = $(this); 219 | 220 | if ($this.prop("checked")) { 221 | arr.push($this.val()) 222 | } 223 | }); 224 | 225 | arr = arr.join(','); 226 | move_cat(arr) 227 | } 228 | }); 229 | 230 | //管理分类 231 | $('.hermit-list-table').on('click', '.hermit-manage-nav', function () { 232 | $.mxlayer({ 233 | title: '分类管理', 234 | main: manageTmpl(hermit), 235 | button: '关闭', 236 | width: 720, 237 | height: 720, 238 | cancel: function () { 239 | }, 240 | confirm: function (that) { 241 | that.fireEvent() 242 | } 243 | }) 244 | }); 245 | 246 | //新建分类 247 | $('body').on('click', '.hermit-new-nav', function () { 248 | var title = window.prompt("新建分类",""); 249 | 250 | if( title ){ 251 | $bodyLoader.showProgress('新建分类中'); 252 | 253 | $.ajax({ 254 | url: hermit.adminUrl, 255 | data: { 256 | type: 'catnew', 257 | title: title 258 | }, 259 | type: 'post', 260 | success: function (data) { 261 | hermit.catList = data; 262 | $bodyLoader.showSuccess('新建分类成功'); 263 | list({ 264 | page: 1, 265 | catid: hermit.currentCatId 266 | }, function () { 267 | initView(); 268 | $('.mxlayer-main-body').html(manageTmpl(hermit)); 269 | }); 270 | }, 271 | error: function () { 272 | $bodyLoader.showError('分类已存在'); 273 | } 274 | }); 275 | } 276 | }); 277 | 278 | //删除分类 279 | $('body').on('click', '.hermit-cat-delete', function () { 280 | var $this = $(this), 281 | id = $this.attr('data-id'); 282 | 283 | if ( id === '1' )return; 284 | 285 | var cofim = window.confirm('确认删除?'); 286 | 287 | if (cofim) { 288 | $bodyLoader.showProgress('删除分类中'); 289 | 290 | $.ajax({ 291 | url: hermit.adminUrl, 292 | type: 'post', 293 | data: { 294 | type: 'catdel', 295 | id: id 296 | }, 297 | success: function (result) { 298 | hermit.catList = result; 299 | $bodyLoader.showSuccess('删除分类成功'); 300 | list({ 301 | page: 1, 302 | catid: hermit.currentCatId 303 | }, function () { 304 | initView(); 305 | $('.mxlayer-main-body').html(manageTmpl(hermit)); 306 | }); 307 | }, 308 | error: function () { 309 | $bodyLoader.showProgress('删除失败,请稍后重试。'); 310 | } 311 | }) 312 | } 313 | }); 314 | 315 | //编辑分类 316 | $('body').on('click', '.hermit-cat-edit', function () { 317 | var title = window.prompt("重命名分类",""), 318 | $this = $(this), 319 | id = $this.attr('data-id'); 320 | 321 | if ( id === '1' )return; 322 | 323 | if( title ){ 324 | $bodyLoader.showProgress('重命名分类中'); 325 | 326 | $.ajax({ 327 | url: hermit.adminUrl, 328 | data: { 329 | type: 'catupd', 330 | title: title, 331 | id: id 332 | }, 333 | type: 'post', 334 | success: function (data) { 335 | hermit.catList = data; 336 | $bodyLoader.showSuccess('重命名分类成功'); 337 | list({ 338 | page: 1, 339 | catid: hermit.currentCatId 340 | }, function () { 341 | initView(); 342 | $('.mxlayer-main-body').html(manageTmpl(hermit)); 343 | }); 344 | }, 345 | error: function () { 346 | $bodyLoader.showError('分类已存在'); 347 | } 348 | }); 349 | } 350 | }); 351 | 352 | //初始化 353 | initView(); 354 | 355 | //监测总数 356 | watch(hermit, 'count', function () { 357 | initCatNav(); 358 | initNavigation(); 359 | }); 360 | 361 | //监测菜单 362 | watch(hermit, 'currentCatId', function () { 363 | list({ 364 | page: 1, 365 | catid: hermit.currentCatId 366 | }, function () { 367 | initView(); 368 | }); 369 | }); 370 | 371 | //监测曲库 372 | watch(hermit, 'data', function () { 373 | initTable() 374 | }); 375 | 376 | //检测分类 377 | watch(hermit, 'catList', function () { 378 | initCatNav(); 379 | }); 380 | 381 | window.showTableByCat = function(catid){ 382 | hermit.currentCatId = catid; 383 | }; 384 | 385 | function initView() { 386 | initCatNav(); 387 | initNavigation(); 388 | initTable(); 389 | } 390 | 391 | function initCatNav() { 392 | $('.subsubsub').html(navTmpl(hermit)); 393 | } 394 | 395 | function initNavigation() { 396 | $('.tablenav-pages').html(navigationTmpl(hermit)) 397 | //分页 398 | .mxpage({ 399 | perPage: 5, 400 | currentPage: 1, //当前页数 401 | maxPage: hermit.maxPage, //最大页数 402 | previousText: '‹', //上一页标题 403 | nextText: '›', //下一页标题 404 | frontPageText: '«', //最前页标题 405 | lastPageText: '»', //最后页标题 406 | click: function (index) { 407 | list({ 408 | page: index, 409 | catid: hermit.currentCatId 410 | }) 411 | } 412 | }); 413 | } 414 | 415 | function initTable() { 416 | $('.wp-list-table tbody').html(tableTmpl(hermit)); 417 | } 418 | 419 | function form(sobj) { 420 | var main_html = formTmpl(sobj), 421 | msg = {}; 422 | 423 | if (sobj.id > 0) { 424 | msg.title = '更新音乐'; 425 | msg.success = '更新成功'; 426 | msg.error = '更新失败,请稍后重试。'; 427 | } else { 428 | msg.title = '新建音乐'; 429 | msg.success = '新建成功'; 430 | msg.error = '新建失败,请稍后重试。'; 431 | } 432 | 433 | $.mxlayer({ 434 | title: msg.title, 435 | main: main_html, 436 | button: msg.title, 437 | width: 720, 438 | height: 720, 439 | cancel: function () { 440 | }, 441 | confirm: function (that) { 442 | var formKey = ['song_name', 'song_author', 'song_url', 'song_cat', 'song_cover', 'song_lrc'], 443 | formObj = {}; 444 | 445 | $bodyLoader.showProgress('数据上传中'); 446 | 447 | for (var i = 0; i < formKey.length; i++) { 448 | var _id = formKey[i], 449 | $elem = $('#hermit-form-' + _id), 450 | val = $elem.val(); 451 | 452 | if (isEmpty(val)) { 453 | if (i < 4) { 454 | $bodyLoader.showError('请输入正确的信息。'); 455 | return false; 456 | } else { 457 | val = ''; 458 | } 459 | } 460 | 461 | formObj[_id] = val 462 | } 463 | 464 | if (sobj.id > 0) { 465 | formObj.id = sobj.id; 466 | formObj.type = 'update'; 467 | } else { 468 | formObj.type = 'new'; 469 | } 470 | 471 | $.ajax({ 472 | url: hermit.adminUrl, 473 | data: formObj, 474 | type: 'post', 475 | success: function (data) { 476 | $bodyLoader.showSuccess(msg.success); 477 | 478 | that.fireEvent(); 479 | 480 | list({ 481 | page: 1, 482 | catid: hermit.currentCatId 483 | }, function () { 484 | initView(); 485 | }); 486 | }, 487 | error: function () { 488 | $bodyLoader.showError(msg.error); 489 | } 490 | }); 491 | } 492 | }) 493 | } 494 | 495 | function list(lobj, callback) { 496 | $bodyLoader.showProgress('音乐加载中'); 497 | 498 | if (lobj.catid > 0) { 499 | lobj = { 500 | type: 'list', 501 | paged: lobj.page, 502 | catid: lobj.catid 503 | } 504 | } else { 505 | lobj = { 506 | type: 'list', 507 | paged: lobj.page 508 | } 509 | } 510 | 511 | $.ajax({ 512 | url: hermit.adminUrl, 513 | data: lobj, 514 | success: function (result) { 515 | $bodyLoader.dismiss(); 516 | 517 | hermit.data = result.data; 518 | 519 | if (callback) { 520 | hermit.count = result.count; 521 | hermit.maxPage = result.maxPage; 522 | hermit.catList = result.catList; 523 | 524 | callback(); 525 | } 526 | }, 527 | error: function () { 528 | $bodyLoader.showError('加载失败'); 529 | } 530 | }) 531 | } 532 | 533 | function dele(ids) { 534 | var cofim = window.confirm('确认删除?'); 535 | 536 | if (cofim) { 537 | $bodyLoader.showProgress('删除音乐中'); 538 | 539 | $.ajax({ 540 | url: hermit.adminUrl, 541 | type: 'post', 542 | data: { 543 | type: 'delete', 544 | ids: ids 545 | }, 546 | success: function (result) { 547 | hermit.catList = result; 548 | list({ 549 | page: 1, 550 | catid: hermit.currentCatId 551 | }, function () { 552 | initView(); 553 | }); 554 | }, 555 | error: function () { 556 | $bodyLoader.showProgress('删除失败,请稍后重试。'); 557 | } 558 | }) 559 | } 560 | } 561 | 562 | function move_cat(ids) { 563 | $.mxlayer({ 564 | title: '选择目标分类', 565 | main: catmovTmpl(hermit), 566 | button: '提交', 567 | width: 720, 568 | height: 220, 569 | cancel: function () { 570 | }, 571 | confirm: function (that) { 572 | $bodyLoader.showProgress('移动音乐中'); 573 | var data = { 574 | type: 'move', 575 | catid: $('#hermit-move-song_cat').val(), 576 | ids: ids 577 | }; 578 | $.ajax({ 579 | url: hermit.adminUrl, 580 | data: data, 581 | type: 'post', 582 | success: function (data) { 583 | $bodyLoader.showSuccess('移动成功'); 584 | 585 | that.fireEvent(); 586 | 587 | list({ 588 | page: 1, 589 | catid: hermit.currentCatId 590 | }, function () { 591 | initView(); 592 | }); 593 | }, 594 | error: function () { 595 | $bodyLoader.showError(msg.error); 596 | } 597 | }); 598 | } 599 | }) 600 | } 601 | 602 | function isEmpty(str) { 603 | if (str == null || str == undefined) { 604 | return true; 605 | } 606 | 607 | return str.replace(/(^\s*)|(\s*$)/g, "").length == 0 608 | } 609 | }); -------------------------------------------------------------------------------- /class.hermit.php: -------------------------------------------------------------------------------- 1 | _settings = get_option('hermit_setting'); 14 | 15 | /** 16 | ** 事件绑定 17 | **/ 18 | add_action('admin_menu', array( 19 | $this, 20 | 'menu', 21 | )); 22 | add_shortcode('hermit', array( 23 | $this, 24 | 'shortcode', 25 | )); 26 | add_action('admin_init', array( 27 | $this, 28 | 'page_init', 29 | )); 30 | add_action('wp_enqueue_scripts', array( 31 | $this, 32 | 'hermit_scripts', 33 | )); 34 | add_filter('plugin_action_links', array( 35 | $this, 36 | 'plugin_action_link', 37 | ), 10, 4); 38 | add_action('wp_ajax_nopriv_hermit', array( 39 | $this, 40 | 'hermit_callback', 41 | )); 42 | add_action('wp_ajax_hermit', array( 43 | $this, 44 | 'hermit_callback', 45 | )); 46 | add_action('in_admin_footer', array( 47 | $this, 48 | 'music_footer', 49 | )); 50 | add_action('wp_ajax_hermit_source', array( 51 | $this, 52 | 'hermit_source_callback', 53 | )); 54 | add_action('wp_footer', array( 55 | $this, 56 | 'aplayer_init', 57 | )); 58 | add_action('admin_enqueue_scripts', array( 59 | $this, 60 | 'cookies_pointer', 61 | )); 62 | add_action('wp_ajax_hermit_ignore_cookies_pointer', array( 63 | $this, 64 | 'ignore_cookies_pointer', 65 | )); 66 | add_action('enqueue_block_editor_assets', array( 67 | $this, 68 | 'hermitx_editor_assets' 69 | )); 70 | } 71 | 72 | /** 73 | * 载入所需要的CSS和js文件 74 | */ 75 | public function hermit_scripts() 76 | { 77 | $strategy = $this->settings('strategy'); 78 | $globalPlayer = $this->settings('globalPlayer'); 79 | 80 | if ($strategy == 1 && $globalPlayer == 0) { 81 | global $post, $posts; 82 | foreach ($posts as $post) { 83 | if (has_shortcode($post->post_content, 'hermit')) { 84 | $this->_load_scripts(); 85 | break; 86 | } 87 | } 88 | } else { 89 | $this->_load_scripts(); 90 | } 91 | } 92 | 93 | /** 94 | * 加载资源 95 | */ 96 | private function _load_scripts() 97 | { 98 | $this->_css('APlayer.min'); 99 | $this->_js('APlayer.min', $this->settings('jsplace')); 100 | if (!$this->settings('debug')) { 101 | $this->_js('hermit-load.min', 1); 102 | } else { 103 | $this->_js('hermit-load', 1); 104 | } 105 | } 106 | 107 | /** 108 | * 添加文章短代码 109 | */ 110 | public function shortcode($atts, $content = null) 111 | { 112 | if (empty($atts["theme"])) { 113 | $color = $this->settings('color'); 114 | } else { 115 | $color = $atts["theme"]; 116 | } 117 | switch ($color) { 118 | case 'default': 119 | $color = "#5895be"; 120 | break; 121 | case 'red': 122 | $color = "#dd4b39"; 123 | break; 124 | case 'blue': 125 | $color = "#5cb85c"; 126 | break; 127 | case 'yellow': 128 | $color = "#f0ad4e"; 129 | break; 130 | case 'pink': 131 | $color = "#f489ad"; 132 | break; 133 | case 'purple': 134 | $color = "#da70d6"; 135 | break; 136 | case 'black': 137 | $color = "#aaaaaa"; 138 | break; 139 | case 'customize': 140 | $color = $this->settings('color_customize'); 141 | break; 142 | default: 143 | break; 144 | } 145 | $atts["theme"] = $color; 146 | $atts["songs"] = $content; 147 | if ($this->settings('listFolded') == 1) { 148 | $atts["listfolded"] = 'true'; 149 | } 150 | 151 | $atts["mode"] = strtolower($atts["mode"]); 152 | 153 | switch ($atts["mode"]) { 154 | case 'random': 155 | $atts["loop"] = 'all'; 156 | $atts["order"] = 'random'; 157 | break; 158 | case 'order': 159 | $atts["loop"] = 'none'; 160 | $atts["order"] = 'list'; 161 | break; 162 | case 'single': 163 | $atts["loop"] = 'one'; 164 | $atts["order"] = 'list'; 165 | break; 166 | default: 167 | $atts["loop"] = 'all'; 168 | $atts["order"] = 'list'; 169 | break; 170 | } 171 | 172 | unset($atts["mode"]); 173 | 174 | $atts["_nonce"] = $this->settings('low_security') ? md5(NONCE_KEY . $content . NONCE_KEY) : wp_create_nonce($content); 175 | 176 | $playlist_max_height = $this->settings('playlist_max_height'); 177 | if ($playlist_max_height != 0 && empty($atts["listmaxheight"])) { 178 | $atts["listmaxheight"] = $playlist_max_height . "px"; 179 | } 180 | 181 | $keys = array_keys($atts); 182 | $apatts = ""; 183 | foreach ($keys as $value) { 184 | if ($value == "auto") { 185 | $apatts = $apatts . 'data-autoplay="' . (($atts[$value] == 1) ? "true" : "false") . '" '; 186 | continue; 187 | } 188 | 189 | $apatts = $apatts . 'data-' . $value . '="' . $atts[$value] . '" '; 190 | } 191 | 192 | return ''; 193 | } 194 | 195 | /** 196 | * 添加写文章按钮 197 | */ 198 | public function custom_button($context) 199 | { 200 | $context .= "