Last active
December 24, 2015 21:18
-
-
Save matori/6863985 to your computer and use it in GitHub Desktop.
記事タイトルと投稿タイプの指定orタームとタクソノミーの指定で簡単リンクなショートコード
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
if (!class_exists("EzLink")) { | |
class EzLink | |
{ | |
/** | |
* エラーメッセージの初期値 | |
* @var array | |
*/ | |
private $error_messages = array( | |
'invalid_shortcode' => array( | |
'text' => '[?]', | |
'message' => '不正なショートコードです。 この記事の編集ページに移動しますか?', | |
), | |
'post_type_not_found' => array( | |
'text' => '[?]', | |
'message' => '投稿タイプ「%s」は存在しません。 この記事の編集ページに移動しますか?', | |
), | |
'post_not_found' => array( | |
'text' => '[?]', | |
'message' => '記事タイトル「%s」は投稿タイプ「%s」内に存在しません。 新しく作成しますか?', | |
), | |
'post_not_published' => array( | |
'text' => '[?]', | |
'message' => '記事「%s」は公開されていません。 「%s」の編集ページに移動しますか?', | |
), | |
'taxonomy_not_found' => array( | |
'text' => '[?]', | |
'message' => 'タクソノミー「%s」は存在しません。 この記事の編集ページに移動しますか?', | |
), | |
'term_not_found' => array( | |
'text' => '[?]', | |
'message' => 'ターム「%s」はタクソノミー「%s」内に存在しません。 この記事の編集ページに移動しますか?', | |
), | |
'taxonomy_not_public' => array( | |
'text' => '[?]', | |
'message' => 'ターム「%s」はタクソノミー「%s」内に存在しますが、「%s」が公開されていません。 この記事の編集ページに移動しますか?', | |
), | |
); | |
/** | |
* 初期化<br> | |
* エラーメッセージを初期値に上書きする | |
* @param array $user_error_messages エラーメッセージのユーザー設定 | |
*/ | |
public function __construct($user_error_messages = null) | |
{ | |
// 引数が配列かどうかをチェックしてから上書き | |
if (is_array($user_error_messages)) { | |
// 各キーごとに上書きする | |
foreach ($this->error_messages as $key => $value) { | |
// 引数に初期設定と同じキーが存在し、それが配列なら上書き | |
if (isset($user_error_messages[$key]) && is_array($user_error_messages[$key])) { | |
$this->error_messages[$key] = array_merge($this->error_messages[$key], $user_error_messages[$key]); | |
} | |
} | |
} | |
} | |
/** | |
* 指定された記事タイトルの情報を取得し、配列として返す<br> | |
* status<br> | |
* 5: 不正なショートコード<br> | |
* 4: 投稿タイプが存在しない<br> | |
* 3: 投稿タイプは存在するが、指定タイトル記事は見つからない<br> | |
* 2: 投稿タイプも記事も存在するが、記事が公開されていない<br> | |
* 1: OK | |
* @param string $title 検索する記事タイトル | |
* @param string $post_type 検索対象とする投稿タイプ | |
* @return array ['status'=>Int, 'url'=>Str, 'error_text'=>Str, 'error_message'=>Str]<br>[検索結果ステータス, URL, エラー表示テキスト, エラーメッセージ] | |
*/ | |
private function ezlink_get_page($title, $post_type) | |
{ | |
// 記事タイトルまたは投稿タイプが指定されていない場合 | |
if ($title === '' || $post_type === '') { | |
return array( | |
'status' => 5, | |
'url' => get_edit_post_link(), | |
'error_text' => $this->error_messages['invalid_shortcode']['text'], | |
'error_message' => $this->error_messages['invalid_shortcode']['message'], | |
); | |
} | |
// 投稿タイプが存在しない場合 | |
if (post_type_exists($post_type) === false) { | |
return array( | |
'status' => 4, | |
'url' => get_edit_post_link(), | |
'error_text' => $this->error_messages['post_type_not_found']['text'], | |
'error_message' => sprintf($this->error_messages['post_type_not_found']['message'], $post_type), | |
); | |
} | |
// 投稿タイプが存在する場合は記事タイトルを検索 | |
// 見つかったら記事データのオブジェクト、見つからない場合はnull | |
$page = get_page_by_title(html_entity_decode($title, ENT_QUOTES), OBJECT, $post_type); | |
// 記事が見つからなかった場合 | |
if ($page === null) { | |
return array( | |
'status' => 3, | |
'url' => admin_url() . 'post-new.php?post_type=' . $post_type . '&post_title=' . $title, | |
'error_text' => $this->error_messages['post_not_found']['text'], | |
'error_message' => sprintf($this->error_messages['post_not_found']['message'], $title, $post_type), | |
); | |
} | |
// 記事は見つかったが、公開されていない場合 | |
if ($page->post_status !== 'publish') { | |
return array( | |
'status' => 2, | |
'url' => get_edit_post_link($page->ID), | |
'error_text' => $this->error_messages['post_not_published']['text'], | |
'error_message' => sprintf($this->error_messages['post_not_published']['message'], $title, $title), | |
); | |
} | |
// これまでの条件にひっかからなかったらOK出す | |
return array( | |
'status' => 1, | |
'url' => get_permalink($page->ID), | |
'error_text' => '', | |
'error_message' => '', | |
); | |
} | |
/** | |
* 指定された記事タイトルを投稿タイプから検索し、見つかったらリンクを返す<br> | |
* 見つからなかったらログインユーザーのみにエラーを表示し、一般ユーザーには指定テキストのみを表示する<br> | |
* @param string $title 検索する記事タイトル | |
* @param string $post_type 検索対象とする投稿タイプ | |
* @param string $hashlink ハッシュリンク対象 | |
* @param string $link_text リンクに使用するテキスト (ない場合は記事タイトルを使う) | |
* @param string $classes リンクに指定するclass属性の値 | |
* @return string HTML | |
*/ | |
private function ezlink_get_page_link($title, $post_type, $hashlink, $link_text, $classes) | |
{ | |
// 記事を探した結果 | |
$page_info = $this->ezlink_get_page($title, $post_type); | |
// リンクテキストが設定されていなかったら記事タイトルを使う | |
$text = $link_text ? $link_text : $title; | |
// URLをエスケープ | |
$url = htmlspecialchars($page_info['url']); | |
// 記事タイトルの検索結果ステータスが *1* 以上の場合 (エラーが出ている) | |
if ($page_info['status'] > 1) { | |
return $this->get_error_message($text, $url, $page_info['error_message'], $page_info['error_text']); | |
} | |
// エラーがなければリンクを作って返す | |
$link_html = '<a href="' . $url; | |
if ($hashlink !== '') { | |
$link_html .= '#' . $hashlink; | |
} | |
$link_html .= '"'; | |
if ($classes !== '') { | |
$link_html .= 'class="' . $classes . '"'; | |
} | |
$link_html .= '>' . $text . '</a>'; | |
return $link_html; | |
} | |
/** | |
* 指定されたタームの情報を取得し、配列として返す<br> | |
* status<br> | |
* 5: 不正なショートコード<br> | |
* 4: タクソノミーが存在しない<br> | |
* 3: タクソノミーは存在するが、タームは見つからない<br> | |
* 2: タクソノミーもタームも存在するが、タクソノミーが公開されていない<br> | |
* 1: OK | |
* @param string $term 検索するターム | |
* @param string $taxonomy 検索対象とするタクソノミー | |
* @return array ['status'=>Int, 'url'=>Str, 'error_text'=>Str 'error_message'=>Str]<br>[検索結果ステータス, URL, エラー表示テキスト, エラーメッセージ] | |
*/ | |
private function ezlink_get_term($term, $taxonomy) | |
{ | |
// タームまたはタクソノミーが指定されていない場合 | |
if ($term === '' || $taxonomy === '') { | |
return array( | |
'status' => 5, | |
'url' => get_edit_post_link(), | |
'error_text' => $this->error_messages['invalid_shortcode']['text'], | |
'error_message' => $this->error_messages['invalid_shortcode']['message'], | |
); | |
} | |
// タクソノミーが指定されていれば、そのタクソノミーのデータを取得 | |
$taxonomy_info = get_taxonomy($taxonomy); | |
// タクソノミーが存在しない場合 | |
if ($taxonomy_info === false) { | |
return array( | |
'status' => 4, | |
'url' => get_edit_post_link(), | |
'error_text' => $this->error_messages['taxonomy_not_found']['text'], | |
'error_message' => sprintf($this->error_messages['taxonomy_not_found']['message'], $taxonomy), | |
); | |
} | |
// タクソノミーが存在していれば、タームを検索 | |
// 見つかったらタームデータのオブジェクト、見つからない場合はfalse | |
$term_page = get_term_by('name', $term, $taxonomy); | |
if ($term_page === false) { | |
return array( | |
'status' => 3, | |
'url' => get_edit_post_link(), | |
'error_text' => $this->error_messages['term_not_found']['text'], | |
'error_message' => sprintf($this->error_messages['term_not_found']['message'], $term, $taxonomy), | |
); | |
} | |
// タームは見つかったが、タクソノミーが非公開の場合 | |
if ($taxonomy_info->public !== true) { | |
return array( | |
'status' => 2, | |
'url' => get_edit_post_link(), | |
'error_text' => $this->error_messages['taxonomy_not_public']['text'], | |
'error_message' => sprintf($this->error_messages['taxonomy_not_public']['message'], $term, $taxonomy, | |
$taxonomy), | |
); | |
} | |
// これまでの条件にひっかからなかったらOK出す | |
return array( | |
'status' => 1, | |
'url' => get_term_link(intval($term_page->term_id), $taxonomy_info->name), | |
'error_text' => '', | |
'error_message' => '', | |
); | |
} | |
/** | |
* 指定されたタームをタクソノミーから検索し、見つかったらリンクを返す<br> | |
* 見つからなかったらログインユーザーのみにエラーを表示し、一般ユーザーには指定テキストのみを表示する<br> | |
* @param string $term 検索するターム | |
* @param string $taxonomy 検索対象とするタクソノミー | |
* @param string $hashlink ハッシュリンク対象 | |
* @param string $link_text リンクに使用するテキスト (ない場合はタームを使う) | |
* @param string $classes リンクに指定するclass属性の値 | |
* @return string HTML | |
*/ | |
private function ezlink_get_term_link($term, $taxonomy, $hashlink, $link_text, $classes) | |
{ | |
// タームを探した結果 | |
$term_info = $this->ezlink_get_term($term, $taxonomy); | |
// リンクテキストが設定されていなかったら記事タイトルを使う | |
$text = $link_text ? $link_text : $term; | |
// URLをエスケープ | |
$url = htmlspecialchars($term_info['url']); | |
// 記事タイトルの検索結果ステータスが *1* 以上の場合 (エラーが出ている) | |
if ($term_info['status'] > 1) { | |
return $this->get_error_message($text, $url, $term_info['error_message'], $term_info['error_text']); | |
} | |
// エラーがなければリンクを作って返す | |
$link_html = '<a href="' . $url; | |
if ($hashlink !== '') { | |
$link_html .= '#' . $hashlink; | |
} | |
$link_html .= '"'; | |
if ($classes) { | |
$link_html .= 'class="' . $classes . '"'; | |
} | |
$link_html .= '>' . $text . '</a>'; | |
return $link_html; | |
} | |
/** | |
* エラー表示HTMLを作って返す | |
* @param string $text リンクテキストになるはずだった文字列 | |
* @param string $url エラーリンクのリンク先 | |
* @param string $error_message エラーの内容 (エラーリンクのtitle属性に入る) | |
* @param string $error_text エラーリンクのテキスト | |
* @return string HTML | |
*/ | |
private function get_error_message($text, $url, $error_message, $error_text) | |
{ | |
if (is_user_logged_in()) { | |
// ログインユーザーにはリンクテキストにエラー表示を加える | |
// エラーメッセージはtitle属性に | |
return $text | |
. '<sup class="ezlink-error">' | |
. '<a href="' . $url . '" title="' . $error_message . '">' . $error_text . '</a>' | |
. '</sup>'; | |
} else { | |
// 一般ユーザーにはリンクテキストだけ | |
return $text; | |
} | |
} | |
/** | |
* ショートコード登録用関数 | |
* @param $atts | |
* @return string HTML | |
*/ | |
public function ezlink_shortcode($atts) | |
{ | |
// オプション配列 | |
$options = array(); | |
$options['title'] = ''; | |
// 投稿タイプの初期値はpage | |
$options['type'] = 'page'; | |
$options['hash'] = ''; | |
$options['term'] = ''; | |
// タクソノミーの初期値はカテゴリー | |
$options['tax'] = 'category'; | |
$options['text'] = ''; | |
$options['class'] = ''; | |
extract(shortcode_atts($options, $atts)); | |
// タイトルが指定されていれば記事を探す | |
if ($title !== '' && is_string($title)) { | |
return $this->ezlink_get_page_link($title, $type, $hash, $text, $class); | |
} | |
// タームが指定されていればタームを探す | |
if ($term !== '' && is_string($term)) { | |
return $this->ezlink_get_term_link($term, $tax, $hash, $text, $class); | |
} | |
// 上の条件に引っかからなかったら一応記事を探す | |
return $this->get_error_message($text, | |
get_edit_post_link(), | |
$this->error_messages['invalid_shortcode']['message'], | |
$this->error_messages['invalid_shortcode']['text']); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
require_once('path/to/EzLink.php'); | |
$ezlink_opt = array( | |
'invalid_shortcode' => array( | |
'text' => '[????]' | |
)); | |
$EzLink = new EzLink($ezlink_opt); | |
add_shortcode('ezlink', array($EzLink, 'ezlink_shortcode')); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment