diff --git a/Config/Migration/1434983278_init.php b/Config/Migration/1434983278_init.php index 390bdd3..a3502f0 100644 --- a/Config/Migration/1434983278_init.php +++ b/Config/Migration/1434983278_init.php @@ -30,29 +30,43 @@ class Init extends CakeMigration { public $migration = array( 'up' => array( 'create_table' => array( + 'user_select_counts' => array( + 'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'unsigned' => false, 'key' => 'primary'), + 'user_id' => array('type' => 'integer', 'null' => false, 'default' => null, 'unsigned' => false), + 'select_count' => array('type' => 'integer', 'null' => false, 'default' => '0', 'unsigned' => false), + 'created_user' => array('type' => 'integer', 'null' => true, 'default' => null, 'unsigned' => false), + 'created' => array('type' => 'datetime', 'null' => true, 'default' => null), + 'modified_user' => array('type' => 'integer', 'null' => true, 'default' => null, 'unsigned' => false), + 'modified' => array('type' => 'datetime', 'null' => true, 'default' => null), + 'indexes' => array( + 'PRIMARY' => array('column' => 'id', 'unique' => 1), + ), + 'tableParameters' => array('charset' => 'utf8', 'collate' => 'utf8_general_ci', 'engine' => 'InnoDB'), + ), 'users' => array( 'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'unsigned' => false, 'key' => 'primary'), - 'username' => array('type' => 'string', 'null' => true, 'default' => null, 'collate' => 'utf8_general_ci', 'charset' => 'utf8', 'comment' => 'ID | ログインID'), - 'password' => array('type' => 'string', 'null' => true, 'default' => null, 'collate' => 'utf8_general_ci', 'charset' => 'utf8', 'comment' => 'Password | パスワード'), - 'key' => array('type' => 'string', 'null' => true, 'default' => null, 'collate' => 'utf8_general_ci', 'charset' => 'utf8', 'comment' => 'Link identifier | リンク識別子'), + 'username' => array('type' => 'string', 'null' => true, 'default' => null, 'collate' => 'utf8_general_ci', 'comment' => 'ID | ログインID', 'charset' => 'utf8'), + 'password' => array('type' => 'string', 'null' => true, 'default' => null, 'collate' => 'utf8_general_ci', 'comment' => 'Password | パスワード', 'charset' => 'utf8'), + 'key' => array('type' => 'string', 'null' => true, 'default' => null, 'collate' => 'utf8_general_ci', 'comment' => 'Link identifier | リンク識別子', 'charset' => 'utf8'), 'is_deleted' => array('type' => 'boolean', 'null' => false, 'default' => '0'), - 'avatar' => array('type' => 'string', 'null' => true, 'default' => null, 'collate' => 'utf8_general_ci', 'charset' => 'utf8', 'comment' => 'Avatar | アバター'), - 'avatar_file_id' => array('type' => 'integer', 'null' => true, 'default' => null, 'unsigned' => false), 'is_avatar_public' => array('type' => 'boolean', 'null' => false, 'default' => '0'), - 'handlename' => array('type' => 'string', 'null' => true, 'default' => null, 'collate' => 'utf8_general_ci', 'charset' => 'utf8', 'comment' => 'Handle | ハンドル'), + 'is_avatar_auto_created' => array('type' => 'boolean', 'null' => false, 'default' => '1'), + 'handlename' => array('type' => 'string', 'null' => true, 'default' => null, 'collate' => 'utf8_general_ci', 'comment' => 'Handle | ハンドル', 'charset' => 'utf8'), 'is_handlename_public' => array('type' => 'boolean', 'null' => false, 'default' => '0'), 'is_name_public' => array('type' => 'boolean', 'null' => false, 'default' => '0'), - 'email' => array('type' => 'string', 'null' => true, 'default' => null, 'collate' => 'utf8_general_ci', 'charset' => 'utf8', 'comment' => 'E-mail | eメール'), + 'email' => array('type' => 'string', 'null' => true, 'default' => null, 'collate' => 'utf8_general_ci', 'comment' => 'E-mail | eメール', 'charset' => 'utf8'), 'is_email_public' => array('type' => 'boolean', 'null' => false, 'default' => '0'), - 'moblie_mail' => array('type' => 'string', 'null' => true, 'default' => null, 'collate' => 'utf8_general_ci', 'charset' => 'utf8', 'comment' => 'Mobile mail | 携帯メール'), + 'is_email_reception' => array('type' => 'boolean', 'null' => false, 'default' => '0'), + 'moblie_mail' => array('type' => 'string', 'null' => true, 'default' => null, 'collate' => 'utf8_general_ci', 'comment' => 'Mobile mail | 携帯メール', 'charset' => 'utf8'), 'is_moblie_mail_public' => array('type' => 'boolean', 'null' => false, 'default' => '0'), - 'sex' => array('type' => 'string', 'null' => true, 'default' => null, 'collate' => 'utf8_general_ci', 'charset' => 'utf8', 'comment' => 'Sex | 性別'), + 'is_moblie_mail_reception' => array('type' => 'boolean', 'null' => false, 'default' => '0'), + 'sex' => array('type' => 'string', 'null' => true, 'default' => null, 'collate' => 'utf8_general_ci', 'comment' => 'Sex | 性別', 'charset' => 'utf8'), 'is_sex_public' => array('type' => 'boolean', 'null' => false, 'default' => '0'), - 'timezone' => array('type' => 'string', 'null' => true, 'default' => null, 'collate' => 'utf8_general_ci', 'charset' => 'utf8', 'comment' => 'TimeZone | タイムゾーン'), + 'timezone' => array('type' => 'string', 'null' => true, 'default' => null, 'collate' => 'utf8_general_ci', 'comment' => 'TimeZone | タイムゾーン', 'charset' => 'utf8'), 'is_timezone_public' => array('type' => 'boolean', 'null' => false, 'default' => '0'), - 'role_key' => array('type' => 'string', 'null' => false, 'default' => null, 'collate' => 'utf8_general_ci', 'charset' => 'utf8', 'comment' => 'Authority | 権限'), + 'role_key' => array('type' => 'string', 'null' => false, 'default' => null, 'collate' => 'utf8_general_ci', 'comment' => 'Authority | 権限', 'charset' => 'utf8'), 'is_role_key_public' => array('type' => 'boolean', 'null' => false, 'default' => '0'), - 'status' => array('type' => 'string', 'null' => true, 'default' => null, 'collate' => 'utf8_general_ci', 'charset' => 'utf8', 'comment' => 'Status | 状態'), + 'status' => array('type' => 'string', 'null' => true, 'default' => null, 'collate' => 'utf8_general_ci', 'comment' => 'Status | 状態', 'charset' => 'utf8'), 'is_status_public' => array('type' => 'boolean', 'null' => false, 'default' => '0'), 'created' => array('type' => 'datetime', 'null' => true, 'default' => null, 'comment' => 'Created | 作成日時'), 'is_created_public' => array('type' => 'boolean', 'null' => false, 'default' => '0'), @@ -66,6 +80,8 @@ class Init extends CakeMigration { 'is_password_modified_public' => array('type' => 'boolean', 'null' => false, 'default' => '0'), 'last_login' => array('type' => 'datetime', 'null' => true, 'default' => null, 'comment' => 'Last login | 最終ログイン日時'), 'is_last_login_public' => array('type' => 'boolean', 'null' => false, 'default' => '0'), + 'previous_login' => array('type' => 'datetime', 'null' => true, 'default' => null, 'comment' => 'PreLast login | 前回ログイン日時'), + 'is_previous_login_public' => array('type' => 'boolean', 'null' => false, 'default' => '0'), 'is_profile_public' => array('type' => 'boolean', 'null' => false, 'default' => '0'), 'is_search_keywords_public' => array('type' => 'boolean', 'null' => false, 'default' => '0'), 'indexes' => array( @@ -77,9 +93,9 @@ class Init extends CakeMigration { 'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'unsigned' => false, 'key' => 'primary'), 'user_id' => array('type' => 'integer', 'null' => false, 'default' => null, 'unsigned' => false), 'language_id' => array('type' => 'integer', 'null' => false, 'default' => null, 'length' => 6, 'unsigned' => false), - 'name' => array('type' => 'string', 'null' => true, 'default' => null, 'collate' => 'utf8_general_ci', 'charset' => 'utf8', 'comment' => 'Name | 氏名'), - 'profile' => array('type' => 'text', 'null' => true, 'default' => null, 'collate' => 'utf8_general_ci', 'charset' => 'utf8', 'comment' => 'Profile | プロフィール'), - 'search_keywords' => array('type' => 'string', 'null' => true, 'default' => null, 'collate' => 'utf8_general_ci', 'charset' => 'utf8', 'comment' => 'Keywords | 検索キーワード'), + 'name' => array('type' => 'string', 'null' => true, 'default' => null, 'collate' => 'utf8_general_ci', 'comment' => 'Name | 氏名', 'charset' => 'utf8'), + 'profile' => array('type' => 'text', 'null' => true, 'default' => null, 'collate' => 'utf8_general_ci', 'comment' => 'Profile | プロフィール', 'charset' => 'utf8'), + 'search_keywords' => array('type' => 'string', 'null' => true, 'default' => null, 'collate' => 'utf8_general_ci', 'comment' => 'Keywords | 検索キーワード', 'charset' => 'utf8'), 'indexes' => array( 'PRIMARY' => array('column' => 'id', 'unique' => 1), ), @@ -89,7 +105,7 @@ class Init extends CakeMigration { ), 'down' => array( 'drop_table' => array( - 'users', 'users_languages' + 'user_select_counts', 'users', 'users_languages' ), ), ); diff --git a/Config/Migration/1447929761_delete_avatar.php b/Config/Migration/1447929761_delete_avatar.php deleted file mode 100644 index 9d2e8c2..0000000 --- a/Config/Migration/1447929761_delete_avatar.php +++ /dev/null @@ -1,67 +0,0 @@ - - * @link http://www.netcommons.org NetCommons Project - * @license http://www.netcommons.org/license.txt NetCommons License - * @copyright Copyright 2014, NetCommons Project - */ - -/** - * Migration file - * - * * アバターに関するフィールド削除('avatar', 'avatar_file_id') - * - * @package NetCommons\Users\Config\Migration - */ -class DeleteAvatar extends CakeMigration { - -/** - * Migration description - * - * @var string - */ - public $description = 'delete_avatar'; - -/** - * Actions to be performed - * - * @var array $migration - */ - public $migration = array( - 'up' => array( - 'drop_field' => array( - 'users' => array('avatar', 'avatar_file_id'), - ), - ), - 'down' => array( - 'create_field' => array( - 'users' => array( - 'avatar' => array('type' => 'string', 'null' => true, 'default' => null, 'collate' => 'utf8_general_ci', 'charset' => 'utf8', 'comment' => 'Avatar | アバター'), - 'avatar_file_id' => array('type' => 'integer', 'null' => true, 'default' => null, 'unsigned' => false), - ), - ), - ), - ); - -/** - * Before migration callback - * - * @param string $direction Direction of migration process (up or down) - * @return bool Should process continue - */ - public function before($direction) { - return true; - } - -/** - * After migration callback - * - * @param string $direction Direction of migration process (up or down) - * @return bool Should process continue - */ - public function after($direction) { - return true; - } -} diff --git a/Config/Migration/1448003986_add_mail_reception.php b/Config/Migration/1448003986_add_mail_reception.php deleted file mode 100644 index d458c36..0000000 --- a/Config/Migration/1448003986_add_mail_reception.php +++ /dev/null @@ -1,67 +0,0 @@ - - * @link http://www.netcommons.org NetCommons Project - * @license http://www.netcommons.org/license.txt NetCommons License - * @copyright Copyright 2014, NetCommons Project - */ - -/** - * Migration file - * - * * 各自でメール受信可否の設定を可能にするフィールド追加('is_email_reception', 'is_moblie_mail_reception') - * - * @package NetCommons\Users\Config\Migration - */ -class AddMailReception extends CakeMigration { - -/** - * Migration description - * - * @var string - */ - public $description = 'Add_mail_reception'; - -/** - * Actions to be performed - * - * @var array $migration - */ - public $migration = array( - 'up' => array( - 'create_field' => array( - 'users' => array( - 'is_email_reception' => array('type' => 'boolean', 'null' => false, 'default' => '0', 'after' => 'is_email_public'), - 'is_moblie_mail_reception' => array('type' => 'boolean', 'null' => false, 'default' => '0', 'after' => 'is_moblie_mail_public'), - ), - ), - ), - 'down' => array( - 'drop_field' => array( - 'users' => array('is_email_reception', 'is_moblie_mail_reception'), - ), - ), - ); - -/** - * Before migration callback - * - * @param string $direction Direction of migration process (up or down) - * @return bool Should process continue - */ - public function before($direction) { - return true; - } - -/** - * After migration callback - * - * @param string $direction Direction of migration process (up or down) - * @return bool Should process continue - */ - public function after($direction) { - return true; - } -} diff --git a/Config/Migration/1448811617_add_user_select_counts.php b/Config/Migration/1448811617_add_user_select_counts.php deleted file mode 100644 index a51f2bb..0000000 --- a/Config/Migration/1448811617_add_user_select_counts.php +++ /dev/null @@ -1,76 +0,0 @@ - - * @link http://www.netcommons.org NetCommons Project - * @license http://www.netcommons.org/license.txt NetCommons License - * @copyright Copyright 2014, NetCommons Project - */ - -/** - * Migration file - * - * * 会員選択した件数をセットするテーブル追加(user_select_counts) - * - * @package NetCommons\Users\Config\Migration - */ -class AddUserSelectCounts extends CakeMigration { - -/** - * Migration description - * - * @var string - */ - public $description = 'Add_user_select_counts'; - -/** - * Actions to be performed - * - * @var array $migration - */ - public $migration = array( - 'up' => array( - 'create_table' => array( - 'user_select_counts' => array( - 'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'unsigned' => false, 'key' => 'primary'), - 'user_id' => array('type' => 'integer', 'null' => false, 'default' => null, 'unsigned' => false), - 'select_count' => array('type' => 'integer', 'null' => false, 'default' => '0', 'unsigned' => false), - 'created_user' => array('type' => 'integer', 'null' => true, 'default' => null, 'unsigned' => false), - 'created' => array('type' => 'datetime', 'null' => true, 'default' => null), - 'modified_user' => array('type' => 'integer', 'null' => true, 'default' => null, 'unsigned' => false), - 'modified' => array('type' => 'datetime', 'null' => true, 'default' => null), - 'indexes' => array( - 'PRIMARY' => array('column' => 'id', 'unique' => 1), - ), - 'tableParameters' => array('charset' => 'utf8', 'collate' => 'utf8_general_ci', 'engine' => 'InnoDB'), - ), - ), - ), - 'down' => array( - 'drop_table' => array( - 'user_select_counts' - ), - ), - ); - -/** - * Before migration callback - * - * @param string $direction Direction of migration process (up or down) - * @return bool Should process continue - */ - public function before($direction) { - return true; - } - -/** - * After migration callback - * - * @param string $direction Direction of migration process (up or down) - * @return bool Should process continue - */ - public function after($direction) { - return true; - } -} diff --git a/Config/Schema/schema.php b/Config/Schema/schema.php index 1409e05..510e2c5 100644 --- a/Config/Schema/schema.php +++ b/Config/Schema/schema.php @@ -76,6 +76,7 @@ public function after($event = array()) { 'key' => array('type' => 'string', 'null' => true, 'default' => null, 'collate' => 'utf8_general_ci', 'comment' => 'Link identifier | リンク識別子', 'charset' => 'utf8'), 'is_deleted' => array('type' => 'boolean', 'null' => false, 'default' => '0'), 'is_avatar_public' => array('type' => 'boolean', 'null' => false, 'default' => '0'), + 'is_avatar_auto_created' => array('type' => 'boolean', 'null' => false, 'default' => '1'), 'handlename' => array('type' => 'string', 'null' => true, 'default' => null, 'collate' => 'utf8_general_ci', 'comment' => 'Handle | ハンドル', 'charset' => 'utf8'), 'is_handlename_public' => array('type' => 'boolean', 'null' => false, 'default' => '0'), 'is_name_public' => array('type' => 'boolean', 'null' => false, 'default' => '0'), @@ -105,6 +106,8 @@ public function after($event = array()) { 'is_password_modified_public' => array('type' => 'boolean', 'null' => false, 'default' => '0'), 'last_login' => array('type' => 'datetime', 'null' => true, 'default' => null, 'comment' => 'Last login | 最終ログイン日時'), 'is_last_login_public' => array('type' => 'boolean', 'null' => false, 'default' => '0'), + 'previous_login' => array('type' => 'datetime', 'null' => true, 'default' => null, 'comment' => 'PreLast login | 前回ログイン日時'), + 'is_previous_login_public' => array('type' => 'boolean', 'null' => false, 'default' => '0'), 'is_profile_public' => array('type' => 'boolean', 'null' => false, 'default' => '0'), 'is_search_keywords_public' => array('type' => 'boolean', 'null' => false, 'default' => '0'), 'indexes' => array( diff --git a/Console/Command/Task/ImportTask.php b/Console/Command/Task/ImportTask.php index a465c03..b11cfba 100644 --- a/Console/Command/Task/ImportTask.php +++ b/Console/Command/Task/ImportTask.php @@ -35,6 +35,8 @@ class ImportTask extends AppShell { * @return void */ public function execute() { + Security::setHash('sha512'); + $file = Hash::get($this->args, '0'); if (! $file) { $this->args[0] = $this->in(__d('users', 'Enter import file path.')); @@ -51,7 +53,6 @@ public function execute() { $user = $this->User->findById(1); CakeSession::write(AuthComponent::$sessionKey, $user['User']); Current::initialize(new CakeRequest()); - $this->User->prepare(); if (! $this->User->importUsers($file)) { //バリデーションエラーの場合 diff --git a/Controller/Component/UserSearchComponent.php b/Controller/Component/UserSearchComponent.php index abeb639..01f52c1 100644 --- a/Controller/Component/UserSearchComponent.php +++ b/Controller/Component/UserSearchComponent.php @@ -33,6 +33,22 @@ class UserSearchComponent extends Component { */ const DEFAULT_LIMIT = 20; +/** + * more_than_days定数 + * ○日以上前(○日以上ログインしていない) + * + * @var const + */ + const MORE_THAN_DAYS = 'more_than_days'; + +/** + * within_days定数 + * ○日以内(○日以内ログインしている) + * + * @var const + */ + const WITHIN_DAYS = 'within_days'; + /** * Other Components this component uses. * @@ -56,9 +72,16 @@ public function startup(Controller $controller) { //Modelの呼び出し $controller->User = ClassRegistry::init('Users.User'); $controller->UsersLanguage = ClassRegistry::init('Users.UsersLanguage'); + } - if (! $controller->request->query && ! $controller->request->named) { - $controller->Session->delete(self::$sessionKey); +/** + * 条件のクリア + * + * @return void + */ + public function clearConditions() { + if (! $this->controller->request->query && ! $this->controller->request->named) { + $this->controller->Session->delete(self::$sessionKey); } } @@ -73,10 +96,34 @@ public function startup(Controller $controller) { */ public function search($conditions = array(), $joins = array(), $orders = array(), $limit = self::DEFAULT_LIMIT) { $defaultConditions = $this->controller->Session->read(self::$sessionKey); + if (! $defaultConditions) { $defaultConditions = array(); } $conditions = Hash::merge($defaultConditions, $conditions); + $fieldKeys = array_keys($conditions); + foreach ($fieldKeys as $field) { + if ($field === 'group_id') { + $joins = Hash::merge(array('Group' => true), $joins); + } elseif ($field === 'created_user') { + $joins = Hash::merge(array('TrackableCreator' => true), $joins); + } elseif ($field === 'modified_user') { + $joins = Hash::merge(array('TrackableUpdater' => true), $joins); + } elseif ($this->controller->User->getOriginalUserField($field) === + $this->controller->User->UploadFile->alias . Inflector::classify($field) . '.field_name') { + $modelName = $this->controller->User->UploadFile->alias . Inflector::classify($field); + $joins = Hash::merge(array($modelName => array( + 'table' => $this->controller->User->UploadFile->table, + 'alias' => $modelName, + 'type' => 'LEFT', + 'conditions' => array( + $modelName . '.content_key' . ' = ' . $this->controller->User->alias . '.id', + $modelName . '.plugin_key' => 'users', + $modelName . '.field_name' => $field, + ), + )), $joins); + } + } //ユーザデータ取得 $this->controller->Paginator->settings = array( diff --git a/Controller/UsersController.php b/Controller/UsersController.php index 8d272ca..02a4aca 100644 --- a/Controller/UsersController.php +++ b/Controller/UsersController.php @@ -12,7 +12,8 @@ * @copyright Copyright 2014, NetCommons Project */ -App::uses('AppController', 'Controller'); +App::uses('UsersAppController', 'Users.Controller'); +App::uses('UserSelectCount', 'Users.Model'); /** * Users Controller @@ -24,8 +25,6 @@ class UsersController extends UsersAppController { /** * 会員一覧の表示する項目 - * - * @var const */ public static $displaField = 'handlename'; @@ -265,7 +264,9 @@ public function search() { 'conditions' => array( 'Room.page_id_top NOT' => null, ) - )) + )), + array(), + UserSelectCount::LIMIT ); $fields = array(self::$displaField => self::$displaField); diff --git a/Locale/jpn/LC_MESSAGES/users.po b/Locale/jpn/LC_MESSAGES/users.po index 46ea424..aa7ee17 100644 --- a/Locale/jpn/LC_MESSAGES/users.po +++ b/Locale/jpn/LC_MESSAGES/users.po @@ -70,3 +70,5 @@ msgstr "選択されていません。" msgid "Please enter handle name." msgstr "ハンドルを入力して下さい。" +msgid "Too many results to show. Can you think of more specific search keywords?" +msgstr "検索結果は、%s件までしか表示できません。もう少し条件を増やしてください。" diff --git a/Model/Behavior/AvatarBehavior.php b/Model/Behavior/AvatarBehavior.php new file mode 100644 index 0000000..56fb752 --- /dev/null +++ b/Model/Behavior/AvatarBehavior.php @@ -0,0 +1,94 @@ + + * @author Shohei Nakajima + * @link http://www.netcommons.org NetCommons Project + * @license http://www.netcommons.org/license.txt NetCommons License + * @copyright Copyright 2014, NetCommons Project + */ + +App::uses('ModelBehavior', 'Model'); + +/** + * SaveUser Behavior + * + * @author Shohei Nakajima + * @package NetCommons\Users\Model\Behavior + */ +class AvatarBehavior extends ModelBehavior { + +/** + * アバター自動生成処理 + * + * @param Model $model ビヘイビア呼び出し元モデル + * @param array $user ユーザデータ配列 + * @return mixed On success Model::$data, false on failure + * @throws InternalErrorException + */ + public function createAvatarAutomatically(Model $model, $user) { + //imagickdraw オブジェクトを作成します + $draw = new ImagickDraw(); + + //文字色のセット + $draw->setfillcolor('white'); + + //フォントサイズを 160 に設定します + $draw->setFontSize(140); + + //テキストを追加します + $draw->setFont(CakePlugin::path($model->plugin) . 'webroot' . DS . 'fonts' . DS . 'ipag.ttf'); + $draw->annotation(19, 143, mb_substr(mb_convert_kana($user['User']['handlename'], 'KVA'), 0, 1)); + + //新しいキャンバスオブジェクトを作成する + $canvas = new Imagick(); + + //ランダムで背景色を指定する + $red1 = strtolower(dechex(mt_rand(3, 12))); + $red2 = strtolower(dechex(mt_rand(0, 15))); + $green1 = strtolower(dechex(mt_rand(3, 12))); + $green2 = strtolower(dechex(mt_rand(0, 15))); + $blue1 = strtolower(dechex(mt_rand(3, 12))); + $blue2 = strtolower(dechex(mt_rand(0, 15))); + $canvas->newImage(179, 179, '#' . $red1 . $red2 . $green1 . $green2 . $blue1 . $blue2); + + //ImagickDraw をキャンバス上に描画します + $canvas->drawImage($draw); + + //フォーマットを PNG に設定します + $canvas->setImageFormat('png'); + + App::uses('TemporaryFolder', 'Files.Utility'); + $folder = new TemporaryFolder(); + $filePath = $folder->path . DS . Security::hash($user['User']['handlename'], 'md5') . '.png'; + $canvas->writeImages($filePath, true); + + return $filePath; + } + +/** + * アバター自動生成チェック + * + * * 削除がチェックONになっている || + * * アップロードファイルがない && + * アバターを自動生成する場合 && + * ハンドルを登録(POSTに含まれている)する場合 && + * 登録前のハンドル名と登録後のハンドル名が異なる場合 + * + * @param Model $model ビヘイビア呼び出し元モデル + * @param array $data リクエストデータ配列 + * @param array $user ユーザデータ配列 + * @param array $beforeUser 変更前ユーザデータ配列 + * @return mixed On success Model::$data, false on failure + * @throws InternalErrorException + */ + public function validAvatarAutomatically(Model $model, $data, $user, $beforeUser) { + return Hash::get($data, 'User.' . User::$avatarField . '.remove') || + $data['User']['is_avatar_auto_created'] && + ! Hash::get($user, 'User.' . User::$avatarField . '.name') && + Hash::get($user, 'User.handlename') && + Hash::get($beforeUser, 'User.handlename') !== Hash::get($user, 'User.handlename'); + } + +} diff --git a/Model/Behavior/SaveUserBehavior.php b/Model/Behavior/SaveUserBehavior.php index c9df510..430e211 100644 --- a/Model/Behavior/SaveUserBehavior.php +++ b/Model/Behavior/SaveUserBehavior.php @@ -113,7 +113,7 @@ private function __setInvalidates(Model $model, $userAttribute, $userAttributesR } //管理者しか強化しない項目のチェック⇒不正エラーとする - if ($userAttribute['UserAttributeSetting']['only_administrator'] && + if ($userAttribute['UserAttributeSetting']['only_administrator_editable'] && ! Current::allowSystemPlugin('user_manager') && isset($model->data[$modelName][$userAttributeKey])) { throw new BadRequestException(__d('net_commons', 'Bad Request')); @@ -181,4 +181,34 @@ private function __setValidates(Model $model, $userAttribute) { } } +/** + * ユーザの登録処理 + * + * @param Model $model ビヘイビア呼び出し元モデル + * @param int $userId ユーザID + * @return mixed On success Model::$data, false on failure + * @throws InternalErrorException + */ + public function updateLoginTime(Model $model, $userId) { + //トランザクションBegin + $model->begin(); + + try { + $update = array( + 'User.previous_login' => 'User.last_login', + 'User.last_login' => '\'' . date('Y-m-d H:i:s') . '\'' + ); + $conditions = array('User.id' => (int)$userId); + if (! $model->updateAll($update, $conditions)) { + throw new InternalErrorException(__d('net_commons', 'Internal Server Error')); + } + $model->commit(); + + } catch (Exception $ex) { + $model->rollback($ex); + } + + return true; + } + } diff --git a/Model/Behavior/UserSearchBehavior.php b/Model/Behavior/UserSearchBehavior.php index d8023f5..4373df5 100644 --- a/Model/Behavior/UserSearchBehavior.php +++ b/Model/Behavior/UserSearchBehavior.php @@ -24,7 +24,7 @@ class UserSearchBehavior extends ModelBehavior { * * @var array */ - public static $readableFields = null; + public $readableFields = null; /** * 事前準備 @@ -34,15 +34,19 @@ class UserSearchBehavior extends ModelBehavior { */ private function __prepare(Model $model) { $model->loadModels([ - 'UserAttribute' => 'UserAttributes.UserAttribute', - 'UserAttributesRole' => 'UserRoles.UserAttributesRole', + //'Group' => 'Groups.Group', + 'GroupsUser' => 'Groups.GroupsUser', 'RolesRoom' => 'Rooms.RolesRoom', 'RolesRoomsUser' => 'Rooms.RolesRoomsUser', 'Room' => 'Rooms.Room', 'RoomRole' => 'Rooms.RoomRole', + 'UserAttribute' => 'UserAttributes.UserAttribute', + 'UserAttributesRole' => 'UserRoles.UserAttributesRole', + 'UploadFile' => 'Files.UploadFile', ]); - if (isset(self::$readableFields)) { + $model->prepare(); + if (isset($this->readableFields)) { return; } @@ -55,29 +59,41 @@ private function __prepare(Model $model) { ) )); - self::$readableFields = array('id'); - foreach ($results as $key => $field) { + $userAttributes = $model->UserAttribute->getUserAttributesForLayout(); + + $this->readableFields = array('id' => 'id'); + foreach ($results as $field) { + $dataType = Hash::extract($userAttributes, '{n}.{n}.{n}.UserAttributeSetting[user_attribute_key=' . $field . ']'); + $dataTypeKey = Hash::get($dataType, '0.data_type_key', ''); + //Fieldのチェック - if ($model->hasField($field)) { - self::$readableFields[$key] = $model->alias . '.' . $field; - } - if ($model->UsersLanguage->hasField($field)) { - self::$readableFields[$key] = $model->UsersLanguage->alias . '.' . $field; - } - //Field(is_xxxx_public)のチェック - $fieldKey = sprintf(UserAttribute::PUBLIC_FIELD_FORMAT, $field); - if ($model->hasField($fieldKey)) { - self::$readableFields[$fieldKey] = $model->alias . '.' . $fieldKey; + if ($dataTypeKey === DataType::DATA_TYPE_IMG) { + $this->readableFields[$field] = $model->UploadFile->alias . Inflector::classify($field) . '.field_name'; + } elseif (in_array($field, UserAttribute::$typeDatetime, true) || $dataTypeKey === DataType::DATA_TYPE_DATETIME) { + //日時型の場合 + $this->readableFields[$field] = $model->alias . '.' . $field; + $this->readableFields[$field . '.' . UserSearchComponent::MORE_THAN_DAYS] = $model->alias . '.' . $field; + $this->readableFields[$field . '.' . UserSearchComponent::WITHIN_DAYS] = $model->alias . '.' . $field; + } elseif ($model->hasField($field)) { + //Userモデル + $this->readableFields[$field] = $model->alias . '.' . $field; + } elseif ($model->UsersLanguage->hasField($field)) { + //UsersLanguageモデル + $this->readableFields[$field] = $model->UsersLanguage->alias . '.' . $field; } - ////Field(xxxx_file_id)のチェック - //$fieldKey = sprintf(UserAttribute::FILE_FIELD_FORMAT, $field); + ////Field(is_xxxx_public)のチェック + //$fieldKey = sprintf(UserAttribute::PUBLIC_FIELD_FORMAT, $field); //if ($model->hasField($fieldKey)) { - // self::$readableFields[$fieldKey] = $model->alias . '.' . $fieldKey; + // $this->readableFields[$fieldKey] = $model->alias . '.' . $fieldKey; //} } - self::$readableFields['room_id'] = $model->Room->alias . '.id'; - self::$readableFields['space_id'] = $model->Room->alias . '.space_id'; - self::$readableFields['room_role_key'] = $model->RolesRoom->alias . '.role_key'; + $this->readableFields['room_id'] = $model->Room->alias . '.id'; + $this->readableFields['space_id'] = $model->Room->alias . '.space_id'; + $this->readableFields['room_role_key'] = $model->RolesRoom->alias . '.role_key'; + $this->readableFields['group_id'] = $model->GroupsUser->alias . '.group_id'; + + $this->readableFields['created_user'] = 'TrackableCreator.handlename'; + $this->readableFields['modified_user'] = 'TrackableUpdater.handlename'; } /** @@ -92,7 +108,7 @@ public function cleanSearchFields(Model $model, $fields) { $fieldKeys = array_keys($fields); foreach ($fieldKeys as $key) { - if (! isset(self::$readableFields[$key])) { + if (! isset($this->readableFields[$key])) { unset($fields[$key]); } } @@ -109,29 +125,30 @@ public function cleanSearchFields(Model $model, $fields) { public function getSearchConditions(Model $model, $conditions = array()) { $this->__prepare($model); - $userAttributes = $model->UserAttribute->getUserAttributesForLayout(); - $fieldKeys = array_keys($conditions); foreach ($fieldKeys as $key) { - $dataType = Hash::extract($userAttributes, '{n}.{n}.{n}.UserAttributeSetting[user_attribute_key=' . $key . ']'); - $dataType = Hash::get($dataType, '0.data_type_key', ''); - if (in_array($dataType, [DataType::DATA_TYPE_TEXT, DataType::DATA_TYPE_TEXTAREA, DataType::DATA_TYPE_EMAIL], true)) { - $sign = ' LIKE'; - $value = '%' . $conditions[$key] . '%'; - } else { - $sign = ''; - $value = $conditions[$key]; + $explode = explode('.', $key); + $field = Hash::get($explode, '0', null); + $setting = Hash::get($explode, '1', null); + + list($sign, $value) = $this->__creanSearchCondtion($model, $field, $setting, $conditions[$key]); + unset($conditions[$key]); + + if (! isset($this->readableFields[$key])) { + continue; } - if (isset(self::$readableFields[$key])) { - $conditions[self::$readableFields[$key] . $sign] = $value; - unset($conditions[$key]); + if ($setting === UserSearchComponent::MORE_THAN_DAYS) { + $conditions[count($conditions)]['OR'] = array( + $this->readableFields[$key] => null, + $this->readableFields[$key] . $sign => $value + ); } else { - $conditions[$key . $sign] = $value; + $conditions[$this->readableFields[$key] . $sign] = $value; } } - if (! isset(self::$readableFields['role_key'])) { + if (! isset($this->readableFields['role_key'])) { $conditions['User.status'] = '1'; } $conditions['User.is_deleted'] = false; @@ -139,6 +156,54 @@ public function getSearchConditions(Model $model, $conditions = array()) { return $conditions; } +/** + * 検索可能のフィールドをチェックして、検索不可なフィールドは削除する + * + * @param Model $model Model ビヘイビア呼び出し前のモデル + * @param array $field フィールド + * @param array $setting セッティングモード(日時型のみ使用) + * @param array $value 値 + * @return array array(符号, SQL値) + */ + private function __creanSearchCondtion(Model $model, $field, $setting, $value) { + $userAttributes = $model->UserAttribute->getUserAttributesForLayout(); + + $dataType = Hash::extract($userAttributes, '{n}.{n}.{n}.UserAttributeSetting[user_attribute_key=' . $field . ']'); + $dataTypeKey = Hash::get($dataType, '0.data_type_key', ''); + + if ($dataTypeKey === DataType::DATA_TYPE_IMG) { + if ($value) { + $sign = ' NOT'; + } else { + $sign = ''; + } + $value = null; + } elseif (in_array($field, UserAttribute::$typeDatetime, true) || $dataTypeKey === DataType::DATA_TYPE_DATETIME) { + //日付型の場合 + if ($setting === UserSearchComponent::MORE_THAN_DAYS) { + //○日以上前(○日以上ログインしていない) + $sign = ' <='; + } else { + //○日以内(○日以内ログインしている) + $sign = ' >='; + } + $date = new DateTime(NetCommonsTime::getNowDatetime()); + $date->sub(new DateInterval(sprintf('P%dD', (int)$value))); + $value = $date->format('Y-m-d H:i:s'); + + } elseif (in_array($dataTypeKey, [DataType::DATA_TYPE_TEXT, DataType::DATA_TYPE_TEXTAREA, DataType::DATA_TYPE_EMAIL], true) || + in_array($field, ['created_user', 'modified_user'], true)) { + // テキスト型、テキストエリア型、メールアドレス型、作成者、更新者の場合 + // ->あいまい検索※今後、MatchAgainstもしくは、前方一致にする必要あり。 + $sign = ' LIKE'; + $value = '%' . $value . '%'; + } else { + $sign = ''; + } + + return array($sign, $value); + } + /** * JOINテーブルを取得 * @@ -147,51 +212,87 @@ public function getSearchConditions(Model $model, $conditions = array()) { * @return array Findで使用するJOIN配列 */ public function getSearchJoinTables(Model $model, $joinModels = array()) { - $joins[] = array( - 'table' => $model->UsersLanguage->table, - 'alias' => $model->UsersLanguage->alias, - 'type' => 'INNER', - 'conditions' => array( - $model->UsersLanguage->alias . '.user_id' . ' = ' . $model->alias . '.id', - $model->UsersLanguage->alias . '.language_id' => Current::read('Language.id'), + $joins = array( + array( + 'table' => $model->UsersLanguage->table, + 'alias' => $model->UsersLanguage->alias, + 'type' => 'INNER', + 'conditions' => array( + $model->UsersLanguage->alias . '.user_id' . ' = ' . $model->alias . '.id', + $model->UsersLanguage->alias . '.language_id' => Current::read('Language.id'), + ), ), + Hash::merge(array( + 'table' => $model->RolesRoomsUser->table, + 'alias' => $model->RolesRoomsUser->alias, + 'type' => 'LEFT', + 'conditions' => array( + $model->RolesRoomsUser->alias . '.user_id' . ' = ' . $model->alias . '.id', + ), + ), Hash::get($joinModels, 'RolesRoomsUser', array())), + Hash::merge(array( + 'table' => $model->RolesRoom->table, + 'alias' => $model->RolesRoom->alias, + 'type' => 'LEFT', + 'conditions' => array( + $model->RolesRoomsUser->alias . '.roles_room_id' . ' = ' . $model->RolesRoom->alias . '.id', + ), + ), Hash::get($joinModels, 'RolesRoom', array())), + Hash::merge(array( + 'table' => $model->RoomRole->table, + 'alias' => $model->RoomRole->alias, + 'type' => 'LEFT', + 'conditions' => array( + $model->RolesRoom->alias . '.role_key' . ' = ' . $model->RoomRole->alias . '.role_key', + ), + ), Hash::get($joinModels, 'RolesRoom', array())), + Hash::merge(array( + 'table' => $model->Room->table, + 'alias' => $model->Room->alias, + 'type' => 'LEFT', + 'conditions' => array( + $model->RolesRoomsUser->alias . '.room_id' . ' = ' . $model->Room->alias . '.id', + ), + ), Hash::get($joinModels, 'Room', array())) ); - $joins[] = Hash::merge(array( - 'table' => $model->RolesRoomsUser->table, - 'alias' => $model->RolesRoomsUser->alias, - 'type' => 'LEFT', - 'conditions' => array( - $model->RolesRoomsUser->alias . '.user_id' . ' = ' . $model->alias . '.id', - ), - ), Hash::get($joinModels, 'RolesRoomsUser', array())); - - $joins[] = Hash::merge(array( - 'table' => $model->RolesRoom->table, - 'alias' => $model->RolesRoom->alias, - 'type' => 'LEFT', - 'conditions' => array( - $model->RolesRoomsUser->alias . '.roles_room_id' . ' = ' . $model->RolesRoom->alias . '.id', - ), - ), Hash::get($joinModels, 'RolesRoom', array())); + if (Hash::get($joinModels, 'Group')) { + $joins[] = array( + 'table' => $model->GroupsUser->table, + 'alias' => $model->GroupsUser->alias, + 'type' => 'INNER', + 'conditions' => array( + $model->GroupsUser->alias . '.user_id' . ' = ' . $model->alias . '.id', + $model->GroupsUser->alias . '.created_user' => Current::read('User.id'), + ), + ); + } - $joins[] = Hash::merge(array( - 'table' => $model->RoomRole->table, - 'alias' => $model->RoomRole->alias, - 'type' => 'LEFT', - 'conditions' => array( - $model->RolesRoom->alias . '.role_key' . ' = ' . $model->RoomRole->alias . '.role_key', - ), - ), Hash::get($joinModels, 'RolesRoom', array())); + if (Hash::get($joinModels, 'TrackableCreator')) { + $joins[] = array( + 'table' => $model->table, + 'alias' => 'TrackableCreator', + 'type' => 'INNER', + 'conditions' => array( + $model->alias . '.created_user' . ' = ' . 'TrackableCreator.id', + ), + ); + } + if (Hash::get($joinModels, 'TrackableUpdater')) { + $joins[] = array( + 'table' => $model->table, + 'alias' => 'TrackableUpdater', + 'type' => 'INNER', + 'conditions' => array( + $model->alias . '.modified_user' . ' = ' . 'TrackableUpdater.id', + ), + ); + } - $joins[] = Hash::merge(array( - 'table' => $model->Room->table, - 'alias' => $model->Room->alias, - 'type' => 'LEFT', - 'conditions' => array( - $model->RolesRoomsUser->alias . '.room_id' . ' = ' . $model->Room->alias . '.id', - ), - ), Hash::get($joinModels, 'Room', array())); + $uploads = Hash::extract($joinModels, '{s}[table=' . $model->UploadFile->table . ']'); + foreach ($uploads as $upload) { + $joins[] = $upload; + } return $joins; } @@ -223,7 +324,7 @@ public function getSearchFields(Model $model) { */ public function getOriginalUserField(Model $model, $field) { $this->__prepare($model); - return Hash::get(self::$readableFields, $field); + return Hash::get($this->readableFields, $field); } } diff --git a/Model/User.php b/Model/User.php index 13e31de..570d034 100644 --- a/Model/User.php +++ b/Model/User.php @@ -87,6 +87,7 @@ class User extends UsersAppModel { 'Users.SaveUser', 'Users.DeleteUser', 'Users.UserSearch', + 'Users.Avatar', ); /** @@ -197,22 +198,27 @@ public function __construct($id = false, $table = null, $ds = null) { if (! Configure::read('NetCommons.installed')) { //インストール時は、アップロードビヘイビアを削除する $this->Behaviors->unload('Files.Attachment'); - } else { - $this->prepare(); + $this->Behaviors->unload('Users.Avatar'); } } /** * UserModelの前準備 * + * @param bool $force 強制的に取得するフラグ * @return void + * @SuppressWarnings(PHPMD.BooleanArgumentFlag) */ - public function prepare() { + public function prepare($force = false) { + if (! $force && $this->userAttributeData && self::$avatarField) { + return; + } + $this->loadModels([ 'UserAttribute' => 'UserAttributes.UserAttribute', 'DataType' => 'DataTypes.DataType', ]); - $userAttributes = $this->UserAttribute->getUserAttributesForLayout(true); + $userAttributes = $this->UserAttribute->getUserAttributesForLayout($force); $this->userAttributeData = Hash::combine($userAttributes, '{n}.{n}.{n}.UserAttribute.id', '{n}.{n}.{n}' ); @@ -425,6 +431,8 @@ public function createUser() { * @return array */ public function getUser($userId, $languageId = null) { + $this->prepare(); + $user = $this->find('first', array( 'recursive' => 0, 'conditions' => array( @@ -462,6 +470,7 @@ public function getUser($userId, $languageId = null) { public function saveUser($data) { //トランザクションBegin $this->begin(); + $this->prepare(); //プライベートルームの登録 $this->loadModels([ @@ -472,6 +481,21 @@ public function saveUser($data) { $currentRoom = Current::read('Room'); Current::$current['Room'] = null; + $beforeUser = $this->find('first', array( + 'recursive' => -1, + 'conditions' => array( + $this->alias . '.id' => Hash::get($data, 'User.id') + ), + )); + + if (Hash::get($data, 'User.' . User::$avatarField . '.remove')) { + $data['User']['is_avatar_auto_created'] = true; + } elseif (Hash::get($data, 'User.' . User::$avatarField . '.name')) { + $data['User']['is_avatar_auto_created'] = false; + } else { + $data['User']['is_avatar_auto_created'] = (bool)Hash::get($beforeUser, 'User.is_avatar_auto_created', true); + } + //バリデーション $this->set($data); if (! $this->validates()) { @@ -484,6 +508,23 @@ public function saveUser($data) { throw new InternalErrorException(__d('net_commons', 'Internal Server Error')); } + if ($this->Behaviors->hasMethod('createAvatarAutomatically')) { + //下記の条件の場合、自動的にアバターを生成する + // * 削除がチェックONになっている || + // * アップロードファイルがない && + // アバターを自動生成する場合 && + // ハンドルを登録(POSTに含まれている)する場合 && + // 登録前のハンドル名と登録後のハンドル名が異なる場合 + if ($this->validAvatarAutomatically($data, $user, $beforeUser)) { + $filePath = $this->createAvatarAutomatically($user); + + $currentDir = getcwd(); + chdir(APP . WEBROOT_DIR); + $this->attachFile($user, User::$avatarField, $filePath, 'id'); + chdir($currentDir); + } + } + //トランザクションCommit $this->commit(); @@ -507,6 +548,7 @@ public function saveUser($data) { public function deleteUser($data) { //トランザクションBegin $this->begin(); + $this->prepare(); try { //Userデータの削除->論理削除 @@ -545,6 +587,7 @@ public function importUsers($filePath) { App::uses('CsvFileReader', 'Files.Utility'); //$this->begin(); + $this->prepare(true); $reader = new CsvFileReader($filePath); foreach ($reader as $i => $row) { diff --git a/Model/UserSelectCount.php b/Model/UserSelectCount.php index 81bef72..51e7fda 100644 --- a/Model/UserSelectCount.php +++ b/Model/UserSelectCount.php @@ -26,7 +26,7 @@ class UserSelectCount extends UsersAppModel { * * @var const */ - const LIMIT = 30; + const LIMIT = 50; /** * Validation rules @@ -217,7 +217,7 @@ public function getUsers($roomId) { ), ), ), - 'order' => array($this->alias . '.select_count' => 'desc'), + 'order' => array($this->alias . '.select_count' => 'desc', $this->alias . '.modified' => 'desc'), 'limit' => self::LIMIT, )); return $users; diff --git a/Test/Fixture/UserFixture.php b/Test/Fixture/UserFixture.php index f11bac0..003d2ab 100644 --- a/Test/Fixture/UserFixture.php +++ b/Test/Fixture/UserFixture.php @@ -24,25 +24,28 @@ class UserFixture extends CakeTestFixture { */ public $fields = array( 'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'unsigned' => false, 'key' => 'primary'), - 'username' => array('type' => 'string', 'null' => true, 'default' => null, 'collate' => 'utf8_general_ci', 'charset' => 'utf8', 'comment' => 'ID | ログインID'), - 'password' => array('type' => 'string', 'null' => true, 'default' => null, 'collate' => 'utf8_general_ci', 'charset' => 'utf8', 'comment' => 'Password | パスワード'), - 'key' => array('type' => 'string', 'null' => true, 'default' => null, 'collate' => 'utf8_general_ci', 'charset' => 'utf8', 'comment' => 'Link identifier | リンク識別子'), + 'username' => array('type' => 'string', 'null' => true, 'default' => null, 'collate' => 'utf8_general_ci', 'comment' => 'ID | ログインID', 'charset' => 'utf8'), + 'password' => array('type' => 'string', 'null' => true, 'default' => null, 'collate' => 'utf8_general_ci', 'comment' => 'Password | パスワード', 'charset' => 'utf8'), + 'key' => array('type' => 'string', 'null' => true, 'default' => null, 'collate' => 'utf8_general_ci', 'comment' => 'Link identifier | リンク識別子', 'charset' => 'utf8'), 'is_deleted' => array('type' => 'boolean', 'null' => false, 'default' => '0'), 'is_avatar_public' => array('type' => 'boolean', 'null' => false, 'default' => '0'), - 'handlename' => array('type' => 'string', 'null' => true, 'default' => null, 'collate' => 'utf8_general_ci', 'charset' => 'utf8', 'comment' => 'Handle | ハンドル'), + 'is_avatar_auto_created' => array('type' => 'boolean', 'null' => false, 'default' => '1'), + 'handlename' => array('type' => 'string', 'null' => true, 'default' => null, 'collate' => 'utf8_general_ci', 'comment' => 'Handle | ハンドル', 'charset' => 'utf8'), 'is_handlename_public' => array('type' => 'boolean', 'null' => false, 'default' => '0'), 'is_name_public' => array('type' => 'boolean', 'null' => false, 'default' => '0'), - 'email' => array('type' => 'string', 'null' => true, 'default' => null, 'collate' => 'utf8_general_ci', 'charset' => 'utf8', 'comment' => 'E-mail | eメール'), + 'email' => array('type' => 'string', 'null' => true, 'default' => null, 'collate' => 'utf8_general_ci', 'comment' => 'E-mail | eメール', 'charset' => 'utf8'), 'is_email_public' => array('type' => 'boolean', 'null' => false, 'default' => '0'), - 'moblie_mail' => array('type' => 'string', 'null' => true, 'default' => null, 'collate' => 'utf8_general_ci', 'charset' => 'utf8', 'comment' => 'Mobile mail | 携帯メール'), + 'is_email_reception' => array('type' => 'boolean', 'null' => false, 'default' => '0'), + 'moblie_mail' => array('type' => 'string', 'null' => true, 'default' => null, 'collate' => 'utf8_general_ci', 'comment' => 'Mobile mail | 携帯メール', 'charset' => 'utf8'), 'is_moblie_mail_public' => array('type' => 'boolean', 'null' => false, 'default' => '0'), - 'sex' => array('type' => 'string', 'null' => true, 'default' => null, 'collate' => 'utf8_general_ci', 'charset' => 'utf8', 'comment' => 'Sex | 性別'), + 'is_moblie_mail_reception' => array('type' => 'boolean', 'null' => false, 'default' => '0'), + 'sex' => array('type' => 'string', 'null' => true, 'default' => null, 'collate' => 'utf8_general_ci', 'comment' => 'Sex | 性別', 'charset' => 'utf8'), 'is_sex_public' => array('type' => 'boolean', 'null' => false, 'default' => '0'), - 'timezone' => array('type' => 'string', 'null' => true, 'default' => null, 'collate' => 'utf8_general_ci', 'charset' => 'utf8', 'comment' => 'TimeZone | タイムゾーン'), + 'timezone' => array('type' => 'string', 'null' => true, 'default' => null, 'collate' => 'utf8_general_ci', 'comment' => 'TimeZone | タイムゾーン', 'charset' => 'utf8'), 'is_timezone_public' => array('type' => 'boolean', 'null' => false, 'default' => '0'), - 'role_key' => array('type' => 'string', 'null' => false, 'default' => null, 'collate' => 'utf8_general_ci', 'charset' => 'utf8', 'comment' => 'Authority | 権限'), + 'role_key' => array('type' => 'string', 'null' => false, 'default' => null, 'collate' => 'utf8_general_ci', 'comment' => 'Authority | 権限', 'charset' => 'utf8'), 'is_role_key_public' => array('type' => 'boolean', 'null' => false, 'default' => '0'), - 'status' => array('type' => 'string', 'null' => true, 'default' => null, 'collate' => 'utf8_general_ci', 'charset' => 'utf8', 'comment' => 'Status | 状態'), + 'status' => array('type' => 'string', 'null' => true, 'default' => null, 'collate' => 'utf8_general_ci', 'comment' => 'Status | 状態', 'charset' => 'utf8'), 'is_status_public' => array('type' => 'boolean', 'null' => false, 'default' => '0'), 'created' => array('type' => 'datetime', 'null' => true, 'default' => null, 'comment' => 'Created | 作成日時'), 'is_created_public' => array('type' => 'boolean', 'null' => false, 'default' => '0'), @@ -56,12 +59,14 @@ class UserFixture extends CakeTestFixture { 'is_password_modified_public' => array('type' => 'boolean', 'null' => false, 'default' => '0'), 'last_login' => array('type' => 'datetime', 'null' => true, 'default' => null, 'comment' => 'Last login | 最終ログイン日時'), 'is_last_login_public' => array('type' => 'boolean', 'null' => false, 'default' => '0'), + 'previous_login' => array('type' => 'datetime', 'null' => true, 'default' => null, 'comment' => 'PreLast login | 前回ログイン日時'), + 'is_previous_login_public' => array('type' => 'boolean', 'null' => false, 'default' => '0'), 'is_profile_public' => array('type' => 'boolean', 'null' => false, 'default' => '0'), 'is_search_keywords_public' => array('type' => 'boolean', 'null' => false, 'default' => '0'), 'indexes' => array( - 'PRIMARY' => array('column' => 'id', 'unique' => 1), + 'PRIMARY' => array('column' => 'id', 'unique' => 1) ), - 'tableParameters' => array('charset' => 'utf8', 'collate' => 'utf8_general_ci', 'engine' => 'InnoDB'), + 'tableParameters' => array('charset' => 'utf8', 'collate' => 'utf8_general_ci', 'engine' => 'InnoDB') ); /** diff --git a/View/Elements/Users/delete_form.ctp b/View/Elements/Users/delete_form.ctp index e48d210..dfac483 100644 --- a/View/Elements/Users/delete_form.ctp +++ b/View/Elements/Users/delete_form.ctp @@ -1,11 +1,6 @@ create() + * 会員削除テンプレート * * @author Noriko Arai * @author Shohei Nakajima diff --git a/View/Elements/Users/select_users.ctp b/View/Elements/Users/select_users.ctp index 568ab9f..cd10ce9 100644 --- a/View/Elements/Users/select_users.ctp +++ b/View/Elements/Users/select_users.ctp @@ -10,7 +10,6 @@ */ ?> -
diff --git a/View/Helper/UserEditFormHelper.php b/View/Helper/UserEditFormHelper.php index 951a31c..0f868b8 100644 --- a/View/Helper/UserEditFormHelper.php +++ b/View/Helper/UserEditFormHelper.php @@ -109,8 +109,12 @@ public function userInput($userAttribute) { public function userInputForSelf($userAttribute) { $html = ''; - if ($userAttribute['UserAttributeSetting']['only_administrator'] || - Current::read('User.id') !== $this->_View->viewVars['user']['User']['id'] || + //以下の条件の場合、何も表示しない + // * 「本人も書けない(管理者のみ書ける)」項目の場合 + // * 他人の場合 + // * 「自分自身が読めない」の場合 + // * 「自分自身が書けない」の場合 + if (Current::read('User.id') !== $this->_View->viewVars['user']['User']['id'] || ! $userAttribute['UserAttributesRole']['self_readable'] || ! $userAttribute['UserAttributesRole']['self_editable']) { @@ -131,7 +135,7 @@ public function userInputForSelf($userAttribute) { public function userPublicForSelf($userAttribute) { $html = ''; - if (! $userAttribute['UserAttributeSetting']['self_publicity'] || + if (! $userAttribute['UserAttributeSetting']['self_public_setting'] || Current::read('User.id') !== Hash::get($this->_View->viewVars, 'user.User.id') || ! $userAttribute['UserAttributesRole']['self_readable'] || ! $userAttribute['UserAttributesRole']['self_editable']) { @@ -160,7 +164,7 @@ public function userMailReceptionForSelf($userAttribute) { $html = ''; if ($userAttribute['UserAttributeSetting']['data_type_key'] !== DataType::DATA_TYPE_EMAIL || - ! $userAttribute['UserAttributeSetting']['self_email_reception_possibility'] || + ! $userAttribute['UserAttributeSetting']['self_email_setting'] || Current::read('User.id') !== Hash::get($this->_View->viewVars, 'user.User.id') || ! $userAttribute['UserAttributesRole']['self_readable'] || ! $userAttribute['UserAttributesRole']['self_editable']) { diff --git a/View/Helper/UserLayoutHelper.php b/View/Helper/UserLayoutHelper.php index 528a8c7..24c2a7b 100644 --- a/View/Helper/UserLayoutHelper.php +++ b/View/Helper/UserLayoutHelper.php @@ -191,11 +191,15 @@ public function userElement($fieldName, $userAttribute) { * @return bool 表示有無 */ public function isDisplayable($userAttribute) { + //表示しない条件 + // * 非表示項目の場合 + // * パスワード項目 + // * 他人の項目が読めない && 他人 + // * 本人の項目が読めない && 本人 if (! $userAttribute['UserAttributeSetting']['display'] || $userAttribute['UserAttributeSetting']['data_type_key'] === DataType::DATA_TYPE_PASSWORD || (! $userAttribute['UserAttributesRole']['other_readable'] && Current::read('User.id') !== $this->_View->viewVars['user']['User']['id']) || - (! $userAttribute['UserAttributesRole']['self_readable'] && Current::read('User.id') === $this->_View->viewVars['user']['User']['id']) || - $userAttribute['UserAttributeSetting']['only_administrator'] && ! Current::allowSystemPlugin('user_manager')) { + (! $userAttribute['UserAttributesRole']['self_readable'] && Current::read('User.id') === $this->_View->viewVars['user']['User']['id'])) { return false; } else { diff --git a/View/Helper/UserSearchHelper.php b/View/Helper/UserSearchHelper.php index d480c5e..7d62af2 100644 --- a/View/Helper/UserSearchHelper.php +++ b/View/Helper/UserSearchHelper.php @@ -97,7 +97,7 @@ public function tableRow($user, $isEdit) { } if ($modelName) { - $output .= $this->tableCell($user, $modelName, $fieldName, $isEdit); + $output .= $this->tableCell($user, $modelName, $fieldName, $isEdit, true); } else { $output .= ''; } @@ -113,43 +113,51 @@ public function tableRow($user, $isEdit) { * @param string $modelName モデル名 * @param string $fieldName 表示フィールド * @param bool $isEdit 編集の有無 + * @param bool $tdElement tdタグの出力 * @return string セルのHTMLタグ */ - public function tableCell($user, $modelName, $fieldName, $isEdit) { + public function tableCell($user, $modelName, $fieldName, $isEdit, $tdElement) { $userAttribute = Hash::get($this->userAttributes, $fieldName); $value = ''; if ($fieldName === 'handlename') { - $value = $this->linkHandlename($user, $modelName, $fieldName, $isEdit); + //ハンドル + $value = $this->linkHandlename($user, $isEdit); } elseif ($fieldName === 'room_role_key') { + //ルーム権限 $value = $this->Rooms->roomRoleName($user[$modelName]['role_key']); } elseif (isset($userAttribute['UserAttributeChoice']) && $user[$modelName][$fieldName]) { + //選択肢 if ($fieldName === 'role_key') { $values = Hash::extract($userAttribute['UserAttributeChoice'], '{n}[key=' . $user[$modelName][$fieldName] . ']'); } else { $values = Hash::extract($userAttribute['UserAttributeChoice'], '{n}[code=' . $user[$modelName][$fieldName] . ']'); } - $value = h($values[0]['name']); + $value = h(Hash::get($values, '0.name')); } elseif ($userAttribute['UserAttributeSetting']['data_type_key'] === DataType::DATA_TYPE_DATETIME || in_array($userAttribute['UserAttribute']['key'], UserAttribute::$typeDatetime, true)) { + //日付型 $value = h($this->Date->dateFormat($user[$modelName][$fieldName])); } else { + //その他 $value = h($user[$modelName][$fieldName]); } - return '' . $value . ''; + if ($tdElement) { + return '' . $value . ''; + } else { + return $value; + } } /** * ハンドルの出力 * * @param array $user ユーザデータ - * @param string $modelName モデル名 - * @param string $fieldName 表示フィールド * @param bool $isEdit 編集の有無 * @return string ハンドルのHTMLタグ */ - public function linkHandlename($user, $modelName, $fieldName, $isEdit) { + public function linkHandlename($user, $isEdit) { if (! $isEdit) { return $this->DisplayUser->handleLink($user, array('avatar' => true), array(), 'User'); } elseif (Current::read('User.role_key') === UserRole::USER_ROLE_KEY_SYSTEM_ADMINISTRATOR || @@ -159,6 +167,8 @@ public function linkHandlename($user, $modelName, $fieldName, $isEdit) { array('plugin' => 'user_manager', 'controller' => 'user_manager', 'action' => 'edit', $user['User']['id']), array('escape' => false) ); + } else { + return $this->DisplayUser->handle($user, array('avatar' => true), 'User'); } } diff --git a/View/Users/select.ctp b/View/Users/select.ctp index 77681d9..d06f2a4 100644 --- a/View/Users/select.ctp +++ b/View/Users/select.ctp @@ -59,37 +59,19 @@ $data += $tokens; end(); ?>
-
-
+
+ +
+ +
+
+ +
+
element('Users/select_users', array('userType' => 'searchResults')); ?>
-
- -
-
-
diff --git a/webroot/fonts/ipag.ttf b/webroot/fonts/ipag.ttf new file mode 100644 index 0000000..1eff0cf Binary files /dev/null and b/webroot/fonts/ipag.ttf differ