Skip to content

Instantly share code, notes, and snippets.

@advanceboy
Last active February 10, 2021 17:08
Show Gist options
  • Save advanceboy/87140e2ea2a4a122bbcbd70f8ee9590f to your computer and use it in GitHub Desktop.
Save advanceboy/87140e2ea2a4a122bbcbd70f8ee9590f to your computer and use it in GitHub Desktop.
Hotfix for Pz-LinkCard v2.4.2.2 that fixes the error "pz-linkcard: Incorrect URL specification. (url=)" in Pz-LinkCard v2.4.2.2.
<?php
/*
Plugin Name: Pz-LinkCard
Plugin URI: http://poporon.poponet.jp/pz-linkcard
Description: リンクをカード形式で表示します。
Version: 2.4.2.2-pl210211hotfix
Author: poporon
Author URI: http://poporon.poponet.jp
License: GPLv2 or later
*/
defined('ABSPATH') || die;
class Pz_LinkCard {
private $slug; // スラッグ
private $text_domain; // テキスト ドメイン(スラッグと同じ内容)
private $charset; // 文字セット
private $amp; // Google AMP
private $now; // 現在日時(ローカル時間)
private $now_mysql; // 現在日時(SQL形式)
private $plugin_basename; // プラグイン ディレクトリの名前
private $plugin_dir_path; // プラグイン ディレクトリのパス
private $plugin_dir_url; // プラグイン ディレクトリのURL
private $plugin_link; // プラグインページのURL
private $upload_dir_path; // アップロード ディレクトリのパス
private $upload_dir_url; // アップロード ディレクトリのURL
private $db_name; // DB名
private $options; // パラメータ
protected $defaults = array(
'plugin-link' => null,
'plugin-url' => 'https://popozure.info/pz-linkcard',
'plugin-name' => 'Pz-LinkCard',
'plugin-version' => '2.4.2.2',
'flg-invalid' => null,
'invalid-url' => null,
'invalid-time' => null,
'special-format' => null,
'link-all' => 1,
'margin-top' => '4px',
'margin-right' => '16px',
'margin-bottom' => '16px',
'margin-left' => '4px',
'card-top' => null,
'card-right' => null,
'card-bottom' => null,
'card-left' => null,
'width' => '500px',
'content-height' => '108px',
'centering' => null,
'blockquote' => null,
'info-position' => 1,
'use-sitename' => 1,
'display-date' => 1,
'heading' => null,
'flg-anker' => 1,
'separator' => null,
'display-url' => 1,
'thumbnail-position' => 2,
'thumbnail-width' => '100px',
'thumbnail-height' => '108px',
'thumbnail-shadow' => null,
'content-inset' => null,
'display-excerpt' => 1,
'shadow-inset' => null,
'shadow' => null,
'radius' => null,
'hover' => null,
'border-style' => 'solid',
'border-width' => '1px',
'style-reset-img' => 1,
'flg-more' => null,
'sns-position' => 2,
'sns-tw' => 1,
'sns-fb' => 1,
'sns-hb' => 1,
'sns-po' => 1,
'color-title' => '#111111',
'color-url' => '#4466ff',
'color-excerpt' => '#333333',
'color-more' => '#444444',
'color-info' => '#222222',
'color-added' => '#222222',
'color-plugin' => '#888888',
'outline-title' => null,
'outline-url' => null,
'outline-excerpt' => null,
'outline-more' => null,
'outline-info' => null,
'outline-added' => null,
'outline-plugin' => null,
'outline-color-title' => '#ffffff',
'outline-color-url' => '#ffffff',
'outline-color-excerpt' => '#ffffff',
'outline-color-more' => '#ffffff',
'outline-color-info' => '#ffffff',
'outline-color-added' => '#ffffff',
'outline-color-plugin' => '#ffffff',
'size-title' => '16px',
'size-url' => '10px',
'size-excerpt' => '11px',
'size-more' => '12px',
'size-info' => '12px',
'size-added' => '12px',
'size-plugin' => '10px',
'height-title' => '24px',
'height-url' => '10px',
'height-excerpt' => '17px',
'height-more' => '40px',
'height-info' => '12px',
'height-added' => '12px',
'height-plugin' => '10px',
'trim-title' => 80,
'trim-url' => 250,
'trim-excerpt' => 500,
'trim-info' => 200,
'nowrap-title' => null,
'nowrap-url' => 1,
'thumbnail-resize' => 1,
'ex-border-color' => '#888888',
'ex-bgcolor' => '#ffffff',
'ex-image' => null,
'ex-thumbnail' => 13,
'ex-favicon' => 3,
'ex-info' => null,
'ex-more-text' => null,
'ex-target' => 2,
'nofollow' => null,
'noopener' => 1,
'use-hatena' => null,
'in-border-color' => '#888888',
'in-bgcolor' => '#f8f8f8',
'in-image' => null,
'in-thumbnail' => 1,
'in-favicon' => 3,
'in-info' => null,
'in-more-text' => null,
'in-target' => null,
'in-get' => null,
'flg-get-pid' => null,
'th-border-color' => '#888888',
'th-bgcolor' => '#eeeeee',
'th-image' => null,
'th-info' => null,
'favicon-api' => 'https://www.google.com/s2/favicons?domain=%DOMAIN%',
'thumbnail-api' => 'https://s.wordpress.com/mshots/v1/%URL%?w=100',
'cache-image-size' => 200,
'thumbnail-dir' => null,
'thumbnail-url' => null,
'css-url' => null,
'css-url-add' => null,
'css-add' => null,
'css-count' => 0,
'css-path' => null,
'css-templete' => null,
'flg-unlink' => 1,
'flg-ssl' => 1,
'flg-redir' => 1,
'flg-referer' => 1,
'flg-agent' => 1,
'user-agent' => null,
'flg-alive' => 1,
'flg-alive-count' => null,
'flg-subdir' => 1,
'code1' => 'blogcard',
'use-inline' => null,
'code2' => null,
'code3' => null,
'code4' => null,
'auto-atag' => null,
'auto-url' => null,
'auto-external' => null,
'flg-do-shortcode' => 1,
'flg-edit-insert' => 1,
'flg-edit-qtag' => 1,
'trail-slash' => '1',
'class-pc' => null,
'class-mobile' => null,
'flg-amp-url' => null,
'flg-idn' => 1,
'flg-relative-url' => null,
'flg-invalid-hide' => null,
'saved-date' => null,
'debug-time' => null,
'initialize' => null
);
public function __construct() {
$this->slug = basename(dirname(__FILE__));
$this->text_domain = $this->slug;
$this->charset = get_bloginfo('charset');
$this->amp = '1';
$this->now = current_time('timestamp', false);
$this->now_mysql = current_time('mysql');
$this->plugin_basename = plugin_basename(__FILE__);
$this->plugin_dir_path = plugin_dir_path(__FILE__);
$this->plugin_dir_url = plugin_dir_url (__FILE__);
$wp_upload_dir = wp_upload_dir();
$this->upload_dir_path = $wp_upload_dir['basedir'].'/'.$this->slug.'/';
$this->upload_dir_url = $wp_upload_dir['baseurl'].'/'.$this->slug.'/';
// オプション読み込み
$this->options = get_option('Pz_LinkCard_options', $this->defaults );
foreach ($this->defaults as $key => $value) {
if (!isset($this->options[$key])) {
$this->options[$key] = null;
}
}
// DB
global $wpdb;
$this->db_name = $wpdb->prefix.'pz_linkcard';
// バージョンが違っていたら、DBとオプションを更新する
if ($this->options['plugin-version'] <> $this->defaults['plugin-version']) {
$this->activate();
}
// 日本語化
load_plugin_textdomain ($this->text_domain, false, $this->slug.'/languages');
// 管理画面のとき
if (is_admin()) {
register_activation_hook (__FILE__, array($this, 'activate') ); // プラグインを有効化するときの処理
register_deactivation_hook (__FILE__, array($this, 'deactivate') ); // プラグインを無効化するときの処理
add_action ('admin_menu', array($this, 'add_menu') ); // 設定メニュー
add_action ('admin_enqueue_scripts', array($this, 'enqueue_admin') ); // 設定メニュー用スクリプト
add_action ('admin_print_footer_scripts', array($this, 'add_footer') ); // テキストエディタ用クイックタグ
add_action ('admin_notices', array($this, 'add_notices')); // 注意書き
add_filter ('mce_buttons', array($this, 'add_mce_button') ); // ビジュアルエディタ用ボタン
add_filter ('mce_external_plugins', array($this, 'add_mce_plugin') ); // ビジュアルエディタ用ボタン
add_filter ('plugin_action_links_'.$this->plugin_basename, array($this, 'action_links') ); // プラグイン画面
} else {
add_action ('wp_enqueue_scripts', array($this, 'enqueue') ); // スタイルシート呼び出し
if ($this->options['auto-atag'] || $this->options['auto-url']) { // 自動置き換え
add_filter ('the_content', array($this, 'auto_replace') );
add_shortcode ('pz-linkcard-auto-replace', array($this, 'shortcode') );
}
if ($this->options['code1']) { // ショートコード1
add_shortcode($this->options['code1'], array($this, 'shortcode'));
}
if ($this->options['code2']) { // ショートコード2
add_shortcode($this->options['code2'], array($this, 'shortcode'));
}
if ($this->options['code3']) { // ショートコード3
add_shortcode($this->options['code3'], array($this, 'shortcode'));
}
if ($this->options['code4']) { // ショートコード4
add_shortcode($this->options['code4'], array($this, 'shortcode'));
}
}
// SNS更新、リンク先チェック
add_action( 'pz_linkcard_check', array( $this, 'schedule_hook_check' ) );
add_action( 'pz_linkcard_alive', array( $this, 'schedule_hook_alive' ) );
if (!wp_next_scheduled('pz_linkcard_check')) {
wp_schedule_event ( time() + 10 , 'hourly', 'pz_linkcard_check');
}
if (!wp_next_scheduled('pz_linkcard_alive')) {
wp_schedule_event ( time() + 1800 , 'daily', 'pz_linkcard_alive');
}
}
// テキストリンクの行とURLのみの行をリンクカードへ置き換える処理(直接HTMLタグにするのでは無くショートコードに変換する。)
public function auto_replace($content ) {
if (!$this->options['auto-external'] ) {
if ($this->options['auto-atag'] ) {
$content = preg_replace('/(^|<br ?\/?>)(<p.*>)?<a .*href=[\'"](https?:\/\/[-_\.!~*()a-zA-Z0-9;\/?:\@&=+\$,%#]+)[\'"]((?!<IMG).)*<\/a>(<\/p>)?$/im', '[pz-linkcard-auto-replace url="$3"]', $content );
}
if ($this->options['auto-url'] ) {
$content = preg_replace('/(^|<br ?\/?>)(<p.*>)?(https?:\/\/[-_\.!~*()a-zA-Z0-9;\/?:\@&=+\$,%#]+)(<\/p>|<br ?\/?>)?$/im', '[pz-linkcard-auto-replace url="$3"]', $content );
}
if ($this->options['flg-do-shortcode'] && ($this->options['auto-atag'] || $this->options['auto-url'] ) ) {
$content = do_shortcode($content );
}
return $content;
} else {
if ($this->options['auto-atag'] ) {
preg_match_all('/(^|<br ?\/?>)(<p.*>)?(<a .*href=[\'"](https?:\/\/[-_\.!~*()a-zA-Z0-9;\/?:\@&=+\$,%#]+)[\'"]((?!<IMG).)*<\/a>)(<\/p>)?$/im', $content, $m );
for ($i = 0; $i < count($m[0]); $i++ ) {
$url = $m[4][$i];
if ($this->Pz_LinkType($url ) == 0 ) {
$tag = '[pz-linkcard-auto-replace url="'.$url.'"]';
$content = preg_replace('{'.$m[0][$i].'}', $tag, $content, 1 );
}
}
}
if ($this->options['auto-url'] ) {
preg_match_all('/(^|<br ?\/?>)(<p.*>)?(https?:\/\/[-_\.!~*()a-zA-Z0-9;\/?:\@&=+\$,%#]+)(<\/p>|<br ?\/?>)?$/im', $content, $m );
for ($i = 0; $i < count($m[0]); $i++ ) {
$url = $m[3][$i];
if ($this->Pz_LinkType($url ) == 0) {
$tag = '[pz-linkcard-auto-replace url="'.$url.'"]';
$content = preg_replace('{'.$m[0][$i].'}', $tag, $content, 1 );
}
}
}
if ($this->options['flg-do-shortcode'] && ($this->options['auto-atag'] || $this->options['auto-url'] ) ) {
$content = do_shortcode($content );
}
return $content;
}
}
// ショートコード処理
public function shortcode($atts, $content = null, $shortcode ) {
// 実行時間
if ($this->options['debug-time']) {
$start_time = microtime(true);
echo PHP_EOL.'<!-- Pz-LkC [Debug mode: On] /-->'.PHP_EOL;
echo '<!-- Pz-LkC [shortcode]'.PHP_EOL;
echo '$atts='.html_entity_decode(print_r($atts, true ) );
echo '$content="'.html_entity_decode($content ).'"'.PHP_EOL;
echo '$shortcode="'.html_entity_decode($shortcode ).'"'.PHP_EOL;
echo '/-->'.PHP_EOL;
}
// URLパラメータ
if (!empty($atts['url'] ) ) {
$url = $atts['url'];
} elseif (!empty($atts['href'] ) ) { // Aタグのようにhrefパラメータも有効にする
$url = $atts['href'];
} elseif (!empty($atts['uri'] ) ) { // 密かに記述ミス対応(uriやurIでもurlとして判定する)
$url = $atts['uri'];
} elseif (!empty($atts['ur1'] ) ) { // 密かに記述ミス対応(ur1でもurlとして判定する)
$url = $atts['ur1'];
} elseif (!empty($atts[0]) && preg_match('/url=[\s \'\"‘’“”″]*(.*?)[\s \'\"‘’“”″]*$/u', $atts[0], $m) ) { // 謎の記述ミスに対応
$url = $m[1];
} elseif (!empty($atts[1]) && preg_match('/url=[\s \'\"‘’“”″]*(.*?)[\s \'\"‘’“”″]*$/u', $atts[1], $m) ) { // 謎の記述ミスに対応
$url = $m[1];
} elseif (!empty($atts[0]) && preg_match('/href\s*=\s*(?:(?P<quo>[\'\"‘’“”″])(?P<url1>.*?)(?P=quo)|(?P<url2>[^ <>\'\"`=]+))/u', $atts[0], $m) ) { // URL が HTML リンクに書き換わって $atts に渡される際の、不可解な shortcode 動作に対応
$url = empty($m['url1']) ? $m['url2'] : $m['url1'];
} elseif (!empty($atts[1]) && preg_match('/href\s*=\s*(?:(?P<quo>[\'\"‘’“”″])(?P<url1>.*?)(?P=quo)|(?P<url2>[^ <>\'\"`=]+))/u', $atts[1], $m) ) { // URL が HTML リンクに書き換わって $atts に渡される際の、不可解な shortcode 動作に対応
$url = empty($m['url1']) ? $m['url2'] : $m['url1'];
} else {
$url = null;
}
$url_org = $url; // 指定されたurlパラメータ(エラー表示用)
if ($this->options['flg-relative-url'] && substr($url, 0, 1) == '/') {
$url = home_url().$url; // 相対パスを絶対パスに変換
}
$url = $this->pz_TrimURL($url ); // URLエンティティ化など(無害化?)
if (!$url ) {
if (!$this->options['flg-invalid']) {
$url_now = get_permalink();
$post_id = url_to_postid($url_now );
if ($post_id) {
$this->options['flg-invalid'] = true;
$this->options['invalid-url'] = $url_now;
$this->options['invalid-time'] = $this->now;
$result = update_option('Pz_LinkCard_options', $this->options);
}
}
return '<div id="lkc-error" class="lkc-error"><div class="lkc-card"><div class="lkc-this-wrap"><div class="lkc-excerpt">'.$this->slug.': '.__('Incorrect URL specification.', $this->text_domain).'(url='.html_entity_decode($url_org).')'.PHP_EOL.'<!-- '.html_entity_decode(print_r($atts, true)).' /-->'.PHP_EOL.'</div></div></div></div>';
}
$atts['url'] = $url;
// titleパラメータ
if (!isset($atts['title'] ) ) {
$atts['title'] = null;
}
// contentパラメータ
if (!isset($atts['excerpt'] ) ) {
if (isset($atts['content'] ) ) {
$atts['excerpt'] = $atts['content'];
} elseif (isset($atts['contents'] ) ) {
$atts['excerpt'] = $atts['contents'];
} elseif (isset($atts['description'] ) ) {
$atts['excerpt'] = $atts['description'];
} else {
$atts['excerpt'] = null;
}
}
// 囲まれ文字(ショートコード1のみ有効)
if ($shortcode == $this->options['code1']) {
switch (isset($this->options['use-inline']) ? $this->options['use-inline'] : null ) {
case '1':
$atts['excerpt'] = isset($content) ? $content : null;
break;
case '2':
$atts['title'] = isset($content) ? $content : null;
break;
}
}
// 記事内容取得
$tag = $this->pz_GetHTML($atts );
// 実行時間
if ($this->options['debug-time']) {
$end_time = microtime(true);
$elasped_time = number_format($end_time - $start_time, 8, '.', ',');
echo '<!-- Pz-LkC [shortcode]'.PHP_EOL;
echo 'ElaspedTime='.$elasped_time.'sec'.PHP_EOL;
echo '] /-->'.PHP_EOL;
}
return $tag;
}
// キャッシュやリンク先からリンクカードのHTMLを生成
private function pz_GetHTML($atts ) {
if ($this->options['debug-time']) {
echo '<!-- Pz-LkC [pz_GetHTML]'.PHP_EOL;
echo '$atts='.html_entity_decode(print_r($atts, true ) );
echo '/-->'.PHP_EOL;
}
// 変数の用意
$is_mobile = false;
$url = (isset($atts['url']) ? $atts['url'] : null);
// URL
if (!$url ) {
return null;
}
// モバイルチェック
if (function_exists('wp_is_mobile') && wp_is_mobile() ) {
$is_mobile = true;
}
if ($this->options['debug-time'] ) {
echo '<!-- Pz-LkC [pz_GetHTML] $is_mobile="'.$is_mobile.'" /-->'.PHP_EOL;
}
// URLパース(ドメイン名などを抽出)
$url_m = parse_url($url );
$scheme = isset($url_m['scheme']) ? $url_m['scheme'] : null; // スキーム
$domain = isset($url_m['host']) ? $url_m['host'] : null; // ドメイン名
$domain_url = isset($url_m['host']) ? $scheme.'://'.$url_m['host'] : null; // ドメインURL
$location = isset($url_m['path']) ? $url_m['path'] : null; // ドメイン名以降
// 自サイトチェック
$link_type = $this->Pz_LinkType($url );
// モバイルかPCかのクラス名を追加
$class_id = 'linkcard';
if ($is_mobile && $this->options['class-mobile'] ) {
$class_id .= ' '.$this->options['class-mobile'];
} elseif ($this->options['class-pc']) {
$class_id .= ' '.$this->options['class-pc'];
}
// キャッシュから取得
$data_id = null;
$data = array();
$data['url'] = $url;
$result = $this->pz_GetCache( $data );
if (isset($result) && is_array($result) && isset($result['url'])) {
$data = $result;
$data_id = $data['id'];
$url = $data['url'];
}
if ($this->options['debug-time']) {
echo '<!-- Pz-LkC [pz_GetHTML] get from cache $data_id="'.$data_id.'" /-->'.PHP_EOL;
}
// 内部リンクの処理
if ( $link_type ) {
if ($this->options['debug-time']) {
echo '<!-- Pz-LkC [pz_GetHTML] Internal link /-->'.PHP_EOL;
}
// リンクターゲットの設定
$target = ''; // 同ページに開く
if (isset($this->options['in-target'])) {
if ($this->options['in-target'] == '1' || ($this->options['in-target'] == '2' && !$is_mobile)) {
$target = ' target="_blank"'; // 新しいページで開く
}
}
// nofollowの指定
$rel = '';
if ( (isset($atts['follow'] ) && mb_strtolower($atts['follow']) == 'no') || (isset($atts['nofollow'] ) && mb_strtolower($atts['nofollow']) == 'true') ) {
$rel = ' rel="nofollow"'; // 要望により内部リンクでもnofollow可能(ショートコードのパラメータで指定時のみ)
}
// キャッシュが無い、もしくは強制取得
if ( is_null($data_id) || ( isset($atts['force']) && $atts['force'] == true ) ) {
$data = $this->pz_GetPost($data ); // 最新記事内容を取得
$data['link_type'] = 1;
$result = $this->pz_SetCache($data ); // 保存
} elseif ($this->options['in-get'] <> 2) {
$data = $this->pz_GetPost( $data ); // 最新記事内容を取得
$data['link_type'] = 1;
}
}
// 外部リンクの処理
if ( !$link_type ) {
if ($this->options['debug-time']) {
echo '<!-- Pz-LkC [pz_GetHTML] External link /-->'.PHP_EOL;
}
// リンクターゲットの設定
$target = null; // 同ページに開く
if (isset($this->options['ex-target'] ) ) {
if ($this->options['ex-target'] == '1' || ($this->options['ex-target'] == '2' && !$is_mobile ) ) {
$target = ' target="_blank"'; // 新しいタブで開く
}
}
// noopenerとnofollowの指定
$rel = 'external';
if ($this->options['nofollow'] || (isset($atts['follow'] ) && mb_strtolower($atts['follow']) == 'no') || (isset($atts['nofollow'] ) && mb_strtolower($atts['nofollow']) == 'true') ) {
$rel .= ' nofollow'; // nofollow指定。趣味の問題?
}
if ($this->options['noopener']) {
$rel .= ' noopenner';
}
$rel = ' rel="'.$rel.'"';
// キャッシュが無い、もしくは強制取得
if ( is_null($data_id) || ( isset($atts['force']) && $atts['force'] == true ) ) {
$result = $this->pz_GetCURL( $data ); // cURLで記事内容を取得
if ( isset($result) && is_array($result) && isset($result['url']) ) {
$data = $result;
$data['link_type'] = 0;
$result = $this->pz_SetCache( $data );
}
}
}
// 念のため初期化
$data_id = isset($data['id']) ? $data['id'] : null;
$site_name = isset($data['site_name']) ? $data['site_name'] : null;
$title = isset($data['title']) ? $data['title'] : null;
$excerpt = isset($data['excerpt']) ? $data['excerpt'] : null;
$post_date = isset($data['post_date']) ? $data['post_date'] : null;
$thumbnail_url = isset($data['thumbnail']) ? $data['thumbnail'] : null;
$favicon_url = isset($data['favicon']) ? $data['favicon'] : null;
$result_code = isset($data['result_code']) ? $data['result_code'] : null;
$sns_tw = isset($data['sns_twitter']) ? $data['sns_twitter'] : null;
$sns_fb = isset($data['sns_facebook']) ? $data['sns_facebook'] : null;
$sns_hb = isset($data['sns_hatena']) ? $data['sns_hatena'] : null;
$sns_po = isset($data['sns_pocket']) ? $data['sns_pocket'] : null;
$alive_result = isset($data['alive_result']) ? $data['alive_result'] : null;
$thumbnail = null;
$favicon = null;
// ラッピング
switch ($link_type) {
case '1':
$wrap_op = '<div class="lkc-this-wrap">';
$wrap_cl = '</div>';
$added_op = '<div class="lkc-this-added">';
$added_cl = '</div>';
$more = null;
$more_text = null;
$info = isset($this->options['th-info']) ? $this->options['th-info'] : null ;
$sw_thumbnail = isset($this->options['in-thumbnail']) ? $this->options['in-thumbnail'] : 0 ;
$sw_favicon = isset($this->options['in-favicon']) ? $this->options['in-favicon'] : 0 ;
break;
case '2':
$wrap_op = '<div class="lkc-internal-wrap">';
$wrap_cl = '</div>';
$added_op = '<div class="lkc-internal-added">';
$added_cl = '</div>';
$more = isset($this->options['flg-more']) ? $this->options['flg-more'] : null ;
$more_text = isset($this->options['in-more-text']) ? $this->options['in-more-text'] : null ;
$info = isset($this->options['in-info']) ? $this->options['in-info'] : null ;
$sw_thumbnail = isset($this->options['in-thumbnail']) ? $this->options['in-thumbnail'] : 0 ;
$sw_favicon = isset($this->options['in-favicon']) ? $this->options['in-favicon'] : 0 ;
break;
default:
$wrap_op = '<div class="lkc-external-wrap">';
$wrap_cl = '</div>';
$added_op = '<div class="lkc-external-added">';
$added_cl = '</div>';
$more = isset($this->options['flg-more']) ? $this->options['flg-more'] : null ;
$more_text = isset($this->options['ex-more-text']) ? $this->options['ex-more-text'] : null ;
$info = isset($this->options['ex-info']) ? $this->options['ex-info'] : null ;
$sw_thumbnail = isset($this->options['ex-thumbnail']) ? $this->options['ex-thumbnail'] : 0 ;
$sw_favicon = isset($this->options['ex-favicon']) ? $this->options['ex-favicon'] : 0 ;
break;
}
// 外部リンクの処理
if ( !$link_type && isset($this->options['use-hatena']) && !is_null($this->options['use-hatena'] ) ) {
// 「はてなブログカード」をそのまま利用する
$tag = '<div class="lkc-iframe-wrap"><iframe src="https://hatenablog-parts.com/embed?url=' .$url.'" class="lkc-iframe" scrolling="no" frameborder="0"></iframe></div>';
if (isset($this->options['blockquote']) ? $this->options['blockquote'] : null == '1') {
$tag = '<div class="'.$class_id.'"><blockquote class="lkc-quote">'.$tag.'</blockquote></div>';
} else {
$tag = '<div class="'.$class_id.'">'.$tag.'</div>';
}
return $tag; // タグを出力してさっさと終了
}
// サムネイル取得
if ( !$this->options['thumbnail-position'] || ( $result_code <> 0 && $result_code <> 200 ) ) {
$thumbnail = null;
} else {
if ($sw_thumbnail == 1 || $sw_thumbnail == 13 ) { // 直接取得
if (!$link_type ) {
$thumbnail_url = $this->pz_GetThumbnail($thumbnail_url ); // 外部サイトのサムネイルをキャッシュ
}
if (isset($thumbnail_url ) && $thumbnail_url <> '' ) {
$thumbnail = '<img class="lkc-thumbnail-img" src="'.$thumbnail_url.'" alt="" />';
} elseif ($sw_thumbnail == 13) { // 直接取得に失敗
$sw_thumbnail = 3;
}
}
if ($sw_thumbnail == 3 ) { // WebAPIを利用
// 画像取得(WebAPI)
if (isset($this->options['thumbnail-api'] ) ) {
$thumbnail = preg_replace('/%DOMAIN_URL%/', $domain_url, $this->options['thumbnail-api'] );
$thumbnail = preg_replace('/%DOMAIN%/', $domain, $thumbnail);
$thumbnail = preg_replace('/%URL%/', rawurlencode($url ), $thumbnail );
$thumbnail = '<img class="lkc-thumbnail-img" src="'.$thumbnail.'" alt="" />';
}
}
}
// ファビコン取得
if (!isset($this->options['info-position'] ) ) {
$favicon = null;
} else{
if ($sw_favicon == 1 || $sw_favicon == 13 ) { // 直接取得
if (!is_null($favicon_url ) ) {
$favicon = '<img class="lkc-favicon" src="'.$favicon_url.'" alt="" width=16 height=16 />';
} elseif ($sw_favicon == 13 ) { // 直接取得に失敗
$sw_favicon == 3;
}
}
if ($sw_favicon == 3 ) { // WebAPIを利用
// サイトアイコン取得(WebAPI)
if (isset($this->options['favicon-api'] ) ) {
$favicon = preg_replace('/%DOMAIN_URL%/', $domain_url, $this->options['favicon-api'] );
$favicon = preg_replace('/%DOMAIN%/', $domain, $favicon);
$favicon = preg_replace('/%URL%/', rawurlencode($url), $favicon);
$favicon = '<img class="lkc-favicon" src="'.$favicon.'" alt="" width=16 height=16 />';
}
}
}
// タイトル
if (!$title ) {
$title = esc_html($url ); // タイトル取得できていなかったらURLをセットする
}
// パラメータ取得(タイトル・抜粋文)
if ($atts['title'] ) { // title パラメータ
$title = $atts['title'];
$excerpt = null;
}
if ($atts['excerpt'] ) { // excerpt パラメータ
$excerpt = $atts['excerpt'];
}
// タイトル整形
if ($title ) {
$str = $title;
$str = strip_tags($str ); // タグの除去
$str = str_replace(array("\r", "\n"), '', $str); // 改行削除
$str = esc_html($str ); // 念のためエスケープ
if ($this->options['trim-title'] ) {
$str = mb_strimwidth($str, 0, $this->options['trim-title'] , '...' );
}
$title = $str;
}
// 抜粋文整形(抜粋文非表示の場合、空欄にする)
if (!$this->options['display-excerpt'] ) {
$excerpt = '';
} else {
if ($excerpt ) {
$str = $excerpt;
$str = strip_tags($str ); // タグの除去
$str = preg_replace('/<!--more-->.+/is', '', $str ); // moreタグ以降削除
$str = preg_replace('/\[[^]]*\]/', '', $str ); // ショートコードすべて除去
$str = str_replace(array("\r", "\n"), '', $str ); // 改行削除
$str = esc_html($str ); // 念のためエスケープ
if ($this->options['trim-excerpt'] ) {
$str = mb_strimwidth($str, 0, $this->options['trim-excerpt'] , '...' );
}
$excerpt = $str;
}
}
// サイト名称を使わない場合、ドメイン名で上書き
$site_title = null;
if ($this->options['use-sitename'] && $site_name ) {
$c_site_name = $site_name;
if ($this->options['trim-info']) {
$str = $site_name;
$str = mb_strimwidth($str, 0, $this->options['trim-info'] , '...');
$site_name = $str;
}
if ($site_name <> $c_site_name ) {
$site_title = ' title="'.$c_site_name.'"';
}
} else {
$site_name = $domain;
// 日本語ドメイン対応
if ($this->options['flg-idn'] && function_exists('idn_to_utf8' ) && substr($domain, 0, 4 ) == 'xn--' ) {
$site_name = idn_to_utf8($domain );
}
}
// リンク先URL
if ($this->options['flg-unlink'] && array_search($alive_result, array('403','404','410' ) ) ) {
// Not Found の時は見え消ししてリンクしない
$a_op_all = '<div style="cursor: not-allowed;" title="">';
$a_cl_all = '</div>';
$a_op = '';
$a_cl = '';
$st_op = '<strike>';
$st_cl = '</strike>';
} elseif ($this->options['link-all'] ) {
// カード全体をリンク(どこをクリックしても良いのが分かり易い)
$a_op_all = '<a class="lkc-link no_icon" href="'.$url.'"'.$target.$rel.'>';
$a_cl_all = '</a>';
$a_op = null;
$a_cl = null;
$st_op = null;
$st_cl = null;
} else {
// タイトルとかURLとかを個別でリンク(タイトルや抜粋文などの文字を範囲指定をしてコピー等がし易い)
$a_op_all = null;
$a_cl_all = null;
$a_op = '<a class="lkc-link no_icon" href="'.$url.'"'.$target.$rel.'>';
$a_cl = '</a>';
$st_op = null;
$st_cl = null;
}
// ソーシャルカウントの表示
$sns = null;
$sns_title = null;
$sns_info = null;
if ($this->options['sns-position'] ) {
// カード全体をリンクにするときは表示のみ
if ($this->options['link-all'] ) {
if ($this->options['sns-tw'] && $sns_tw > 0 ) {
$sns .= ' <div class="lkc-sns-tw">'.$sns_tw.'&nbsp;tweet' .(($sns_tw > 1) ? 's' : '').'</div>';
}
if ($this->options['sns-fb'] && $sns_fb > 0 ) {
$sns .= ' <div class="lkc-sns-fb">'.$sns_fb.'&nbsp;share' .(($sns_fb > 1) ? 's' : '').'</div>';
}
if ($this->options['sns-hb'] && $sns_hb > 0 ) {
$sns .= ' <div class="lkc-sns-hb">'.$sns_hb.'&nbsp;user' .(($sns_hb > 1) ? 's' : '').'</div>';
}
if ($this->options['sns-po'] && $sns_po > 0 ) {
$sns .= ' <div class="lkc-sns-po">'.$sns_po.'&nbsp;pocket'.(($sns_po > 1) ? 's' : '').'</div>';
}
} else {
// 外部リンクアイコンを表示させるプラグイン対応のため no_icon を付与
if ($this->options['sns-tw'] && $sns_tw > 0 ) {
$sns .= ' <a class="lkc-sns-tw no_icon" href="https://twitter.com/search?q=' .preg_replace('/.*\/\/(.*)/', '$1', $url).'&text='.esc_html($title).'" target="_blank">'.$sns_tw.'&nbsp;tweet'.(($sns_tw > 1) ? 's' : '').'</a>';
}
if ($this->options['sns-fb'] && $sns_fb > 0 ) {
$sns .= ' <a class="lkc-sns-fb no_icon" href="https://www.facebook.com/" target="_blank">'.$sns_fb.'&nbsp;share'.(($sns_fb > 1) ? 's' : '').'</a>';
}
if ($this->options['sns-hb'] && $sns_hb > 0 ) {
$sns .= ' <a class="lkc-sns-hb no_icon" href="https://b.hatena.ne.jp/entry/s/' .preg_replace('/.*\/\/(.*)/', '$1', $url).'" target="_blank">'.$sns_hb.'&nbsp;user'.(($sns_hb > 1) ? 's' : '').'</a>';
}
if ($this->options['sns-po'] && $sns_po > 0 ) {
$sns .= ' <a class="lkc-sns-po no_icon" href="https://getpocket.com/" target="_blank">'.$sns_po.'&nbsp;pocket'.(($sns_po > 1) ? 's' : '').'</a>';
}
}
if ($sns ) {
if ($this->options['sns-position'] == '1') {
$sns_title = '<div class="lkc-share">'.$sns.'</div>';
} else {
$sns_info = '&nbsp;'.'<div class="lkc-share">'.$sns.'</div>';
}
}
}
// サムネイル
if ($thumbnail ) {
$thumbnail = '<figure class="lkc-thumbnail">'.$thumbnail.'</figure>';
}
// 日本語ドメイン対応
if ($this->options['flg-idn'] && function_exists('idn_to_utf8') && substr($domain, 0, 4 ) == 'xn--') {
$url = $scheme.'://'.idn_to_utf8($domain ).$location;
}
// 続きを読むボタン
if ($more && $more_text ) {
$moretag = '<div class="lkc-more">'.$a_op.'<div class="lkc-more-text">'.$more_text.'</div>'.$a_cl.'</div>';
} else {
$moretag = null;
}
// リンク先URL
$url1 = null;
$url2 = null;
if ($this->options['display-url'] ) {
if ($this->options['display-url'] == '2' ) {
$url2 = '&nbsp;<div class="lkc-url-info"><cite>'.$st_op.$a_op.$url.$st_cl.$a_cl.'</cite></div>';
} else {
$url1 = '<div class="lkc-url"><cite>'.$st_op.$a_op.$url.$st_cl.$a_cl.'</cite></div>';
}
}
// サイト情報
if ($info ) {
$added_info = $added_op.$info.$added_cl;
} else {
$added_info = null;
}
if ($this->options['display-date'] && $link_type ) {
$post_dat = '<div class="lkc-date">'.date('Y.m.d', strtotime($post_date)).'</div>';
} else {
$post_date = null;
}
$domain_info = '<div class="lkc-info">'.$a_op.$favicon.'<div class="lkc-domain"'.$site_title.'>'.$site_name.'</div>'.$added_info.$a_cl.$sns_info.$url2.$post_date.'</div>';
// Google AMPに対応
if ((function_exists('is_amp_endpoint' ) && is_amp_endpoint() ) || $this->amp || ($this->options['flg-amp-url'] && (preg_match('/\/amp\/?$/i', $_SERVER["REQUEST_URI"]) || preg_match('/\?amp=1$/i', $_SERVER["REQUEST_URI"]) ) ) ) {
// 簡易タグ作成
$tag = '<table border="1" cellspacing="0" cellpadding="4"><tbody></tr><tr><td>'.$excerpt.'<br>'.$a_op_all.$a_op.$title.$a_cl.$a_cl_all.' - '.$site_name.'</td></tr></tbody></table>';
} else {
// HTMLタグ作成
switch (isset($this->options['info-position']) ? $this->options['info-position'] : null) {
case '1':
$tag = $wrap_op.$a_op_all.'<div class="lkc-card">'.$domain_info.'<div class="lkc-content">'.$a_op.$thumbnail.'<div class="lkc-title"><div class="lkc-title-text">'.$title.'</div>'.$a_cl.$sns_title.'</div>'.$url1.'<div class="lkc-excerpt">'.$excerpt.'</div>'.$moretag.'</div><div class="clear"></div></div>'.$a_cl_all.$wrap_cl;
break;
case '2':
$tag = $wrap_op.$a_op_all.'<div class="lkc-card"><div class="lkc-content">'.$a_op.$thumbnail.'<div class="lkc-title"><div class="lkc-title-text">'.$title.'</div>'.$a_cl.$sns_title.'</div>'.$url1.'<div class="lkc-excerpt">'.$excerpt.'</div>'.$moretag.'</div>'.$domain_info.'<div class="clear"></div></div>'.$a_cl_all.$wrap_cl;
break;
case '3':
$tag = $wrap_op.$a_op_all.'<div class="lkc-card"><div class="lkc-content">'.$a_op.$thumbnail.$domain_info.'<div class="lkc-title"><div class="lkc-title-text">'.$title.'</div>'.$a_cl.$sns_title.$url1.'</div><div class="lkc-excerpt">'.$excerpt.'</div>'.$moretag.'</div><div class="clear"></div></div>'.$a_cl_all.$wrap_cl;
break;
default:
$tag = $wrap_op.$a_op_all.'<div class="lkc-card"><div class="lkc-content">'.$a_op.$thumbnail.'<div class="lkc-title"><div class="lkc-title-text">'.$title.'</div>'.$a_cl.$sns_title.'</div>'.$url1.'<div class="lkc-excerpt">'.$excerpt.'</div>'.$moretag.'</div><div class="clear"></div></div>'.$a_cl_all.$wrap_cl;
}
}
// 引用文扱い
if (isset($this->options['blockquote']) ? $this->options['blockquote'] : null == '1') {
$tag = '<div class="'.$class_id.'"><blockquote class="lkc-quote">'.$tag.'</blockquote></div>';
} else {
$tag = '<div class="'.$class_id.'">'.$tag.'</div>';
}
return $tag;
}
// URLのエンティティ化など(無害化?)
private function pz_TrimURL($url = null ) {
if ($this->options['debug-time']) {
echo '<!-- Pz-LkC [pz_TrimURL]'.PHP_EOL;
echo '$url='.html_entity_decode($url ).PHP_EOL;
echo '/-->'.PHP_EOL;
}
if (!$url ) {
return $url;
}
$url = html_entity_decode($url );
$url = preg_replace('/^[\s \'\"‘’“”″]*(.*?)[\s \'\"‘’“”″]*$/u', '\1', $url ); // 色んな打ち間違え対応
$url = esc_url($url ); // プロトコル除外など
$url = trim($url );
switch (isset($this->options['trail-slash']) ? $this->options['trail-slash'] : null ) {
case '1': // URLがドメイン名だけの場合、最後のスラッシュを除外する
$array_url = parse_url($url);
if (!isset($array_url['path']) || $array_url['path'] == '/') {
$url = rtrim($url, '/');
}
break;
case '2': // 常に最後のスラッシュを除外する
$url = rtrim($url, '/');
break;
}
if ($this->options['debug-time']) {
echo '<!-- Pz-LkC [pz_TrimURL]'.PHP_EOL;
echo 'return'.PHP_EOL;
echo '$url='.html_entity_decode($url ).PHP_EOL;
echo '/-->'.PHP_EOL;
}
return $url;
}
// 内部サイト・外部サイトの判断
private function pz_LinkType($url = null ) {
if (substr($url, 0, mb_strlen(home_url() ) ) == home_url() ) {
if (get_permalink() == $url) {
$link_type = 1; // 自ページ
} else {
$link_type = 2; // 自サイト内
}
} else {
$link_type = 0; // 外部サイト
}
// サブディレクトリ型マルチサイト対応
if ($this->options['flg-subdir'] && function_exists('is_multisite') && is_multisite() && function_exists('is_subdomain_install') && !is_subdomain_install() && function_exists('is_main_site') && is_main_site()) {
$this_blog_id = get_current_blog_id();
$blog_id = 0;
do {
$blog_id++;
$blog_url = get_site_url($blog_id);
if ($blog_url && $blog_id <> $this_blog_id && substr($url, 0, mb_strlen($blog_url) ) == $blog_url ) {
// ドメイン名
if (preg_match('/https?:\/\/(.*)\//i', $blog_url.'/',$m)) {
$domain_url = $m[0];
$domain = $m[1];
} else {
$domain_url = null;
$domain = null;
}
$link_type = 0; // 外部サイト
}
} while ($blog_url);
}
if ($this->options['debug-time']) {
echo '<!-- Pz-LkC [TYPE='.$link_type.'] /-->'.PHP_EOL;
}
return $link_type;
}
// 相対パスをURLにする
private function pz_RelToURL( $base_url = '', $rel_path = '' ) {
if (preg_match('/^https?\:\/\//', $rel_path ) ) { // 絶対パスだった場合
return $rel_path;
} elseif (substr($rel_path, 0, 2) == '//' ) { // 絶対パスだった場合(スキーム省略)
return $rel_path;
}
$parse = parse_url($base_url );
if (substr($rel_path, 0, 1) == '/' ) { // ドキュメントルート指定
return $parse['scheme'].'://'.$parse ['host'].$rel_path;
}
return $parse['scheme'].'://'.$parse['host'].dirname($parse['path'] ).'/'.$rel_path;
}
// ソーシャルカウント取得
private function pz_RenewSNSCount($data ) {
if (!isset($this->options['sns-position']) || $this->options['sns-position'] == '') {
return null;
}
if (!isset($data) || !is_array($data)) {
return null;
}
$data = $this->pz_GetCache($data);
if (!isset($data) || !is_array($data)) {
return null;
}
// ソーシャルカウント
$sns_renew = false;
$update_cnt = false;
// タイムオーバー
$opt = array( 'timeout' => 30 );
// 保存期間満了でソーシャルカウントをリセット
if ($this->now > $data['sns_nexttime'] && $data['result_code'] <= 200 ) {
$sns_renew = true;
}
// エンコードURL
$url_raw = rawurlencode($data['url']);
// Twitter Digitminimiのcount.jsoonを使用
if (isset($this->options['sns-tw']) && !is_null($this->options['sns-tw'])) {
$count_before = isset($data['sns_twitter']) ? $data['sns_twitter'] : -1;
if ($sns_renew || $count_before < 0) {
$result = wp_remote_get( 'https://jsoon.digitiminimi.com/twitter/count.json?url=' .$url_raw, $opt );
if (isset($result) && !is_wp_error($result) && $result['response']['code'] == 200) {
$json = json_decode($result['body']);
$count = intval($json->count);
if ($count > $count_before) {
$data['sns_twitter'] = $count;
$update_cnt = true;
}
}
}
}
// facebook
//if (isset($this->options['sns-fb']) && !is_null($this->options['sns-fb'])) {
// $count_before = intval(isset($data['sns_facebook']) ? $data['sns_facebook'] : -1);
// if ($sns_renew || $count_before < 0) {
// $result = wp_remote_get( 'https://graph.facebook.com?fields=og_object{engagement}&id=' .$url_raw, $opt );
// if (isset($result) && !is_wp_error($result) && $result['response']['code'] == 200) {
// $json = json_decode($result['body']);
// $count = intval($json->{'og_object'}->{'engagement'}->{'count'});
// if ($count > $count_before) {
// $data['sns_facebook'] = $count;
// $update_cnt = true;
// }
// }
// }
//}
// はてなブックマーク
if (isset($this->options['sns-hb']) && !is_null($this->options['sns-hb'])) {
$count_before = isset($data['sns_hatena']) ? $data['sns_hatena'] : -1;
if ($sns_renew || $count_before < 0) {
$result = wp_remote_get( 'http://api.b.st-hatena.com/entry.count?url=' .$url_raw, $opt );
if (isset($result) && !is_wp_error($result) && $result['response']['code'] == 200) {
$count = intval($result['body']);
if ($count > $count_before) {
$data['sns_hatena'] = $count;
$update_cnt = true;
}
}
}
}
// Pocket
if (isset($this->options['sns-po']) && !is_null($this->options['sns-po'])) {
$count_before = isset($data['sns_pocket']) ? $data['sns_pocket'] : -1;
if ($sns_renew || $count_before < 0) {
$result = wp_remote_get( 'https://widgets.getpocket.com/api/saves?url=' .$url_raw, $opt );
if (isset($result) && !is_wp_error($result) && $result['response']['code'] == 200) {
$json = json_decode($result['body']);
$count = intval($json->saves);
if ($count > $count_before) {
$data['sns_pocket'] = $count;
$update_cnt = true;
}
}
}
}
// 登録してから一週間までは毎日、それ以降は週一回更新(取得が固まらないようにランダム時間付与)
if ($update_cnt || ($this->now - strtotime($data['regist']) < WEEK_IN_SECONDS)) {
$sns_nexttime = $this->now + DAY_IN_SECONDS + rand(0, DAY_IN_SECONDS); // 1day + 0-24h
} else {
$sns_nexttime = $this->now + WEEK_IN_SECONDS + rand(0, DAY_IN_SECONDS); // 7days + 0-24h
}
// MINUTE_IN_SECONDS = 60
// HOUR_IN_SECONDS = 60 * MINUTE_IN_SECONDS = 3600
// DAY_IN_SECONDS = 24 * HOUR_IN_SECONDS = 86400
// WEEK_IN_SECONDS = 7 * DAY_IN_SECONDS = 604800
// YEAR_IN_SECONDS = 365 * DAY_IN_SECONDS
global $wpdb;
$wpdb->update(
$this->db_name,
array(
'sns_twitter' => $data['sns_twitter'],
'sns_facebook' => $data['sns_facebook'],
'sns_hatena' => $data['sns_hatena'],
'sns_pocket' => $data['sns_pocket'],
'sns_time' => $this->now,
'sns_nexttime' => $sns_nexttime,
'uptime' => $this->now
),
array(
'id' => $data['id']
)
);
return $data;
}
// キャッシュデータを取得
private function pz_GetCache($data ) {
if (!isset($data) || !is_array($data)) {
return null;
}
global $wpdb;
if (!empty($data['url'])) {
$url = $data['url'];
$data = $wpdb->get_row($wpdb->prepare("SELECT * FROM $this->db_name WHERE url=%s", $url));
} elseif (isset($data['id']) && !is_null($data['id'])) {
$data_id = intval($data['id']);
$data = $wpdb->get_row($wpdb->prepare("SELECT * FROM $this->db_name WHERE id=%d", $data_id));
} else {
return null;
}
if ($wpdb->last_error <> '') { // DBエラーのとき、初期化する
$this->activate();
}
if (is_wp_error($data)) {
return null;
}
return (array) $data; // Arrayに直して返す
}
// キャッシュデータを保存
private function pz_SetCache($data ) {
global $wpdb;
if (!isset($data) || !is_array($data)) {
return null;
}
if (!isset($data['url']) || is_null($data['url']) || $data['result_code'] < 100) {
return null;
}
// リンク先URL
$url = $this->pz_TrimURL($data['url']);
$data['url'] = $url;
// URLからキーの生成
if (!isset($data['url_key']) || is_null($data['url_key']) || $data['url_key'] == '' ) {
$data['url_key'] = hash( 'sha256', esc_url( $url ), true);
}
// 登録時情報
if (!isset($data['regist_result']) || !$data['regist_result']) {
$data['regist_title'] = $data['title'];
$data['regist_excerpt'] = $data['excerpt'];
$data['regist_charset'] = $data['charset'];
$data['regist_result'] = $data['result_code'];
$data['regist_time'] = $this->now;
}
// 最終更新日時
$data['uptime'] = $this->now;
// DB更新
if ( isset($data['id']) ) {
$result = $wpdb->update(
$this->db_name,
$data,
array(
'id' => $data['id']
)
);
} else {
$result = $wpdb->update(
$this->db_name,
$data,
array(
'url_key' => $data['url_key']
)
);
}
// DB更新失敗の場合、挿入
if (!$result) {
// 登録日
$data['regist'] = $this->now_mysql;
// 新規の場合、IDをクリア
unset($data['id']);
$result = $wpdb->insert(
$this->db_name,
$data
);
// DB挿入失敗の場合、日本語項目(サイト名)をクリアして挿入
if (!$result) {
unset($data['site_name']);
$result = $wpdb->insert(
$this->db_name,
$data
);
// DB挿入失敗の場合、日本語項目(概要文)をクリアして挿入
if (!$result) {
unset($data['excerpt']);
$result = $wpdb->insert(
$this->db_name,
$data
);
// DB挿入失敗の場合、日本語項目(タイトル)をクリアして挿入
if (!$result) {
unset($data['title']);
$result = $wpdb->insert(
$this->db_name,
$data
);
// DB挿入失敗の場合、諦める
if (!$result) {
return $data;
}
}
}
}
}
// 登録された内容を読み直す
return $this->pz_GetCache($data);
}
// キャッシュデータを削除
private function pz_DelCache($data ) {
global $wpdb;
if (!isset($data) || !is_array($data)) {
return null;
}
if (isset($data['id']) && !is_null($data['id'])) {
$data_id = intval($data['id']);
$result = $wpdb->delete($this->db_name, array('id' => $data_id), array('%d') );
return $result;
} elseif (isset($data['url']) && !is_null($data['url'])) {
$url = $this->pz_TrimURL($data['url']);
$result = $wpdb->delete($this->db_name, array('url' => $url), array('%s') );
return $result;
}
return null;
}
// サイト内取得
private function pz_GetPost( $data ) {
// サイト名取得
$site_name = get_bloginfo('name');
// ドメイン名
if (preg_match('/https?:\/\/(.*)\//i', home_url().'/',$m)) {
$domain_url = $m[0];
$domain = $m[1];
} else {
$domain_url = null;
$domain = null;
}
// サイトアイコン
if (function_exists('has_site_icon') && has_site_icon()) {
$favicon = get_site_icon_url(16, '', 0);
} else {
$favicon = null;
}
$title = null;
$excerpt = null;
$thumbnail = null;
// 記事内容
$url = $data['url'];
$post_id = url_to_postid($url ); // 記事IDを取得
if ($this->options['debug-time']) {
echo '<!-- Pz-LkC [PID='.$post_id.'] /-->'.PHP_EOL;
}
if ( !$post_id && isset($this->options['flg-get-pid']) ? true : false) {
$url = $this->Pz_GetRedirURL( $data ); // 本当の記事URLを取得
$post_id = url_to_postid($url ); // 記事IDを取得
if ($this->options['debug-time']) {
echo '<!-- Pz-LkC [PID='.$post_id.'(REDIR)] /-->'.PHP_EOL;
}
}
if ( $post_id ) {
$result_code = 200; // 外部取得と同じコードをセット
$post = get_post($post_id); // 記事情報
if ( $this->options['in-get'] == '1') {
$title = $post->post_title; // 記事タイトル
$excerpt = $post->post_excerpt; // 抜粋文優先
if ($excerpt == '') {
$excerpt = $post->post_content; // 抜粋文が無かったら記事
}
} else {
$title = $post->post_title; // 記事タイトル
$excerpt = $post->post_content; // 記事内容から抜粋
}
$post_date = $post->post_date;
$thumbnail_id = get_post_thumbnail_id( $post_id ); // サムネイル
if ($this->options['debug-time']) {
echo '<!-- Pz-LkC [TID='.$thumbnail_id.'] /-->'.PHP_EOL;
}
$attach = wp_get_attachment_image_src( $thumbnail_id, 'thumbnail', true );
if (isset($attach) && count($attach) > 3 && isset($attach[0])) {
$thumbnail = $attach[0];
if (preg_match('/.*(\/\/.*)/', $thumbnail, $m)) { // スキームを外す
$thumbnail = $m[1];
}
}
} else {
$title = get_bloginfo('name');
$excerpt = get_bloginfo('description');
$site_name = get_bloginfo('name');
$thumbnail = '';
$result_code = '404';
// カテゴリ ページの処理
$cat_dir = get_option('category_base');
$cat_url = home_url().'/'.($cat_dir ? $cat_dir : 'category').'/';
$cat_len = mb_strlen($cat_url );
if (substr($url, 0, $cat_len ) == $cat_url ) {
$cat_slug = substr($url, $cat_len );
$cat_data = get_category_by_slug($cat_slug );
$cat_count = ($cat_data->count - 0);
$title = __('Category', $this->text_domain ).' '.__('‘', $this->text_domain ).$cat_data->name.__('’', $this->text_domain );
$excerpt = __('(', $this->text_domain ).__('Count', $this->text_domain ).':'.($cat_data->count - 0).__(')', $this->text_domain ).' '.$cat_data->description;
if (isset($cat_data->slug)) {
$result_code = '200';
}
} else {
// タグ ページの処理
$cat_dir = get_option('tag_base');
$cat_url = home_url().'/'.($cat_dir ? $cat_dir : 'tag').'/';
$cat_len = mb_strlen($cat_url );
if (substr($url, 0, $cat_len ) == $cat_url ) {
$cat_slug = substr($url, $cat_len );
$cat_data = get_tags( array( 'slug' => $cat_slug ) );
$title = __('Tag', $this->text_domain ).' '.__('‘', $this->text_domain ).$cat_data[0]->name.__('’', $this->text_domain );
$excerpt = __('(', $this->text_domain ).__('Count', $this->text_domain ).':'.($cat_data[0]->count - 0).__(')', $this->text_domain ).' '.$cat_data[0]->description;
if (isset($cat_data[0]->slug)) {
$result_code = '200';
}
} else {
if ( !$post_id && isset($this->options['flg-get-pid']) ? true : false) {
$data = $this->Pz_GetCURL($data ); // 外部サイトとして読み込み
return $data;
}
}
}
}
// タイトル整形
if (isset($title)) {
$str = $title;
$str = strip_tags($str); // タグの除去
$str = str_replace(array("\r", "\n"), '', $str); // 改行削除
$str = esc_html($str); // 念のためエスケープ
$str = mb_strimwidth($str, 0, 200, '...'); // 保管用のタイトルは200文字で切る
$title = $str;
}
// 抜粋文整形
if (isset($excerpt)) {
$str = $excerpt;
$str = strip_tags($str); // タグの除去
$str = preg_replace('/<!--more-->.+/is', '', $str); // moreタグ以降削除
$str = preg_replace('/\[[^]]*\]/', '', $str); // ショートコードすべて除去
$str = str_replace(array("\r", "\n"), '', $str); // 改行削除
$str = esc_html($str); // 念のためエスケープ
$str = mb_strimwidth($str, 0, 500, '...'); // 保管用の記事内容は500文字で切る
$excerpt = $str;
}
// URLパース(ドメイン名などを抽出)
$url_m = parse_url($url );
$scheme = isset($url_m['scheme']) ? $url_m['scheme'] : null; // スキーム
$domain = isset($url_m['host']) ? $url_m['host'] : null; // ドメイン名
$domain_url = isset($url_m['host']) ? $scheme.'://'.$url_m['host'] : null; // ドメインURL
$location = isset($url_m['path']) ? $url_m['path'] : null; // ドメイン名以降
// データセット
if (isset($data['title']) && $data['title'] == $title ) {
$before['mod_title'] = 0;
} else {
$before['mod_title'] = 1;
}
if (isset($data['excerpt']) && $data['excerpt'] == $excerpt ) {
$before['mod_excerpt'] = 0;
} else {
$before['mod_excerpt'] = 1;
}
if (!isset($data['use_post_id1'])) {
$data['use_post_id1'] = get_the_ID();
}
$data['scheme'] = $scheme;
$data['domain'] = $domain;
$data['location'] = $location;
$data['site_name'] = $site_name;
$data['title'] = $title;
$data['excerpt'] = $excerpt;
$data['post_date'] = $post_date;
$data['thumbnail'] = $thumbnail;
$data['favicon'] = $favicon;
$data['charset'] = 'UTF-8';
$data['result_code'] = $result_code;
$data['alive_result'] = $result_code;
$data['favicon'] = $favicon;
return $data;
}
// リダイレクト先URL取得
private function pz_GetRedirURL( $data ) {
$url = $data['url'];
if ( function_exists( 'curl_init' ) ) { // cURLを使用する
$result_code = 0;
$ch = curl_init($url);
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true ); // データで取得
curl_setopt( $ch, CURLOPT_NOBODY, true ); // ヘッダのみ取得
curl_setopt( $ch, CURLOPT_TIMEOUT, 120 ); // タイムアウト
curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, true ); // リダイレクトを処理する
curl_setopt( $ch, CURLOPT_MAXREDIRS, 5 ); // リダイレクトを処理する階層
$html = curl_exec($ch);
$errno = intval( curl_errno( $ch ) ); // cURL実行
if ( $errno ) {
$result_code = $errno;
$error = true;
} else {
$header = curl_getinfo($ch);
$result_code = $header['http_code']; // HTTPステータス
$error = false;
$url = $header['url'];
}
curl_close($ch);
}
return $url;
}
// 外部サイト取得
private function pz_GetCURL($data ) {
$url = $this->pz_TrimURL( $data['url'] );
if (!isset( $url ) || $url == '') {
return null;
}
// リンク先サイト取得
$html = null;
$error = true;
$domain = null;
$site_name = null;
$title = null;
$excerpt = null;
$charset = null;
$result_code = null;
// URLパース(ドメイン名などを抽出)
$url_m = parse_url($url );
$scheme = isset($url_m['scheme']) ? $url_m['scheme'] : null; // スキーム
$domain = isset($url_m['host']) ? $url_m['host'] : null; // ドメイン名
$domain_url = isset($url_m['host']) ? $scheme.'://'.$url_m['host'] : null; // ドメインURL
$location = isset($url_m['path']) ? $url_m['path'] : null; // ドメイン名以降
if ( function_exists('curl_init' ) ) { // cURLを使用する
$result_code = 0;
$ch = curl_init($url);
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true ); // データで取得
curl_setopt( $ch, CURLOPT_TIMEOUT, 8 ); // タイムアウト
if (isset($this->options['flg-referer']) ? true : false) {
curl_setopt( $ch, CURLOPT_REFERER, get_permalink() ); // リファラ
}
if (isset($this->options['flg-agent']) ? true : false) {
curl_setopt( $ch, CURLOPT_USERAGENT, $this->options['user-agent'] ); // ユーザーエージェントにPz-LinkCard-Crawlerを使う
} else {
curl_setopt( $ch, CURLOPT_USERAGENT, esc_html( $_SERVER['HTTP_USER_AGENT'] ) ); // アクセス者のユーザーエージェントを使う
}
if (isset($this->options['flg-redir']) ? true : false) {
curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, true ); // リダイレクトを処理する
curl_setopt( $ch, CURLOPT_MAXREDIRS, 8 ); // リダイレクトを処理する階層
curl_setopt( $ch, CURLOPT_AUTOREFERER, true ); // リダイレクト用リファラを自動セット
} else {
curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, false ); // リダイレクトを処理しない
}
curl_setopt( $ch, CURLOPT_COOKIESESSION, true ); // セッションCOOKIEを使用する
curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, (isset($this->options['flg-ssl']) ? false : true) ); // SSL検証
$html = curl_exec($ch);
$errno = intval( curl_errno( $ch ) ); // cURL実行
if ( $errno ) {
$html = ''; // cURLエラー
$result_code = $errno;
$error = true;
} else {
$header = curl_getinfo($ch);
$result_code = $header['http_code']; // HTTPステータス
$error = false;
}
curl_close($ch);
} else { // cURLが使用できない場合
$result = wp_remote_get( $url ); //wp_remote_get実行
if ( is_wp_error( $result ) ) {
$html = '';
$result_code = -1; // wp_remote_getエラー
$error = true;
} else {
$html = $result['body'];
$result_code = $result['response']['code']; // HTTPステータス
$error = false;
}
}
// 文字コード判定
$charset = null;
if ($html <> '') {
if (preg_match('/charset\s*=\s*"*([^>\/\s"]*).*<\/head/si', $html, $m)) {
$m[1] = trim(trim($m[1]), '\'\"');
$charset = $m[1];
} else {
foreach(array('UTF-8','SJIS','EUC-JP','eucJP-win','ASCII','JIS','SJIS-win') as $c_charset) {
// 文字コード変換してみて内容が変わらないものを文字セットと判断する
if (mb_convert_encoding($html, $this->charset, $c_charset) == $html) {
$charset = $c_charset;
break;
}
}
}
if (is_null($charset)) {
$charset = mb_detect_encoding($html, 'ASCII,JIS,UTF-7,EUC-JP,SJIS,UTF-8');
$html = mb_convert_encoding($html, $this->charset, 'ASCII,JIS,UTF-7,EUC-JP,SJIS,UTF-8');
} elseif ($this->charset <> $charset) {
$html = mb_convert_encoding($html, $this->charset, $charset);
}
// HEADタグ(METAタグ解析)
$head = null;
$tags = null;
if (preg_match('/<\s*head[^>]*>(.*)<\s*\/head\s*>/si', $html, $m)) {
$head = $m[1];
$tags = $this->pz_GetMeta($head);
}
// タイトル
if (isset( $tags['og:title'] ) && $tags['og:title'] ) {
$title = $tags['og:title'] ;
} elseif (isset( $tags['twitter:title'] ) && $tags['twitter:title'] ) {
$title = $tags['twitter:title'] ;
} elseif (isset( $tags['title'] ) && $tags['title'] ) {
$title = $tags['title'] ;
}
// 抜粋文・概要文
if (isset( $tags['og:description'] ) && $tags['og:description'] ) {
$excerpt = $tags['og:description'] ;
} elseif (isset( $tags['twitter:description'] ) && $tags['twitter:description'] ) {
$excerpt = $tags['twitter:description'] ;
} elseif (isset( $tags['description'] ) && $tags['description'] ) {
$excerpt = $tags['description'] ;
}
// OGPから画像URL取得
if (isset( $tags['og:image'] ) && $tags['og:image'] ) {
$thumbnail_url = $tags['og:image'] ;
} elseif (isset( $tags['twitter:image'] ) && $tags['twitter:image'] ) {
$thumbnail_url = $tags['twitter:image'] ;
} else {
$thumbnail_url = '';
}
if ($thumbnail_url && !preg_match('/^https*:\/\//', $thumbnail_url, $m) ) {
$thumbnail_url = $this->pz_RelToURL($url, $thumbnail_url);
}
// OGPからサイトアイコンURL取得
if (isset( $tags['icon'] ) && $tags['icon'] ) {
$favicon_url = $tags['icon'] ;
} elseif (isset( $tags['shortcut icon'] ) && $tags['shortcut icon'] ) {
$favicon_url = $tags['shortcut icon'] ;
} elseif (isset( $tags['apple-touch-icon'] ) && $tags['apple-touch-icon']) {
$favicon_url = $tags['apple-touch-icon'] ;
} else {
$favicon_url = '';
}
if ($favicon_url && !preg_match('/^https*:\/\//', $favicon_url, $m) ) {
$favicon_url = $this->pz_RelToURL($url, $favicon_url);
}
// サイト名
if (isset( $tags['og:site_name'] ) && $tags['og:site_name'] ) {
$site_name = $tags['og:site_name'] ;
}
// タイトル整形
if (isset($title)) {
$str = $title;
$str = strip_tags($str); // タグの除去
$str = str_replace(array("\r", "\n"), '', $str); // 改行削除
$str = esc_html($str); // 念のためエスケープ
$str = mb_strimwidth($str, 0, 200, '...'); // 保管用のタイトルは200文字で切る
$title = $str;
}
// 抜粋文整形
if (isset($excerpt)) {
$str = $excerpt;
$str = strip_tags($str); // タグの除去
$str = str_replace(array("\r", "\n"), '', $str); // 改行削除
$str = esc_html($str); // 念のためエスケープ
$str = mb_strimwidth($str, 0, 500, '...'); // 保管用の記事内容は500文字で切る
$excerpt = $str;
}
// データセット
if (isset($data_id) && !is_null($data_id)) {
$data['id'] = $data_id;
}
if (isset($url_key) && !is_null($url_key)) {
$data['url_key'] = $url_key;
}
$data['site_name'] = $site_name;
$data['title'] = $title;
$data['excerpt'] = $excerpt;
$data['mod_title'] = 0;
$data['mod_excerpt'] = 0;
$data['charset'] = $charset;
}
$data['url'] = $url;
$data['thumbnail'] = ( isset($thumbnail_url) ? $thumbnail_url : null );
$data['result_code'] = $result_code;
$data['alive_result'] = $result_code;
$data['scheme'] = $scheme;
$data['domain'] = $domain;
$data['location'] = $location;
$data['favicon'] = ( isset($favicon_url) ? $favicon_url : null );
if (!isset($data['use_post_id1']) || !$data['use_post_id1']) {
$data['use_post_id1'] = get_the_ID();
}
$data['sns_twitter'] = (isset( $data['sns_twitter'] ) ? $data['sns_twitter'] : -1 );
$data['sns_facebook'] = (isset( $data['sns_facebook'] ) ? $data['sns_facebook'] : -1 );
$data['sns_hatena'] = (isset( $data['sns_hatena'] ) ? $data['sns_hatena'] : -1 );
$data['sns_nexttime'] = (isset( $data['sns_nexttime'] ) ? $data['sns_nexttime'] : 0 );
$data['uptime'] = $this->now;
$data['alive_time'] = $this->now;
$data['alive_result'] = $result_code;
return $data;
}
// TITLEとMETAタグを分解
private function pz_GetMeta($html, $tags = null, $clear = false ) {
if ($clear == true || !isset($tags)) {
$tags = null;
$tags = array('none' => 'none');
}
// TITLEタグ
if (preg_match('/<\s*title\s*[^>]*>\s*([^<]*)\s*<\s*\/title\s*[^>]*>/si', $html, $m)) {
$tags['title'] = esc_html($m[1]);
}
// metaタグ パース
$match = null;
preg_match_all('/<\s*meta\s(?=[^>]*?\b(?:name|property)\s*=\s*(?|"\s*([^"]*?)\s*"|\'\s*([^\']*?)\s*\'|([^"\'>]*?)(?=\s*\/?\s*>|\s\w+\s*=)))[^>]*?\bcontent\s*=\s*(?|"\s*([^"]*?)\s*"|\'\s*([^\']*?)\s*\'|([^"\'>]*?)(?=\s*\/?\s*>|\s\w+\s*=))[^>]*>/is', $html, $match);
if (isset($match) && is_array($match) && count($match) == 3 && count($match[1]) > 0) {
foreach ($match[1] as &$m) {
$m = strtolower($m);
}
unset($m);
$tags += array_combine($match[1], $match[2]);
}
// linkタグ パース
$match = null;
preg_match_all('/<\s*link\s(?=[^>]*?\brel\s*=\s*(?|"\s*([^"]*?)\s*"|\'\s*([^\']*?)\s*\'|([^"\'>]*?)(?=\s*\/?\s*>|\s\w+\s*=)))[^>]*?\bhref\s*=\s*(?|"\s*([^"]*?)\s*"|\'\s*([^\']*?)\s*\'|([^"\'>]*?)(?=\s*\/?\s*>|\s\w+\s*=))[^>]*>/is', $html, $match);
if (isset($match) && is_array($match) && count($match) == 3 && count($match[1]) > 0) {
foreach ($match[1] as &$m) {
$m = strtolower($m);
}
unset($m);
$tags += array_combine($match[1], $match[2]);
}
return $tags;
}
// サムネイル取得(外部リンクOGP画像取得)
private function pz_GetThumbnail($url, $force = false ) {
if (!isset($url) || $url == '' || $url == 'https://s0.wp.com/i/blank.jpg') {
return null;
}
$file_dir = $this->options['thumbnail-dir']; // サムネイルのディレクトリ
$file_dir_url = $this->options['thumbnail-url']; // サムネイルのディレクトリURL
if (!$file_dir || !$file_dir_url) {
return null;
}
$file_name = bin2hex(hash('sha256', esc_url( $url ), true)); // ファイル名(URLをハッシュしてファイル名にする)
$file_ext = '.jpeg'; // 拡張子
$file_path_old = $file_dir.$file_name; // ファイルのフルパス
$file_path_jpeg = $file_dir.$file_name.$file_ext; // ファイルのフルパス
$file_url = $file_dir_url.$file_name.$file_ext; // 画像URL
if (!$force) {
if (file_exists ($file_path_jpeg)) { // ファイルが見つかった
if (filesize($file_path_jpeg) < 34) {
return null;
}
return $file_url;
}
if (file_exists ($file_path_old)) { // ファイルが見つかった(拡張子なし)
rename ($file_path_old, $file_path_jpeg); // リネーム
if (filesize($file_path_jpeg) < 34) {
return null;
}
return $file_url;
}
}
// cURLで画像取得
$ch=curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 3);
$result=curl_exec($ch);
curl_close($ch);
if (!$result) {
touch($file_path_jpeg); // 空ファイル作成
return null;
}
// 画像生成
$image = imagecreatefromstring($result); // 画像読み込み
$image_width = imagesx($image);
$image_height = imagesy($image);
if ($image_width < 8 || $image_height < 8) { // 8x8未満は画像ではないと見なす
touch($file_path_jpeg); // 空ファイル作成
return null;
}
$new_size = $this->options['cache-image-size']; // サムネイル画像サイズ
if ($new_size < $this->defaults['cache-image-size']) { // 小さすぎたらデフォルト値を採用
$new_size = $this->defaults['cache-image-size'];
}
$new_width = $new_size; // 幅
$new_height = $new_size; // 高さ
if ($image_width <> $image_height) { // 正方形でない
if ($image_width > $image_height) { // 幅の方が大きい
$new_height = $image_height * ( $new_width / $image_width ); // 幅に合わせる
} else { // 高さの方が大きい
$new_width = $image_width * ( $new_height / $image_height ); // 高さに合わせる
}
}
$new_width = intval($new_width);
$new_height = intval($new_height);
if ($new_width <= 1 || $new_height <= 1) {
touch($file_path_jpeg); // 空ファイル作成
return null;
}
$image_p = imagecreatetruecolor($new_width, $new_height); // パレットを用意
if (!$image_p) {
touch($file_path_jpeg); // 空ファイル作成
return null;
}
imagecopyresampled($image_p, $image, 0, 0, 0, 0, $new_width, $new_height, $image_width, $image_height); // サイズ変更してコピー
imagejpeg($image_p, $file_path_jpeg); // JPEGで保存
return $file_url; // 画像URLを返す
}
// 管理画面のスタイルシート、スクリプト設定
public function enqueue_admin($hook ) {
// カラーピッカー用のスタイルシート、スクリプト
wp_enqueue_script ('pz-linkcard-colorpicker', plugins_url('js/color-picker.js', __FILE__), array('wp-color-picker'), false, true);
wp_enqueue_script ('wp-color-picker');
wp_enqueue_style ('wp-color-picker');
// 設定画面用のスタイルシート、スクリプト
wp_enqueue_script ('pz-linkcard-admin', plugins_url('js/admin-settings.js', __FILE__), array('jquery'), false, true);
wp_enqueue_style ('pz-linkcard-admin', plugin_dir_url(__FILE__).'css/admin.css', array(), $this->options['plugin-version']);
}
// 管理画面時の設定(フッター)
public function add_footer() {
// テキスト エディタ用のクイックタグ
if ($this->options['flg-edit-qtag']) {
if (wp_script_is('quicktags') ) {
echo '<script>QTags.addButton(\'pz-lkc\',\''.__('Linkcard', $this->text_domain ).'\',\'['.$this->options['code1'].' url="\',\'"]\',\'\',\''.__('Make Linkcard', $this->text_domain ).'\');</script>';
}
}
// ビジュアル エディタ用の挿入ダイアログ
require('lib/pz-linkcard-modal.php');
}
// 管理画面時の注意書き設定
public function add_notices() {
if ($this->options['flg-invalid']) {
if (!$this->options['flg-invalid-hide']) {
echo '<div class="error"><p><strong>'.$this->slug.': '.__('Invalid URL parameter in ', $this->text_domain).'<a href="'.$this->options['invalid-url'].'#lkc-error" target="_blank">'.$this->options['invalid-url'].'</a></strong><br>'.__('*', $this->text_domain).' '.__('You can cancel this message from <a href="./options-general.php?page=pz-linkcard-settings">the setting screen</a>.', $this->text_domain).'</p></div>';
}
}
}
// 管理画面時のスタイルシート、スクリプト設定
public function add_mce_button($buttons ) {
if ($this->options['flg-edit-insert']) {
$buttons[] = 'pz_linkcard_insert_shortcode';
}
return $buttons;
}
public function add_mce_plugin($plugins ) {
if ($this->options['flg-edit-insert']) {
$plugins[ "pz_linkcard_tinymce" ] = $this->plugin_dir_url.'js/mce-button.js';
}
return $plugins;
}
// 通常時のスタイルシート
public function enqueue($hook ) {
$this->amp = null;
$css_version = $this->options['plugin-version'].'.'.$this->options['css-count'];
wp_enqueue_style ('pz-linkcard', $this->options['css-url'], array(), $css_version);
if ($this->options['css-url-add']) {
wp_enqueue_style('pz-linkcard-add', $this->options['css-url-add'], array(), $css_version);
}
}
// 管理画面のサブメニュー追加
public function add_menu() {
$menu_manager = __('Pz LkC Cache', $this->text_domain);
$menu_settings = __('Pz LinkCard', $this->text_domain);
if ($this->options['flg-alive'] && $this->options['flg-alive-count']) {
global $wpdb;
$result = $wpdb->get_row("SELECT COUNT(*) AS count FROM $this->db_name WHERE alive_result = '404'");
if (isset($result) && isset($result->count)) {
$menu_manager .= '&nbsp;<span class="update-plugins"><span class="update-count lkc-menu-count">'.$result->count.'</span></span>';
}
}
add_management_page (__('LinkCard cache manager', $this->text_domain), $menu_manager, 'manage_options', 'pz-linkcard-cache', array($this, 'page_cacheman') );
add_options_page (__('LinkCard Settings', $this->text_domain), $menu_settings, 'manage_options', 'pz-linkcard-settings', array($this, 'page_settings') );
}
// WP-CRONスケジュール(SNSカウント取得)
public function schedule_hook_check() {
if (!isset($this->options['sns-position']) || $this->options['sns-position'] == '') {
return null;
}
global $wpdb;
$result = (array) $wpdb->get_results($wpdb->prepare("SELECT url,sns_nexttime FROM $this->db_name WHERE sns_nexttime<%d ORDER BY sns_nexttime ASC", $this->now));
$i = 0;
if (isset($result) && is_array($result) && count($result) > 0) {
foreach($result as $data) {
$i++;
if ($i > 10) {
wp_schedule_single_event(time() + 30, 'pz_linkcard_check');
break;
}
if (isset($data) && isset($data->url)) {
$data = $this->pz_RenewSNSCount(array('url' => $data->url) );
}
}
}
}
// WP-CRONスケジュール(存在チェック)
public function schedule_hook_alive() {
if (!isset($this->options['flg-alive']) || $this->options['flg-alive'] == '') {
return null;
}
global $wpdb;
$result = (array) $wpdb->get_results($wpdb->prepare("SELECT url,alive_time FROM $this->db_name WHERE alive_nexttime<%d ORDER BY alive_time ASC, id ASC", $this->now - WEEK_IN_SECONDS ));
$i = 0;
if (isset($result) && is_array($result) && count($result) > 0) {
foreach($result as $data) {
$i++;
if ($i > 5) {
wp_schedule_single_event(time() + 3600, 'pz_linkcard_alive');
break;
}
if (isset($data) && isset($data->url)) {
$before = $this->pz_GetCache( array( 'url' => $data->url ) );
$after = $this->pz_GetCURL( $before );
if ($before['title'] == $after['title'] ) {
$before['mod_title'] = 0;
} else {
$before['mod_title'] = 1;
}
if ($before['excerpt'] == $after['excerpt'] ) {
$before['mod_excerpt'] = 0;
} else {
$before['mod_excerpt'] = 1;
}
$before['alive_result'] = $after['result_code'];
$before['alive_time'] = $this->now;
$before['alive_nexttime'] = $this->now + WEEK_IN_SECONDS * 4 + rand(0, DAY_IN_SECONDS);
$before['thumbnail'] = $after['thumbnail'];
$before['favicon'] = $after['favicon'];
$before = $this->pz_SetCache( $before );
}
}
}
}
// スタイルシート生成
private function pz_SetStyle() {
require('lib/pz-linkcard-style.php');
}
// Pz カード管理 キャッシュ・マネージャ
public function page_cacheman() {
require('lib/pz-linkcard-cacheman.php');
}
// Pz カード 設定画面
public function page_settings() {
require('lib/pz-linkcard-settings.php');
}
// プラグイン一覧のクイックメニュー
public function action_links($links ) {
$links = array('<a href="options-general.php?page=pz-linkcard-settings">'.__('Settings', $this->text_domain).'</a>' , '<a href="tools.php?page=pz-linkcard-cache">'.__('Manage', $this->text_domain).'</a>' ) + $links;
return $links;
}
// プラグイン有効化
public function activate() {
require('lib/pz-linkcard-init.php');
}
// プラグイン停止
public function deactivate() {
wp_clear_scheduled_hook('pz_linkcard_check');
wp_clear_scheduled_hook('pz_linkcard_alive');
}
}
$Class_Pz_LinkCard = new Pz_LinkCard;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment