PHP 一覧

WordPressで出欠確認(function.php)

  • web, PHP
6月ごろ、某所で運用しているWordPressに出欠管理機能を追加しました。
せっかくなのでソースコード共々紹介したいと思います!

地球上に何十億人もいるらしい人類うちの、誰か一人にでも役立てば幸いですww

下記の記事で公開されていたコードを基にして改造を加えました。
なので僕の記事でなく下記の記事を参考にするのも大いにアリです!
(ただ、当ブログのコードの21行目と71行目に相当する部分だけ注意したほうがいい......かも?)

ゴーゴーウェブマーケット技術BLOG | Wordpressで簡易的な出欠確認をする。

設置方法
下記のコードを "wordpress/wp-content/themes/テーマ名" 以下の"function.php"に追記します。


使い方
記事作成時にカテゴリを「出欠確認」にします。

ログインした状態で記事を閲覧すると、出欠確認画面が表示されているハズです。
(ログインしていないと使えません。)


注意事項
僕は責任取りません。無責任です。ご利用は自己責任でお願いします。

環境次第では、レイアウトが崩れそうな気がします。
特に、行折り返しの部分(117行目~133行目と138行目~142行目)は無謀なことをしている気がするのでヤバイです。

いっそのこと、該当部分をまるまる削除するのもアリです。

カスタムフィールドを利用しています。
記事を作成する方は該当するカスタムフィールドを間違って編集しないように気をつけてください。


お願い
問題点の報告や改善案、アドバイスなど大歓迎です。

function.php
/////////以下、function.phpへの追記箇所///////////


//出欠確認
add_filter('the_content', 'join_check');
function join_check($content){

	//選択肢をここで設定
	$key_select = array("参加","保留","不参加");
	$ret="";

	//ログインしてないユーザーには表示しない
	if(is_user_logged_in()){
		global $user_identity,$post;

		//カスタムフィールドからデータを読み込む
		$join_data = unserialize(get_post_meta($post->ID,'join_meta',true));
		$comment_data = unserialize(get_post_meta($post->ID,'comment_meta',true));

		//送信ボタンを押したときの処理(各カスタムフィールドを更新する)
		if($_POST['select_join_'.$post->ID]){

			//出欠登録
			$join_data[$user_identity] = $_POST['select_join_'.$post->ID];
			$join_s = serialize($join_data);
			update_post_meta($post->ID, 'join_meta', $join_s);

			//コメント登録
			$comment_data[$user_identity] = $_POST['comment'];
			$comment_s = serialize($comment_data);
			update_post_meta($post->ID, 'comment_meta', $comment_s);
		}

		//出欠の回答ごとにグループ分けをして
		//出力内容を連想配列に格納。
		foreach($join_data as $key => $value){

			foreach($key_select as $key_group){

				if($value == $key_group){
					$flag = 0;

					foreach($comment_data as $key2 => $value2){

						if($key2 == $key){	//joinとcommentのユーザ名が一致したとき

							if($value2){	//コメントがあればTRUE

								//出力内容(名前とコメント)を格納
								$group[$key_group][] = $key.'<font color="#999999">('.$value2.')</font>';
							}else{

								//出力内容(名前)を格納
								$group[$key_group][] = $key;
							}
							$flag=1;
						}
					}

					if($flag == 0){$group[$key_group][] = $key;};
				}
			}
		}

		///////OUT PUT////////

		//カテゴリが"出欠確認"の場合のみ表示する
		if(in_category('出欠確認')){

			//出欠確認フォーム
			$ret .= '<ul>';
			$ret .= '<br><form method="POST">';
			$ret .= '<input type="hidden" value="join_check" >';
			$ret .= '<select name="select_join_'.$post->ID.'">';

			foreach($key_select as $key_option){
				$ret .= '<option value="' . $key_option . '"';

				if($join_data[$user_identity] == $key_option){
					$ret .= 'selected';
				}
				$ret .='>' . $key_option . '</option>';
			}
			$ret .= '</select>';
			$ret .= ' <small>コメント</small>:<input type="text" name="comment" value="'.$comment_data[$user_identity].'" size="30"/>';
			$ret .= '<input type="submit" value="post">';
			$ret .= '</form>';

			//出欠回答状況
			$ret .='<table><tr><td>';

			//回答ごとにループ
			$grp_no = 0;
			foreach($key_select as $key_title){
				$grp_no++;

				//回答ごとの人数をカウント
				$ninzu_count = 0;
				foreach($group[$key_title] as $group_user){
					$ninzu_count++;
				}
				$ret .= '<div class="join_group join_no_' . $grp_no . ' "style="margin:0px 0px 0px 0px;">';
				$ret .= '<b>'. $key_title . '('.$ninzu_count.')</b><br/>';
				$ret .= '<font size="2">';

				//ユーザごとにループ
				$ret .='<ul>';
				$flag = 0;
				$str_count = 0;
				foreach($group[$key_title] as $group_user){

					if($flag ==1){
						$ret .= ', ';
						$str_count += 3;
					}

					//一行あたりの文字数が多すぎるときの改行処理。
					//文字長45文字以上でコメントありと判定して
					//HTMLタグ分の41文字を文字数から差し引く
					//文字長が$max_strを超えたら改行処理
					$str_len = strlen($group_user);
					$str_count += $str_len;

					if($str_len > 45){
						$str_count -= 41;
						$str_len -= 41;
					}
					$max_str = 93;

					if($str_count > $max_str){
						$ret .='<br/>';
						$str_count = $str_len;
					}

					//名前、コメントを出力
					$ret .= $group_user;

					//一行あたりの文字数が異常に多いときにもう一度改行
					if($str_len > $max_str){
						$ret .='<br/>';
						$str_count = 0;
					}
					$flag = 1;
				}
				$ret .='</ul>';
				$ret .='</font><br/>';
			}
			$ret .= '</td></tr></table></ul>';
		}
	}
	return $content . $ret;
}

ちなみにこんな感じになります。
syukketu.jpg


bot_logo.JPG


先日、夏休みの自由工作で「ごますりぼっと」というTwitterのbotを作りました。
(詳しくは -> 「Twitter_botつくった:ごますりぼっと」)

完成したbotについて冷静になって考察しいるうちに、だんだんと悲しくなってきました。
一見すると小学生が作ったbotのように見えるかもしれませんが、中の人は24歳のピチピチなおじさんなのです(ドヤッ

ただ、ブログのネタが無くて困っていたところでせっかく作ったbotなので、ソースコードは掲載しておくことにします。

某所からコピペしたコードだったり、同じ処理なのに場所によって書き方が違ったり、テストが超不十分だったりしますが、細かいことは気にしないでくださいネ♪
あ、でもアドバイスとかは大歓迎です!

あと前提として「twitteroauth」を導入してます。
先人の知恵は素晴らしいです♪


connect.php
<?php

require_once("twitteroauth.php");

//botのスクリーンネーム
$ids = "surisuri_bot";


//OAuth認証、オブジェクト生成
$consumer_key = "HOGEHOGE";
$consumer_secret = "FUGAFUGA";
$access_token = "MORIMORI";
$access_token_secret = "BUHIBUHI";

$bot = new TwitterOAuth
        ($consumer_key, $consumer_secret, 
        $access_token, $access_token_secret);



follow.php
<?php

/*********************************************
  フォロー返し、リムーブ返しを自動で実行する
 **********************************************/

require_once("connect.php");

//followerとfriendを取得
$followers = $bot->OAuthRequest
	("http://api.twitter.com/1/statuses/followers.xml", 
	"GET", array());
$friends = $bot->OAuthRequest
	("http://api.twitter.com/1/statuses/friends.xml", 
	"GET", array());

$followers = simplexml_load_string($followers);
$friends = simplexml_load_string($friends);

//ユーザIDを配列に格納
$followers_id = array();
$friends_id = array();
foreach($followers as $key => $val){ $followers_id[] = $val->id; }
foreach($friends as $key => $val){ $friends_id[] = $val->id; }

//処理を実行するユーザのリストを生成
$follow_user_list = array_diff($followers_id, $friends_id);
$destroy_user_list = array_diff($friends_id, $followers_id);

//自動フォロー
foreach ($follow_user_list as $value) {
	$bot->OAuthRequest
		("http://twitter.com/friendships/create/".$value.".xml",
		"POST",array());
}

//自動リムーブ
foreach ($destroy_user_list as $value) {
	$bot->OAuthRequest
		("http://twitter.com/friendships/destroy/".$value.".xml",
		"POST",array());
}



post.php
参考 : mtFlash | twitter bot
<?php

/**********************************
  定時tweetを実行
 **********************************/

require_once("follow.php");

//infile_post.txtファイルからtweetするメッセージをランダムに取得
$input_array = file("infile_post.txt");
$key = array_rand($input_array,1);
$msg = $input_array[$key];

//日付を取得
$month = date("m");
$date = date("d");

//ステータス生成
$status = sprintf("%s月%s日なう。%s", $month, $date, $msg);

//ツイート
$bot->OAuthRequest
	("http://api.twitter.com/1/statuses/update.xml",
	"POST", array("status"=>$status));



getTweet.php
参考 : twitterのbotで超巨大なステータスナンバーを比較できた
<?php

/*************************************************
  これまでに未取得のツイート中から、
  各ユーザ最新ツイートのstatusIDを連想配列に格納
 ************************************************/

require_once("connect.php");

//前回処理時の最終statusID取得
$file = 'sid_count.txt';
if (! ($fp = fopen ( $file, "r" ))) echo "file open failure";
$sid_count = fgets($fp);
$array_sid_count = str_split($sid_count);
fclose($fp);

//フラグ
$page_end_flag = false;

//tweet収集
$page = 1;
while($page <= 16){

	//status取得
	$req = $bot->OAuthRequest
		("http://api.twitter.com/1/statuses/friends_timeline.xml",
		"GET",array("page" => "$page"));
	$xml = simplexml_load_string($req);

	//statusIDの最新値をtxtファイルに書き込み
	if($page == 1){
		$max_sid = strval($xml->status->id);
		if (! ($fp = fopen ( $file, "w" ))) echo "file open failure";
		fwrite($fp, $max_sid);
		fclose($fp);
	}

	//statusID比較。前回収集時の最終値以降のもののみ取得。
	foreach( $xml->status as $s){

		//statusIDを配列に格納
		$sid = strval($s->id);
		$array_sid = str_split($sid);

		//比較のためのフラグ
		$exec_flag = false;
		$break_flag = false;

		//初めに桁数比較。次に文字→数字変換を順に実行
		if(count($array_sid) > count($array_sid_count) ){ //桁数が違う場合
			$exec_flag = true;

		} else { //桁数が同じ場合

			$i = 0;
			foreach($array_sid as $val){

				if($val === $array_sid_count[$i] && $break_flag === false){
					//処理しない。
				}elseif($val > $array_sid_count[$i] && $break_flag === false){
					$exec_flag = true;
					$break_flag = true;
				}else{
					$break_flag = true;
				}

				$i++;
			}
		}

		//比較結果ごとに処理を分岐
		if ($exec_flag){//新しいstatusの場合
			$uname = $s->user->screen_name;
			$text = $s->text;

			//各ユーザ最新1件のみ、statusIDを連想配列に格納
			$uid = (string)($s->user->id);
			if(isset($user_list[$uid])){
				//処理せず.
			}else{
				$user_list[$uid] =  $sid;
			}

		}else{//古いstatusの場合
			$page_end_flag = true;

		}
	}

	$page++;

	if($page_end_flag)break;
}



fav.php
<?php

/***************************************************
  user_list配列に格納されているstatusをふぁぼり、
  ごますりリプライを行う。
 **************************************************/

require_once("follow.php");
require_once("getTweet.php");

if(isset($user_list)){

	foreach($user_list as $uid => $sid){

		//infile_surisuri.txtファイルからtweetするメッセージをランダムに生成
		$input_array = file("infile_surisuri.txt");
		$key = array_rand($input_array,1);
		$msg = $input_array[$key];

		//ユーザIDからスクリーンネームを取得
		$req = $bot->OAuthRequest
			("http://api.twitter.com/1/users/show/".$uid.".xml",
			"GET", array());
		$xml = simplexml_load_string($req);
		$reply_uname = $xml->screen_name;

		//スクリーンネームが空でなく、尚且つ自分以外のときの処理
		if(!empty($reply_uname) && ($reply_uname != $ids)){

			//リプライをツイート
			$status = sprintf("@%s %s", $reply_uname, $msg);
			$bot->OAuthRequest
				("http://api.twitter.com/1/statuses/update.xml",
				"POST",
				array("status"=>$status, "in_reply_to_status_id"=>$sid));

			//ふぁぼる
			$bot->OAuthRequest
				("http://api.twitter.com/1/favorites/create/".$sid.".xml",
				"POST", array());
		}
	}
}


上記5つのファイルとは別に「sid_count.txt」「infile_post.txt」「infile_surisuri.txt」というファイルを用意します。

infile_post.txt」「infile_surisuri.txt」にはごますり用のセリフを書きまくります。
sid_count.txt」は、前回処理をしたステータスIDを保存しておくためのファイルです。

毎日7時に「post.php」を、0時、10時、20時に「fav.php」を実行するように設定すれば完成(笑)

このページの上部へ