hiroaki のすべての投稿

Syntax Highlighter ComPressでエラー

blog上でのコード表示用にSyntaxHighlighterを利用していました。
WPに乗り換えるにあたって直接header.phpにJavaScriptの呼び出しを記述するのではなく、プラグインを利用することにしました。
Syntax Highlighter ComPress バージョン 3.0.83.3を利用しましたが、問題点が2点出ました。
まず1点目は縦スクロールが必要ない場面でも縦スクロールが出ることです。
これはwp-content/plugins/syntax-highlighter-compress/styles/shCoreDefault.cssを変更することで解消されました。

変更前

.syntaxhighlighter {
  width: 100% !important;
  margin: 1em 0 1em 0 !important;
  position: relative !important;
  overflow: auto !important;
  font-size: 1em !important;
}

変更後

.syntaxhighlighter {
  width: 100% !important;
  margin: 1em 0 1em 0 !important;
  position: relative !important;
  font-size: 1em !important;
  overflow-x: auto !important;
  overflow-y: hidden !important;
  padding: 1px !important;
}

次に管理画面に以下の警告が出るようになりました。

Notice: has_cap がバージョン 2.0.0 から非推奨になった引数付きで呼び出されました。ユーザーレベルの使用は推奨されていません。代わりに権限を使ってください。

検索したところ以下のページを見つけました。
「Notice: has_cap の使用は…」はプラグインを確認する
※既にリンク先のサイトはなくなっているようです。

要は数字ではなく文字列で権限を指定しろということらしいです。
で、Syntax Highlighter ComPressで該当する箇所はwp-content/plugins/syntax-highlighter-compress/syntax-highlighter-compress.php内のadd_submenu_page関数でした。
add_submenu_pageの75行目を以下のように修正したら無事警告も出なくなりました。

変更前

add_submenu_page('options-general.php', __('Syntax Highlighter ComPress Options', 'SHC'), $menutitle, 8, basename(__FILE__), 'shc_options_subpanel');

変更後

add_submenu_page('options-general.php', __('Syntax Highlighter ComPress Options', 'SHC'), $menutitle, 'administrator', basename(__FILE__), 'shc_options_subpanel');

WordPressにカウンターを設置(同じIPはカウントしない)

blognplusからWordPressへ移行した際に良いカウンターがなかったので自作しました。
自作と言っても元はblogplusのモジュール用に作られた「カルカン(お手軽カウンター)」をWordPress用に改造したものです。
作者様に改造品の掲載許可を頂きたかったのですが、既にHPも閉鎖されているようで連絡が取れず…
もし作者様がこのブログを見られましたら許可・非許可のコメントを頂ければ幸いです。

「カルカン(お手軽カウンター)」で出来ることは以下の3つです。
1.トータルのカウント数を表示
2.当日のカウント数を表示
3.昨日のカウント数を表示
全てのカウント数で同じ日の同じIPからのアクセスは、何度アクセスしても1回としてカウントされます。
いわゆる「延べ数」なPVとは違い、実際の訪問者数が分かります。
(BOTかどうかまでは分かりませんが)
尚、7行目のIPアドレス保存件数しかIPを保存しないので、人気のあるサイトは数を大目にしないと直ぐに同じIPでもカウントアップしてしまいます。

使い方は簡単で以下のソースコードをテーマのfunction.phpに追記するだけで、ウィジェットとして使用することが可能となります。

/*
* カウンターウィジェット
*/
// 保存ファイル名
define('WIDGET_COUNTER_FILE', WP_CONTENT_DIR."/widget_counter_file");
// IPアドレス保存件数
define('WIDGET_COUNTER_REMOTE', 30);
class Counter_Widget extends WP_Widget {
	/* コンストラクタ */
	function __construct() {
		parent::__construct(
			false,
			$name = 'カウンター',
			array( 'description' => 'IP重複なしのカウンターです', )
		);
	}
	
	/* 管理画面のウィジェット設定用コード */
	function form($instance) {
	?>

	<?php
	}

	/* 管理画面のウィジェット設定を変更した時の処理 */
	function update($new_instance, $old_instance) {
		$instance = $old_instance;
		$instance['title'] = strip_tags($new_instance['title']);
		return $instance;
	}

	/* ウィジェットを配置した時の表示用コード */
	function widget($args, $instance) {
		extract( $args );
		
		// カウント取得
		$counter = $this->widgetCounterGetCount('default');
		$out_count = '';
		$out_count .= "合計: ".$counter['total']."\n";
		$out_count .= "今日: ".$counter['today']."\n";
		$out_count .= "昨日: ".$counter['yesterday']."\n";

		if($instance['title'] != ''){
			$title = apply_filters('widget_title', $instance['title']);
		}
		echo $before_widget;
		if( $title ){
			echo $before_title . $title . $after_title;
		}
		echo $out_count;
		echo $after_widget;
	}
	
	/* 日付を取得-----------------------------------------------------------------*/
	function widgetCounterGetDate($format, $timestamp = NULL) {
		$format = preg_replace('/(?<!\\\)T/', preg_replace('/(.)/', '\\\$1', 'JST'), $format);

		$time = 9 * 3600 + (($timestamp !== NULL) ? $timestamp : time() - date('Z'));

		return date($format, $time);
	}

	/* カウンターの値の取得及びカウントアップ-------------------------------------*/
	function widgetCounterGetCount($page) {
		$ipMax				= (WIDGET_COUNTER_REMOTE<1) ? 1 : WIDGET_COUNTER_REMOTE;
		
		$default = array(
			'total'		=> 0,
			'date'		=> $this->widgetCounterGetDate('Y/m/d'),
			'today'		=> 0,
			'yesterday'	=> 0
		);
		
		$counters			= array();
		$couterns[$page]	= $default;
		
		for ($i=0; $i<$ipMax; $i++) {
			$default["ip$i"] = '';
		}
		
		$file = WIDGET_COUNTER_FILE.'.'.$page.'.dat';
		
		$modify = FALSE;	//更新フラグ
		
		if (! $fp = @fopen($file, file_exists($file) ? 'r+' : 'w+')) return $default;
		set_file_buffer($fp, 0);
		flock($fp, LOCK_EX);
		rewind($fp);
		foreach ($default as $key=>$val) {
			//データ取得
			$counters[$page][$key] = rtrim(fgets($fp, 256));
			if (feof($fp)) break;
		}
		if ($counters[$page]['date'] != $default['date']) {
			// 新しい日付
			$modify = TRUE;
			$yesterday = ($counters[$page]['date'] == $this->widgetCounterGetDate('Y/m/d', (time() - date('Z') - 3600 * 24)));
			for ($i=$ipMax-1; $i>0; $i--) {
				$counters[$page]["ip$i"] = '';
			}
			$counters[$page]['ip0']       = $_SERVER['REMOTE_ADDR'];
			$counters[$page]['date']      = $default['date'];
			$counters[$page]['yesterday'] = $yesterday ? $counters[$page]['today'] : 0;
			$counters[$page]['today']     = 1;
			$counters[$page]['total']++;
			
		} else {
			$newer = TRUE;
			for ($i=0; $i<$ipMax; $i++) {
				if ($counters[$page]["ip$i"] == $_SERVER['REMOTE_ADDR']) {
					$newer = FALSE;
					break;
				}
			}
			if ($newer) {
				// カウントアップ
				$modify = TRUE;
				for ($i=$ipMax-1; $i>0; $i--) {
					$j = $i-1;
					$counters[$page]["ip$i"] = $counters[$page]["ip$j"];
				}
				$counters[$page]['ip0'] = $_SERVER['REMOTE_ADDR'];
				$counters[$page]['today']++;
				$counters[$page]['total']++;
			}
		}
		
		// 更新されていた場合
		if ($modify) {
			rewind($fp);
			ftruncate($fp, 0);
			foreach (array_keys($default) as $key)
				fputs($fp, $counters[$page][$key] . "\n");
		}
		
		flock($fp, LOCK_UN);
		fclose($fp);

		return $counters[$page];
	}
}
/* カウンターウィジェットを使えるように登録 */
register_widget('Counter_Widget');

上記コードをfunction.phpに登録すると、テーマのカスタマイズのウィジェットで選択して使用可能となります。

カウンタの数はデータベースではなくファイルに保存されます。
ファイルの保存場所は「wp-content」の直下でファイル名は「widget_counter_file.default.dat」です。
テーマを変更しても変更したテーマのfunction.phpに上記コードを書けば、カウンター数の内容を引き継ぐことが出来ます。

設置後初回だけはファイルが存在せずにエラーが出るかもしれませんが、自動でファイルが作成されますので2回目以降はエラーにならないはずです。
wp-contentの下にファイルが出来ていない場合は、ディレクトリに正しく権限が付与されていない可能性があります。
(プラグインのインストールが失敗するケースなどと同じ理由です)
基本は正しく権限を与えてもらうべきですが、手動でwidget_counter_file.default.datを作成して全権限を与えるというお勧めできない方法もあるにはあります。

また、見られても特に困るファイルではないと思いますが、念のために「wp-content」の直下に.htaccessを置いて以下の記述をしておくとwidget_counter_file.default.datへのアクセスが不可となります。
(アクセスしようとしても403エラーが返るようになります)

<Files widget_counter_file.default.dat>
    Deny from all
</Files>

ブログをBlognplusからWordPressへ変更しました

既に配布もメンテも終了しているBlognplusを長い間使わせて頂きましたが、流石に限界かと思いWordPressへと乗り換えました。

データの移行も結構大変でした。
記事内に自身のブログのリンクが張られていたりするので、その整合性を取るのにインポート前のファイルを編集したりしました。
WordPressへのインポート自体は、Blognplusのエクスポート機能でMovableType形式で吐き出せば簡単なのですが、Blognplus側で削除した記事の分だけ、WordPress側では詰めて投稿が作成されるのでズレていくのです…
エクスポートファイルを修正したり、DBを直接いじって値を変更したり、なんとかほとんどの記事を同じIDで作成できました。

他にも画像のリンクなども修正が必要でした。
(これは置換で一発でしたが)

URLもblognplusからblogに変更し、URLパラメーターもblognplus形式のindex.php?e=123からWordPress形式の?p=123へ変更になりました。
そこでApacheのRewriteEngineを使い、以前のblognplusのURL形式で開いても、新しいWordPressのURLで同じ記事が開くようにリダイレクトしています。
尚、カテゴリーに関しては、サブカテゴリーを見直して一部変更したため、以前のURLとの整合性がそもそも取れないので、RewriteEngineでの処理は行っていません。

あとは同一IPではカウントアップしないカウンターのウィジェットを自作したりしました。
(コアなロジックはblognplusのカルカンカウンターを流用させて頂きました)

そして固定ページには、カテゴリー毎に記事の見出しを自動で生成する機能も作成しました。

色々やってやっと形になったので、この度BlognplusからWordPressへ切り替えました。
色々やったおかげでWordPressの作りの勉強にもなりました。
近年仕事でやってるWeb系はAngularなどのJS系フロントエンドやJSFなどが殆どだったので、PHPを久々にちゃんと触りました。

PCX(EBJ-JF56)にデイトナ BSCホリゾンタルミラー取り付け

以前、ロゼッタミラーへの交換の記事を載せていますが、今回別のミラーに交換しました。
PCX(EBJ-JF56)にナポレオン ロゼッタミラー取り付け

あれからずっとロゼッタミラーを使っていました。
ただメッキがダメなのか、サビが結構酷いので見た目が悪くなってきました。
あと、ミラーに少し当たるだけでミラーの向きが変わるので、ミラーの調整頻度が高くて困ってました。
(かなり強めにボールジョイント部分を締め込んでますが、それでも結構緩い感じです)

そこでロゼッタミラーから別のミラーへ交換することにしました。
今回選んだのはローポジションで使用可能なデイトナのBSCホリゾンタルミラーです。
(はっきり言って見た目重視です!)

DAYTONA(デイトナ) BSCホリゾンタルミラー
BSCホリゾンタルミラー

ちなみにBSCホリゾンタルミラーは左右共通で1個売りなので、1台分だと2個買う必要があります。
新品は結構なお値段がしますので、今回は美品の中古(ブラストレッド)を購入しました!

DAYTONA(デイトナ) ホリゾンタルミラー

取り合えず何もせずに一番低い位置(アームを水平)で取り付けてみましたが、身長178cmの私だと左右共に後ろがまともに見えませんでした…
もちろん乗車位置や姿勢でも変わるとは思いますが、PCXだと結構辛い人が多いのではないかと思います。

そこで写真のようにアームを水平より1段上に上げてみました。
すると右側はミラーを最大まで上に向けることで、なんとか後方確認ができるようになりました。
ただ左側はそれでも道路の下しか見えません…

原因はPCXのミラー取り付け位置とボールジョイント部分の可動範囲が狭いことだと思いますが、見た目的に取り付け位置は出来るだけ動かしたくなかったので、ボールジョイント部の可動域を広くすることにしました。
実際にオフセットホルダーで、かさ上げ+前へ移動をやってみたのですが、移動すればするほどステルスミラー感が失われていくので、このミラーを選んだ理由から移動させるのはやめました。
(本当は1段上げずに水平のままで行きたかったですが、この程度の可動域の広げ方では無理でした)

DAYTONA(デイトナ) ホリゾンタルミラー

上の写真だとちょっと見辛いですが、青い矢印の部分をリューターで削ることで、ボールジョイント部分の可動域を広げてます。
かなり削りにくい場所なので、これくらい広げるだけでもそこそこの時間が掛かりました。
(あまり雑にやるとボール部分まで削れそうで…)

DAYTONA(デイトナ) ホリゾンタルミラー

可動域を広げたことで、左側も後方確認ができるようになりました。
本当はあと1段下げて水平にしたいところですが、右側も削る必要が出てきますし、左側も更に削るのはかなり大変なので、今回はこれで妥協しました。

DAYTONA(デイトナ) ホリゾンタルミラー

ロゼッタミラーと違って多少ミラーに当たっても動かないので、今後はミラー調整の頻度も減りそうです。
後方の視認性はロゼッタミラーに比べれば結構狭くなりますが、狭くなるのは上下の範囲が殆どなので、きっちりミラーを調整してればそれほど困ることはなさそうです。

DAYTONA(バイク用品)
¥5,834 (2024/01/29 15:20時点 | Yahooショッピング調べ)

東京マルイAK47(スタンダード)にMULE製ウッドストックセットを取り付け

新品未使用のウッドストックセットを安くゲットしました。
普通に新品で買うと2万くらいするものですが、かなり安く手に入れることができました。

MULE 東京マルイ スタンダードAK47用
MULE 東京マルイ スタンダードAK47用 ウッドストックセット

株式会社MULLという日本国内の会社が国内生産しているものです。

MULE 東京マルイ スタンダードAK47用 ウッドストックセット

中身はストック、ハンドガード(上下)、グリップとネジ類少々です。

MULE 東京マルイ スタンダードAK47用 ウッドストックセット

純正と色合いの比較をしてみました。
上の写真ではハンドガードとグリップを、下の写真ではストックを比較しています。
グリップは純正に比べて結構太くなりますので、手が小さい人や細身のグリップが好きな人には辛いかもしれません。

MULE 東京マルイ スタンダードAK47用 ウッドストックセット

木製品なのである程度の色ムラが発生するのは仕方ありませんが、グリップだけかなり濃い目の茶色です。
ハンドガードやストックは写真で見ると明るい色に見えますが、肉眼で見るともう少し暗くて赤っぽい感じに見えます。

では、早速交換していきます。
まずはハンドガードから。
下の写真の赤丸のネジを外します。

MULE 東京マルイ スタンダードAK47用 ウッドストックセット

ネジを外すとハンドガードを止めているパーツが左にスライド可能になりますのでスライドさせます。

MULE 東京マルイ スタンダードAK47用 ウッドストックセット

スライドさせたらハンドガードを左にずらせば取り外せます。

MULE 東京マルイ スタンダードAK47用 ウッドストックセット

取り外して気付いたのは、このAK47のガスチューブの部分はマルイ純正ではないということです。
(上の写真の青で囲った部分がずっと太いのですが、マルイ純正では前側の部分はもっと細くなってます)
このAK47は、マルイAK47(ロアレシーバーをメタル製に交換)とうたわれていたものを中古で購入したという経緯があります。
ロアレシーバーだけでなく、他の部分もマイル純正じゃない個所が存在したようです。
そして上の写真と下の写真で分かるように、ガスチューブの大きさに対して上側のハンドガードの穴の前側の大きさが小さく、取り付けができませんでした。
これはハンドガード側を削るか、ガスチューブを純正に交換するしかありません。

MULE 東京マルイ スタンダードAK47用 ウッドストックセット

ということで上側のハンドガードは後回しにして、次は下側のハンドガードです。
下側のハンドガード部分はレシーバーに刺さる部分の出っ張りがないので、そのまま嵌めるとカパカパします。
なので、出っ張り部分を作ってあげる必要があります。
付属品に小さい金属のプレートとネジが入ってますので、それを使って出っ張りを作ります。

ネジ用の穴が予め掘ってあるわけではないので、下の写真のように、まずはネジ用の穴を開けます。
付属のネジは木ネジなので、穴を開けなくてもねじ込んでいくことは可能ですが、木が割れるのを防ぐために予め穴を開けることをお勧めします。
ちなみに3~3.2mm程度の穴を開ければサイズ的には大丈夫だと思います。

MULE 東京マルイ スタンダードAK47用 ウッドストックセット

穴を開けたらプレートをネジで固定すればハンドガードの下側は完成です。
外した時と逆の手順で取り付ければOKです。
ちなみに上側のハンドガードは無加工で取り付け可能です。
(私のマルイ純正じゃないガスチューブでは加工が必要でしたが…)

MULE 東京マルイ スタンダードAK47用 ウッドストックセット

次にグリップを交換しましたが、写真を取り忘れてました。
グリップは加工の必要はなく、グリップ下部のネジを外して交換するだけです。

最後にストックの交換です。
下の写真のようにストックにも予め穴は開けられてないので、自分で穴を開ける必要があります。

MULE 東京マルイ スタンダードAK47用 ウッドストックセット

下の写真の右側のネジ穴には短いネジを使用します。
長いネジだとレシーバー側の金属部分と干渉して奥まで入りません。
付属品にはストック用に長いネジ2本と短いネジ1本が付属してましたが、短い方を使っても最後まで入らなかったので、純正のネジを使って止めました。
純正のネジは木ネジではないので、純正のネジを使う場合は事前の穴あけは必須になります。

MULE 東京マルイ スタンダードAK47用 ウッドストックセット

上下に穴を開けたらストックをレシーバーにネジで止めるだけです。

MULE 東京マルイ スタンダードAK47用 ウッドストックセット

ストックにはもう1つ作業があります。
このセットにはストックパッドが付属しないので、純正のストックパッドを流用する必要があります。
下の写真のようにストックの上側にパッドの出っ張りを差し込む穴は開けられていました。
しかし、純正のように下側をはめ込む部分がありません。
ウッドストックの下側にあるのは穴だけです。

MULE 東京マルイ スタンダードAK47用 ウッドストックセット

この穴をどうやって使うんだろう?と一瞬考えましたが、付属品を見ると丁度いい大きさの鬼目ナットのようなものが入ってます。

MULE 東京マルイ スタンダードAK47用 ウッドストックセット

この鬼目ナットを穴に差し込めばOKです。
鬼目ナットをストックよりも少し深く押し込めば、ストックパッド側は加工なしで取り付け可能です。
パッドをストックに当ててみて、パッドがストックと接するところまで押し込めばOKです。

MULE 東京マルイ スタンダードAK47用 ウッドストックセット

ストックパッド側はダミーのネジが付いているので、そのダミーのネジを外して鬼目ナットに付いてたネジと交換します。

MULE 東京マルイ スタンダードAK47用 ウッドストックセット

付属のネジでストックにパッドを取り付けたら完成です。

MULE 東京マルイ スタンダードAK47用 ウッドストックセット

MULLのウッドストックセットは基本的に穴あけ以外の加工が必要ないので、加工が苦手な方にもお勧めできると思います。
とはいえ、全く加工が必要ないというわけでもありませんし、個体差ですり合わせが必要な場合があるかもしれません。
あくまでも木製品なので、その点だけはご注意を。
※この記事を書いている時点では、ハンドガードの上側を取り付けていないので、全体の写真を載せれません…

2018/10/30 追記
ハンドガード部分を加工し、やっと取り付けが完了しました。
結構削りました…

MULE 東京マルイ スタンダードAK47用 ウッドストックセット
MULE 東京マルイ スタンダードAK47用 ウッドストックセット

本物のウッドだとやはり質感が違います。
フェイクウッドでは出せない手触りもリアルウッドの良いところですね。

MULE 東京マルイ スタンダードAK47用 ウッドストックセット
バラエティショップ トマトハウス
¥21,500 (2025/07/05 18:49時点 | 楽天市場調べ)

東京マルイAK47(スタンダード)にのアウターバレルをスチール製に交換

東京マルイAK47(スタンダード)用のスチールアウターバレルがAmazonで1,000円を切る特価で売られていたので購入。

G&P AK47対応 スチールアウターバレル GP597
G&P AK47対応 スチール・アウター・バレル GP597

下の写真はマルイ純正とスチールアウターバレルを並べたものです。
上がマルイ製で下がG&Pのスチールアウターバレルです。

G&P AK47対応 スチール・アウター・バレル GP597

アウターバレルを外すには、まず下の写真の2ヶ所のネジを外します。

G&P AK47対応 スチール・アウター・バレル GP597

するとフロントサイトの部分とハンドガードを止めてる部分が外れます。
次に下の写真の赤丸のネジとアウターバレルを止めてるパーツを外します。
3ヶ所の青丸のネジは緩めるだけでOKです。

G&P AK47対応 スチール・アウター・バレル GP597
G&P AK47対応 スチール・アウター・バレル GP597

あとはアウターバレルを引き抜けばアウターバレルが外れます。

G&PのGP597は無加工でポン付け可能でした。