| 1 |
<?php |
| 2 |
/* |
| 3 |
Name: 常用简码 |
| 4 |
URI: https://blog.wpjam.com/m/wpjam-basic-shortcode/ |
| 5 |
Description: 添加 email, list, table, bilibili, youku, qqv 等常用简码,并在后台罗列系统的所有可用的简码。 |
| 6 |
Version: 1.0 |
| 7 |
*/ |
| 8 |
class WPJAM_Shortcode{ |
| 9 |
public static function callback($attr, $text, $tag){ |
| 10 |
$attr = array_map('esc_attr', (array)$attr); |
| 11 |
$text = wp_kses($text, 'post'); |
| 12 |
|
| 13 |
if($tag == 'hide'){ |
| 14 |
return ''; |
| 15 |
}elseif($tag == 'email'){ |
| 16 |
return antispambot($text, shortcode_atts(['mailto'=>false], $attr)['mailto']); |
| 17 |
}elseif(in_array($tag, ['bilibili', 'youku', 'tudou', 'qqv', 'sohutv'])){ |
| 18 |
return wp_video_shortcode(array_merge($attr, ['src'=>$text])); |
| 19 |
}elseif($tag == 'code'){ |
| 20 |
$attr = shortcode_atts(['type'=>'php'], $attr); |
| 21 |
$type = $attr['type'] == 'html' ? 'markup' : $attr['type']; |
| 22 |
$text = str_replace(["<br />\n", "</p>\n", "\n<p>"], ["\n", "\n\n", "\n"], $text); |
| 23 |
$text = trim(str_replace('&', '&', esc_textarea($text))); // wptexturize 会再次转化 & => & |
| 24 |
|
| 25 |
return $type ? '<pre><code class="language-'.$type.'">'.$text.'</code></pre>' : '<pre>'.$text.'</pre>'; |
| 26 |
}elseif($tag == 'list'){ |
| 27 |
$attr = shortcode_atts(['type'=>'', 'class'=>''], $attr); |
| 28 |
$tag = in_array($attr['type'], ['order', 'ol']) ? 'ol' : 'ul'; |
| 29 |
$items = wpjam_lines(str_replace(["\r\n", "<br />\n", "</p>\n", "\n<p>"], "\n", $text), fn($v)=> "<li>".do_shortcode($v)."</li>\n"); |
| 30 |
|
| 31 |
return '<'.$tag.($attr['class'] ? ' class="'.$attr['class'].'"' : '').">\n".implode($items)."</".$tag.">\n"; |
| 32 |
}elseif($tag == 'table'){ |
| 33 |
$attr = shortcode_atts(['cellpading'=>0, 'cellspacing'=>0, 'class'=>'', 'caption'=>'', 'th'=>0], $attr); |
| 34 |
$render = $attr['caption'] ? '<caption>'.$attr['caption'].'</caption>' : ''; |
| 35 |
$rows = wpjam_lines(str_replace(["\r\n", "<br />\n", "\n<p>", "</p>\n"], ["\n", "\n", "\n", "\n\n"], $text), "\n\n"); |
| 36 |
|
| 37 |
if($attr['th'] == 1 || $attr['th'] == 4){ // 1-横向,4-横向并且有 footer |
| 38 |
$thead = '<tr>'."\n".implode(wpjam_lines(array_shift($rows), fn($v)=> '<th>'.$v.'</th>'."\n")).'</tr>'."\n"; |
| 39 |
$render .= '<thead>'."\n".$thead.'</thead>'."\n"; |
| 40 |
$render .= $attr['th'] == 4 ? '<tfoot>'."\n".$thead.'</tfoot>'."\n" : ''; |
| 41 |
} |
| 42 |
|
| 43 |
$tag = $attr['th'] == 2 && $i == 0 ? 'th' : 'td'; // 2-纵向 |
| 44 |
$rows = array_map(fn($tr)=> '<tr>'."\n".implode(wpjam_lines($tr, fn($v)=> '<'.$tag.'>'.$v.'</'.$tag.'>'."\n")), $rows); |
| 45 |
$render .= '<tbody>'."\n".implode($rows).'</tbody>'."\n"; |
| 46 |
|
| 47 |
return wpjam_tag('table', wpjam_pick($attr, ['border', 'cellpading', 'cellspacing', 'width', 'class']), $render); |
| 48 |
} |
| 49 |
} |
| 50 |
|
| 51 |
public static function query_items($args){ |
| 52 |
return wpjam_reduce($GLOBALS['shortcode_tags'], fn($carry, $callback, $tag)=> [...$carry, ['tag'=>wpautop($tag), 'callback'=>wpjam_callback('render', $callback)]], []); |
| 53 |
} |
| 54 |
|
| 55 |
public static function get_actions(){ |
| 56 |
return []; |
| 57 |
} |
| 58 |
|
| 59 |
public static function get_fields($action_key='', $id=0){ |
| 60 |
return [ |
| 61 |
'tag' => ['title'=>'简码', 'type'=>'view', 'show_admin_column'=>true], |
| 62 |
'callback' => ['title'=>'回调函数', 'type'=>'view', 'show_admin_column'=>true] |
| 63 |
]; |
| 64 |
} |
| 65 |
|
| 66 |
public static function add_hooks(){ |
| 67 |
array_map(fn($tag)=> add_shortcode($tag, [self::class, 'callback']), ['hide', 'email', 'list', 'table', 'code', 'youku', 'qqv', 'bilibili', 'tudou', 'sohutv']); |
| 68 |
|
| 69 |
array_map('wpjam_add_video_parser', [[ |
| 70 |
'//www.bilibili.com/video/(BV[a-zA-Z0-9]+)', |
| 71 |
fn($m)=> 'https://player.bilibili.com/player.html?bvid='.esc_attr($m[1]) |
| 72 |
], [ |
| 73 |
'//v.qq.com/(.*)iframe/(player|preview).html\?vid=(.+)', |
| 74 |
fn($m)=> 'https://v.qq.com/'.esc_attr($m[1]).'iframe/player.html?vid='.esc_attr($m[3]) |
| 75 |
], [ |
| 76 |
'//v.youku.com/v_show/id_(.*?).html', |
| 77 |
fn($m)=> 'https://player.youku.com/embed/'.esc_attr($m[1]) |
| 78 |
], [ |
| 79 |
'//www.tudou.com/programs/view/(.*?)', |
| 80 |
fn($m)=> 'https://www.tudou.com/programs/view/html5embed.action?code='.esc_attr($m[1]) |
| 81 |
], [ |
| 82 |
'//tv.sohu.com/upload/static/share/share_play.html\#(.+)', |
| 83 |
fn($m)=> 'https://tv.sohu.com/upload/static/share/share_play.html#'.esc_attr($m[1]) |
| 84 |
], [ |
| 85 |
'//www.youtube.com/watch\?v=([a-zA-Z0-9\_]+)', |
| 86 |
fn($m)=> 'https://www.youtube.com/embed/'.esc_attr($m[1]) |
| 87 |
]]); |
| 88 |
} |
| 89 |
} |
| 90 |
|
| 91 |
function wpjam_add_video_parser($args){ |
| 92 |
static $object; |
| 93 |
$object ??= wpjam_hook('wp_video_shortcode_override', 'bind', function($override, $attr, $content){ |
| 94 |
$src = $attr['src'] ?? $content; |
| 95 |
$src = $src ? wpjam_find($this->parsers ?: [], fn($v)=> $v, fn($v)=> preg_match('#'.$v[0].'#i', $src, $matches) ? $v[1]($matches) : '') : ''; |
| 96 |
|
| 97 |
if($src){ |
| 98 |
$attr = shortcode_atts(['width'=>0, 'height'=>0], $attr); |
| 99 |
$attr = ($attr['width'] || $attr['height']) ? image_hwstring($attr['width'], $attr['height']).' style="aspect-ratio:4/3;"' : 'style="width:100%; aspect-ratio:4/3;"'; |
| 100 |
|
| 101 |
return '<iframe class="wpjam_video" '.$attr.' src="'.$src.'" scrolling="no" border="0" frameborder="no" framespacing="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>'; |
| 102 |
} |
| 103 |
|
| 104 |
return $override; |
| 105 |
}, 10, 3); |
| 106 |
|
| 107 |
$object->update_arg('parsers[]', $args); |
| 108 |
} |
| 109 |
|
| 110 |
wpjam_add_menu_page('wpjam-shortcodes', [ |
| 111 |
'parent' => 'wpjam-basic', |
| 112 |
'menu_title' => '常用简码', |
| 113 |
'model' => 'WPJAM_Shortcode', |
| 114 |
'network' => false, |
| 115 |
'summary' => __FILE__, |
| 116 |
'function' => 'list', |
| 117 |
'list_table' => ['primary_key'=>'tag', 'numberable'=>'No.'] |
| 118 |
]); |