社長BLOG
OpenPNE3アクティビティのUI案
- 2010-07-22 (木)
- 社長BLOG
アクティビティ機能はOpenPNEにTwitter風の機能を追加してくれる。
現在のUIは
これはこれでシンプルで良いのだが、もっと洗練させたい。
ということで、素人ながらUI案を作ってみた。
※フンパツしてCS5買ったし、使いこなしていかないとね。
Twitter風UIによってOpenPNEのリアルタイム性を高めたい。
組織コミュニケーションのゴールは「以心伝心」の実現
- 2010-07-22 (木)
- 社長BLOG
OpenPNEを使って組織コミュニケーションを進化させる。ゴールは「以心伝心」の実現だ。
以心伝心はもともと禅宗で使われている仏教用語で、意味は
「考えていることが、言葉を使わないでも互いにわかること」
「無言のうちに心が通じ合うこと」
その要素をソフトウエア的な観点で三つに分解した。
リアルタイム
最新の情報を遅延なしで伝える。
リアルタイムコミュニケーションが以心伝心の第一歩。
現在では、携帯電話やTwitterなどでかなりカバーできるようになった。
FAX、メール、手紙、メモはリアルタイムでは無い。
常時接続
伝えたいと思った瞬間に、伝えることができる。いつでもつながった状態をつくる。
オフィスにいなくても、会議中でも、電車の中でも、いつでもつながった状態を作ること、参加者全員がつながっているような状態を演出すること。
情報共有
組織全員で欠損なしで情報が共有できること。伝聞であったり、途中で情報を編集すると、どうしても欠損がおき、全員が同じ情報を共有することができなくなる。
手嶋屋を進化させるプラグインを自分で作っているが、この3要素を意識して設計している。
OpenPNEのレイアウトのおさらい
- 2010-07-21 (水)
- 社長BLOG
※Ver3.7の開発がいよいよ始まった。
ここで、これまでのOpenPNEのレイアウトのおさらいを。
トップページのレイアウト方針は、上記のようなスタイル。
3カラムを基本として、
・左側:自分についての情報
・中央:周りについての情報
・右側:世間(SNS全体、もしくはネット全体)についての情報
と分けている。だいたいmixiもこのような方針で分けているんじゃないかと思う。
実際にはVer3からガジェットで自由に配置できるようになり、
現在ではあくまでも原則的な方針になっている。
Ver3.7系では、どのようにUIを進化させようかな。
TheApacheWay オープンソースコミュニティの運営について
- 2010-07-16 (金)
- 社長BLOG
2008年と少し古いが、中国で聞いた講演の資料。
運営方法や情報公開の原則が参考になった。
プラグイン作成時なるべくモデルを作らないようにする
- 2010-07-15 (木)
- 社長BLOG
※技術、設計ネタです
OpenPNE3のプラグインをつくるとき、自分はかたくななまでにモデル(=テーブル)を作らないようにしている。
プラグインごとにわざわざモデルをつくることに、それほど価値があるとは思えないからだ。
OpenPNE3にはmember_config sns_config member_profileなど、SNSに対して1:多、
メンバーに対して1:多の関係でデータを保持できる、汎用のテーブルが存在する。
できる限り、これを使うようにしている。
一見設計上はひどく見えるかもしれないが、モデルを作らないプラグインにもメリットはある
・取り外しが簡単、ポータビリティが高い
・開発や運用が楽
・テーブルがズラッと並ぶというユーザーの心理的負担が少ない
デメリットといえば
・将来的にパフォーマンスの不安がある
・他のプラグインとの名前空間の衝突などで混乱したり、データが破損することがある
などがある。これも本当にデメリットになるのかどうかは、将来になってみないとわからない。
OpenPNE3はインストールが終わった時点で70個ほどのモデルが作成される。これは運営者への心理的負担がかなり大きいと感じた。
一方WordPress先輩はテーブル数が非常に少ない。プラグインを追加してもあんまり増えない。
何でも設定保存用のwp_optionsテーブルに放りこめという文化ができ上がっているのだろう。
これが唯一の成功パターンだとは思わないが、実際に成功している先輩の事例はきっちり勉強して、われわれのソフトウエアの進化につなげていきたい。
勤怠報告プラグインを作成(その1)
- 2010-07-14 (水)
- 社長BLOG
社内OpenPNEで勤怠報告をするためのプラグインを作成する。
・プラグイン名はopKintaiPlugin
・ソフトウエアはオープンソース化する=>Githubに公開 http://github.com/tejima/opKintaiPlugin
・作り方を本ブログで紹介する。
登場人物
・勤怠報告をするスタッフ
・勤怠報告を収集するスタッフ
・勤怠報告のファシリテーションを行うボットプログラム
ユーザーワークフロー
ボットが出社リンクをつぶやく
スタッフが出勤する前(8:00ごろ)ボットが以下のようなメッセージをつぶやく。
「おはようございます。出勤リンクをクリックしてください2010/07/13 出勤」
このようなイメージ
スタッフの出社
スタッフが出社し、ボットがつぶやいた出社(出勤)リンクをクリックする。
クリックするとその時刻で打刻される。
データは月ごと、個人ごとの集計テーブルに書き出され、当月の出社状況を閲覧できる。
出社状況の閲覧とデータはシンプルな表形式を想定。画面閲覧は
このような形式。
ファイルとしては
このようなシンプルな形式に。
ボットが退勤リンクをつぶやく
出社時と同じように退勤用のメッセージをつぶやく。
「お疲れ様でした。退勤リンクをクリックしてください2010/07/13 退勤」
スタッフの退勤
これまた出社時と同じように退勤用のリンクをクリックする。
メモや報告がある場合は、クリック後にメモ追加が行えるようにする。
仕様
・ボットが出勤、退勤のリンクをつぶやき、スタッフへアクションを促す
・出勤、退勤、休憩、メモを報告できる
・当日中は何度でも上書き保存ができる
・当日以外のレコードは管理スタッフ以外は変更できない
・管理スタッフは、直行直帰、在宅勤務、などを管理するため、直接勤怠レコードを操作できる
・「管理スタッフコミュニティ」のメンバーを管理スタッフと定義する=>複数人での管理が可能に
・月末締めで出退勤状況をCSVファイルとして出力する
設計方針
・PC、携帯両方で操作できるようにする
・誰でも簡単に使えるようにする
・特別な管理画面は用意せず、極力ユーザー画面で操作が行えるようにする
・データベースのテーブルを新規に構築しない
・データはOpenPNE3の既存テーブルに格納する
本チュートリアルシリーズについて
OpenPNE3は組織のソフトウエアとして、十分実用的に使えるんだ!
しかも
OpenPNEのプラグインなら、自分たちでも開発、拡張が簡単にできるんだ!
これらをテーマに、要件定義から開発、実運用、完成までガイドしたい。
ソースコードはすべてオープンソースにするので、自分の組織向けに拡張することも自由だ。
OpenPNEを使えば、自分たちの手で、自分たちの組織コミュニケーションを設計することができる。
「オープン・コア・ビジネスモデルはよろしくない」From:八田さんつぶやき
- 2010-07-13 (火)
- 社長BLOG
Open Core Is Bad For You – Community – ComputerworldUK http://bit.ly/aROAA6
ついぴーねから
オープン・コア・ビジネスモデルとは、企業の中核のソフトウエアをオープンソースとして公開し、エンタープライズ用の拡張部分を通常のクローズドソフトとして展開する方式。
このビジネスモデル結局は最終的にベンダーロックインが発生するので、ユーザーにとって良くないのではないか?と超訳した。
MySQLやSugarCRM、バックアップのAmandaなどが該当するだろう。
自分も体感的にだが、このビジネスモデルは良くないと思う。
理由は、ベンダーロックインが発生するとか、儲かるとかではなく、オープンソースの進化を止める可能性があるからだ。
コアがオープンで、外側がクローズだとすると、必然的にクローズ部分を増やしていったほうが商売としての価値が高くなる。そうなるとコア部分は無料で利用するユーザーに嫌われないギリギリ最低限のレベルにとどめておこうという力が働く。
これでは、オープンソースの力を活かしきっているとは言えないのではないか?
これに対向するのがRedhatのビジネスモデルだ。
全く逆のパターン。
FedoraはタダでRedhat EnterpriseLinuxが有料。
機能が豊富だが、完璧な検証が行われていないものは無料で、機能は少ないが組み合わせ検証済みのプログラムが有料で提供される。
このモデルのほうが、オープンソースの進化を止めないので、利用者も開発社も気持ちよく共存できるのではないかと、考えている。
オープンソーシャルを搭載したSNSプラットフォームがフリーで使える
- 2010-07-09 (金)
- 社長BLOG
OpenPNEはVer3.5からモバイルオープンソーシャルに対応した。
まだ先行するSNSの独自仕様に対応していない部分もあるが、今後のバージョンアップで対応レベルを上げていくつもりだ。
人数規模で国内3番手までのマス型エンタメSNSは、運営会社ごとにそれぞれ独自開発している。
その中でOpenPNEがソーシャルプラットフォームをオープンソースでリリースする意義は大きいと思う。
手嶋屋としては、それ以降のSNSプラットフォームにはなるべくOpenPNEを採用していただきたいと考えている。プラットフォームを増やすことは、ソーシャルアプリ提供者にとってハッピーではない。
組織やサービスをソーシャル化して付加価値を高めるため、OpenPNEをぜひ活用していただきたい。
【OP3TIPS】無ドキュメント時代の関数リファレンス
- 2010-07-09 (金)
- 社長BLOG
OpenPNE3にはドキュメントが無い。
そんな中どうやって開発をするか?
ちょっとしたTIPSを紹介する。
よくあるのがこんなケース。
「データベースのテーブル(モデル)を操作したいんだが、どういう関数を呼び出したらいいかわからない」
今回はこれを解説する。もう少し課題を具体的にする。
「フレンドリンクを管理するmember_relationshipテーブル(MemberRelationshipモデル)で、フレンド関係にあるか判定する関数の使い方を調べたい」
1:OpenPNEのソースコードをgrepし MemberRelationshipをさがす。
grep MemberRelationship ./ -R | less
するとこんな結果が返る。
./lib/action/opMemberAction.class.php: $this->relation = new MemberRelationship();
./lib/config/opApplicationConfiguration.class.php: ‘friend_confirm’ => array(‘MemberRelationshipTable’, ‘friendConfirmList’),
./lib/config/opApplicationConfiguration.class.php: ‘friend_confirm’ => array(‘MemberRelationshipTable’, ‘processFriendConfirm’),
./lib/filter/doctrine/base/BaseMemberRelationshipFormFilter.class.php: * MemberRelationship filter form base class.
./lib/filter/doctrine/base/BaseMemberRelationshipFormFilter.class.php:abstract class BaseMemberRelationshipFormFilter extends BaseFormFilterDoctrine
./lib/filter/doctrine/base/BaseMemberRelationshipFormFilter.class.php: return ‘MemberRelationship’;
./lib/filter/doctrine/MemberRelationshipFormFilter.class.php: * MemberRelationship filter form.
./lib/filter/doctrine/MemberRelationshipFormFilter.class.php: * @subpackage MemberRelationship *
./lib/filter/doctrine/MemberRelationshipFormFilter.class.php:class MemberRelationshipFormFilter extends BaseMemberRelationshipFormFilter
./lib/form/doctrine/base/BaseMemberRelationshipForm.class.php: * MemberRelationship form base class.
./lib/form/doctrine/base/BaseMemberRelationshipForm.class.php: * @method MemberRelationship getObject() Returns the current form’s model object
./lib/form/doctrine/base/BaseMemberRelationshipForm.class.php:abstract class BaseMemberRelationshipForm extends BaseFormDoctrine./lib/form/doctrine/base/BaseMemberRelationshipForm.class.php: new sfValidatorDoctrineUnique(array(‘model’ => ‘MemberRelationship’, ‘column’ => array(‘me
mber_id_to’, ‘member_id_from’))),./lib/form/doctrine/base/BaseMemberRelationshipForm.class.php: new sfValidatorDoctrineUnique(array(‘model’ => ‘MemberRelationship’, ‘column’ => array(‘me
mber_id_from’, ‘member_id_to’))),
./lib/form/doctrine/base/BaseMemberRelationshipForm.class.php: return ‘MemberRelationship’;
./lib/form/doctrine/InviteForm.class.php: $relation = Doctrine::getTable(‘MemberRelationship’)->retrieveByFromAndTo($fromMemberId, $toMemberId);
./lib/form/doctrine/InviteForm.class.php: $relation = new MemberRelationship();
./lib/form/doctrine/MemberRelationshipForm.class.php: * MemberRelationship form.
./lib/form/doctrine/MemberRelationshipForm.class.php: * @subpackage MemberRelationship
./lib/form/doctrine/MemberRelationshipForm.class.php:class MemberRelationshipForm extends BaseMemberRelationshipForm./lib/form/MemberConfigForm/MemberConfigAccessBlock.class.php: $relations = Doctrine::getTable(‘MemberRelationship’)->retrievesAccessBlockByMemberIdFrom($thi
s->member->getId());
./lib/form/MemberConfigForm/MemberConfigAccessBlock.class.php: $relationship = Doctrine::getTable(‘MemberRelationship’)
./lib/form/MemberConfigForm/MemberConfigAccessBlock.class.php: $relationship = Doctrine::getTable(‘MemberRelationship’)
./lib/form/MemberConfigForm/MemberConfigAccessBlock.class.php: $relationship = Doctrine::getTable(‘MemberRelationship’)
./lib/form/MemberConfigForm/MemberConfigAccessBlock.class.php: $relationship = new MemberRelationship();
./lib/model/doctrine/ActivityDataTable.class.php: $friendIds = Doctrine::getTable(‘MemberRelationship’)->getFriendMemberIds($memberId);
./lib/model/doctrine/ActivityDataTable.class.php: $relation = Doctrine::getTable(‘MemberRelationship’)->retrieveByFromAndTo($viewerMemberId, $memberId);
./lib/model/doctrine/base/BaseMember.class.php: * @property Doctrine_Collection $MemberRelationship./lib/model/doctrine/base/BaseMember.class.php: * @method Doctrine_Collection getMemberRelationship()
あとはこの中からlessコマンド内サーチ(/コマンド)で、それっぽい使われ方をしている関数を探すのだ。
今回の目的では
$relation = Doctrine::getTable(‘MemberRelationship’)->retrieveByFromAndTo($fromMemberId, $toMemberId);
これが当たりだ。
「新規でフレンドリンクさせたい」
という目的であれば、
new と MemberRelationshipを探せばいいので、
./lib/action/opMemberAction.class.php: $this->relation = new MemberRelationship();
これがヒントになる。
./lib/action/opMemberAction.class.php
このファイルを開けば、
$this->relation = new MemberRelationship();
$this->relation->setMemberIdFrom($this->getUser()->getMemberId());
$this->relation->setMemberIdTo($this->id);
こんなコードが出てくるので、これに習って新規のフレンドリンクをつくることができる。
ドキュメントが無いことは、決してほめられたものでは無いが、
それでもOpenPNE開発の助けになれば嬉しい。
(コミュニティ自動フレンド機能搭載)opAutoFriendPlugin 1.1.0
- 2010-07-09 (金)
- 社長BLOG
opAutoFriendPlugin Ver 1.1.0 をリリースした。
Ver1.1.0の新機能は、コミュニティメンバー同士の自動フレンド機能だ。
たとえば、「友達募集コミュニティ」「サークル一年生コミュニティ」「営業部コミュニティ」など、コミュニティの参加者を自動的に友達関係にしたい場合に利用できる。
使い方はREADME参照。
http://github.com/tejima/opAutoFriendPlugin
ぜひお試しあれ。
■更新情報
・2010/07/09 Ver1.1 指定したコミュニティ内の全メンバーとのフレンドリンクに対応した。
・2010/07/04 Ver1.0 全メンバーのリンク、個別メンバーのリンクに対応した。