mirror of
https://git.imnavajas.es/jjimenez/safekat.git
synced 2025-07-25 22:52:08 +00:00
Merge branch 'feat/wiki' into 'main'
Feat/wiki See merge request jjimenez/safekat!581
This commit is contained in:
@ -27,6 +27,7 @@ class Routing extends BaseRouting
|
||||
*/
|
||||
public array $routeFiles = [
|
||||
APPPATH . 'Config/Routes.php',
|
||||
APPPATH . 'Config/Wiki/WikiRoutes.php',
|
||||
];
|
||||
|
||||
/**
|
||||
|
||||
20
ci4/app/Config/Wiki/WikiRoutes.php
Normal file
20
ci4/app/Config/Wiki/WikiRoutes.php
Normal file
@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
use CodeIgniter\Router\RouteCollection;
|
||||
|
||||
|
||||
$routes->group('wiki', ['namespace' => 'App\Controllers\Wiki'], function ($routes) {
|
||||
$routes->get('','WikiController::index',["as" => "wikiIndex"]);
|
||||
$routes->get('view/(:segment)','WikiController::show_page/$1',["as" => "showWikiPage"]);
|
||||
$routes->get('section/(:num)','WikiController::get_section/$1',["as" => "getWikiSection"]);
|
||||
$routes->post('section','WikiController::store_section',["as" => "storeWikiSection"]);
|
||||
$routes->delete('section/(:num)','WikiController::delete_section/$1',["as" => "deleteWikiSection"]);
|
||||
$routes->post('update/section','WikiController::update_section',["as" => "updateWikiSection"]);
|
||||
$routes->post('save/(:num)','WikiController::store_save_page/$1',["as" => "storeWikiSavePage"]);
|
||||
$routes->post('publish/(:num)','WikiController::store_publish_page/$1',["as" => "storeWikiPublishPage"]);
|
||||
$routes->post('file/upload/(:num)','WikiController::wiki_file_upload/$1',["as" => "storeWikiFileUpload"]);
|
||||
$routes->get('file/(:num)','WikiController::get_wiki_file/$1',["as" => "getWikiFile"]);
|
||||
$routes->post('section/update/order','WikiController::wiki_section_update_order',["as" => "updateWikiSectionOrder"]);
|
||||
|
||||
|
||||
});
|
||||
219
ci4/app/Controllers/Wiki/WikiController.php
Normal file
219
ci4/app/Controllers/Wiki/WikiController.php
Normal file
@ -0,0 +1,219 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controllers\Wiki;
|
||||
|
||||
use App\Controllers\BaseController;
|
||||
use App\Models\Wiki\WikiContentModel;
|
||||
use App\Models\Wiki\WikiFileModel;
|
||||
use App\Models\Wiki\WikiPageModel;
|
||||
use App\Models\Wiki\WikiSectionModel;
|
||||
use App\Models\Wiki\WikiSectionRoleModel;
|
||||
use CodeIgniter\HTTP\RequestInterface;
|
||||
use CodeIgniter\HTTP\ResponseInterface;
|
||||
use CodeIgniter\I18n\Time;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Throwable;
|
||||
|
||||
class WikiController extends BaseController
|
||||
{
|
||||
protected WikiSectionModel $wikiSectionModel;
|
||||
protected WikiContentModel $wikiContentModel;
|
||||
protected WikiPageModel $wikiPageModel;
|
||||
protected WikiFileModel $wikiFileModel;
|
||||
protected WikiSectionRoleModel $wikiSectionRoleModel;
|
||||
|
||||
|
||||
protected string $locale;
|
||||
protected array $viewData;
|
||||
|
||||
public function initController(RequestInterface $request, ResponseInterface $response, LoggerInterface $logger)
|
||||
{
|
||||
$this->wikiSectionModel = model(WikiSectionModel::class);
|
||||
$this->wikiPageModel = model(WikiPageModel::class);
|
||||
$this->wikiContentModel = model(WikiContentModel::class);
|
||||
$this->wikiFileModel = model(WikiFileModel::class);
|
||||
$this->wikiSectionRoleModel = model(WikiSectionRoleModel::class);
|
||||
|
||||
$sections = $this->wikiSectionModel->sections();
|
||||
$this->locale = session()->get('lang');
|
||||
|
||||
$this->viewData['wiki_sections'] = $sections;
|
||||
parent::initController($request, $response, $logger);
|
||||
}
|
||||
public function index()
|
||||
{
|
||||
return view('themes/vuexy/wiki/pages/render', $this->viewData);
|
||||
}
|
||||
public function show_page(string $slug)
|
||||
{
|
||||
|
||||
$section = $this->wikiSectionModel->where('slug', $slug)->first();
|
||||
if($section){
|
||||
if(auth()->user()->inGroup(...$section->roles_array()) || auth()->user()->inGroup('admin')){
|
||||
$this->viewData['slug'] = $slug;
|
||||
$this->viewData['section'] = $section->withAll($this->locale);
|
||||
$this->viewData['breadcrumb'] = [
|
||||
['title' => lang("Wiki." . $section->slug), 'route' => route_to('showWikiPage', $slug), 'active' => true],
|
||||
];
|
||||
return view('themes/vuexy/wiki/pages/render', $this->viewData);
|
||||
}else{
|
||||
return $this->response->setStatusCode(403);
|
||||
}
|
||||
}else{
|
||||
return redirect_to('/');
|
||||
}
|
||||
}
|
||||
public function get_section(int $section_id)
|
||||
{
|
||||
$section = $this->wikiSectionModel->find($section_id)->withAll($this->locale);
|
||||
if(auth()->user()->inGroup(...$section->roles_array()) || auth()->user()->inGroup('admin')){
|
||||
|
||||
return $this->response->setJSON(["data" => $section, "message" => lang("App.global_alert_fetch_success")]);
|
||||
}else{
|
||||
return $this->response->setStatusCode(403);
|
||||
}
|
||||
}
|
||||
public function store_save_page(int $section_id)
|
||||
{
|
||||
$bodyData = $this->request->getPost();
|
||||
$wikiSectionPage = $this->wikiSectionModel->find($section_id)->page();
|
||||
if ($wikiSectionPage) {
|
||||
$wikiPageId = $wikiSectionPage->id;
|
||||
} else {
|
||||
$wikiPageId = $this->wikiPageModel->insert(['section_id' => $section_id]);
|
||||
}
|
||||
$content = $this->wikiContentModel->where('locale', $this->locale)->where('page_id', $wikiPageId)->countAllResults();
|
||||
if ($content > 0) {
|
||||
$this->wikiContentModel->where('locale', $this->locale)->where('page_id', $wikiPageId)->delete();
|
||||
}
|
||||
|
||||
$this->wikiContentModel->insert([
|
||||
"locale" => $this->locale,
|
||||
"page_id" => $wikiPageId,
|
||||
"last_edit_by" => auth()->user()->id,
|
||||
"editor_data" => json_encode($bodyData)
|
||||
]);
|
||||
return $this->response->setJSON(["data" => [], "message" => lang("App.global_alert_save_success")]);
|
||||
}
|
||||
public function store_publish_page(int $section_id)
|
||||
{
|
||||
$bodyData = $this->request->getPost();
|
||||
$wikiSectionPage = $this->wikiSectionModel->find($section_id)->page();
|
||||
if ($wikiSectionPage) {
|
||||
$wikiPageId = $wikiSectionPage->id;
|
||||
$wikiContentId = $this->wikiContentModel->where("page_id", $wikiPageId)->where('locale', $this->locale)->first()->id;
|
||||
$this->wikiContentModel->update($wikiContentId, [
|
||||
"published_by" => auth()->user()->id,
|
||||
"last_edit_by" => auth()->user()->id,
|
||||
"editor_data" => json_encode($bodyData),
|
||||
"published_data" => json_encode($bodyData),
|
||||
"published_at" => Time::now()->format('Y-m-d H:i:s'),
|
||||
|
||||
]);
|
||||
$response = $this->response->setJSON(["data" => [], "message" => lang("App.global_alert_save_success")]);
|
||||
} else {
|
||||
$response = $this->response->setStatusCode(400)->setJSON(["data" => [], "error" => lang('Wiki.errors.publish_before_save')]);
|
||||
}
|
||||
return $response;
|
||||
}
|
||||
public function wiki_file_upload(int $section_id)
|
||||
{
|
||||
try {
|
||||
$file = $this->request->getFile('image');
|
||||
$section = $this->wikiSectionModel->find($section_id);
|
||||
$content = $section->content();
|
||||
$r = null;
|
||||
$fullpath = null;
|
||||
if ($file->isValid() && !$file->hasMoved()) {
|
||||
$fullpath = $file->store('wiki_images/' . $section->slug);
|
||||
$r = $this->wikiFileModel->insert(["content_id" => $content->id, "path" => $fullpath]);
|
||||
return $this->response->setJSON(["success" => 1, "file" => [
|
||||
"url" => '/wiki/file/' . $r
|
||||
]]);
|
||||
} else {
|
||||
return $this->response->setJSON(["success" => 0, "file" => [
|
||||
"url" => null
|
||||
]]);
|
||||
}
|
||||
} catch (\Throwable $th) {
|
||||
|
||||
return $this->response->setJSON(["success" => 0, "error" => $th->getMessage()])->setStatusCode(403);
|
||||
}
|
||||
}
|
||||
public function get_wiki_file(int $wiki_file_id)
|
||||
{
|
||||
$wikiFile = $this->wikiFileModel->find($wiki_file_id);
|
||||
if ($wikiFile->path) {
|
||||
$filePath = WRITEPATH . 'uploads/' . $wikiFile->path;
|
||||
$mimeType = mime_content_type($filePath);
|
||||
return $this->response
|
||||
->setHeader('Content-Type', $mimeType)
|
||||
->setHeader('Content-Length', filesize($filePath))
|
||||
->setBody(file_get_contents($filePath));
|
||||
} else {
|
||||
return $this->response->setJSON(["success" => 0, "error" => lang('Wiki.file_dont_exist')])->setStatusCode(400);
|
||||
}
|
||||
}
|
||||
public function wiki_section_update_order()
|
||||
{
|
||||
try {
|
||||
$bodyData = $this->request->getPost();
|
||||
$orders = $bodyData['orders'];
|
||||
foreach ($orders as $key => $section_id) {
|
||||
$this->wikiSectionModel->update($section_id, ['order' => $key]);
|
||||
}
|
||||
return $this->response->setJSON(["status" => 1, "message" => lang('Wiki.order_success')]);
|
||||
} catch (\Throwable $th) {
|
||||
return $this->response->setJSON(["status" => 0, "message" => lang('Wiki.order_error')])->setStatusCode(400);
|
||||
}
|
||||
}
|
||||
public function store_section()
|
||||
{
|
||||
try {
|
||||
$bodyData = $this->request->getPost();
|
||||
$sectionName = $bodyData['name'];
|
||||
$roles = $bodyData['roles'];
|
||||
$bodyData["slug"] = implode('-', array_map(fn($e) => strtolower($e), explode(' ', $sectionName)));
|
||||
$bodyData["order"] = $this->wikiSectionModel->selectMax('order')->first()->order + 1;
|
||||
$wikiSectionId = $this->wikiSectionModel->insert($bodyData);
|
||||
if(count($roles) > 0){
|
||||
foreach ($roles as $key => $role) {
|
||||
$this->wikiSectionRoleModel->insert(['wiki_section_id' => $wikiSectionId , 'role' => $role]);
|
||||
}
|
||||
}
|
||||
return $this->response->setJSON(["status" => 1, "message" => lang('Wiki.section_new_success')]);
|
||||
} catch (\Throwable $th) {
|
||||
return $this->response->setJSON(["status" => 0, "message" => $th->getMessage()])->setStatusCode(400);
|
||||
}
|
||||
}
|
||||
public function update_section()
|
||||
{
|
||||
try {
|
||||
$bodyData = $this->request->getPost();
|
||||
$wikiSectionId = $bodyData['wiki_section_id'];
|
||||
$roles = $bodyData['roles'];
|
||||
$this->wikiSectionModel->update($wikiSectionId, [
|
||||
"name" => $bodyData['name'],
|
||||
"icon" => $bodyData['icon']
|
||||
]);
|
||||
$this->wikiSectionRoleModel->where('wiki_section_id',$wikiSectionId)->delete();
|
||||
if(count($roles) > 0){
|
||||
foreach ($roles as $key => $role) {
|
||||
$this->wikiSectionRoleModel->insert(['wiki_section_id' => $wikiSectionId , 'role' => $role]);
|
||||
}
|
||||
}
|
||||
return $this->response->setJSON(["status" => 1, "message" => lang('Wiki.section_edit_success')]);
|
||||
} catch (\Throwable $th) {
|
||||
return $this->response->setJSON(["status" => 0, "message" => $th->getMessage()])->setStatusCode(400);
|
||||
}
|
||||
}
|
||||
public function delete_section(int $section_id)
|
||||
{
|
||||
try{
|
||||
$this->wikiSectionModel->delete($section_id);
|
||||
return $this->response->setJSON(["status" => 1, "message" => lang('Wiki.section_delete_success')]);
|
||||
}catch(Throwable $th){
|
||||
return $this->response->setJSON(["status" => 0, "message" => $th->getMessage()])->setStatusCode(400);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
namespace App\Database\Migrations;
|
||||
|
||||
use CodeIgniter\Database\Migration;
|
||||
use CodeIgniter\Database\RawSql;
|
||||
|
||||
class WikiSectionsMigration extends Migration
|
||||
{
|
||||
protected array $COLUMNS = [
|
||||
|
||||
'id' => [
|
||||
'type' => 'INT',
|
||||
'unsigned' => true,
|
||||
'auto_increment' => true,
|
||||
],
|
||||
'order' => [
|
||||
'type' => 'INT',
|
||||
'unsigned' => true,
|
||||
'null'=> true,
|
||||
],
|
||||
'name' => [
|
||||
'type' => 'VARCHAR',
|
||||
'constraint' => 255,
|
||||
],
|
||||
'slug' => [
|
||||
'type' => 'VARCHAR',
|
||||
'constraint' => 255,
|
||||
],
|
||||
'icon' => [
|
||||
'type' => 'VARCHAR',
|
||||
'constraint' => 255,
|
||||
'null' => true,
|
||||
],
|
||||
'parent_section_id' => [
|
||||
'type' => 'INT',
|
||||
'unsigned' => true,
|
||||
'null' => true,
|
||||
|
||||
],
|
||||
|
||||
];
|
||||
|
||||
public function up()
|
||||
{
|
||||
$this->forge->addField($this->COLUMNS);
|
||||
$currenttime = new RawSql('CURRENT_TIMESTAMP');
|
||||
$this->forge->addField([
|
||||
'created_at' => [
|
||||
'type' => 'TIMESTAMP',
|
||||
'default' => $currenttime,
|
||||
|
||||
],
|
||||
'updated_at' => [
|
||||
'type' => 'TIMESTAMP',
|
||||
'null' => true,
|
||||
|
||||
],
|
||||
'deleted_at' => [
|
||||
'type' => 'TIMESTAMP',
|
||||
'null' => true,
|
||||
|
||||
],
|
||||
]);
|
||||
$this->forge->addPrimaryKey('id');
|
||||
$this->forge->addForeignKey('parent_section_id','wiki_sections','id');
|
||||
$this->forge->createTable("wiki_sections");
|
||||
}
|
||||
|
||||
public function down()
|
||||
{
|
||||
$this->forge->dropTable("wiki_sections");
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
namespace App\Database\Migrations;
|
||||
|
||||
use CodeIgniter\Database\Migration;
|
||||
use CodeIgniter\Database\RawSql;
|
||||
|
||||
class WikiPagesMigration extends Migration
|
||||
{
|
||||
protected array $COLUMNS = [
|
||||
|
||||
'id' => [
|
||||
'type' => 'INT',
|
||||
'unsigned' => true,
|
||||
'auto_increment' => true,
|
||||
],
|
||||
'section_id' => [
|
||||
'type' => 'INT',
|
||||
'unsigned' => true,
|
||||
],
|
||||
];
|
||||
|
||||
public function up()
|
||||
{
|
||||
$this->forge->addField($this->COLUMNS);
|
||||
$currenttime = new RawSql('CURRENT_TIMESTAMP');
|
||||
$this->forge->addField([
|
||||
'created_at' => [
|
||||
'type' => 'TIMESTAMP',
|
||||
'default' => $currenttime,
|
||||
],
|
||||
'updated_at' => [
|
||||
'type' => 'TIMESTAMP',
|
||||
'null' => true,
|
||||
],
|
||||
'deleted_at' => [
|
||||
'type' => 'TIMESTAMP',
|
||||
'null' => true,
|
||||
|
||||
],
|
||||
]);
|
||||
$this->forge->addPrimaryKey('id');
|
||||
$this->forge->addForeignKey('section_id','wiki_sections','id');
|
||||
$this->forge->createTable("wiki_pages");
|
||||
}
|
||||
|
||||
public function down()
|
||||
{
|
||||
$this->forge->dropTable("wiki_pages");
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,83 @@
|
||||
<?php
|
||||
|
||||
namespace App\Database\Migrations;
|
||||
|
||||
use CodeIgniter\Database\Migration;
|
||||
use CodeIgniter\Database\RawSql;
|
||||
|
||||
class WikiContentsMigration extends Migration
|
||||
{
|
||||
protected array $COLUMNS = [
|
||||
|
||||
'id' => [
|
||||
'type' => 'INT',
|
||||
'unsigned' => true,
|
||||
'auto_increment' => true,
|
||||
],
|
||||
'locale' => [
|
||||
'type' => 'VARCHAR',
|
||||
'constraint' => 255,
|
||||
'default' => 'es',
|
||||
],
|
||||
'page_id' => [
|
||||
'type' => 'INT',
|
||||
'unsigned' => true,
|
||||
],
|
||||
'editor_data' => [
|
||||
'type' => 'LONGTEXT',
|
||||
'null' => true,
|
||||
],
|
||||
'published_data' => [
|
||||
'type' => 'LONGTEXT',
|
||||
'null' => true,
|
||||
],
|
||||
'published_by' => [
|
||||
'type' => 'INT',
|
||||
'unsigned' => true,
|
||||
'null' => true,
|
||||
'constraint' => 10,
|
||||
],
|
||||
'last_edit_by' => [
|
||||
'type' => 'INT',
|
||||
'unsigned' => true,
|
||||
'null' => true,
|
||||
'constraint' => 10,
|
||||
],
|
||||
];
|
||||
|
||||
public function up()
|
||||
{
|
||||
$this->forge->addField($this->COLUMNS);
|
||||
$currenttime = new RawSql('CURRENT_TIMESTAMP');
|
||||
$this->forge->addField([
|
||||
'published_at' => [
|
||||
'type' => 'TIMESTAMP',
|
||||
'null' => true,
|
||||
],
|
||||
|
||||
'created_at' => [
|
||||
'type' => 'TIMESTAMP',
|
||||
'default' => $currenttime,
|
||||
],
|
||||
'updated_at' => [
|
||||
'type' => 'TIMESTAMP',
|
||||
'null' => true,
|
||||
],
|
||||
'deleted_at' => [
|
||||
'type' => 'TIMESTAMP',
|
||||
'null' => true,
|
||||
|
||||
],
|
||||
]);
|
||||
$this->forge->addPrimaryKey('id');
|
||||
$this->forge->addForeignKey('page_id','wiki_pages','id');
|
||||
$this->forge->addForeignKey('published_by','users','id');
|
||||
$this->forge->addForeignKey('last_edit_by','users','id');
|
||||
$this->forge->createTable("wiki_contents");
|
||||
}
|
||||
|
||||
public function down()
|
||||
{
|
||||
$this->forge->dropTable("wiki_contents");
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
namespace App\Database\Migrations;
|
||||
|
||||
use CodeIgniter\Database\Migration;
|
||||
use CodeIgniter\Database\RawSql;
|
||||
|
||||
class WikiFilesMigration extends Migration
|
||||
{
|
||||
protected array $COLUMNS = [
|
||||
|
||||
'id' => [
|
||||
'type' => 'INT',
|
||||
'unsigned' => true,
|
||||
'auto_increment' => true,
|
||||
],
|
||||
'content_id' => [
|
||||
'type' => 'INT',
|
||||
'unsigned' => true,
|
||||
],
|
||||
'path' => [
|
||||
'type' => 'LONGTEXT',
|
||||
'null' => true,
|
||||
],
|
||||
|
||||
];
|
||||
|
||||
public function up()
|
||||
{
|
||||
$this->forge->addField($this->COLUMNS);
|
||||
$currenttime = new RawSql('CURRENT_TIMESTAMP');
|
||||
$this->forge->addField([
|
||||
'created_at' => [
|
||||
'type' => 'TIMESTAMP',
|
||||
'default' => $currenttime,
|
||||
],
|
||||
'updated_at' => [
|
||||
'type' => 'TIMESTAMP',
|
||||
'null' => true,
|
||||
],
|
||||
'deleted_at' => [
|
||||
'type' => 'TIMESTAMP',
|
||||
'null' => true,
|
||||
|
||||
],
|
||||
]);
|
||||
$this->forge->addPrimaryKey('id');
|
||||
$this->forge->addForeignKey('content_id','wiki_contents','id');
|
||||
$this->forge->createTable("wiki_files");
|
||||
}
|
||||
|
||||
public function down()
|
||||
{
|
||||
$this->forge->dropTable("wiki_files");
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
namespace App\Database\Migrations;
|
||||
|
||||
use CodeIgniter\Database\Migration;
|
||||
use CodeIgniter\Database\RawSql;
|
||||
|
||||
class WikiSectionRolesMigration extends Migration
|
||||
{
|
||||
protected array $COLUMNS = [
|
||||
|
||||
'id' => [
|
||||
'type' => 'INT',
|
||||
'unsigned' => true,
|
||||
'auto_increment' => true,
|
||||
],
|
||||
'wiki_section_id' => [
|
||||
'type' => 'INT',
|
||||
'unsigned' => true,
|
||||
],
|
||||
'role' => [
|
||||
'type' => 'VARCHAR',
|
||||
'constraint' => 255,
|
||||
'default' => 'admin'
|
||||
],
|
||||
|
||||
|
||||
];
|
||||
|
||||
public function up()
|
||||
{
|
||||
$this->forge->addField($this->COLUMNS);
|
||||
$currenttime = new RawSql('CURRENT_TIMESTAMP');
|
||||
$this->forge->addField([
|
||||
'created_at' => [
|
||||
'type' => 'TIMESTAMP',
|
||||
'default' => $currenttime,
|
||||
|
||||
],
|
||||
'updated_at' => [
|
||||
'type' => 'TIMESTAMP',
|
||||
'null' => true,
|
||||
|
||||
],
|
||||
'deleted_at' => [
|
||||
'type' => 'TIMESTAMP',
|
||||
'null' => true,
|
||||
|
||||
],
|
||||
]);
|
||||
$this->forge->addPrimaryKey('id');
|
||||
$this->forge->addForeignKey('wiki_section_id','wiki_sections','id');
|
||||
$this->forge->createTable("wiki_section_roles");
|
||||
}
|
||||
|
||||
public function down()
|
||||
{
|
||||
$this->forge->dropTable("wiki_section_roles");
|
||||
}
|
||||
}
|
||||
165
ci4/app/Database/Seeds/WikiSectionSeeder.php
Normal file
165
ci4/app/Database/Seeds/WikiSectionSeeder.php
Normal file
@ -0,0 +1,165 @@
|
||||
<?php
|
||||
|
||||
namespace App\Database\Seeds;
|
||||
|
||||
use App\Models\Configuracion\ConfigVariableModel;
|
||||
use App\Models\Wiki\WikiSectionModel;
|
||||
use App\Models\Wiki\WikiSectionRoleModel;
|
||||
use CodeIgniter\Database\Seeder;
|
||||
|
||||
class WikiSectionSeeder extends Seeder
|
||||
{
|
||||
protected array $dataAdmin = [
|
||||
[
|
||||
"name" => 'Introducción',
|
||||
"slug" => 'intro-admin',
|
||||
"icon" => 'ti ti-home-2',
|
||||
"roles" => [
|
||||
"admin",
|
||||
],
|
||||
],
|
||||
[
|
||||
"name" => 'Presupuesto',
|
||||
"slug" => 'presupuesto-admin',
|
||||
"icon" => 'ti ti-currency-dollar',
|
||||
"roles" => [
|
||||
"admin",
|
||||
],
|
||||
],
|
||||
[
|
||||
"name" => 'Pedidos',
|
||||
"slug" => 'pedidos-admin',
|
||||
"icon" => 'ti ti-file-description',
|
||||
"roles" => [
|
||||
"admin",
|
||||
],
|
||||
|
||||
],
|
||||
[
|
||||
"name" => 'Facturación',
|
||||
"slug" => 'facturacion-admin',
|
||||
"icon" => 'ti ti-file-dollar',
|
||||
"roles" => [
|
||||
"admin",
|
||||
],
|
||||
|
||||
],
|
||||
[
|
||||
"name" => 'Logística',
|
||||
"slug" => 'logistica-admin',
|
||||
"icon" => 'ti ti-truck',
|
||||
"roles" => [
|
||||
"admin",
|
||||
],
|
||||
|
||||
],
|
||||
[
|
||||
"name" => 'Tarifas',
|
||||
"slug" => 'tarifas-admin',
|
||||
"icon" => 'ti ti-receipt',
|
||||
"roles" => [
|
||||
"admin",
|
||||
],
|
||||
|
||||
],
|
||||
[
|
||||
"name" => 'Configuración',
|
||||
"slug" => 'config-admin',
|
||||
"icon" => 'ti ti-adjustments-horizontal',
|
||||
"roles" => [
|
||||
"admin",
|
||||
],
|
||||
|
||||
],
|
||||
[
|
||||
"name" => 'Mensajería',
|
||||
"slug" => 'messages-admin',
|
||||
"icon" => 'ti ti-message',
|
||||
"roles" => [
|
||||
"admin",
|
||||
],
|
||||
|
||||
]
|
||||
];
|
||||
protected array $dataCliente = [
|
||||
[
|
||||
"name" => 'Introducción',
|
||||
"slug" => 'intro-cliente',
|
||||
"icon" => 'ti ti-home-2',
|
||||
"roles" => [
|
||||
"cliente-admin",
|
||||
"cliente-editor",
|
||||
]
|
||||
],
|
||||
[
|
||||
"name" => 'Presupuesto(Cliente)',
|
||||
"slug" => 'presupuesto-cliente',
|
||||
"role" => 'cliente',
|
||||
"icon" => 'ti ti-currency-dollar',
|
||||
"roles" => [
|
||||
"cliente-admin",
|
||||
"cliente-editor",
|
||||
]
|
||||
],
|
||||
[
|
||||
"name" => 'Pedidos(Cliente)',
|
||||
"slug" => 'pedidos-cliente',
|
||||
"icon" => 'ti ti-file-description',
|
||||
"roles" => [
|
||||
"cliente-admin",
|
||||
"cliente-editor",
|
||||
]
|
||||
],
|
||||
[
|
||||
"name" => 'Facturación (Cliente)',
|
||||
"slug" => 'facturacion-cliente',
|
||||
"icon" => 'ti ti-file-dollar',
|
||||
"roles" => [
|
||||
"cliente-admin",
|
||||
"cliente-editor",
|
||||
]
|
||||
],
|
||||
[
|
||||
"name" => 'Tarifas (Cliente)',
|
||||
"slug" => 'tarifas-cliente',
|
||||
"icon" => 'ti ti-receipt',
|
||||
"roles" => [
|
||||
"cliente-admin",
|
||||
"cliente-editor",
|
||||
]
|
||||
],
|
||||
[
|
||||
"name" => 'Mensajería (Cliente)',
|
||||
"slug" => 'messages-cliente',
|
||||
"icon" => 'ti ti-message',
|
||||
"roles" => [
|
||||
"cliente-admin",
|
||||
"cliente-editor",
|
||||
]
|
||||
]
|
||||
];
|
||||
public function run()
|
||||
{
|
||||
|
||||
$wikiSectionModel = model(WikiSectionModel::class);
|
||||
$wikiSectionRoleModel = model(WikiSectionRoleModel::class);
|
||||
$section_order = 0;
|
||||
foreach ($this->dataAdmin as $key => $row) {
|
||||
$row['order'] = $section_order;
|
||||
$wikiSectionId = $wikiSectionModel->insert($row);
|
||||
$section_order++;
|
||||
foreach ($row['roles'] as $key => $role) {
|
||||
$wikiSectionRoleModel->insert(['wiki_section_id' => $wikiSectionId,"role" => $role]);
|
||||
|
||||
}
|
||||
}
|
||||
foreach ($this->dataCliente as $key => $row) {
|
||||
$row['order'] = $section_order;
|
||||
$wikiSectionId = $wikiSectionModel->insert($row);
|
||||
$section_order++;
|
||||
foreach ($row['roles'] as $key => $role) {
|
||||
$wikiSectionRoleModel->insert(['wiki_section_id' => $wikiSectionId,"role" => $role]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
35
ci4/app/Entities/Wiki/WikiContentEntity.php
Normal file
35
ci4/app/Entities/Wiki/WikiContentEntity.php
Normal file
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace App\Entities\Wiki;
|
||||
|
||||
use App\Models\Usuarios\UserModel;
|
||||
use CodeIgniter\Entity\Entity;
|
||||
|
||||
class WikiContentEntity extends Entity
|
||||
{
|
||||
protected $attributes = [
|
||||
"locale" => null,
|
||||
"page_id" => null,
|
||||
"editor_data" => null,
|
||||
"published_data" => null,
|
||||
"last_edit_by" => null,
|
||||
"published_by" => null,
|
||||
"published_at" => null,
|
||||
];
|
||||
protected $casts = [
|
||||
"locale" => "string",
|
||||
"page_id" => "int",
|
||||
"editor_data" => "string",
|
||||
"published_data" => "string",
|
||||
"last_edit_by" => "int",
|
||||
"published_by" => "int",
|
||||
"published_at" => "string",
|
||||
];
|
||||
public function publish_by() : string
|
||||
{
|
||||
$m = model(UserModel::class);
|
||||
$user = $m->find($this->attributes['published_by']);
|
||||
return $user->first_name." ".$user->last_name;
|
||||
}
|
||||
|
||||
}
|
||||
17
ci4/app/Entities/Wiki/WikiFileEntity.php
Normal file
17
ci4/app/Entities/Wiki/WikiFileEntity.php
Normal file
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
namespace App\Entities\Wiki;
|
||||
|
||||
use CodeIgniter\Entity\Entity;
|
||||
|
||||
class WikiFileEntity extends Entity
|
||||
{
|
||||
protected $attributes = [
|
||||
"content_id" => null,
|
||||
"path" => null,
|
||||
];
|
||||
protected $casts = [
|
||||
"content_id" => "int",
|
||||
"path" => "string",
|
||||
];
|
||||
|
||||
}
|
||||
18
ci4/app/Entities/Wiki/WikiPageEntity.php
Normal file
18
ci4/app/Entities/Wiki/WikiPageEntity.php
Normal file
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
namespace App\Entities\Wiki;
|
||||
|
||||
use App\Models\Usuarios\UserModel;
|
||||
use CodeIgniter\Entity\Entity;
|
||||
|
||||
class WikiPageEntity extends Entity
|
||||
{
|
||||
protected $attributes = [
|
||||
"section_id" => null,
|
||||
];
|
||||
protected $casts = [
|
||||
"section_id" => "int",
|
||||
];
|
||||
|
||||
|
||||
|
||||
}
|
||||
94
ci4/app/Entities/Wiki/WikiSectionEntity.php
Normal file
94
ci4/app/Entities/Wiki/WikiSectionEntity.php
Normal file
@ -0,0 +1,94 @@
|
||||
<?php
|
||||
namespace App\Entities\Wiki;
|
||||
|
||||
use App\Models\Wiki\WikiContentModel;
|
||||
use App\Models\Wiki\WikiPageModel;
|
||||
use App\Models\Wiki\WikiSectionRoleModel;
|
||||
use CodeIgniter\Entity\Entity;
|
||||
|
||||
class WikiSectionEntity extends Entity
|
||||
{
|
||||
protected $attributes = [
|
||||
"name" => null,
|
||||
"slug" => null,
|
||||
"role" => null,
|
||||
"order" => null,
|
||||
"icon" => null,
|
||||
"parent_id" => null
|
||||
];
|
||||
protected $casts = [
|
||||
"name" => "string",
|
||||
"slug" => "string",
|
||||
"role" => "string",
|
||||
"icon" => "string",
|
||||
"order" => "int",
|
||||
"parent_id" => "int"
|
||||
];
|
||||
|
||||
public function withPage(): self
|
||||
{
|
||||
$this->attributes['pages'] = $this->page();
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function withContents(string $locale = "es"): self
|
||||
{
|
||||
$m = model(WikiContentModel::class);
|
||||
$this->attributes['contents'] = $this->content($locale);
|
||||
return $this;
|
||||
}
|
||||
public function withRoles(): self
|
||||
{
|
||||
$m = model(WikiSectionRoleModel::class);
|
||||
$this->attributes['roles'] = $this->roles();
|
||||
return $this;
|
||||
}
|
||||
public function withRolesArray(): self
|
||||
{
|
||||
$m = model(WikiSectionRoleModel::class);
|
||||
$this->attributes['roles_array'] = $this->roles_array();
|
||||
return $this;
|
||||
}
|
||||
public function withAll(string $locale = "es") : self
|
||||
{
|
||||
$this->withPage();
|
||||
$this->withContents($locale);
|
||||
$this->withRoles();
|
||||
$this->withRolesArray();
|
||||
|
||||
return $this;
|
||||
|
||||
}
|
||||
public function page(): ?WikiPageEntity
|
||||
{
|
||||
$m = model(WikiPageModel::class);
|
||||
return $m->where('section_id',$this->attributes['id'])->first();
|
||||
}
|
||||
public function roles_array(): ?array
|
||||
{
|
||||
$m = model(WikiSectionRoleModel::class);
|
||||
$section_roles = $m->where('wiki_section_id',$this->attributes['id'])->findAll();
|
||||
$roles = array_map(fn($r) => $r->role,$section_roles);
|
||||
return $roles;
|
||||
}
|
||||
public function roles(): ?array
|
||||
{
|
||||
$m = model(WikiSectionRoleModel::class);
|
||||
$section_roles = $m->where('wiki_section_id',$this->attributes['id'])->findAll();
|
||||
return $section_roles;
|
||||
}
|
||||
public function content(string $locale = "es"): ?WikiContentEntity
|
||||
{
|
||||
$page = $this->page();
|
||||
$content = null;
|
||||
$m = model(WikiContentModel::class);
|
||||
if($page){
|
||||
$content = $m->where('page_id',$page->id)
|
||||
->where('locale',$locale)
|
||||
->first();
|
||||
}
|
||||
return $content;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
28
ci4/app/Entities/Wiki/WikiSectionRoleEntity.php
Normal file
28
ci4/app/Entities/Wiki/WikiSectionRoleEntity.php
Normal file
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
namespace App\Entities\Wiki;
|
||||
|
||||
use App\Models\Wiki\WikiContentModel;
|
||||
use App\Models\Wiki\WikiPageModel;
|
||||
use App\Models\Wiki\WikiSectionModel;
|
||||
use CodeIgniter\Entity\Entity;
|
||||
|
||||
class WikiSectionRoleEntity extends Entity
|
||||
{
|
||||
protected $attributes = [
|
||||
"wiki_section_id" => null,
|
||||
"role" => null,
|
||||
];
|
||||
protected $casts = [
|
||||
"wiki_section_id" => "int",
|
||||
"role" => "string",
|
||||
];
|
||||
|
||||
public function page(): ?WikiSectionEntity
|
||||
{
|
||||
$m = model(WikiSectionModel::class);
|
||||
return $m->where('id',$this->attributes['section_id'])->first();
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
44
ci4/app/Language/en/Wiki.php
Normal file
44
ci4/app/Language/en/Wiki.php
Normal file
@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'help' => "Help",
|
||||
'intro-admin' => "Introduction",
|
||||
'presupuesto-cliente' => "Client budget",
|
||||
'presupuesto-admin' => "Admin budget",
|
||||
'pedidos-cliente' => "Orders",
|
||||
'pedidos-admin' => "Orders",
|
||||
'facturacion-admin' => "Invoice",
|
||||
'facturacion-cliente' => "Invoice (Client)",
|
||||
'logistica-admin' => "Logistic",
|
||||
'tarifas-admin' => "Tariff",
|
||||
'tarifas-cliente' => "Tariff (Client)",
|
||||
'config-admin' => "Configuration",
|
||||
'messages-admin' => "Messages",
|
||||
'messages-cliente' => "Messages (Client)",
|
||||
'save' => "Save",
|
||||
'release' => "Release",
|
||||
'preview' => "Preview",
|
||||
'edit' => "Edit",
|
||||
'new_section' => "New section",
|
||||
'edit_section' => "Edit section",
|
||||
'header-placeholder' => "Start writing a header ...",
|
||||
'errors' => [
|
||||
'publish_before_save' => "You have to save before publish the content"
|
||||
],
|
||||
'alt' => [
|
||||
"sort" => "Drag to set the section order"
|
||||
],
|
||||
'order_success' => 'Order updated',
|
||||
'order_error' => 'An error has ocurred',
|
||||
'published' => 'Released',
|
||||
'not_published' => 'Not released',
|
||||
'section_new_success' => 'Section created successfully',
|
||||
'section_edit_success' => 'Section updated successfully',
|
||||
'need_reload' => 'You need to refresh the page after creating/updating a section to see the changes.',
|
||||
'file_dont_exist' => "File doesn't exist",
|
||||
'need_editor_to_save' => 'Need to be in edit mode to save the content.',
|
||||
'no_content' => 'Page is empty',
|
||||
'dropdown_roles' => 'Roles that can see this section',
|
||||
|
||||
|
||||
];
|
||||
@ -19,6 +19,7 @@ return [
|
||||
"global_come_back" => "Volver",
|
||||
"global_save" => "Guardar",
|
||||
"global_alert_save_success" => "¡Guardado exitosamente!",
|
||||
"global_alert_fetch_success" => "Obtenido exitosamente!",
|
||||
"global_alert_save_error" => "¡Error al guardar!",
|
||||
"global_activate" => "Activar",
|
||||
"global_disable" => "Desactivar",
|
||||
|
||||
50
ci4/app/Language/es/Wiki.php
Normal file
50
ci4/app/Language/es/Wiki.php
Normal file
@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'help' => "Ayuda",
|
||||
'intro-admin' => "Introducción",
|
||||
'intro-cliente' => "Introducción",
|
||||
'presupuesto-cliente' => "Presupuesto (Cliente)",
|
||||
'presupuesto-admin' => "Presupuesto admin",
|
||||
'pedidos-admin' => "Pedidos",
|
||||
'pedidos-cliente' => "Pedidos (Cliente)",
|
||||
'facturacion-admin' => "Facturación",
|
||||
'facturacion-cliente' => "Facturación(Cliente)",
|
||||
'logistica-admin' => "Logística",
|
||||
'tarifas-admin' => "Tarifas",
|
||||
'tarifas-cliente' => "Tarifas (Cliente)",
|
||||
'config-admin' => "Configuración",
|
||||
'messages-admin' => "Mensajería",
|
||||
'messages-cliente' => "Mensajería (Cliente)",
|
||||
'save' => "Guardar",
|
||||
'release' => "Publicar",
|
||||
'preview' => "Vista previa",
|
||||
'edit' => "Editar",
|
||||
'name' => "Nombre sección",
|
||||
'icon' => "Icono sección",
|
||||
'section_placeholder' => "Introduce el nombre de la sección",
|
||||
'section_order' => "Orden",
|
||||
'section_icon_placeholder' => "Introduce el nombre de la sección",
|
||||
'edit_section' => "Editar sección",
|
||||
'new_section' => "Nueva sección",
|
||||
'header-placeholder' => "Escribe un encabezado ...",
|
||||
'errors' => [
|
||||
'publish_before_save' => "Es necesario guardar antes de publicar"
|
||||
],
|
||||
'alt' => [
|
||||
"sort" => "Arrastra para establecer el orden de la sección"
|
||||
],
|
||||
'order_success' => 'Orden actualizado correctamente',
|
||||
'order_error' => 'Ha ocurriendo un error al ordenar',
|
||||
'published' => 'Publicado',
|
||||
'not_published' => 'Sin publicar',
|
||||
'section_new_success' => 'Sección creada correctamente',
|
||||
'section_edit_success' => 'Sección actualizada correctamente',
|
||||
'need_reload' => 'Es necesario recargar la página para ver la nueva sección creada o editada.',
|
||||
'file_dont_exist' => 'El fichero no existe',
|
||||
'need_editor_to_save' => 'Tienes que estar en modo editar para guardar.',
|
||||
'no_content' => 'No hay contenido en la página',
|
||||
'dropdown_roles' => 'Roles que pueden ver la sección',
|
||||
|
||||
|
||||
];
|
||||
58
ci4/app/Models/Wiki/WikiContentModel.php
Normal file
58
ci4/app/Models/Wiki/WikiContentModel.php
Normal file
@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models\Wiki;
|
||||
|
||||
use App\Entities\Wiki\WikiContentEntity;
|
||||
use CodeIgniter\Model;
|
||||
|
||||
class WikiContentModel extends Model
|
||||
{
|
||||
protected $table = 'wiki_contents';
|
||||
protected $primaryKey = 'id';
|
||||
protected $useAutoIncrement = true;
|
||||
protected $returnType = WikiContentEntity::class;
|
||||
protected $useSoftDeletes = true;
|
||||
protected $protectFields = true;
|
||||
protected $allowedFields = [
|
||||
"locale",
|
||||
"page_id",
|
||||
"editor_data",
|
||||
"published_data",
|
||||
"last_edit_by",
|
||||
"published_by",
|
||||
"published_at"
|
||||
|
||||
];
|
||||
|
||||
protected bool $allowEmptyInserts = false;
|
||||
protected bool $updateOnlyChanged = true;
|
||||
|
||||
protected array $casts = [];
|
||||
protected array $castHandlers = [];
|
||||
|
||||
// Dates
|
||||
protected $useTimestamps = true;
|
||||
protected $dateFormat = 'datetime';
|
||||
protected $createdField = 'created_at';
|
||||
protected $updatedField = 'updated_at';
|
||||
protected $deletedField = 'deleted_at';
|
||||
|
||||
// Validation
|
||||
protected $validationRules = [];
|
||||
protected $validationMessages = [];
|
||||
protected $skipValidation = false;
|
||||
protected $cleanValidationRules = true;
|
||||
|
||||
// Callbacks
|
||||
protected $allowCallbacks = true;
|
||||
protected $beforeInsert = [];
|
||||
protected $afterInsert = [];
|
||||
protected $beforeUpdate = [];
|
||||
protected $afterUpdate = [];
|
||||
protected $beforeFind = [];
|
||||
protected $afterFind = [];
|
||||
protected $beforeDelete = [];
|
||||
protected $afterDelete = [];
|
||||
|
||||
|
||||
}
|
||||
51
ci4/app/Models/Wiki/WikiFileModel.php
Normal file
51
ci4/app/Models/Wiki/WikiFileModel.php
Normal file
@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models\Wiki;
|
||||
|
||||
use App\Entities\Wiki\WikiFileEntity;
|
||||
use CodeIgniter\Model;
|
||||
|
||||
class WikiFileModel extends Model
|
||||
{
|
||||
protected $table = 'wiki_files';
|
||||
protected $primaryKey = 'id';
|
||||
protected $useAutoIncrement = true;
|
||||
protected $returnType = WikiFileEntity::class;
|
||||
protected $useSoftDeletes = false;
|
||||
protected $protectFields = true;
|
||||
protected $allowedFields = [
|
||||
"content_id",
|
||||
"path"
|
||||
|
||||
];
|
||||
|
||||
protected bool $allowEmptyInserts = false;
|
||||
protected bool $updateOnlyChanged = true;
|
||||
|
||||
protected array $casts = [];
|
||||
protected array $castHandlers = [];
|
||||
|
||||
// Dates
|
||||
protected $useTimestamps = true;
|
||||
protected $dateFormat = 'datetime';
|
||||
protected $createdField = 'created_at';
|
||||
protected $updatedField = 'updated_at';
|
||||
protected $deletedField = 'deleted_at';
|
||||
|
||||
// Validation
|
||||
protected $validationRules = [];
|
||||
protected $validationMessages = [];
|
||||
protected $skipValidation = false;
|
||||
protected $cleanValidationRules = true;
|
||||
|
||||
// Callbacks
|
||||
protected $allowCallbacks = true;
|
||||
protected $beforeInsert = [];
|
||||
protected $afterInsert = [];
|
||||
protected $beforeUpdate = [];
|
||||
protected $afterUpdate = [];
|
||||
protected $beforeFind = [];
|
||||
protected $afterFind = [];
|
||||
protected $beforeDelete = [];
|
||||
protected $afterDelete = [];
|
||||
}
|
||||
49
ci4/app/Models/Wiki/WikiPageModel.php
Normal file
49
ci4/app/Models/Wiki/WikiPageModel.php
Normal file
@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models\Wiki;
|
||||
|
||||
use App\Entities\Wiki\WikiPageEntity;
|
||||
use CodeIgniter\Model;
|
||||
|
||||
class WikiPageModel extends Model
|
||||
{
|
||||
protected $table = 'wiki_pages';
|
||||
protected $primaryKey = 'id';
|
||||
protected $useAutoIncrement = true;
|
||||
protected $returnType = WikiPageEntity::class;
|
||||
protected $useSoftDeletes = true;
|
||||
protected $protectFields = true;
|
||||
protected $allowedFields = [
|
||||
"section_id",
|
||||
];
|
||||
|
||||
protected bool $allowEmptyInserts = false;
|
||||
protected bool $updateOnlyChanged = true;
|
||||
|
||||
protected array $casts = [];
|
||||
protected array $castHandlers = [];
|
||||
|
||||
// Dates
|
||||
protected $useTimestamps = true;
|
||||
protected $dateFormat = 'datetime';
|
||||
protected $createdField = 'created_at';
|
||||
protected $updatedField = 'updated_at';
|
||||
protected $deletedField = 'deleted_at';
|
||||
|
||||
// Validation
|
||||
protected $validationRules = [];
|
||||
protected $validationMessages = [];
|
||||
protected $skipValidation = false;
|
||||
protected $cleanValidationRules = true;
|
||||
|
||||
// Callbacks
|
||||
protected $allowCallbacks = true;
|
||||
protected $beforeInsert = [];
|
||||
protected $afterInsert = [];
|
||||
protected $beforeUpdate = [];
|
||||
protected $afterUpdate = [];
|
||||
protected $beforeFind = [];
|
||||
protected $afterFind = [];
|
||||
protected $beforeDelete = [];
|
||||
protected $afterDelete = [];
|
||||
}
|
||||
63
ci4/app/Models/Wiki/WikiSectionModel.php
Normal file
63
ci4/app/Models/Wiki/WikiSectionModel.php
Normal file
@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models\Wiki;
|
||||
|
||||
use App\Entities\Wiki\WikiSectionEntity;
|
||||
use CodeIgniter\Model;
|
||||
|
||||
class WikiSectionModel extends Model
|
||||
{
|
||||
protected $table = 'wiki_sections';
|
||||
protected $primaryKey = 'id';
|
||||
protected $useAutoIncrement = true;
|
||||
protected $returnType = WikiSectionEntity::class;
|
||||
protected $useSoftDeletes = true;
|
||||
protected $protectFields = true;
|
||||
protected $allowedFields = [
|
||||
"name",
|
||||
"slug",
|
||||
"icon",
|
||||
"order",
|
||||
"parent_id"
|
||||
];
|
||||
|
||||
protected bool $allowEmptyInserts = false;
|
||||
protected bool $updateOnlyChanged = true;
|
||||
|
||||
protected array $casts = [];
|
||||
protected array $castHandlers = [];
|
||||
|
||||
// Dates
|
||||
protected $useTimestamps = true;
|
||||
protected $dateFormat = 'datetime';
|
||||
protected $createdField = 'created_at';
|
||||
protected $updatedField = 'updated_at';
|
||||
protected $deletedField = 'deleted_at';
|
||||
|
||||
// Validation
|
||||
protected $validationRules = [];
|
||||
protected $validationMessages = [];
|
||||
protected $skipValidation = false;
|
||||
protected $cleanValidationRules = true;
|
||||
|
||||
// Callbacks
|
||||
protected $allowCallbacks = true;
|
||||
protected $beforeInsert = [];
|
||||
protected $afterInsert = [];
|
||||
protected $beforeUpdate = [];
|
||||
protected $afterUpdate = [];
|
||||
protected $beforeFind = [];
|
||||
protected $afterFind = [];
|
||||
protected $beforeDelete = [];
|
||||
protected $afterDelete = [];
|
||||
|
||||
/**
|
||||
* Get wiki sections
|
||||
*
|
||||
* @return array<WikiSectionEntity>
|
||||
*/
|
||||
public function sections() : array
|
||||
{
|
||||
return $this->orderBy('order','asc')->findAll();
|
||||
}
|
||||
}
|
||||
52
ci4/app/Models/Wiki/WikiSectionRoleModel.php
Normal file
52
ci4/app/Models/Wiki/WikiSectionRoleModel.php
Normal file
@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models\Wiki;
|
||||
|
||||
use App\Entities\Wiki\WikiSectionRoleEntity;
|
||||
use CodeIgniter\Model;
|
||||
|
||||
class WikiSectionRoleModel extends Model
|
||||
{
|
||||
protected $table = 'wiki_section_roles';
|
||||
protected $primaryKey = 'id';
|
||||
protected $useAutoIncrement = true;
|
||||
protected $returnType = WikiSectionRoleEntity::class;
|
||||
protected $useSoftDeletes = false;
|
||||
protected $protectFields = true;
|
||||
protected $allowedFields = [
|
||||
"wiki_section_id",
|
||||
"role"
|
||||
];
|
||||
|
||||
protected bool $allowEmptyInserts = false;
|
||||
protected bool $updateOnlyChanged = true;
|
||||
|
||||
protected array $casts = [];
|
||||
protected array $castHandlers = [];
|
||||
|
||||
// Dates
|
||||
protected $useTimestamps = true;
|
||||
protected $dateFormat = 'datetime';
|
||||
protected $createdField = 'created_at';
|
||||
protected $updatedField = 'updated_at';
|
||||
protected $deletedField = 'deleted_at';
|
||||
|
||||
// Validation
|
||||
protected $validationRules = [];
|
||||
protected $validationMessages = [];
|
||||
protected $skipValidation = false;
|
||||
protected $cleanValidationRules = true;
|
||||
|
||||
// Callbacks
|
||||
protected $allowCallbacks = true;
|
||||
protected $beforeInsert = [];
|
||||
protected $afterInsert = [];
|
||||
protected $beforeUpdate = [];
|
||||
protected $afterUpdate = [];
|
||||
protected $beforeFind = [];
|
||||
protected $afterFind = [];
|
||||
protected $beforeDelete = [];
|
||||
protected $afterDelete = [];
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,50 @@
|
||||
<!-- Modal -->
|
||||
<div class="modal fade" id="modalSection" tabindex="-1" aria-hidden="true">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title d-none" id="modalTitleNew"><?= lang('Wiki.new_section') ?></h5>
|
||||
<h5 class="modal-title d-none" id="modalTitleEdit"><?= lang('Wiki.edit_section') ?></h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="alert alert-primary" role="alert">
|
||||
<?= lang('Wiki.need_reload') ?>
|
||||
</div>
|
||||
<form id="formSection">
|
||||
<div class="form-group">
|
||||
<div class="row">
|
||||
<div class="col-12 mb-2">
|
||||
<label for="section-name" class="form-label"><?= lang('Wiki.name') ?></label>
|
||||
<input type="text" id="section-name" name="name" placeholder="<?= lang('Wiki.section_placeholder') ?>" class="form-control" required />
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="section-icon" class="form-label"><?= lang('Wiki.icon') ?></label>
|
||||
<select id="section-icon" class="select2-icons form-select">
|
||||
</select>
|
||||
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="section-roles" class="form-label"><?= lang('Wiki.roles') ?></label>
|
||||
<select id="section-roles" class="select2-icons form-select" name="roles[]" multiple>
|
||||
<?php
|
||||
foreach(config('AuthGroups')->groups as $key => $value):?>
|
||||
<option value="<?=$key?>"><?=isset($value['title']) ? $value['title'] : $key?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<?php if (auth()->user()->inGroup('admin')): ?>
|
||||
<button type="button" class="btn btn-label-secondary" data-bs-dismiss="modal"><?= lang('App.global_come_back') ?></button>
|
||||
<button type="button" id="submit-new-section" class="btn btn-primary d-none"><?= lang('App.global_save') ?></button>
|
||||
<button type="button" id="submit-update-section" class="btn btn-primary d-none"><?= lang('App.global_save') ?></button>
|
||||
<?php endif ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -346,6 +346,7 @@ $picture = "/assets/img/default-user.png";
|
||||
<!-- build:js assets/vendor/js/core.js -->
|
||||
<script src="<?= site_url('themes/vuexy/vendor/libs/jquery/jquery.js') ?>"></script>
|
||||
<script src="<?= site_url('themes/vuexy/vendor/libs/popper/popper.js') ?>"></script>
|
||||
<script src="<?= site_url('themes/vuexy/vendor/libs/jquery/jquery.js') ?>"></script>
|
||||
<script src="<?= site_url('themes/vuexy/vendor/js/bootstrap.js') ?>"></script>
|
||||
<script src="<?= site_url('themes/vuexy/vendor/libs/flatpickr/flatpickr.js') ?>"></script>
|
||||
<script src="<?= site_url('themes/vuexy/vendor/libs/perfect-scrollbar/perfect-scrollbar.js') ?>"></script>
|
||||
|
||||
@ -47,11 +47,15 @@
|
||||
require "menus/configuracion_menu.php";
|
||||
|
||||
require "menus/mensajes_menu.php";
|
||||
|
||||
require "menus/wiki_menu.php";
|
||||
|
||||
require "menus/soporte_menu.php";
|
||||
|
||||
require "menus/sistema_menu.php";
|
||||
|
||||
|
||||
|
||||
?>
|
||||
|
||||
</ul>
|
||||
|
||||
16
ci4/app/Views/themes/vuexy/main/menus/wiki_menu.php
Normal file
16
ci4/app/Views/themes/vuexy/main/menus/wiki_menu.php
Normal file
@ -0,0 +1,16 @@
|
||||
|
||||
<!-- Messages -->
|
||||
<li class="menu-item">
|
||||
<?php if(auth()->user()->inGroup('admin')):?>
|
||||
<a href="<?= route_to('showWikiPage','intro-admin') ?>" class="menu-link">
|
||||
<i class="menu-icon tf-icons ti ti-books"></i>
|
||||
<?= lang("Wiki.help") ?>
|
||||
</a>
|
||||
<?php endif;?>
|
||||
<?php if(auth()->user()->inGroup('cliente-editor')):?>
|
||||
<a href="<?= route_to('showWikiPage','intro-cliente') ?>" class="menu-link">
|
||||
<i class="menu-icon tf-icons ti ti-books"></i>
|
||||
<?= lang("Wiki.help") ?>
|
||||
</a>
|
||||
<?php endif;?>
|
||||
</li>
|
||||
54
ci4/app/Views/themes/vuexy/wiki/breadcrumbs.php
Normal file
54
ci4/app/Views/themes/vuexy/wiki/breadcrumbs.php
Normal file
@ -0,0 +1,54 @@
|
||||
<?php if (isset($breadcrumb)) { ?>
|
||||
<div id="bc-card" class="card sticky-breadcrumb border border-secondary mb-3">
|
||||
<div class="card-header header-elements">
|
||||
<nav aria-label="breadcrumb">
|
||||
<ol class="breadcrumb">
|
||||
<?php
|
||||
foreach ($breadcrumb as $item) {
|
||||
?>
|
||||
<li class="breadcrumb-item <?= $item['active'] ? 'active' : '' ?>">
|
||||
<a href="<?= $item['route'] ?>"><?= $item['title'] ?></a>
|
||||
</li>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
</ol>
|
||||
</nav>
|
||||
<div id="bc-save-div" class="card-header-elements ms-auto" style="display: none">
|
||||
<button id="bc-save"
|
||||
type="button"
|
||||
class="btn btn-sm btn-primary waves-effect waves-light"
|
||||
>
|
||||
<?= lang('Basic.global.Save') ?>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
} else { ?>
|
||||
<div class="card sticky-breadcrumb border border-secondary mb-3">
|
||||
<div class="card-header header-elements">
|
||||
<nav aria-label="breadcrumb">
|
||||
<ol class="breadcrumb">
|
||||
<li class="breadcrumb-item active">
|
||||
<a href="<?= site_url(); ?>">Home</a>
|
||||
</li>
|
||||
</ol>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
<?php } ?>
|
||||
|
||||
<?= $this->section('globalJsFunctions') ?>
|
||||
|
||||
function showBreadCrumbSaveButton(showIt = false){
|
||||
if(showIt === true){
|
||||
$('#bc-save-div').show();
|
||||
$('#bc-card').addClass('bg-warning');
|
||||
} else if(showIt === false){
|
||||
$('#bc-save-div').hide();
|
||||
$('#bc-card').removeClass('bg-warning');
|
||||
}
|
||||
}
|
||||
|
||||
<?= $this->endSection() ?>
|
||||
384
ci4/app/Views/themes/vuexy/wiki/layout.php
Normal file
384
ci4/app/Views/themes/vuexy/wiki/layout.php
Normal file
@ -0,0 +1,384 @@
|
||||
<?php
|
||||
$session = session();
|
||||
$settings = $session->get('settings');
|
||||
$picture = "/assets/img/default-user.png";
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html
|
||||
lang="<?= $session->get('lang') ?>"
|
||||
class="h-100 light-style layout-navbar-fixed layout-menu-fixed"
|
||||
dir="ltr"
|
||||
data-theme="theme-default"
|
||||
data-assets-path="<?= site_url('themes/vuexy/') ?>"
|
||||
data-template="vertical-menu-template-no-customizer">
|
||||
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta
|
||||
name="viewport"
|
||||
content="width=device-width, initial-scale=1.0, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0" />
|
||||
|
||||
<meta name="locale" content="<?= $session->get("lang") ?>">
|
||||
|
||||
<title><?= config('Safekat')->appName ?></title>
|
||||
|
||||
<meta name="description" content="" />
|
||||
|
||||
<!-- Favicon -->
|
||||
<link rel="icon" type="image/x-icon" href="<?= site_url('themes/vuexy/img/favicon/favicon.ico') ?>" />
|
||||
<link rel="apple-touch-icon" sizes="57x57" href="<?= site_url('themes/vuexy/img/favicon/apple-icon-57x57.png') ?>">
|
||||
<link rel="apple-touch-icon" sizes="60x60" href="<?= site_url('themes/vuexy/img/favicon/apple-icon-60x60.png') ?>">
|
||||
<link rel="apple-touch-icon" sizes="72x72" href="<?= site_url('themes/vuexy/img/favicon/apple-icon-72x72.png') ?>">
|
||||
<link rel="apple-touch-icon" sizes="76x76" href="<?= site_url('themes/vuexy/img/favicon/apple-icon-76x76.png') ?>">
|
||||
<link rel="apple-touch-icon" sizes="114x114"
|
||||
href="<?= site_url('themes/vuexy/img/favicon/apple-icon-114x114.png') ?>">
|
||||
<link rel="apple-touch-icon" sizes="120x120"
|
||||
href="<?= site_url('themes/vuexy/img/favicon/apple-icon-120x120.png') ?>">
|
||||
<link rel="apple-touch-icon" sizes="144x144"
|
||||
href="<?= site_url('themes/vuexy/img/favicon/apple-icon-144x144.png') ?>">
|
||||
<link rel="apple-touch-icon" sizes="152x152"
|
||||
href="<?= site_url('themes/vuexy/img/favicon/apple-icon-152x152.png') ?>">
|
||||
<link rel="apple-touch-icon" sizes="180x180"
|
||||
href="<?= site_url('themes/vuexy/img/favicon/apple-icon-180x180.png') ?>">
|
||||
<link rel="icon" type="image/png" sizes="192x192"
|
||||
href="<?= site_url('themes/vuexy/img/favicon/android-icon-192x192.png') ?>">
|
||||
<link rel="icon" type="image/png" sizes="32x32"
|
||||
href="<?= site_url('themes/vuexy/img/favicon/favicon-32x32.png') ?>">
|
||||
<link rel="icon" type="image/png" sizes="96x96"
|
||||
href="<?= site_url('themes/vuexy/img/favicon/favicon-96x96.png') ?>">
|
||||
<link rel="icon" type="image/png" sizes="16x16"
|
||||
href="<?= site_url('themes/vuexy/img/favicon/favicon-16x16.png') ?>">
|
||||
<link rel="manifest" href="<?= site_url('themes/vuexy/img/favicon/manifest.json') ?>">
|
||||
|
||||
<!-- Fonts -->
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=Public+Sans:ital,wght@0,300;0,400;0,500;0,600;0,700;1,300;1,400;1,500;1,600;1,700&display=swap"
|
||||
rel="stylesheet" />
|
||||
|
||||
<!-- Icons -->
|
||||
<link rel="stylesheet" href="<?= site_url('themes/vuexy/vendor/fonts/fontawesome.css') ?>" />
|
||||
<link rel="stylesheet" href="<?= site_url('themes/vuexy/vendor/fonts/tabler-icons.css') ?>" />
|
||||
<link rel="stylesheet" href="<?= site_url('themes/vuexy/vendor/fonts/flag-icons.css') ?>" />
|
||||
|
||||
<!-- Core CSS -->
|
||||
<link rel="stylesheet" href="<?= site_url('themes/vuexy/vendor/css/rtl/core.css') ?>" />
|
||||
<link rel="stylesheet" href="<?= site_url('themes/vuexy/vendor/css/rtl/theme-semi-dark.css') ?>" />
|
||||
<link rel="stylesheet" href="<?= site_url('themes/vuexy/css/safekat.css') ?>" />
|
||||
<link rel="stylesheet" href="<?= site_url('themes/vuexy/vendor/libs/flatpickr/flatpickr.css') ?>" />
|
||||
|
||||
|
||||
|
||||
<!-- Vendors CSS -->
|
||||
<link rel="stylesheet" href="<?= site_url('themes/vuexy/vendor/libs/perfect-scrollbar/perfect-scrollbar.css') ?>" />
|
||||
|
||||
<!-- Page CSS -->
|
||||
<?= $this->renderSection('css') ?>
|
||||
|
||||
<link rel="stylesheet" href="<?= site_url('themes/vuexy/css/safekat.css') ?>" />
|
||||
|
||||
|
||||
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<!-- Layout wrapper -->
|
||||
<div class="layout-wrapper layout-content-navbar">
|
||||
<div class="layout-container">
|
||||
<aside id="layout-menu" class="layout-menu menu-vertical menu bg-menu-theme">
|
||||
<div class="app-brand">
|
||||
<a href="<?= site_url('home') ?>" class="app-brand-link">
|
||||
<span class="app-brand-logo">
|
||||
<img src="<?= site_url('themes/vuexy/img/safekat/logos/sk-logo.png') ?>" width="150px">
|
||||
</span>
|
||||
</a>
|
||||
<a href="javascript:void(0);" class="layout-menu-toggle menu-link text-large ms-auto">
|
||||
<i class="ti menu-toggle-icon d-none d-xl-block ti-sm align-middle"></i>
|
||||
<i class="ti ti-x d-block d-xl-none ti-sm align-middle"></i>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="menu-inner-shadow"></div>
|
||||
|
||||
<ul class="menu-inner py-1 list-group list-group-flush" id="menu-inner-list">
|
||||
|
||||
<!-- Iterate throught sections -->
|
||||
|
||||
<?php foreach ($wiki_sections as $key => $value) : ?>
|
||||
<?php if (auth()->user()->inGroup(...$value->roles_array()) || auth()->user()->inGroup('admin')): ?>
|
||||
|
||||
<li class="menu-item <?= ($value->slug == $slug) ? "active" : "" ?>" data-id="<?= $value->id ?>">
|
||||
<!-- Check if user can view the section link -->
|
||||
<span class="d-flex justify-content-between align-items-center">
|
||||
<a href="<?= site_url("wiki/view/" . $value->slug) ?>" class="menu-link">
|
||||
<i class="menu-icon tf-icons <?= $value->icon ?>"></i>
|
||||
<?= lang("Wiki." . $value->slug) ?>
|
||||
</a>
|
||||
<?php if (auth()->user()->inGroup('admin')): ?>
|
||||
<i class="drag-handle cursor-grab icon-base ti ti-arrows-sort align-text-bottom me-2" title="<?= lang('Wiki.alt.sort') ?>"></i>
|
||||
<?php endif; ?>
|
||||
|
||||
</span>
|
||||
</li>
|
||||
<?php endif; ?>
|
||||
<?php endforeach; ?>
|
||||
|
||||
</ul>
|
||||
</aside>
|
||||
|
||||
<!-- Layout container -->
|
||||
<div class="layout-page">
|
||||
|
||||
<!-- Navbar -->
|
||||
<nav
|
||||
class="layout-navbar container-fluid navbar navbar-expand-xl navbar-detached align-items-center bg-navbar-theme"
|
||||
id="layout-navbar">
|
||||
<div class="layout-menu-toggle navbar-nav align-items-xl-center me-3 me-xl-0 d-xl-none">
|
||||
<a class="nav-item nav-link px-0 me-xl-4" href="javascript:void(0)">
|
||||
<i class="ti ti-menu-2 ti-sm"></i>
|
||||
</a>
|
||||
</div>
|
||||
<div class="navbar-nav-left d-flex align-items-center" id="navbar-collapse">
|
||||
|
||||
<ul class="navbar-nav flex-row justify-content-start align-items-center ms-auto">
|
||||
<div>
|
||||
<a class="nav-link" href="<?= route_to("home") ?>">
|
||||
<i class="ti ti-home rounded-circle me-1 fs-3"></i>
|
||||
</a>
|
||||
</div>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="navbar-nav-right d-flex align-items-center" id="navbar-collapse">
|
||||
|
||||
<ul class="navbar-nav flex-row justify-content-start align-items-center ms-auto">
|
||||
|
||||
<!-- Language -->
|
||||
<li class="nav-item dropdown-language dropdown me-2 me-xl-0">
|
||||
<a class="nav-link dropdown-toggle hide-arrow" href="javascript:void(0);"
|
||||
data-bs-toggle="dropdown">
|
||||
<i class="fi <?= getCurrentLanguageFlag(); ?> fis rounded-circle me-1 fs-3"></i>
|
||||
</a>
|
||||
|
||||
<ul class="dropdown-menu dropdown-menu-end">
|
||||
<li>
|
||||
<a class="dropdown-item" href="<?= site_url('lang/es'); ?>" data-language="es">
|
||||
<i class="fi fi-es fis rounded-circle me-1 fs-3"></i>
|
||||
<span class="align-middle"><?= lang("App.lang_es") ?></span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="dropdown-item" href="<?= site_url('lang/en'); ?>" data-language="en">
|
||||
<i class="fi fi-gb fis rounded-circle me-1 fs-3"></i>
|
||||
<span class="align-middle"><?= lang("App.lang_en") ?></span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<!-- User -->
|
||||
<li class="nav-item navbar-dropdown dropdown-user dropdown">
|
||||
<a class="nav-link dropdown-toggle hide-arrow" href="javascript:void(0);"
|
||||
data-bs-toggle="dropdown">
|
||||
<div class="avatar">
|
||||
<img src="<?= $picture ?? '' ?>" alt class="h-auto rounded-circle" />
|
||||
</div>
|
||||
</a>
|
||||
<ul class="dropdown-menu dropdown-menu-end">
|
||||
<li>
|
||||
<a class="dropdown-item" href="#">
|
||||
<div class="d-flex">
|
||||
<div class="flex-shrink-0 me-3">
|
||||
<div class="avatar avatar">
|
||||
<img src="<?= $picture ?? '' ?>" alt class="h-auto rounded-circle" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex-grow-1">
|
||||
<span class="fw-semibold d-block"><?= auth()->user()->getFullName(); ?></span>
|
||||
<small class="text-muted"><?= auth()->user()->getEmail(); ?></small>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<div class="dropdown-divider"></div>
|
||||
</li>
|
||||
<li>
|
||||
<a class="dropdown-item" href="<?= site_url('profile'); ?>">
|
||||
<i class="ti ti-user-check me-2 ti-sm"></i>
|
||||
<span class="align-middle"><?= lang("App.menu_profile") ?></span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<div class="dropdown-divider"></div>
|
||||
</li>
|
||||
<li>
|
||||
<a class="dropdown-item" id="btn-log-out" href="<?= site_url("logout") ?>">
|
||||
<i class="ti ti-logout me-2 ti-sm"></i>
|
||||
<span class="align-middle"><?= lang("App.menu_logout") ?></span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<!--/ User -->
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</nav>
|
||||
<!-- / Navbar -->
|
||||
|
||||
<!-- Content wrapper -->
|
||||
<div class="content-wrapper">
|
||||
<!-- Content -->
|
||||
|
||||
<div class="container-fluid flex-grow-1 container-p-y">
|
||||
<?php
|
||||
// Include breadcrumbs block
|
||||
include "breadcrumbs.php"
|
||||
?>
|
||||
|
||||
<?=
|
||||
// Render the content section
|
||||
$this->renderSection('content')
|
||||
?>
|
||||
</div>
|
||||
<!-- / Content -->
|
||||
|
||||
<!-- Footer -->
|
||||
<footer class="content-footer footer bg-footer-theme">
|
||||
<div class="container-fluid">
|
||||
<div class="footer-container d-flex align-items-center justify-content-between py-2 flex-md-row flex-column">
|
||||
<div>
|
||||
<a href="#" target="_blank" class="fw-semibold">Safekat</a> © <?= date('Y'); ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
<!-- / Footer -->
|
||||
|
||||
<div class="content-backdrop fade"></div>
|
||||
</div>
|
||||
<!-- Content wrapper -->
|
||||
</div>
|
||||
<!-- / Layout page -->
|
||||
</div>
|
||||
|
||||
<!-- Overlay -->
|
||||
<div class="layout-overlay layout-menu-toggle"></div>
|
||||
|
||||
<!-- Drag Target Area To SlideIn Menu On Small Screens -->
|
||||
<div class="drag-target"></div>
|
||||
</div>
|
||||
<!-- / Layout wrapper -->
|
||||
|
||||
<?= $this->renderSection('footerAdditions') ?>
|
||||
|
||||
<!-- Core JS -->
|
||||
<!-- build:js assets/vendor/js/core.js -->
|
||||
<script src="<?= site_url('themes/vuexy/vendor/libs/jquery/jquery.js') ?>"></script>
|
||||
<script src="<?= site_url('themes/vuexy/vendor/libs/popper/popper.js') ?>"></script>
|
||||
<script src="<?= site_url('themes/vuexy/vendor/js/bootstrap.js') ?>"></script>
|
||||
<script src="<?= site_url('themes/vuexy/vendor/libs/flatpickr/flatpickr.js') ?>"></script>
|
||||
<script src="<?= site_url('themes/vuexy/vendor/libs/perfect-scrollbar/perfect-scrollbar.js') ?>"></script>
|
||||
<script src="<?= site_url('themes/vuexy/vendor/libs/hammer/hammer.js') ?>"></script>
|
||||
<script src="<?= site_url('themes/vuexy/vendor/js/menu.js') ?>"></script>
|
||||
|
||||
|
||||
<script type="module" src="<?= site_url('assets/js/safekat/pages/layout.js') ?>"></script>
|
||||
<!-- Helpers -->
|
||||
<script src="<?= site_url('themes/vuexy/vendor/js/helpers.js') ?>"></script>
|
||||
<script src="<?= site_url('themes/vuexy/js/config.js') ?>"></script>
|
||||
|
||||
<!-- endbuild -->
|
||||
|
||||
<!-- Vendors JS -->
|
||||
<?= $this->renderSection('additionalExternalJs') ?>
|
||||
|
||||
<script src="<?= site_url('themes/vuexy/js/main.js') ?>"></script>
|
||||
<?php if (auth()->user()->inGroup('admin')): ?>
|
||||
<script type="module" src="<?= site_url('assets/js/safekat/pages/wiki/menuSortable.js') ?>"></script>
|
||||
<?php endif; ?>
|
||||
|
||||
|
||||
<?= sweetAlert() ?>
|
||||
|
||||
<?php
|
||||
if (isset($global_js_variables)) {
|
||||
echo "<script>\n";
|
||||
foreach ($global_js_variables as $name => $value):
|
||||
echo "\t" . "var $name = $value;" . "\n";
|
||||
endforeach;
|
||||
echo "</script>\n";
|
||||
}
|
||||
?>
|
||||
|
||||
|
||||
<script type="text/javascript">
|
||||
<?= $this->renderSection('globalJsFunctions') ?>
|
||||
|
||||
var theTable;
|
||||
var <?= csrf_token() ?? 'token' ?>v = '<?= csrf_hash() ?>';
|
||||
|
||||
function yeniden(andac = null) {
|
||||
if (andac == null) {
|
||||
andac = <?= csrf_token() ?>v;
|
||||
} else {
|
||||
<?= csrf_token() ?>v = andac;
|
||||
}
|
||||
$('input[name="<?= csrf_token() ?>"]').val(andac);
|
||||
$('meta[name="<?= config('Security')->tokenName ?>"]').attr('content', andac)
|
||||
$.ajaxSetup({
|
||||
headers: {
|
||||
'<?= config('Security')->headerName ?>': andac,
|
||||
'X-Requested-With': 'XMLHttpRequest'
|
||||
},
|
||||
<?= csrf_token() ?>: andac
|
||||
});
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
|
||||
function adjustSidebar4ContentWrapper() {
|
||||
if ($('#sidebar').hasClass('d-none') && $(window).width() <= 768) {
|
||||
$('#contentWrapper').addClass('full-width');
|
||||
} else {
|
||||
if (!$('#sidebar').hasClass('inactive')) {
|
||||
$('#contentWrapper').removeClass('full-width');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
adjustSidebar4ContentWrapper();
|
||||
|
||||
$('#sidebarCollapse').on('click', function() {
|
||||
|
||||
if ($('#sidebar').hasClass('d-none') && $(window).width() <= 768) {
|
||||
$('#sidebar').removeClass('d-none d-sm-none d-md-block');
|
||||
|
||||
$('#contentWrapper').removeClass('full-width');
|
||||
} else {
|
||||
$('#sidebar').toggleClass('inactive');
|
||||
$('#contentWrapper').toggleClass('full-width');
|
||||
$('.collapse.in').toggleClass('in');
|
||||
$('a[aria-expanded=true]').attr('aria-expanded', 'false');
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
$(window).resize(function() {
|
||||
adjustSidebar4ContentWrapper();
|
||||
});
|
||||
|
||||
<?= $this->renderSection('additionalInlineJs') ?>
|
||||
|
||||
});
|
||||
</script>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
102
ci4/app/Views/themes/vuexy/wiki/pages/render.php
Normal file
102
ci4/app/Views/themes/vuexy/wiki/pages/render.php
Normal file
@ -0,0 +1,102 @@
|
||||
<?= $this->include('themes/_commonPartialsBs/select2bs5') ?>
|
||||
<?= $this->include('themes/_commonPartialsBs/datatables') ?>
|
||||
<?= $this->include('themes/_commonPartialsBs/_confirm2delete') ?>
|
||||
<?= $this->include("themes/_commonPartialsBs/sweetalert") ?>
|
||||
<?= $this->extend('themes/vuexy/wiki/layout') ?>
|
||||
<?php
|
||||
|
||||
use CodeIgniter\I18n\Time;
|
||||
?>
|
||||
<?= $this->section('content'); ?>
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
|
||||
<div class="card card-info">
|
||||
<div class="card-header">
|
||||
<div class="row">
|
||||
<div class="col-md-10 col-xs-12 col-sm-12 d-flex flex-row flex-wrap justify-content-start align-items-center pb-2 gap-2">
|
||||
<?php if ($section->content()?->published_data): ?>
|
||||
<span class="badge badge-center rounded-pill text-bg-success"><i class="ti ti-check"></i></span>
|
||||
<strong><?= lang('Wiki.published') ?></strong>
|
||||
<strong><?= $section->content()->published_at ? Time::createFromFormat('Y-m-d H:i:s', $section->content()->published_at)->format('d/m/Y H:i') : "" ?></strong>
|
||||
<strong class="text-secondary"><?= $section->content()->publish_by() ?></strong>
|
||||
|
||||
<?php else: ?>
|
||||
<span class="badge badge-center rounded-pill text-bg-danger"><i class="ti ti-alert-circle"></i></span>
|
||||
<strong><?= lang('Wiki.not_published') ?></strong>
|
||||
<?php endif; ?>
|
||||
|
||||
|
||||
</div>
|
||||
<?php if (auth()->user()->inGroup('admin')): ?>
|
||||
<div class="col-md-2 d-flex flex-row flex-wrap justify-content-end align-items-stretch pb-2 gap-2">
|
||||
<div class="btn-sm-group">
|
||||
<button type="button" class="btn btn-sm btn-primary btn-icon rounded-pill dropdown-toggle hide-arrow" data-bs-toggle="dropdown">
|
||||
<i class="icon-base ti ti-dots-vertical"></i>
|
||||
</button>
|
||||
<ul class="dropdown-menu">
|
||||
<li><button type="button" class="dropdown-item btn btn-success btn-xs col-xs-12 " id="new-section"><i class="icon-base ti ti-plus icon-xs me-2"></i><?= lang('Wiki.new_section') ?></button></li>
|
||||
<li><button type="button" class="dropdown-item btn btn-warning btn-xs col-auto " id="edit-section"><i class="icon-base ti ti-pencil icon-xs me-2"></i><?= lang('Wiki.edit_section') ?></button></li>
|
||||
<li><button type="button" class="dropdown-item btn btn-danger btn-xs col-auto " id="delete-section"><i class="icon-base ti ti-trash icon-xs me-2"></i><?= lang('Wiki.delete_section') ?></button></li>
|
||||
|
||||
<li>
|
||||
<hr class="dropdown-divider">
|
||||
</li>
|
||||
<li><button type="button" class="dropdown-item btn btn-primary btn-xs col-auto " id="save-editor"><i class="icon-base ti ti-device-floppy icon-xs me-2"></i><?= lang('App.global_save') ?></button></li>
|
||||
<li><button type="button" class="dropdown-item btn btn-danger btn-xs col-auto " id="release-editor"><i class="icon-base ti ti-upload icon-xs me-2"></i><?= lang('Wiki.release') ?></button></li>
|
||||
<li><button type="button" class="dropdown-item btn btn-secondary btn-xs d-none col-auto " id="preview-editor"><i class="icon-base ti ti-eye icon-xs me-2"></i><?= lang('Wiki.preview') ?></button></li>
|
||||
<li><button type="button" class="dropdown-item btn btn-warning btn-xs col-auto " id="edit-editor"><i class="icon-base ti ti-pencil icon-xs me-2"></i><?= lang('Wiki.edit') ?></button></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="btn-sm-group">
|
||||
<button type="button" class="btn btn-sm btn-warning btn-icon rounded-pill dropdown-toggle hide-arrow" data-bs-toggle="dropdown" title="<?=lang('Wiki.dropdown_roles')?>">
|
||||
<i class="icon-base ti ti-users"></i>
|
||||
</button>
|
||||
<ul class="dropdown-menu">
|
||||
<?php foreach ($section->roles() as $key => $roleEntity): ?>
|
||||
<li><span class="dropdown-item badge bg-label-success"><?=config("AuthGroups")->groups[$roleEntity->role]["title"]?></span></li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div><!--//.card-header -->
|
||||
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<form action="POST" id="form-wiki">
|
||||
<input type="hidden" name="slug" id="section-slug">
|
||||
<input type="hidden" name="wiki_page_id" id="wiki-section-id" value="<?= $section->id ?>">
|
||||
<input type="hidden" name="wiki_page_id" id="wiki-page-id">
|
||||
<input type="hidden" name="wiki_page_id" id="wiki-content-id">
|
||||
</form>
|
||||
<div class="col-md-12">
|
||||
<div id="editorjs"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div><!--//.card-body -->
|
||||
<div class="card-footer">
|
||||
|
||||
</div><!--//.card-footer -->
|
||||
</div><!--//.card -->
|
||||
</div><!--//.col -->
|
||||
</div><!--//.row -->
|
||||
<?= view("themes/vuexy/components/modals/modalSection") ?>
|
||||
|
||||
<?= $this->endSection() ?>
|
||||
|
||||
<?= $this->section('css') ?>
|
||||
<link rel="stylesheet" href="<?= site_url('themes/vuexy/vendor/libs/sweetalert2/sweetalert2.css') ?>" />
|
||||
<?= $this->endSection() ?>
|
||||
|
||||
<?= $this->section("additionalExternalJs") ?>
|
||||
|
||||
<script src="<?= site_url('themes/vuexy/vendor/libs/sweetalert2/sweetalert2.js') ?>"></script>
|
||||
<?php if (auth()->user()->inGroup('admin')) : ?>
|
||||
<script type="module" src="<?= site_url('assets/js/safekat/pages/wiki/home.js') ?>"></script>
|
||||
<?php else : ?>
|
||||
<script type="module" src="<?= site_url('assets/js/safekat/pages/wiki/viewOnly.js') ?>"></script>
|
||||
<?php endif; ?>
|
||||
|
||||
<?= $this->endSection() ?>
|
||||
30
ci4/app/Views/themes/vuexy/wiki/sidebar.php
Normal file
30
ci4/app/Views/themes/vuexy/wiki/sidebar.php
Normal file
@ -0,0 +1,30 @@
|
||||
<!-- Menu -->
|
||||
<aside id="layout-menu" class="layout-menu menu-vertical menu bg-menu-theme">
|
||||
<div class="app-brand">
|
||||
<a href="<?= site_url('home') ?>" class="app-brand-link">
|
||||
<span class="app-brand-logo">
|
||||
<img src="<?= site_url('themes/vuexy/img/safekat/logos/sk-logo.png') ?>" width="150px">
|
||||
</span>
|
||||
</a>
|
||||
<a href="javascript:void(0);" class="layout-menu-toggle menu-link text-large ms-auto">
|
||||
<i class="ti menu-toggle-icon d-none d-xl-block ti-sm align-middle"></i>
|
||||
<i class="ti ti-x d-block d-xl-none ti-sm align-middle"></i>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="menu-inner-shadow"></div>
|
||||
|
||||
<ul class="menu-inner py-1">
|
||||
|
||||
<li class="menu-item">
|
||||
<?php foreach ($wiki_sections as $key => $value) :?>
|
||||
<a href="<?= site_url("wiki/presupuesto")?>" class="menu-link menu-toggle" data-id="<?= $slug ?>">
|
||||
<i class="menu-icon tf-icons ti ti-book"></i>
|
||||
<?= lang("App.menu_presupuestos") ?>
|
||||
</a>
|
||||
<?php endforeach;?>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</aside>
|
||||
<!-- / Menu -->
|
||||
Reference in New Issue
Block a user