From 7d3f8ebf955f8b5b061af721a925e6d0e57147e6 Mon Sep 17 00:00:00 2001 From: Kevin Day Date: Mon, 4 Sep 2017 06:17:22 -0500 Subject: [PATCH] Progress: User Profile / User View Page The profile images should be file ids and not byteas. - These columns should also be foreign keys to the file table. Enable use of profile image in the user object. Update/Fix the Japanese related translations. The User Profile / User View page is intended to be a simpler version of the User Settings page with a focus on user information and less focus on user settings values. --- common/base/classes/base_users.php | 123 ++++++++++++++++++ common/standard/classes/standard_users.php | 27 +++- common/standard/paths/u/ja/user_settings.php | 181 +++++++++++++++++++++++--- common/standard/paths/u/ja/user_view.php | 185 +-------------------------- common/standard/paths/u/user_settings.php | 1 + common/standard/paths/u/user_view.php | 151 +++++++++++++++++++--- database/sql/standard/standard-files.sql | 4 + database/sql/standard/standard-users.sql | 6 +- 8 files changed, 460 insertions(+), 218 deletions(-) diff --git a/common/base/classes/base_users.php b/common/base/classes/base_users.php index 36ad702..31d9bc7 100644 --- a/common/base/classes/base_users.php +++ b/common/base/classes/base_users.php @@ -35,6 +35,10 @@ class c_base_users_user extends c_base_return_array { protected $date_locked; protected $date_deleted; + protected $image_original; + protected $image_cropped; + protected $image_icon; + /** * Class constructor. */ @@ -62,6 +66,10 @@ class c_base_users_user extends c_base_return_array { $this->date_synced = NULL; $this->date_locked = NULL; $this->date_deleted = NULL; + + $this->image_original = NULL; + $this->image_cropped = NULL; + $this->image_icon = NULL; } /** @@ -90,6 +98,10 @@ class c_base_users_user extends c_base_return_array { unset($this->date_locked); unset($this->date_deleted); + unset($this->image_original); + unset($this->image_cropped); + unset($this->image_icon); + parent::__destruct(); } @@ -344,6 +356,69 @@ class c_base_users_user extends c_base_return_array { } /** + * Set the original image. + * + * @param int|null $image_original + * The numeric id representing the image in the database. + * Set to NULL to remove the image. + * + * @return c_base_return_status + * TRUE on success. + * FALSE with error bit set is returned on error. + */ + public function set_image_original($image_original) { + if (!is_int($image_original) && !is_null($image_original)) { + $error = c_base_error::s_log(NULL, array('arguments' => array(':{argument_name}' => 'image_original', ':{function_name}' => __CLASS__ . '->' . __FUNCTION__)), i_base_error_messages::INVALID_ARGUMENT); + return c_base_return_error::s_false($error); + } + + $this->image_original = $image_original; + return new c_base_return_true(); + } + + /** + * Set the cropped image. + * + * @param int|null $image_cropped + * The numeric id representing the image in the database. + * Set to NULL to remove the image. + * + * @return c_base_return_status + * TRUE on success. + * FALSE with error bit set is returned on error. + */ + public function set_image_cropped($image_cropped) { + if (!is_int($image_cropped) && !is_null($image_cropped)) { + $error = c_base_error::s_log(NULL, array('arguments' => array(':{argument_name}' => 'image_cropped', ':{function_name}' => __CLASS__ . '->' . __FUNCTION__)), i_base_error_messages::INVALID_ARGUMENT); + return c_base_return_error::s_false($error); + } + + $this->image_cropped = $image_cropped; + return new c_base_return_true(); + } + + /** + * Set the icon image. + * + * @param int|null $image_icon + * The numeric id representing the image in the database. + * Set to NULL to remove the image. + * + * @return c_base_return_status + * TRUE on success. + * FALSE with error bit set is returned on error. + */ + public function set_image_icon($image_icon) { + if (!is_int($image_icon) && !is_null($image_icon)) { + $error = c_base_error::s_log(NULL, array('arguments' => array(':{argument_name}' => 'image_icon', ':{function_name}' => __CLASS__ . '->' . __FUNCTION__)), i_base_error_messages::INVALID_ARGUMENT); + return c_base_return_error::s_false($error); + } + + $this->image_icon = $image_icon; + return new c_base_return_true(); + } + + /** * Get the currently assigned user id. * * @return c_base_return_int @@ -552,6 +627,54 @@ class c_base_users_user extends c_base_return_array { } /** + * Get the currently assigned original image. + * + * @return c_base_return_null|c_base_return_int + * Image ID on success. + * NULL without error bit is returned if not defined. + * NULL with error bit set is returned on error. + */ + public function get_image_original() { + if (is_null($this->image_original)) { + return new c_base_return_null(); + } + + return c_base_return_int::s_new($this->image_original); + } + + /** + * Get the currently assigned cropped image. + * + * @return c_base_return_null|c_base_return_int + * Image ID on success. + * NULL without error bit is returned if not defined. + * NULL with error bit set is returned on error. + */ + public function get_image_cropped() { + if (is_null($this->image_cropped)) { + return new c_base_return_null(); + } + + return c_base_return_int::s_new($this->image_cropped); + } + + /** + * Get the currently assigned icon image. + * + * @return c_base_return_null|c_base_return_int + * Image ID on success. + * NULL without error bit is returned if not defined. + * NULL with error bit set is returned on error. + */ + public function get_image_icon() { + if (is_null($this->image_icon)) { + return new c_base_return_null(); + } + + return c_base_return_int::s_new($this->image_icon); + } + + /** * Get the is private setting. * * @param bool|null $is_private diff --git a/common/standard/classes/standard_users.php b/common/standard/classes/standard_users.php index 39aea64..e4d549d 100644 --- a/common/standard/classes/standard_users.php +++ b/common/standard/classes/standard_users.php @@ -69,7 +69,7 @@ class c_standard_users_user extends c_base_users_user { return c_base_return_error::s_false($error); } - $query_string = 'select id, id_external, id_sort, name_machine, name_human, address_email, is_public, is_system, is_requester, is_drafter, is_editor, is_reviewer, is_insurer, is_financer, is_publisher, is_auditor, is_manager, is_administer, is_private, is_locked, is_deleted, is_roler, date_created, date_changed, date_synced, date_locked, date_deleted, settings '; + $query_string = 'select id, id_external, id_sort, name_machine, name_human, address_email, is_public, is_system, is_requester, is_drafter, is_editor, is_reviewer, is_insurer, is_financer, is_publisher, is_auditor, is_manager, is_administer, is_private, is_locked, is_deleted, is_roler, date_created, date_changed, date_synced, date_locked, date_deleted, image_original, image_cropped, image_icon, settings '; $query_arguments = array(); if (is_null($user_name_or_id)) { @@ -272,8 +272,29 @@ class c_standard_users_user extends c_base_users_user { $this->date_locked = c_base_defaults_global::s_get_timestamp($columns[25], c_base_database::STANDARD_TIMESTAMP_FORMAT)->get_value_exact(); $this->date_deleted = c_base_defaults_global::s_get_timestamp($columns[26], c_base_database::STANDARD_TIMESTAMP_FORMAT)->get_value_exact(); - if (isset($columns[27])) { - $this->settings = json_decode($columns[27], TRUE); + if (is_null($columns[27])) { + $this->image_original = NULL; + } + else { + $this->image_original = (int) $columns[27]; + } + + if (is_null($columns[28])) { + $this->image_cropped = NULL; + } + else { + $this->image_cropped = (int) $columns[28]; + } + + if (is_null($columns[29])) { + $this->image_icon = NULL; + } + else { + $this->image_icon = (int) $columns[29]; + } + + if (isset($columns[30])) { + $this->settings = json_decode($columns[30], TRUE); } else { $this->settings = array(); diff --git a/common/standard/paths/u/ja/user_settings.php b/common/standard/paths/u/ja/user_settings.php index 22a80dd..5d161e2 100644 --- a/common/standard/paths/u/ja/user_settings.php +++ b/common/standard/paths/u/ja/user_settings.php @@ -16,52 +16,201 @@ class c_standard_path_user_dashboard_ja extends c_standard_path_user_dashboard { $string = ''; switch ($code) { case 0: - $string = 'ダッシュボード'; + if (array_key_exists(':{user_name}', $arguments)) { + $string = 'ユーザー設定:{user_name}'; + } + else { + $string = 'ユーザー設定'; + } break; case 1: - $string = ''; + $string = 'パブリック'; break; case 2: - $string = ''; + $string = 'システム'; break; case 3: - $string = ''; + $string = 'ユーザー'; break; case 4: - $string = 'パブリック'; + $string = 'リクエスタ'; break; case 5: - $string = 'ユーザー'; + $string = 'ドレイター'; break; case 6: - $string = 'リクエスタ'; + $string = '編集者'; break; case 7: - $string = 'ドレイター'; + $string = 'レビューア'; break; case 8: - $string = '編集者'; + $string = 'ファイナンサー'; break; case 9: - $string = 'レビューア'; + $string = '保険会社'; break; case 10: - $string = 'ファイナンサー'; + $string = '出版社'; break; case 11: - $string = '保険会社'; + $string = '審査員'; break; case 12: - $string = '出版社'; + $string = 'マネージャー'; break; case 13: - $string = '審査員'; + $string = '管理者'; break; case 14: - $string = 'マネージャー'; + $string = '口座情報'; break; case 15: - $string = '管理者'; + $string = '個人情報'; + break; + case 16: + $string = 'アクセス情報'; + break; + case 17: + $string = '履歴情報'; + break; + case 18: + $string = '身元'; + break; + case 19: + $string = '外部身元'; + break; + case 20: + $string = '名'; + break; + case 21: + $string = 'Eメール'; + break; + case 22: + $string = 'ロール'; + break; + case 23: + $string = 'ロールマネージャ'; + break; + case 24: + $string = 'ロックされている'; + break; + case 25: + $string = '削除されました'; + break; + case 26: + $string = 'パブリックです'; + break; + case 27: + $string = 'プライベートです'; + break; + case 28: + $string = '作成日'; + break; + case 29: + $string = '日付変更'; + break; + case 30: + $string = '日付同期'; + break; + case 31: + $string = 'ロックされた日付'; + break; + case 32: + $string = '削除された日付'; + break; + case 33: + $string = 'はい'; + break; + case 34: + $string = 'いいえ'; + break; + case 35: + $string = '有効'; + break; + case 36: + $string = '無効'; + break; + case 37: + $string = '接頭辞'; + break; + case 38: + $string = '最初'; + break; + case 39: + $string = '中間'; + break; + case 40: + $string = '最終'; + break; + case 41: + $string = 'サフィックス'; + break; + case 42: + $string = 'フル'; + break; + case 43: + $string = '未公開'; + break; + case 44: + $string = 'ユーザーID'; + break; + case 45: + $string = 'タイトル'; + break; + case 46: + $string = 'タイプ'; + break; + case 47: + $string = 'サブタイプ'; + break; + case 48: + $string = '重大度'; + break; + case 49: + $string = '施設'; + break; + case 50: + $string = '詳細'; + break; + case 51: + $string = '日付'; + break; + case 52: + $string = 'クライアント'; + break; + case 53: + $string = 'レスポンスコード'; + break; + case 54: + $string = 'セッションユーザーID'; + break; + case 55: + $string = 'リクエストパス'; + break; + case 56: + $string = '引数を要求する'; + break; + case 57: + $string = 'リクエストクライアント'; + break; + case 58: + $string = 'リクエスト日'; + break; + case 59: + $string = 'リクエストヘッダー'; + break; + case 60: + $string = '応答ヘッダー'; + break; + case 61: + $string = 'レスポンスコード'; + break; + case 62: + $string = 'ユーザー履歴'; + break; + case 63: + $string = 'アクセス履歴'; break; default: unset($string); diff --git a/common/standard/paths/u/ja/user_view.php b/common/standard/paths/u/ja/user_view.php index ae49289..c28f6b9 100644 --- a/common/standard/paths/u/ja/user_view.php +++ b/common/standard/paths/u/ja/user_view.php @@ -30,193 +30,16 @@ class c_standard_path_user_view_ja extends c_standard_path_user_view { } break; case 1: - $string = 'パブリック'; + $string = '画像'; break; case 2: - $string = 'システム'; + $string = 'ユーザー情報'; break; case 3: - $string = 'ユーザー'; + $string = '画像がありません'; break; case 4: - $string = 'リクエスタ'; - break; - case 5: - $string = 'ドレイター'; - break; - case 6: - $string = '編集者'; - break; - case 7: - $string = 'レビューア'; - break; - case 8: - $string = 'ファイナンサー'; - break; - case 9: - $string = '保険会社'; - break; - case 10: - $string = '出版社'; - break; - case 11: - $string = '審査員'; - break; - case 12: - $string = 'マネージャー'; - break; - case 13: - $string = '管理者'; - break; - case 14: - $string = '口座情報'; - break; - case 15: - $string = '個人情報'; - break; - case 16: - $string = 'アクセス情報'; - break; - case 17: - $string = '履歴情報'; - break; - case 18: - $string = '身元'; - break; - case 19: - $string = '外部身元'; - break; - case 20: - $string = '名'; - break; - case 21: - $string = 'Eメール'; - break; - case 22: - $string = 'ロール'; - break; - case 23: - $string = 'ロールマネージャ'; - break; - case 24: - $string = 'ロックされている'; - break; - case 25: - $string = '削除されました'; - break; - case 26: - $string = 'パブリックです'; - break; - case 27: - $string = 'プライベートです'; - break; - case 28: - $string = '作成日'; - break; - case 29: - $string = '日付変更'; - break; - case 30: - $string = '日付同期'; - break; - case 31: - $string = 'ロックされた日付'; - break; - case 32: - $string = '削除された日付'; - break; - case 33: - $string = 'はい'; - break; - case 34: - $string = 'いいえ'; - break; - case 35: - $string = '有効'; - break; - case 36: - $string = '無効'; - break; - case 37: - $string = '接頭辞'; - break; - case 38: - $string = '最初'; - break; - case 39: - $string = '中間'; - break; - case 40: - $string = '最終'; - break; - case 41: - $string = 'サフィックス'; - break; - case 42: - $string = 'フル'; - break; - case 43: - $string = '未公開'; - break; - case 44: - $string = 'ユーザーID'; - break; - case 45: - $string = 'タイトル'; - break; - case 46: - $string = 'タイプ'; - break; - case 47: - $string = 'サブタイプ'; - break; - case 48: - $string = '重大度'; - break; - case 49: - $string = '施設'; - break; - case 50: - $string = '詳細'; - break; - case 51: - $string = '日付'; - break; - case 52: - $string = 'クライアント'; - break; - case 53: - $string = 'レスポンスコード'; - break; - case 54: - $string = 'セッションユーザーID'; - break; - case 55: - $string = 'リクエストパス'; - break; - case 56: - $string = '引数を要求する'; - break; - case 57: - $string = 'リクエストクライアント'; - break; - case 58: - $string = 'リクエスト日'; - break; - case 59: - $string = 'リクエストヘッダー'; - break; - case 60: - $string = '応答ヘッダー'; - break; - case 61: - $string = 'レスポンスコード'; - break; - case 62: - $string = 'ユーザー履歴'; - break; - case 63: - $string = 'アクセス履歴'; + $string = 'プロフィールの写真'; break; default: unset($string); diff --git a/common/standard/paths/u/user_settings.php b/common/standard/paths/u/user_settings.php index 96e7db9..ffd98e5 100644 --- a/common/standard/paths/u/user_settings.php +++ b/common/standard/paths/u/user_settings.php @@ -25,6 +25,7 @@ class c_standard_path_user_settings extends c_standard_path_user { protected const NAME_MENU_CONTENT = 'menu_content_user_view'; protected const HANDLER_MENU_CONTENT = 'c_standard_menu_content_user_view'; + protected const CLASS_USER_SETTINGS_ACCOUNT = 'user_settings-account'; protected const CLASS_USER_SETTINGS_PERSONAL = 'user_settings-personal'; protected const CLASS_USER_SETTINGS_ACCESS = 'user_settings-access'; diff --git a/common/standard/paths/u/user_view.php b/common/standard/paths/u/user_view.php index a17dea8..ffb5a0a 100644 --- a/common/standard/paths/u/user_view.php +++ b/common/standard/paths/u/user_view.php @@ -25,6 +25,12 @@ class c_standard_path_user_view extends c_standard_path_user { protected const NAME_MENU_CONTENT = 'menu_content_user_view'; protected const HANDLER_MENU_CONTENT = 'c_standard_menu_content_user_view'; + protected const CLASS_USER_VIEW_IMAGE = 'user_view-image'; + protected const CLASS_USER_VIEW_INFORMATION = 'user_view-information'; + + protected const IMAGE_CROPPED_HEIGHT = '192'; + protected const IMAGE_CROPPED_WIDTH = '192'; + /** * Implements do_execute(). */ @@ -49,21 +55,7 @@ class c_standard_path_user_view extends c_standard_path_user { return $executed; } - // @todo: this function needs to check to see if the user has administer (or manager?) roles (c_base_roles::MANAGER, c_base_roles::ADMINISTER) and if they do, set administrative to TRUE when calling do_load(). - #$user = $this->session->get_user_current(); - #$roles_current = $user->get_roles()->get_value_exact(); - - $wrapper = $this->pr_create_tag_section(array(1 => 0)); - - // initialize the content as HTML. - $this->pr_create_html(); - $this->html->set_tag($wrapper); - unset($wrapper); - - $this->pr_add_menus(); - - $executed->set_output($this->html); - unset($this->html); + $this->pr_do_execute_view($executed); return $executed; } @@ -104,6 +96,18 @@ class c_standard_path_user_view extends c_standard_path_user { $string = 'View User'; } break; + case 1: + $string = 'Picture'; + break; + case 2: + $string = 'User Information'; + break; + case 3: + $string = 'No Image Available'; + break; + case 4: + $string = 'Profile Picture'; + break; } if (!empty($arguments)) { @@ -112,4 +116,121 @@ class c_standard_path_user_view extends c_standard_path_user { return $string; } + + /** + * Execution of the view path. + * + * @param c_base_path_executed &$executed + * The execution results to be returned. + * + * @return null|array + * NULL is returned if no errors are found. + * An array of errors are returned if found. + */ + protected function pr_do_execute_view(&$executed) { + $errors = NULL; + + $arguments = array(); + $arguments[':{user_name}'] = $this->path_user->get_name_human()->get_first()->get_value_exact() . ' ' . $this->path_user->get_name_human()->get_last()->get_value_exact(); + if (mb_strlen($arguments[':{user_name}']) == 0) { + unset($arguments[':{user_name}']); + } + + $roles_current = $this->session->get_user_current()->get_roles()->get_value_exact(); + $is_private = $this->path_user->is_private()->get_value_exact(); + + $full_view_access = FALSE; + if ($this->path_user_id === $this->session->get_user_current()->get_id()->get_value_exact()) { + $full_view_access = TRUE; + } + elseif (isset($roles_current[c_base_roles::MANAGER]) || isset($roles_current[c_base_roles::ADMINISTER])) { + $full_view_access = TRUE; + } + unset($roles_current); + + + // do not show pages for private users. + if ($is_private && !$full_view_access) { + unset($is_private); + unset($full_view_access); + + $error = c_base_error::s_log(NULL, array('arguments' => array(':{path_name}' => static::PATH_SELF . '/' . implode('/', $this->arguments), ':{function_name}' => __CLASS__ . '->' . __FUNCTION__)), i_base_error_messages::NOT_FOUND_PATH); + $executed->set_error($error); + unset($error); + + return $executed; + } + + + // initialize the content as HTML. + $this->pr_create_html(TRUE, $arguments); + + if (is_int($this->path_user_id)) { + $text_id_user = $this->pr_create_tag_text('[id: ' . $this->path_user_id . ']', array(), NULL, static::CLASS_ID_USER); + $wrapper = $this->pr_create_tag_section(array(1 => array('text' => 0, 'append-inside' => $text_id_user)), $arguments); + unset($text_id_user); + } + else { + $wrapper = $this->pr_create_tag_section(array(1 => 0), $arguments); + } + + $this->html->set_tag($wrapper); + unset($wrapper); + unset($arguments); + + + // profile picture + $fieldset = $this->pr_create_tag_fieldset(1, array(), static::CLASS_USER_VIEW_IMAGE, static::CLASS_USER_VIEW_IMAGE); + + $content = c_theme_html::s_create_tag(c_base_markup_tag::TYPE_DIVIDER, static::CSS_AS_FIELD_SET_CONTENT, array(static::CSS_AS_FIELD_SET_CONTENT)); + + $image = $this->path_user->get_image_cropped()->get_value(); + if (is_int($image)) { + // @todo: image file paths should be stored as constants in a base or standard class, such as 'f' and 'i' for the '/f/i/' uri. + $tag = c_theme_html::s_create_tag(c_base_markup_tag::TYPE_IMAGE); + $tag->set_attribute(c_base_markup_attributes::ATTRIBUTE_SOURCE, $this->settings['base_path'] . 'f/i/' . $image); + $tag->set_attribute(c_base_markup_attributes::ATTRIBUTE_WIDTH, self::IMAGE_CROPPED_WIDTH); + $tag->set_attribute(c_base_markup_attributes::ATTRIBUTE_HEIGHT, self::IMAGE_CROPPED_HEIGHT); + $tag->set_attribute(c_base_markup_attributes::ATTRIBUTE_ALTERNATE, $this->pr_get_text(4)); + $content->set_tag($tag); + unset($tag); + } + else { + $tag = c_theme_html::s_create_tag_text(c_base_markup_tag::TYPE_SPAN, $this->pr_get_text(3)); + $content->set_tag($tag); + unset($tag); + } + unset($image); + + $fieldset->set_tag($content); + unset($content); + + $this->html->set_tag($fieldset); + unset($fieldset); + + + // account information + $fieldset = $this->pr_create_tag_fieldset(2, array(), static::CLASS_USER_VIEW_INFORMATION, static::CLASS_USER_VIEW_INFORMATION); + $content = c_theme_html::s_create_tag(c_base_markup_tag::TYPE_DIVIDER, static::CSS_AS_FIELD_SET_CONTENT, array(static::CSS_AS_FIELD_SET_CONTENT)); + + // @todo: implement basic user profile information. + $tag = c_theme_html::s_create_tag_text(c_base_markup_tag::TYPE_SPAN, $this->path_user->get_name_human()->get_first()->get_value() . ' ' . $this->path_user->get_name_human()->get_last()->get_value()); + $content->set_tag($tag); + unset($tag); + + $fieldset->set_tag($content); + unset($content); + + $this->html->set_tag($fieldset); + unset($fieldset); + + + // remaining additions + $this->pr_add_menus(); + + $executed->set_output($this->html); + unset($this->html); + + return $errors; + } } diff --git a/database/sql/standard/standard-files.sql b/database/sql/standard/standard-files.sql index b26d985..b5581ff 100644 --- a/database/sql/standard/standard-files.sql +++ b/database/sql/standard/standard-files.sql @@ -49,6 +49,10 @@ create table s_tables.t_files ( create sequence s_tables.se_files_id owned by s_tables.t_files.id; alter table s_tables.t_files alter column id set default nextval('s_tables.se_files_id'::regclass); +alter table s_tables.t_users add constraint cf_users_image_original foreign key (image_original) references s_tables.t_files (id) on delete cascade on update cascade; +alter table s_tables.t_users add constraint cf_users_image_cropped foreign key (image_cropped) references s_tables.t_files (id) on delete cascade on update cascade; +alter table s_tables.t_users add constraint cf_users_image_icon foreign key (image_icon) references s_tables.t_files (id) on delete cascade on update cascade; + create index i_files_deleted_not on s_tables.t_files (id) where not is_deleted; diff --git a/database/sql/standard/standard-users.sql b/database/sql/standard/standard-users.sql index d1ed751..293d08d 100644 --- a/database/sql/standard/standard-users.sql +++ b/database/sql/standard/standard-users.sql @@ -48,9 +48,9 @@ create table s_tables.t_users ( date_locked timestamp with time zone, date_deleted timestamp with time zone, - image_original bytea, - image_cropped bytea, - image_icon bytea, + image_original bigint, + image_cropped bigint, + image_icon bigint, settings json, -- 1.8.3.1