entryName = $entryName;
$lock->entryId = $entryId;
// entryname.entryid.*.lock が存在するかどうか調べる
$alreadyLocked = glob( App::createEntryLockFilePath( $entryName, $entryId, '*' ) );
if ( $alreadyLocked )
{
// 既に(自分を含む)誰かによってロックされている場合
// ロック情報を取得する。
$lockFilePath = $alreadyLocked[0];
$lock->load( $lockFilePath );
// 自分のロックだったら、最終更新日を更新する。
if ( $lock->isOwner( $userId ) )
{
$lock->touch();
}
//print "alredy locked.";
}
else
{
// まだ誰にもロックされていなかった場合
// ロックファイルを生成する。
$lockFilePath = App::createEntryLockFilePath( $entryName, $entryId, $userId );
$fp = fopen( $lockFilePath, 'w' );
fclose( $fp );
// ロック情報を取得する。
$lock->load( $lockFilePath );
//print "locked now.";
}
return $lock;
}
// ロック中か?
function IsLocked( $entryName, $entryId, $userId )
{
return file_exists( App::createEntryLockFilePath( $entryName, $entryId, $userId ) );
}
// ロック解除
function RelaseLock( $entryName, $entryId, $userId )
{
// ロック中なら、ロックファイルを削除する。
if ( EditingEntryLock::IsLocked( $entryName, $entryId, $userId ) )
{
unlink( App::createEntryLockFilePath( $entryName, $entryId, $userId ) );
}
}
// 強制ロック
function ForceLock( $entryName, $entryId, $userId )
{
// 現在のロック状態を強制的に解除する。
$files = glob( App::createEntryLockFilePath( $entryName, $entryId, '*' ) );
if ( $files )
{
foreach( $files as $lockFile )
{
unlink( $lockFile );
}
}
// ロックを取得する。
EditingEntryLock::CatchLock( $entryName, $entryId, $userId );
}
// 指定ユーザーの全ロックを解除
function ReleaseLocksByUser( $userId )
{
$files = glob( App::createEntryLockFilePath( '*', '*', $userId ) );
if ( $files )
{
foreach( $files as $lockFile )
{
unlink( $lockFile );
}
}
}
/* インスタンスメンバ */
var $ownerUserId = '';
var $lastUpdate = null;
var $entryName = '';
var $entryId = '';
// ロックオーナーか?
function isOwner( $userId )
{
return ( $this->ownerUserId == $userId );
}
// ロックファイルからロック情報を読み込む。
function load( $lockFilePath )
{
// ファイル名を分解して最後尾から取得していく。
//
$lockFileName = basename( $lockFilePath );
$tokens = explode( '.', $lockFileName );
array_pop( $tokens ); // .lock
$this->ownerUserId = array_pop( $tokens ); // userId
$this->entryId = array_pop( $tokens ); // entryId
$this->entryName = array_pop( $tokens ); // entryName
// 最終操作時刻を取得
$this->lastUpdate = filemtime( $lockFilePath );
}
// ロックを更新する。
function touch()
{
// 最終更新日を更新
$lockFilePath = App::createEntryLockFilePath( $this->entryName, $this->entryId, $this->ownerUserId );
touch( $lockFilePath );
// 最終操作時刻を取得
$this->lastUpdate = filemtime( $lockFilePath );
}
}
/* -----------------------------------------------------------------
* ログイン管理クラス
* ---------------------------------------------------------------*/
class LoginManager
{
/* クラスメンバ */
function Logout()
{
unset ( $_SESSION['autheduser'] );
// ユーザーとパスワード名をクッキーから削除する。
$timeout = time() - 60 * 60; // 1時間前(強制的に過去にする)
$path = '/';
$domain = $_SERVER['SERVER_NAME'];
setcookie( 'cmsd_param1', '', $timeout, $path, $domain );
setcookie( 'cmsd_param2', '', $timeout, $path, $domain );
}
function IsAuthed()
{
return isset( $_SESSION['autheduser'] );
}
function GetAuthedUser()
{
return $_SESSION['autheduser'];
}
function Login( $userId, $password )
{
$user = SiteUser::AuthUser( $userId, $password );
if ( is_null( $user ) )
{
// 存在しないユーザーなので、ログイン失敗
return false;
}
else
{
// ログイン成功
$_SESSION['autheduser'] = $user;
// ユーザーとパスワード名をクッキーに保存する。
$timeout = time() + 60 * 60 * 24 * 30; // 1ヶ月
$path = '/';
$domain = $_SERVER['SERVER_NAME'];
setcookie( 'cmsd_param1', $userId, $timeout, $path, $domain );
setcookie( 'cmsd_param2', $password, $timeout, $path, $domain );
return true;
}
}
}
/* -----------------------------------------------------------------
* ユーザー情報クラス
* ---------------------------------------------------------------*/
class SiteUser
{
/* クラスメンバ */
function AuthUser( $userId, $password )
{
// 入力値のチェック
if ( SiteUser::IsErrorUserId( $userId ) or SiteUser::IsErrorPassword( $password ) )
{
return null;
}
$user = new SiteUser( $userId );
if ( $user->isNew )
{
return null;
}
else
{
if ( $user->Auth( $password ) )
{
return $user;
}
else
{
return null;
}
}
}
function UserExists( $userId )
{
$user = new SiteUser( $userId );
if ( $user->isNew )
{
return null;
}
else
{
return $user;
}
}
function LoadAllUsers()
{
// ユーザー情報をUsers.Configから読み込む。
if ( ! file_exists( App::getUsersConfigFilePath() ) )
{
die('users.config.xmlが存在しません。');
}
$xmlDocUsers = domxml_open_file( App::getUsersConfigFilePath() );
$xpath = $xmlDocUsers->xpath_new_context();
$xmlUserArr = $xpath->xpath_eval( "/users/user" );
$userArr = array();
foreach( $xmlUserArr->nodeset as $xmlUser )
{
$user = new SiteUser();
$user->LoadFromXMLNode( $xmlUser );
$userArr[] = $user;
}
return $userArr;
}
function Delete( $userIdArr )
{
// 引数が配列でない場合、要素が1つの配列に変換する。
if ( ! is_array($userIdArr) )
{
$userIdArr = array( $userIdArr );
}
// 認証済ユーザーIDを取得する。
$user = LoginManager::GetAuthedUser();
$authedUserId = $user->getUserId();
// ユーザー情報をUsers.Configから読み込む。
if ( ! file_exists( App::getUsersConfigFilePath() ) )
{
die('users.config.xmlが存在しません。');
}
$xmlDocUsers = domxml_open_file( App::getUsersConfigFilePath() );
$xmlUsersRoot = $xmlDocUsers->document_element();
$xpath = $xmlDocUsers->xpath_new_context();
foreach ( $userIdArr as $userId )
{
// 自分自身のユーザーを削除しないようにする。
if ( $userId != $authedUserId )
{
// 該当のuser要素を検索して、ルート要素から削除する。
$xmlUserArr = $xpath->xpath_eval( "/users/user[@id='" . $userId . "']" );
if ( $xmlUserArr->nodeset )
{
$xmlUsersRoot->remove_child( $xmlUserArr->nodeset[0] );
}
}
}
$xmlDocUsers->dump_file( App::getUsersConfigFilePath(), false, true );
}
function IsErrorUserId( $userId )
{
// ユーザーIDの長さチェック
if ( strlen( $userId ) < 3 || strlen( $userId ) > 20 )
{
return "ユーザーIDは3文字以上、20文字以下で入力して下さい。";
}
// ユーザーIDの文字チェック(半角英数字のみ許可)
if ( ! eregi( '^[a-zA-Z0-9_-]+$', $userId ) )
{
return "ユーザーIDには半角英数字のみ使用できます。";
}
return false;
}
function IsErrorPassword( $newPassword, $role = null )
{
// 長さチェック
if ( strlen( $newPassword ) > 20 )
{
return "パスワードは長さ20文字以下で入力して下さい。";
}
// 新しいパスワードは、システム管理者の場合は4文字以上必要。
if ( $role == 'administrator' && strlen( $newPassword ) < 4 )
{
return "システム管理者のパスワードは長さ4文字以上必要です。";
}
// 文字チェック
// 文字チェック(半角英数字のみ許可)
if ( ! eregi( '^[a-zA-Z0-9_-]*$', $newPassword ) )
{
return "パスワードには半角英数字のみ使用できます。";
}
return false;
}
/* インスタンスメンバ */
var $userId = ""; // ユーザーID
var $password = ""; // パスワード(暗号化後)
var $role = "publisher"; // ロール(役割)
var $isNew = true; // このユーザーが新規ユーザーか?(ファイルから読み込まれたなら既存ユーザー)
function SiteUser( $userId = null )
{
if ( $userId )
{
$this->Load( $userId );
}
}
function getUserId()
{
return $this->userId;
}
function setUserId( $newUserId )
{
$this->userId = $newUserId;
}
function setPassword( $newUncreptedPassword )
{
$this->password = crypt( $newUncreptedPassword, 'cm' );
}
function setRole( $newRole )
{
$this->role = $newRole;
}
function getRole()
{
return $this->role;
}
function isAdminitrator()
{
return ( $this->role == 'administrator' );
}
function isPublisher()
{
return ( $this->role == 'publisher' );
}
function Auth( $inputPassword )
{
if ( $this->password == crypt( $inputPassword, 'cm') )
{
return true;
}
else
{
return false;
}
}
function LoadFromXMLNode( &$xmlUser )
{
$this->userId = $xmlUser->get_attribute('id');
$this->password = $xmlUser->get_attribute('password');
$this->role = $xmlUser->get_attribute('role');
// パスワードが空白なら、暗号化する。
if ( strlen( $this->password ) <= 0 )
{
$this->password = crypt( '', 'cm' );
}
// ロール名チェック
if ( $this->role != 'administrator' && $this->role != 'publisher' )
{
die('users.config.xmlに未定義のrole名が設定されています。');
}
// 既存ユーザー
$this->isNew = false;
}
function Load( $userId )
{
// ユーザー情報をUsers.Configから読み込む。
if ( ! file_exists( App::getUsersConfigFilePath() ) )
{
die('users.config.xmlが存在しません。');
}
$xmlDocUsers = domxml_open_file( App::getUsersConfigFilePath() );
$xpath = $xmlDocUsers->xpath_new_context();
$xmlUserArr = $xpath->xpath_eval( "/users/user[@id='$userId']" );
if ( $xmlUserArr->nodeset )
{
// 該当ユーザーが存在すれば、その情報を取得する。
$xmlUser = $xmlUserArr->nodeset[0];
$this->LoadFromXMLNode( $xmlUser );
}
else
{
// 該当ユーザーが存在しなければ、新規ユーザーとして初期化する。
$this->userId = $userId; // 指定されたユーザーID
$this->password = crypt( '', 'cm' ); // 空白(暗号化)
$this->role = 'publisher'; // ロール : publisher
// 新規ユーザー
$this->isNew = true;
}
}
function Save()
{
// ユーザー情報をUsers.Configから読み込む。
$usersconfigfilepath = App::getUsersConfigFilePath();
if ( ! file_exists( $usersconfigfilepath ) )
{
die( "'$usersconfigfilepath'が存在しません。" );
}
// ユーザー情報ファイルが書き込み可能かチェックする。
if ( ! is_writable( $usersconfigfilepath ) )
{
die( "'$usersconfigfilepath'を更新できません。ファイルのパーミッションが606(又は666)以上になっているかを確認してください。" );
}
$xmlDocUsers = domxml_open_file( App::getUsersConfigFilePath() );
$xpath = $xmlDocUsers->xpath_new_context();
$xmlUserArr = $xpath->xpath_eval( "/users/user[@id='" . $this->userId . "']" );
if ( $xmlUserArr->nodeset )
{
if ( $this->isNew )
{
// 新規ユーザーなのに、設定ファイル中に同一ユーザーが存在するのはおかしい。
die("ユーザーの新規追加に失敗しました。ユーザー'" . $this->userId . "'は既に存在します。");
}
// 該当ユーザーが存在すれば、現在のインスタンス内容を上書き設定する。
$xmlUser = $xmlUserArr->nodeset[0];
$xmlUser->set_attribute('password', $this->password );
$xmlUser->set_attribute('role', $this->role );
}
else
{
if ( ! $this->isNew )
{
// 新規ユーザーじゃないのに、設定ファイル中にそのユーザーが存在しないのはおかしい。
die("ユーザー情報の更新に失敗しました。ユーザー'". $this->userId . "'が存在しません。");
}
$xmlUser = $xmlDocUsers->create_element('user');
$xmlUser->set_attribute('id', $this->userId );
$xmlUser->set_attribute('password', $this->password );
$xmlUser->set_attribute('role', $this->role );
$xmlUserRoot = $xmlDocUsers->document_element();
$xmlUserRoot->append_child( $xmlUser );
// もう追加したので、新規ユーザーではなくなる。
$this->isNew = false;
}
$xmlDocUsers->dump_file( App::getUsersConfigFilePath(), false, true );
}
function DispStatus()
{
print "---------------------
\n";
print 'userId = ' . $this->userId . "
\n";
print 'password = ' . $this->password . "
\n";
print 'role = ' . $this->role . "
\n";
print 'isNew = ' . ( $this->isNew ? 'true' : 'false' ) . "
\n";
print "---------------------
\n";
}
}
/* -----------------------------------------------------------------
* ユーザー一覧編集画面クラス
* ---------------------------------------------------------------*/
class EditUserListForm
{
/* ----------------------------------------------------------------
* コンストラクタ。
*/
function EditUserListForm()
{
}
/* ----------------------------------------------------------------
* リクエストの処理。外部から呼び出されるメソッド。
*/
function procRequest()
{
// Admin権限をチェック
$authedUser = LoginManager::GetAuthedUser();
if ( $authedUser->isAdminitrator() )
{
// 各処理実行
switch ( getPOSTParam( 'action' ) )
{
case 'delete' :
$itemlist = $_POST[ 'items' ];
EditUserListForm::DeleteItems( $itemlist );
break;
}
// ユーザー情報リストを取得
$userArr = SiteUser::LoadAllUsers();
}
else
{
// admin権限が無い場合は、空のユーザーリストを渡す。
$userArr = array();
}
// 画面表示
print( $this->renderHTMLXML( $userArr, LoginManager::GetAuthedUser() ) );
}
/* ----------------------------------------------------------------
* [クラスメソッド]
* 指定したエントリID群を削除する。
* $entryName : エントリ名。
* $itemlist : エントリIDの配列。
*/
function DeleteItems( $itemlist )
{
// ユーザーを削除する。
SiteUser::Delete( $itemlist );
}
/* ----------------------------------------------------------------
* 画面の描画。XMLで画面情報を生成し、XSLTを使って整形結果を出力する。
*/
function renderHTMLXML( $userArr, $authedUser )
{
// HTML生成開始
// DOMをを生成。
// ルートノード'users'を生成。
$xmlDocOutput = domxml_new_doc( '1.0' );
$xmlOutputRoot = $xmlDocOutput->add_root( 'edituserlistform' );
$xmlOutputRoot->set_attribute('autheduserid', $authedUser->getUserId() );
$xmlOutputRoot->set_attribute('autheduserrole', $authedUser->getRole() );
// 各ユーザーを出力ノードに加える。
foreach( $userArr as $user )
{
// 出力用DOMにエントリ1件分の情報を書き出す。
$xmlOutputUser = $xmlDocOutput->create_element('user');
$xmlOutputUser->set_attribute('id', $user->getUserId() );
$xmlOutputUser->set_attribute('role', $user->getRole() );
$xmlOutputRoot->append_child( $xmlOutputUser );
}
// HTML生成終了
// XSL変換処理
$strFormHTML = ADXslt::process( $xmlDocOutput, dirname(__FILE__) . "/entryeditor.xsl" );
return $strFormHTML;
}
}
/* -----------------------------------------------------------------
* ユーザー編集画面クラス
* ---------------------------------------------------------------*/
class EditUserForm
{
var $userId = '';
var $newPassword = '';
var $passwordSetting = false;
var $role = '';
var $isNew = true;
var $errorMessage = '';
var $criticalError = false;
/* ----------------------------------------------------------------
* コンストラクタ。
*/
function EditUserForm( $userId )
{
// 小文字に変換。
$userId = strtolower( $userId );
if ($userId == 'new')
{
// 新規ユーザーの作成。
$user = new SiteUser();
}
else
{
// 既存ユーザーのロード。
$user = new SiteUser( $userId );
}
// 画面フィールドを初期化。
if ( ! is_null( $user ) )
{
//$user->DispStatus();
$this->userId = $user->getUserId();
$this->role = $user->getRole();
$this->isNew = $user->isNew;
$this->newPassword = '';
$this->passwordSetting = false;
}
}
/* ----------------------------------------------------------------
* リクエストの処理。外部から呼び出されるメソッド。
*/
function procRequest()
{
// エラーをクリア
$this->errorMessage = '';
$this->criticalError = false;
// 次画面IDは初期値:なし。
$nextFormId = null;
// 認証済みユーザーを取得。
$authedUser = LoginManager::GetAuthedUser();
if ( $authedUser->isAdminitrator() )
{
// Admin権限アリ。
if ( $authedUser->isAdminitrator() )
{
// 各処理実行
switch ( getPOSTParam( 'action' ) )
{
case 'save' :
$this->update();
$this->save();
if ( ! $this->errorMessage )
{
// エラーが無ければ、1つ前の画面へ画面遷移。
$nextFormId = 'edituserlist';
}
break;
}
}
}
else
{
// Admin権限が無い
$this->criticalError = true;
$this->errorMessage = 'この操作にはシステム管理者権限が必要です。';
}
if ( $nextFormId == null )
{
// 画面表示
print( $this->renderHTMLXML() );
}
return $nextFormId;
}
function update()
{
if ( $this->isNew )
{
$this->userId = strtolower( $_POST['userid'] );
}
$this->role = ( strtolower( $_POST['role'] ) == 'administrator' ) ? 'administrator' : 'publisher';
$this->passwordSetting = ( isset( $_POST['passwordsetting'] ) );
if ($this->passwordSetting)
{
$this->newPassword = $_POST['newpassword'];
}
}
/* ----------------------------------------------------------------
* 編集中のユーザー情報をファイルに保存する。
*/
function save()
{
// ----------------------------------------------------------------
// 入力チェック
if ( $this->isNew )
{
// ユーザーIDの長さチェック、文字チェック
$errorMessage = SiteUser::IsErrorUserId( $this->userId );
if ( $errorMessage )
{
$this->errorMessage = $errorMessage;
return;
}
/*
// ユーザーIDの長さチェック
if ( strlen( $this->userId ) < 3 || strlen( $this->userId ) > 20 )
{
$this->errorMessage = "ユーザーIDは3文字以上、20文字以下で入力して下さい。";
return;
}
// ユーザーIDの文字チェック(半角英数字のみ許可)
if ( ! eregi( '^[a-z0-9\-_]+$', $this->userId ) )
{
$this->errorMessage = "ユーザーIDには半角英数字のみ使用できます。";
return;
}
*/
// ユーザーIDの存在チェック
if ( SiteUser::UserExists( $this->userId ) )
{
$this->errorMessage = "そのユーザーIDは既に使われています。";
return;
}
}
else
{
// ユーザーIDの存在チェック
if ( ! SiteUser::UserExists( $this->userId ) )
{
$this->errorMessage = "そのユーザーは存在しません。";
return;
}
}
// 新しいパスワードの入力チェック
if ( $this->passwordSetting )
{
// パスワードの長さチェック、文字チェック
$errorMessage = SiteUser::IsErrorPassword( $this->newPassword, $this->role );
if ( $errorMessage )
{
$this->errorMessage = $errorMessage;
return;
}
/*
// 長さチェック
if ( strlen( $this->newPassword ) > 20 )
{
$this->errorMessage = "パスワードは長さ20文字以下で入力して下さい。";
return;
}
// 新しいパスワードは、システム管理者の場合は4文字以上必要。
if ( $this->role == 'administrator' && strlen( $this->newPassword ) < 4 )
{
$this->errorMessage = "システム管理者のパスワードは長さ4文字以上必要です。";
return;
}
// 文字チェック
// 文字チェック(半角英数字のみ許可)
if ( ! eregi( '^[a-zA-Z0-9\-_]+$', $this->userId ) )
{
$this->errorMessage = "ユーザーIDには半角英数字のみ使用できます。";
return;
}
*/
}
// ----------------------------------------------------------------
// ユーザーオブジェクトに設定
$user = new SiteUser( $this->userId );
// 新しいパスワード
if ( $this->passwordSetting )
{
$user->setPassword( $this->newPassword );
}
// 役割
$user->setRole( $this->role );
// 保存
$user->save();
}
/* ----------------------------------------------------------------
* 画面の描画。XMLで画面情報を生成し、XSLTを使って整形結果を出力する。
*/
function renderHTMLXML()
{
// HTML生成開始
// DOMをを生成。
// ルートノード'users'を生成。
$xmlDocOutput = domxml_new_doc( '1.0' );
$xmlOutputRoot = $xmlDocOutput->add_root( 'edituserform' );
// 致命的エラーフラグ
$xmlOutputRoot->set_attribute('criticalerror', $this->criticalError ? 'true' : 'false');
// 致命的エラーでなければ、内容を設定する。
if ( ! $this->criticalError )
{
// ユーザーID
$xmlOutputRoot->set_attribute('userid', $this->userId);
// 新しいパスワード
$xmlOutputRoot->set_attribute('newpassword', $this->newPassword);
// ロール
$xmlOutputRoot->set_attribute('role', $this->role);
// 新規フラグ
$xmlOutputRoot->set_attribute('isnew', $this->isNew ? 'true' : 'false');
}
// エラーメッセージがあれば出力する。
if ( $this->errorMessage )
{
$xmlOutputErrorMessage = $xmlDocOutput->create_element('errormessage');
$xmlOutputErrorMessage->set_content( fileconv( $this->errorMessage ) );
$xmlOutputRoot->append_child( $xmlOutputErrorMessage );
}
// HTML生成終了
// XSL変換処理
$strFormHTML = ADXslt::process( $xmlDocOutput, dirname(__FILE__) . "/entryeditor.xsl" );
return $strFormHTML;
}
}
?>