私立・プログラミングキャンプ 2014東京 作業ログ #upcamp

8月17日に「私立・プログラミングキャンプ 2014」に行ってきましたので、その時の作業ログをTwitterでのつぶやきを基本にまとめてみました。
この投稿はほぼ自分のメモを公開するだけなので、成果物の報告とかは別で投稿します。

つぶやきだけ見てると何をしているのかがさっぱりわからないと思うのですが、「Jetpack Sharing Source Pack」というWordPressプラグインを開発して、Jetpackの共有メニューにFeedlyやはてなブックマークのボタンを追加してみる。ということをやっています。


10:30 作業開始。

10:50: 作業内容決定。

まずはplugins_loadedアクションでJetpackの存在を確認。

add_action( 'plugins_loaded', array( $this, 'is_jetpack_active' ) );

function is_jetpack_active() {
	if ( class_exists( 'Jetpack' ) ) {
		// Jetpack is active
	} else {
		// Jetpack is NOT active
	}
}

sharedaddyモジュールが有効かどうかを確認するには、jetpack_modules_loadedアクションでJetpackクラスの関数をコールして確認。

add_action( 'jetpack_modules_loaded', array( $this, 'is_sharedaddy_modules_active' ) );

function is_sharedaddy_modules_active() {
	if ( Jetpack::is_module_active( 'sharedaddy' ) ) {
		// sharedaddy is active
	} else {
		// sharedaddy is NOT active
	}
}

sharing_servicesフィルターで$services[‘feedly’]が存在しなければ、クラス名を文字列として追加。

add_filter( 'sharing_services', array( $this, 'add_sharing_services' ) );

function sharing_services( $services ) {
	require_once( dirname( __FILE__ ) . '/class.sharing-sources.php' );
	if ( ! array_key_exists( 'feedly', $services ) ) {
		$services['feedly'] = 'Share_Feedly';
	}
}

sharing_global_optionsアクションでoptions-general.php?page=sharingの設定項目追加。
保存時に複雑な処理が必要な場合は特に、保存処理だけをsharing_admin_updateアクションに分けて記述する。

add_action( 'sharing_global_options', array( $this, 'add_sharing_options_init' ) );

function add_sharing_options_init() { ?>
	<tr>
		<th scope="row">
			<label><?php esc_html_e( 'WordPress.com Likes are', 'jetpack' ); ?></label>
		</th>
		<td>
			<div>
				<label>
					<input type="radio" name="wpl_default" value="on" <?php checked( $this->is_enabled_sitewide(), true ); ?> />
					<?php esc_html_e( 'On for all posts', 'jetpack' ); ?>
				</label>
			</div>
			<div>
				<label>
					<input type="radio" name="wpl_default" value="off" <?php checked( $this->is_enabled_sitewide(), false ); ?> />
					<?php esc_html_e( 'Turned on per post', 'jetpack' ); ?>
				</label>
			<div>
		</td>
	</tr>
<?php }
add_action( 'sharing_admin_update', array( $this, 'add_sharing_options_callback' ) );

function add_sharing_options_callback() {
	$new_state = ( ! empty( $_POST['wpl_default'] ) ) ? $_POST['wpl_default'] : 'on';

	switch( $new_state ) {
		case 'off' :
			update_option( 'disabled_likes', 1 );
			break;
		case 'on'  :
		default:
			delete_option( 'disabled_likes' );
			break;
	}
}

実際の共有先の定義はSharing_Sourceクラスを継承して作る。

class Share_Facebook extends Sharing_Source {
	var $shortname = 'facebook';
	private $share_type = 'default';

	public function __construct( $id, array $settings ) {
		parent::__construct( $id, $settings );

		if ( isset( $settings['share_type'] ) )
			$this->share_type = $settings['share_type'];

		if ( 'official' == $this->button_style )
			$this->smart = true;
		else
			$this->smart = false;
	}

	public function get_name() {
		return __( 'Facebook', 'jetpack' );
	}

	public function display_header() {
	}

	public function get_display( $post ) {
		$share_url = $this->get_share_url( $post->ID );
		if ( $this->smart ) {
			$url = $this->http() . '://www.facebook.com/plugins/like.php?href=' . rawurlencode( $share_url ) . '&amp;layout=button_count&amp;show_faces=false&amp;action=like&amp;colorscheme=light&amp;height=21';

			// Default widths to suit English
			$inner_w = 90;

			$widths = 100;

			$widths = apply_filters( 'sharing_facebook_like_widths', $widths );

			$url .= '&amp;width='.$inner_w;
			return '<div class="like_button"><iframe src="'.$url.'" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:'.( $inner_w + 6 ).'px; height:21px;" allowTransparency="true"></iframe></div>';
		}

		if ( apply_filters( 'jetpack_register_post_for_share_counts', true, $post->ID, 'facebook' ) ) {
			sharing_register_post_for_share_counts( $post->ID );
		}
		return $this->get_link( get_permalink( $post->ID ), _x( 'Facebook', 'share to', 'jetpack' ), __( 'Share on Facebook', 'jetpack' ), 'share=facebook', 'sharing-facebook-' . $post->ID );
	}

	public function process_request( $post, array $post_data ) {
		$fb_url = $this->http() . '://www.facebook.com/sharer.php?u=' . rawurlencode( $this->get_share_url( $post->ID ) ) . '&t=' . rawurlencode( $this->get_share_title( $post->ID ) );

		// Record stats
		parent::process_request( $post, $post_data );

		// Redirect to Facebook
		wp_redirect( $fb_url );
		die();
	}

	public function display_footer() {
		$this->js_dialog( $this->shortname );
	}
}

11:48: WordPressの構造を見ていたらふと思った。

12:17: おにぎりを食べながら、宣言してみた

16:13: 共有ボタンの表示にはおおむね成功。

自分のサイト上でテストしていたせいでバグにより何回かサイトが落ちたとか、落ちなかったとか。

17:41: 決定的な問題に直面。

これにより、17日中の完成は不可能なことが確定…。


ここから、WordPress関係のサイトを調べまくって思いついた解決方法がAPIの中継という方法。
仕組みは簡単で、

  1. [JS]出力用のURLをコール
  2. [PHP]FeedlyのAPIを叩く
  3. [PHP]WordPressのtransient APIに結果を取っておく
  4. [PHP]前後にごにょごにょ付けてJSONをJSONPに変換して出力
  5. [JS]以後、jQueryで通常通り

といった感じ。リバースプロキシ的な何か。

そのしばらく後、見事にRewrite APIの謎仕様の数々に苦戦するも、立食&LTのため #upcamp 会場での作業終了のため中断。

18:45: 食事・LT


ということで、会場提供や食事提供をしてくださった株式会社オプティム様とゲヒルン株式会社様、ありがとうございます!

コメントを残す