From a9e73422c0a6443f1ebdd29bc34d73b70c96f039 Mon Sep 17 00:00:00 2001 From: Relintai Date: Fri, 7 Jan 2022 14:00:17 +0100 Subject: [PATCH] Started porting the menu. --- SConstruct | 3 +- app/menu/menu_controller.cpp | 449 +++++++++++++++++++++++++++++++++++ app/menu/menu_controller.h | 78 ++++++ app/menu/menu_data.cpp | 19 ++ app/menu/menu_data.h | 25 ++ app/menu/menu_data_entry.cpp | 19 ++ app/menu/menu_data_entry.h | 23 ++ app/menu/menu_model.cpp | 123 ++++++++++ app/menu/menu_model.h | 35 +++ 9 files changed, 773 insertions(+), 1 deletion(-) create mode 100644 app/menu/menu_controller.cpp create mode 100644 app/menu/menu_controller.h create mode 100644 app/menu/menu_data.cpp create mode 100644 app/menu/menu_data.h create mode 100644 app/menu/menu_data_entry.cpp create mode 100644 app/menu/menu_data_entry.h create mode 100644 app/menu/menu_model.cpp create mode 100644 app/menu/menu_model.h diff --git a/SConstruct b/SConstruct index 83aecb8..549e76f 100644 --- a/SConstruct +++ b/SConstruct @@ -33,10 +33,11 @@ import traceback folders = [ 'app', + 'app/menu', ] module_folders = [ - '../custom_modules', + '../modules', ] databases=True diff --git a/app/menu/menu_controller.cpp b/app/menu/menu_controller.cpp new file mode 100644 index 0000000..ccafe82 --- /dev/null +++ b/app/menu/menu_controller.cpp @@ -0,0 +1,449 @@ +#include "menu_controller.h" + +#include "core/error_macros.h" + +#include "core/html/form_validator.h" +#include "core/html/html_builder.h" +#include "core/http/cookie.h" +#include "core/http/http_session.h" +#include "core/http/request.h" +#include "core/http/session_manager.h" + +#include "menu_model.h" + +void MenuController::handle_request_main(Request *request) { +} + +void MenuController::create_validators() { +} + +void MenuController::admin_handle_request_main(Request *request) { + String seg = request->get_current_path_segment(); + + if (seg == "") { + admin_render_rank_list(request); + return; + } else if (seg == "new_rank") { + request->push_path(); + + admin_handle_new_rank(request); + } else if (seg == "edit_rank") { + request->push_path(); + + admin_handle_edit_rank(request); + } else if (seg == "permission_editor") { + request->push_path(); + + admin_permission_editor(request); + } +} + +void MenuController::admin_handle_new_rank(Request *request) { + +/* + if (request->get_method() == HTTP_METHOD_POST) { + Ref rank; + rank.instance(); + + rank->name = request->get_parameter("name"); + rank->name_internal = request->get_parameter("name_internal"); + rank->settings = request->get_parameter("settings"); + + RBACModel::get_singleton()->save_rank(rank); + + _ranks[rank->id] = rank; + + request->send_redirect(request->get_url_root_parent() + "edit_rank/" + String::num(rank->id)); + return; + } + + RBACAdminRankViewData data; + render_rank_view(request, &data); + */ +} + +void MenuController::admin_handle_edit_rank(Request *request) { + /* + String seg = request->get_current_path_segment(); + + //check whether it's numeric + //if (!seg.is) + + int id = seg.to_int(); + + if (id == 0) { + RLOG_MSG("MenuController::admin_handle_edit_rank: id == 0!\n"); + request->send_redirect(request->get_url_root_parent()); + return; + } + + Ref rank = _ranks[id]; + + if (!rank.is_valid()) { + RLOG_MSG("MenuController::admin_handle_edit_rank: !rank.is_valid()\n"); + request->send_redirect(request->get_url_root_parent()); + return; + } + + RBACAdminRankViewData data; + data.rank = rank; + + if (request->get_method() == HTTP_METHOD_POST) { + rank->name = request->get_parameter("name"); + rank->name_internal = request->get_parameter("name_internal"); + rank->settings = request->get_parameter("settings"); + + RBACModel::get_singleton()->save_rank(rank); + + data.messages.push_back("Save Success!"); + } + + render_rank_view(request, &data); + */ +} + +void MenuController::render_rank_view(Request *request, RBACAdminRankViewData *data) { + /* + int id = 0; + String name = ""; + String name_internal = ""; + String settings = ""; + int base_permissions = 0; + int rank_permissions = 0; + + if (data->rank.is_valid()) { + id = data->rank->id; + name = data->rank->name; + name_internal = data->rank->name_internal; + settings = data->rank->settings; + base_permissions = data->rank->base_permissions; + rank_permissions = data->rank->rank_permissions; + } + + HTMLBuilder b; + + b.h4()->f()->a()->href(request->get_url_root_parent())->f()->w("<- Back")->ca()->ch4(); + b.h4()->f()->w("RBAC Editor")->ch4(); + + b.div()->cls("messages"); + for (int i = 0; i < data->messages.size(); ++i) { + b.w(data->messages[i])->br(); + } + b.cdiv(); + + b.form()->method("POST")->action(request->get_url_root() + String::num(id)); + { + //b.input()->type("hidden")->name("id")->value(String::num(id))->f()->cinput(); + b.w("Name:")->br(); + b.input()->type("text")->name("name")->value(name)->f()->br(); + b.w("Name (Internal):")->br(); + b.input()->type("text")->name("name_internal")->value(name_internal)->f()->cinput()->br(); + b.w("Custom Settings:")->br(); + b.input()->type("text")->name("settings")->value(settings)->f()->cinput()->br(); + b.input()->type("submit")->value("Save"); + } + b.cform(); + + request->body += b.result; + */ +} + +void MenuController::admin_permission_editor(Request *request) { +/* + String seg = request->get_current_path_segment(); + + //check whether it's numeric + //if (!seg.is) + + int id = seg.to_int(); + + if (id == 0) { + RLOG_MSG("MenuController::admin_permission_editor: id == 0!\n"); + request->send_redirect(request->get_url_root_parent()); + return; + } + + Ref rank = _ranks[id]; + + if (!rank.is_valid()) { + RLOG_MSG("MenuController::admin_permission_editor: !rank.is_valid()\n"); + request->send_redirect(request->get_url_root_parent()); + return; + } + + RBACAdminEditPermissionView data; + data.rank = rank; + + request->push_path(); + + String segn = request->get_current_path_segment(); + + if (segn == "") { + admin_render_permission_editor_main_view(request, &data); + return; + } + + if (segn == "new") { + request->push_path(); + + if (request->get_method() == HTTP_METHOD_POST) { + if (admin_process_permission_editor_entry_edit_create_post(request, &data)) { + return; + } + } + + admin_render_permission_editor_entry_edit_create_view(request, &data); + return; + } + + if (segn.is_uint()) { + int perm_index = segn.to_int(); + + request->push_path(); + + if (perm_index < 0 || perm_index >= rank->permissions.size()) { + RLOG_ERR("(perm_index < 0 || perm_index >= rank->permissions.size())!\n"); + request->send_redirect(request->get_url_root_parent()); + return; + } + + data.permission = rank->permissions[perm_index]; + + if (!data.permission.is_valid()) { + RLOG_ERR("(!data.permission.is_valid()\n"); + request->send_error(503); + return; + } + + if (request->get_method() == HTTP_METHOD_POST) { + if (admin_process_permission_editor_entry_edit_create_post(request, &data)) { + return; + } + } + + admin_render_permission_editor_entry_edit_create_view(request, &data); + return; + } + + request->send_error(404); + */ +} + +void MenuController::admin_render_permission_editor_main_view(Request *request, RBACAdminEditPermissionView *data) { + /* + HTMLBuilder b; + + Ref rank = data->rank; + + b.h4()->f()->a()->href(request->get_url_root_parent(2))->f()->w("<- Back")->ca()->ch4(); + b.h4()->f()->w("RBAC Editor")->ch4(); + + b.div()->cls("heading"); + { + b.w("[ Id ]: ")->wn(rank->id)->w(", [ Name ]: ")->w(rank->name)->w(", [ Name Internal ]: ")->w(rank->name_internal); + } + b.cdiv(); + + b.br(); + + for (int i = 0; i < rank->permissions.size(); ++i) { + Ref perm = rank->permissions[i]; + + if (!perm.is_valid()) { + RLOG_ERR("MenuController::admin_render_permission_editor_main_view: !perm.is_valid()\n"); + continue; + } + + b.div()->cls("row"); + { + b.a()->href(request->get_url_root() + String::num(i)); + + b.w("-- Rank: [ Id ]: ")->wn(perm->id)->w(", [ Rank Id ]: ")->wn(perm->rank_id)->w(", [ Name ]: ")->w(perm->name); + b.w(" [ URL ]: ")->w(perm->url)->w(", [ Sort Order ]: ")->wn(perm->sort_order); + b.ca(); + } + b.cdiv(); + } + + b.br(); + + b.a()->href(request->get_url_root("new")); + b.w("New Permission"); + b.ca(); + + request->body += b.result; + */ +} + +void MenuController::admin_render_permission_editor_entry_edit_create_view(Request *request, RBACAdminEditPermissionView *data) { + /* + HTMLBuilder b; + + Ref rank = data->rank; + Ref perm = data->permission; + + String name; + String url; + int sort_order = 0; + int permissions = 0; + + if (perm.is_valid()) { + name = perm->name; + url = perm->url; + sort_order = perm->sort_order; + permissions = perm->permissions; + } + + b.h4()->f()->a()->href(request->get_url_root_parent())->f()->w("<- Back")->ca()->ch4(); + b.h4()->f()->w("RBAC Editor")->ch4(); + b.br(); + + b.div()->cls("messages"); + for (int i = 0; i < data->messages.size(); ++i) { + b.w(data->messages[i])->br(); + } + b.cdiv(); + b.br(); + + b.div()->cls("heading"); + { + b.w("Rank: [ Id ]: ")->wn(rank->id)->w(", [ Name ]: ")->w(rank->name)->w(", [ Name Internal ]: ")->w(rank->name_internal); + } + b.cdiv(); + b.br(); + + b.form()->method("POST")->action(request->get_url_root()); + { + b.w("Name:")->br(); + b.input()->type("text")->name("name")->value(name)->f()->br(); + b.w("URL:")->br(); + b.input()->type("text")->name("url")->value(url)->f()->cinput()->br(); + b.input()->type("submit")->value("Save"); + } + b.cform(); + + request->body += b.result; + */ +} + +bool MenuController::admin_process_permission_editor_entry_edit_create_post(Request *request, RBACAdminEditPermissionView *data) { + /* + Ref rank = data->rank; + + Ref perm = data->permission; + + if (!perm.is_valid()) { + perm.instance(); + + perm->rank_id = rank->id; + + if (rank->permissions.size() > 0) { + Ref p = rank->permissions[rank->permissions.size() - 1]; + + perm->sort_order = p->sort_order + 1; + } + + rank->permissions.push_back(perm); + } + + perm->name = request->get_parameter("name"); + perm->url = request->get_parameter("url"); + + //set this up in the form by default + //perm->sort_order = request->get_parameter("sort_order").to_int(); + + RBACModel::get_singleton()->save_permission(perm); + + if (perm->id == 0) { + RLOG_ERR("MenuController::admin_process_permission_editor_entry_edit_create_post: perm->id == 0!\n"); + } + + request->send_redirect(request->get_url_root_parent()); +*/ + return true; +} + +void MenuController::admin_render_rank_list(Request *request) { + /* + HTMLBuilder b; + + b.h4()->f()->a()->href(request->get_url_root_parent())->f()->w("<- Back")->ca()->ch4(); + b.h4()->f()->w("RBAC Editor")->ch4(); + + for (std::map >::iterator p = _ranks.begin(); p != _ranks.end(); p++) { + Ref r = p->second; + + if (!r.is_valid()) { + continue; + } + + b.div()->cls("row"); + { + b.a()->href(request->get_url_root("permission_editor/") + String::num(r->id)); + b.w("[ Id ]: ")->wn(r->id)->w(", [ Name ]: ")->w(r->name)->w(", [ Name Internal ]: ")->w(r->name_internal); + b.ca(); + + b.w(" - "); + + b.a()->href(request->get_url_root("edit_rank/") + String::num(r->id)); + b.w("[ Edit ]"); + b.ca(); + } + b.cdiv(); + } + + b.br(); + + b.a()->href(request->get_url_root("new_rank")); + b.w("New Rank"); + b.ca(); + + request->body += b.result; + */ +} + +void MenuController::admin_render_rank_editor(Request *request) { +} + +String MenuController::admin_get_section_name() { + return "Menu Editor"; +} + +void MenuController::admin_add_section_links(Vector *links) { + links->push_back(AdminSectionLinkInfo("Editor", "")); +} + +void MenuController::initialize() { + _data = MenuModel::get_singleton()->load(); +} + +Ref MenuController::get_data() { + return _data; +} + +bool MenuController::continue_on_missing_default_rank() { + //todo, add setting + return false; +} + +MenuController *MenuController::get_singleton() { + return _self; +} + +MenuController::MenuController() : + AdminController() { + + if (_self) { + printf("MenuController::MenuController(): Error! self is not null!/n"); + } + + _self = this; +} + +MenuController::~MenuController() { + if (_self == this) { + _self = nullptr; + } +} + +MenuController *MenuController::_self = nullptr; diff --git a/app/menu/menu_controller.h b/app/menu/menu_controller.h new file mode 100644 index 0000000..fd45032 --- /dev/null +++ b/app/menu/menu_controller.h @@ -0,0 +1,78 @@ +#ifndef MENU_CONTROLLER_H +#define MENU_CONTROLLER_H + +#include "modules/admin_panel/admin_controller.h" + +#include "core/containers/vector.h" +#include "core/string.h" + +#include "menu_data.h" +#include "menu_data_entry.h" + + +class Request; +class FormValidator; + +class MenuController : public AdminController { + RCPP_OBJECT(MenuController, AdminController); + +public: + void handle_request_main(Request *request); + void create_validators(); + + void admin_handle_request_main(Request *request); + String admin_get_section_name(); + void admin_add_section_links(Vector *links); + + struct RBACAdminRankViewData { + Ref rank; + Vector messages; + + int id = 0; + String name = ""; + String name_internal = ""; + String settings = ""; + int rank_permissions = 0; + }; + + void admin_handle_new_rank(Request *request); + void admin_handle_edit_rank(Request *request); + void render_rank_view(Request *request, RBACAdminRankViewData *data); + + struct RBACAdminEditPermissionView { + Ref rank; + Ref permission; + Vector messages; + + int rank_id = 0; + int permission_id = 0; + }; + + void admin_permission_editor(Request *request); + void admin_render_permission_editor_main_view(Request *request, RBACAdminEditPermissionView* data); + void admin_render_permission_editor_entry_edit_create_view(Request *request, RBACAdminEditPermissionView* data); + bool admin_process_permission_editor_entry_edit_create_post(Request *request, RBACAdminEditPermissionView* data); + + void admin_render_rank_list(Request *request); + void admin_render_rank_editor(Request *request); + + void initialize(); + + Ref get_data(); + + String &get_redirect_url(); + + bool continue_on_missing_default_rank(); + + static MenuController *get_singleton(); + + MenuController(); + ~MenuController(); + +protected: + static MenuController *_self; + + Ref _data; +}; + +#endif \ No newline at end of file diff --git a/app/menu/menu_data.cpp b/app/menu/menu_data.cpp new file mode 100644 index 0000000..1151be8 --- /dev/null +++ b/app/menu/menu_data.cpp @@ -0,0 +1,19 @@ +#include "menu_data.h" + +void MenuData::sort_entries() { + for (int i = 0; i < entries.size(); ++i) { + for (int j = i + 1; j < entries.size(); ++j) { + if (entries[j]->is_smaller(entries[i])) { + entries.swap(i, j); + } + } + } +} + +MenuData::MenuData() : + SharedResource() { +} + +MenuData::~MenuData() { + entries.clear(); +} diff --git a/app/menu/menu_data.h b/app/menu/menu_data.h new file mode 100644 index 0000000..488bcdc --- /dev/null +++ b/app/menu/menu_data.h @@ -0,0 +1,25 @@ +#ifndef MENU_DATA_H +#define MENU_DATA_H + +#include "core/string.h" +#include "core/containers/vector.h" + +#include "core/shared_resource.h" + +#include "menu_data_entry.h" + +class Request; + +class MenuData : public SharedResource { + RCPP_OBJECT(MenuData, SharedResource); + +public: + Vector > entries; + + void sort_entries(); + + MenuData(); + ~MenuData(); +}; + +#endif \ No newline at end of file diff --git a/app/menu/menu_data_entry.cpp b/app/menu/menu_data_entry.cpp new file mode 100644 index 0000000..789fb73 --- /dev/null +++ b/app/menu/menu_data_entry.cpp @@ -0,0 +1,19 @@ +#include "menu_data_entry.h" + +bool MenuDataEntry::is_smaller(const Ref &b) const { + if (!b.is_valid()) { + return true; + } + + return sort_order < b->sort_order; +} + +MenuDataEntry::MenuDataEntry() : + SharedResource() { + + id = 0; + sort_order = 0; +} + +MenuDataEntry::~MenuDataEntry() { +} diff --git a/app/menu/menu_data_entry.h b/app/menu/menu_data_entry.h new file mode 100644 index 0000000..7a7db78 --- /dev/null +++ b/app/menu/menu_data_entry.h @@ -0,0 +1,23 @@ +#ifndef MEUN_DATA_ENTRY_H +#define MEUN_DATA_ENTRY_H + +#include "core/string.h" + +#include "core/shared_resource.h" + +class MenuDataEntry : public SharedResource { + RCPP_OBJECT(MenuDataEntry, SharedResource); + +public: + int id; + String name; + String url; + int sort_order; + + bool is_smaller(const Ref &b) const; + + MenuDataEntry(); + ~MenuDataEntry(); +}; + +#endif \ No newline at end of file diff --git a/app/menu/menu_model.cpp b/app/menu/menu_model.cpp new file mode 100644 index 0000000..a7158a8 --- /dev/null +++ b/app/menu/menu_model.cpp @@ -0,0 +1,123 @@ +#include "menu_model.h" + +#include "core/database/database.h" +#include "core/database/database_manager.h" +#include "core/database/query_builder.h" +#include "core/database/query_result.h" +#include "core/database/table_builder.h" + +#include "core/settings/settings.h" + +#define MENU_TABLE "menu" + +Ref MenuModel::load() { + Ref data; + data.instance(); + + Ref qb = DatabaseManager::get_singleton()->ddb->get_query_builder(); + + qb->select("id,name,url,sort_order")->from(MENU_TABLE); + Ref res = qb->run(); + + while (res->next_row()) { + Ref e; + e.instance(); + + e->id = res->get_cell_int(0); + e->name = res->get_cell_str(1); + e->url = res->get_cell_str(2); + e->sort_order = res->get_cell_int(3); + + data->entries.push_back(e); + } + + data->sort_entries(); + + return data; +} + +void MenuModel::save(const Ref &menu) { + for (int i = 0; i < menu->entries.size(); ++i) { + Ref entry = menu->entries[i]; + + save_menu_entry(entry); + } +} + +void MenuModel::save_menu_entry(const Ref &entry) { + Ref qb = DatabaseManager::get_singleton()->ddb->get_query_builder(); + + if (entry->id == 0) { + qb->insert(MENU_TABLE, "name,url,sort_order")->values(); + qb->val(entry->name)->val(entry->url); + qb->val(entry->sort_order); + qb->cvalues(); + qb->select_last_insert_id(); + Ref res = qb->run(); + //qb->print(); + + Ref e = entry; + + e->id = res->get_last_insert_rowid(); + } else { + qb->update(MENU_TABLE)->set(); + qb->setp("name", entry->name); + qb->setp("url", entry->url); + qb->setp("sort_order", entry->sort_order); + qb->cset(); + qb->where()->wp("id", entry->id); + qb->end_command(); + qb->run_query(); + //qb->print(); + } +} + +void MenuModel::create_table() { + Ref tb = DatabaseManager::get_singleton()->ddb->get_table_builder(); + + tb->create_table(MENU_TABLE); + tb->integer("id")->auto_increment()->next_row(); + tb->varchar("name", 60)->not_null()->next_row(); + tb->varchar("url", 500)->not_null()->next_row(); + tb->integer("sort_order")->not_null()->next_row(); + tb->primary_key("id"); + tb->ccreate_table(); + tb->run_query(); + //tb->print(); +} +void MenuModel::drop_table() { + Ref tb = DatabaseManager::get_singleton()->ddb->get_table_builder(); + + tb->drop_table_if_exists(MENU_TABLE)->run_query(); + //tb->print(); +} +void MenuModel::migrate() { + drop_table(); + create_table(); + create_default_entries(); +} + +void MenuModel::create_default_entries() { +} + +MenuModel *MenuModel::get_singleton() { + return _self; +} + +MenuModel::MenuModel() : + Model() { + + if (_self) { + printf("MenuModel::MenuModel(): Error! self is not null!/n"); + } + + _self = this; +} + +MenuModel::~MenuModel() { + if (_self == this) { + _self = nullptr; + } +} + +MenuModel *MenuModel::_self = nullptr; diff --git a/app/menu/menu_model.h b/app/menu/menu_model.h new file mode 100644 index 0000000..f0e4b53 --- /dev/null +++ b/app/menu/menu_model.h @@ -0,0 +1,35 @@ +#ifndef MENU_MODEL_H +#define MENU_MODEL_H + +#include "core/http/model.h" + +#include "core/containers/vector.h" +#include "core/string.h" + +#include "menu_data.h" +#include "menu_data_entry.h" + +class MenuModel : public Model { + RCPP_OBJECT(MenuModel, Model); + +public: + virtual Ref load(); + + virtual void save(const Ref &menu); + virtual void save_menu_entry(const Ref &entry); + + void create_table(); + void drop_table(); + void migrate(); + virtual void create_default_entries(); + + static MenuModel *get_singleton(); + + MenuModel(); + ~MenuModel(); + +protected: + static MenuModel *_self; +}; + +#endif \ No newline at end of file