Compare commits

..

17 Commits

Author SHA1 Message Date
7c951565bd bd 13.0 2024-05-24 18:03:12 +03:00
eb361ff002 bd 12.0 2024-05-21 15:53:19 +03:00
8e13f4a425 bd 11.0 2024-05-03 18:11:43 +03:00
143fa9f324 bd 10.0 2024-05-02 17:52:03 +03:00
f26754ca79 bd 9.0 2024-04-22 11:31:44 +03:00
13dbef5b4f bd 8.0 2024-04-17 17:30:00 +03:00
05cbb7ef43 bd 7.0 2024-04-16 17:54:37 +03:00
a3faec247e bd 7.0 2024-04-16 17:13:42 +03:00
87deac2576 bd 6.0 2024-04-15 17:46:33 +03:00
569c9348ba bd 5.0 2024-04-05 18:47:38 +03:00
38ec704a03 bd 4.0 2024-04-04 17:47:39 +03:00
cfe5b3cca5 bd 3.0 2024-04-03 18:25:38 +03:00
09b5167a1a bd 2.0 2024-04-02 18:00:13 +03:00
a0458705fb bd 1.0 2024-04-01 17:56:37 +03:00
432b2547cf bd 2024-03-29 17:47:46 +03:00
74719c7250 bd 2024-03-27 17:24:47 +03:00
e91e44ded9 bd 2024-03-25 18:07:54 +03:00
112 changed files with 5221 additions and 44 deletions

5
.env Executable file
View File

@ -0,0 +1,5 @@
DB_DRIVER=mysql
DB_HOST="127.0.0.1"
DB_NAME=forms
DB_USER=root
DB_PASSWORD=kali

0
.gitignore vendored Normal file → Executable file
View File

19
bootstrap/db.php Executable file
View File

@ -0,0 +1,19 @@
<?php
require "vendor/autoload.php";
use Dotenv\Dotenv;
use Illuminate\Database\Capsule\Manager as Capsule;
$dotenv = Dotenv::createImmutable(ROOT_PATH);
$dotenv->load();
$capsule = new Capsule;
$capsule->addConnection([
"driver" => "mysql",
"host" =>"127.0.0.1",
"database" => "forms",
"username" => "root",
"password" => "kali"
]);
$capsule->setAsGlobal();
$capsule->bootEloquent();

0
checkPOST.php Normal file → Executable file
View File

View File

@ -0,0 +1,96 @@
<?php
use Twig\Environment;
use Twig\Error\LoaderError;
use Twig\Error\RuntimeError;
use Twig\Extension\SandboxExtension;
use Twig\Markup;
use Twig\Sandbox\SecurityError;
use Twig\Sandbox\SecurityNotAllowedTagError;
use Twig\Sandbox\SecurityNotAllowedFilterError;
use Twig\Sandbox\SecurityNotAllowedFunctionError;
use Twig\Source;
use Twig\Template;
/* main/index.html.twig */
class __TwigTemplate_09ccf709a9c7f01a6f9c635608c9f350 extends Template
{
private $source;
private $macros = [];
public function __construct(Environment $env)
{
parent::__construct($env);
$this->source = $this->getSourceContext();
$this->blocks = [
'title' => [$this, 'block_title'],
'content' => [$this, 'block_content'],
];
}
protected function doGetParent(array $context)
{
// line 1
return "layouts/simple.html.twig";
}
protected function doDisplay(array $context, array $blocks = [])
{
$macros = $this->macros;
$this->parent = $this->loadTemplate("layouts/simple.html.twig", "main/index.html.twig", 1);
$this->parent->display($context, array_merge($this->blocks, $blocks));
}
// line 3
public function block_title($context, array $blocks = [])
{
$macros = $this->macros;
echo twig_escape_filter($this->env, ($context["title"] ?? null), "html", null, true);
}
// line 5
public function block_content($context, array $blocks = [])
{
$macros = $this->macros;
// line 6
echo " ";
echo twig_escape_filter($this->env, $this->env->getFunction('create_form')->getCallable()(), "html", null, true);
echo "
";
// line 7
echo twig_escape_filter($this->env, ($context["content"] ?? null), "html", null, true);
echo "
";
}
/**
* @codeCoverageIgnore
*/
public function getTemplateName()
{
return "main/index.html.twig";
}
/**
* @codeCoverageIgnore
*/
public function isTraitable()
{
return false;
}
/**
* @codeCoverageIgnore
*/
public function getDebugInfo()
{
return array ( 63 => 7, 58 => 6, 54 => 5, 47 => 3, 36 => 1,);
}
public function getSourceContext()
{
return new Source("", "main/index.html.twig", "/home/kali/php/untitled/views/main/index.html.twig");
}
}

View File

@ -0,0 +1,98 @@
<?php
use Twig\Environment;
use Twig\Error\LoaderError;
use Twig\Error\RuntimeError;
use Twig\Extension\SandboxExtension;
use Twig\Markup;
use Twig\Sandbox\SecurityError;
use Twig\Sandbox\SecurityNotAllowedTagError;
use Twig\Sandbox\SecurityNotAllowedFilterError;
use Twig\Sandbox\SecurityNotAllowedFunctionError;
use Twig\Source;
use Twig\Template;
/* form/resultItem.html.twig */
class __TwigTemplate_94bc2d1f79a7d79af045673fc12da74a extends Template
{
private $source;
private $macros = [];
public function __construct(Environment $env)
{
parent::__construct($env);
$this->source = $this->getSourceContext();
$this->blocks = [
'title' => [$this, 'block_title'],
'content' => [$this, 'block_content'],
];
}
protected function doGetParent(array $context)
{
// line 1
return "layouts/simple.html.twig";
}
protected function doDisplay(array $context, array $blocks = [])
{
$macros = $this->macros;
$this->parent = $this->loadTemplate("layouts/simple.html.twig", "form/resultItem.html.twig", 1);
$this->parent->display($context, array_merge($this->blocks, $blocks));
}
// line 3
public function block_title($context, array $blocks = [])
{
$macros = $this->macros;
echo twig_escape_filter($this->env, ($context["title"] ?? null), "html", null, true);
}
// line 5
public function block_content($context, array $blocks = [])
{
$macros = $this->macros;
// line 6
echo " <h1 class=\"display-4\">";
echo twig_escape_filter($this->env, ($context["title"] ?? null), "html", null, true);
echo "</h1>
";
// line 8
echo twig_escape_filter($this->env, $this->env->getFunction('create_get_action')->getCallable()(), "html", null, true);
echo "
";
}
/**
* @codeCoverageIgnore
*/
public function getTemplateName()
{
return "form/resultItem.html.twig";
}
/**
* @codeCoverageIgnore
*/
public function isTraitable()
{
return false;
}
/**
* @codeCoverageIgnore
*/
public function getDebugInfo()
{
return array ( 64 => 8, 58 => 6, 54 => 5, 47 => 3, 36 => 1,);
}
public function getSourceContext()
{
return new Source("", "form/resultItem.html.twig", "/home/kali/php/untitled/views/form/resultItem.html.twig");
}
}

View File

@ -0,0 +1,97 @@
<?php
use Twig\Environment;
use Twig\Error\LoaderError;
use Twig\Error\RuntimeError;
use Twig\Extension\SandboxExtension;
use Twig\Markup;
use Twig\Sandbox\SecurityError;
use Twig\Sandbox\SecurityNotAllowedTagError;
use Twig\Sandbox\SecurityNotAllowedFilterError;
use Twig\Sandbox\SecurityNotAllowedFunctionError;
use Twig\Source;
use Twig\Template;
/* form/form.html.twig */
class __TwigTemplate_1782f108c6541d589defb1221fcbfccb extends Template
{
private $source;
private $macros = [];
public function __construct(Environment $env)
{
parent::__construct($env);
$this->source = $this->getSourceContext();
$this->blocks = [
'title' => [$this, 'block_title'],
'content' => [$this, 'block_content'],
];
}
protected function doGetParent(array $context)
{
// line 1
return "layouts/simple.html.twig";
}
protected function doDisplay(array $context, array $blocks = [])
{
$macros = $this->macros;
$this->parent = $this->loadTemplate("layouts/simple.html.twig", "form/form.html.twig", 1);
$this->parent->display($context, array_merge($this->blocks, $blocks));
}
// line 3
public function block_title($context, array $blocks = [])
{
$macros = $this->macros;
echo twig_escape_filter($this->env, ($context["title"] ?? null), "html", null, true);
}
// line 5
public function block_content($context, array $blocks = [])
{
$macros = $this->macros;
// line 6
echo " <h1 class=\"display-4\">";
echo twig_escape_filter($this->env, ($context["title"] ?? null), "html", null, true);
echo "</h1>
";
// line 7
echo twig_escape_filter($this->env, $this->env->getFunction('create_form')->getCallable()(), "html", null, true);
echo "
";
}
/**
* @codeCoverageIgnore
*/
public function getTemplateName()
{
return "form/form.html.twig";
}
/**
* @codeCoverageIgnore
*/
public function isTraitable()
{
return false;
}
/**
* @codeCoverageIgnore
*/
public function getDebugInfo()
{
return array ( 63 => 7, 58 => 6, 54 => 5, 47 => 3, 36 => 1,);
}
public function getSourceContext()
{
return new Source("", "form/form.html.twig", "/home/kali/php/untitled/views/form/form.html.twig");
}
}

View File

@ -0,0 +1,103 @@
<?php
use Twig\Environment;
use Twig\Error\LoaderError;
use Twig\Error\RuntimeError;
use Twig\Extension\SandboxExtension;
use Twig\Markup;
use Twig\Sandbox\SecurityError;
use Twig\Sandbox\SecurityNotAllowedTagError;
use Twig\Sandbox\SecurityNotAllowedFilterError;
use Twig\Sandbox\SecurityNotAllowedFunctionError;
use Twig\Source;
use Twig\Template;
/* layouts/simple.html.twig */
class __TwigTemplate_e48551b2ca758109aa7de7556ee07a2e extends Template
{
private $source;
private $macros = [];
public function __construct(Environment $env)
{
parent::__construct($env);
$this->source = $this->getSourceContext();
$this->parent = false;
$this->blocks = [
'title' => [$this, 'block_title'],
'content' => [$this, 'block_content'],
];
}
protected function doDisplay(array $context, array $blocks = [])
{
$macros = $this->macros;
// line 1
echo "<!DOCTYPE html>
<html lang=\"en\">
<head>
<meta charset=\"UTF-8\">
<title>";
// line 5
$this->displayBlock('title', $context, $blocks);
echo " </title>
<link rel=\"stylesheet\" href=\"vendor/twbs/bootstrap/dist/css/bootstrap.css\">
<link href=\"https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css\" rel=\"stylesheet\"
integrity=\"sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN\" crossorigin=\"anonymous\" />
</head>
<body>
<div class=\"container\">
<div class=\"row\">
<div class=\"col-12\">
";
// line 15
$this->displayBlock('content', $context, $blocks);
// line 16
echo " </div>
</div>
</div>
</body>
</html>";
}
// line 5
public function block_title($context, array $blocks = [])
{
$macros = $this->macros;
}
// line 15
public function block_content($context, array $blocks = [])
{
$macros = $this->macros;
}
/**
* @codeCoverageIgnore
*/
public function getTemplateName()
{
return "layouts/simple.html.twig";
}
/**
* @codeCoverageIgnore
*/
public function getDebugInfo()
{
return array ( 78 => 15, 72 => 5, 60 => 16, 58 => 15, 45 => 5, 39 => 1,);
}
public function getSourceContext()
{
return new Source("", "layouts/simple.html.twig", "/home/kali/php/untitled/views/layouts/simple.html.twig");
}
}

View File

@ -0,0 +1,102 @@
<?php
use Twig\Environment;
use Twig\Error\LoaderError;
use Twig\Error\RuntimeError;
use Twig\Extension\SandboxExtension;
use Twig\Markup;
use Twig\Sandbox\SecurityError;
use Twig\Sandbox\SecurityNotAllowedTagError;
use Twig\Sandbox\SecurityNotAllowedFilterError;
use Twig\Sandbox\SecurityNotAllowedFunctionError;
use Twig\Source;
use Twig\Template;
/* form/result.html.twig */
class __TwigTemplate_e631c8331e0b3314f0fca4478f143546 extends Template
{
private $source;
private $macros = [];
public function __construct(Environment $env)
{
parent::__construct($env);
$this->source = $this->getSourceContext();
$this->blocks = [
'title' => [$this, 'block_title'],
'content' => [$this, 'block_content'],
];
}
protected function doGetParent(array $context)
{
// line 1
return "layouts/simple.html.twig";
}
protected function doDisplay(array $context, array $blocks = [])
{
$macros = $this->macros;
$this->parent = $this->loadTemplate("layouts/simple.html.twig", "form/result.html.twig", 1);
$this->parent->display($context, array_merge($this->blocks, $blocks));
}
// line 3
public function block_title($context, array $blocks = [])
{
$macros = $this->macros;
echo twig_escape_filter($this->env, ($context["title"] ?? null), "html", null, true);
}
// line 5
public function block_content($context, array $blocks = [])
{
$macros = $this->macros;
// line 6
echo " <h1 class=\"display-4\">";
echo twig_escape_filter($this->env, ($context["title"] ?? null), "html", null, true);
echo "</h1>
";
// line 8
echo twig_escape_filter($this->env, $this->env->getFunction('create_table')->getCallable()(), "html", null, true);
echo "
";
// line 9
echo twig_escape_filter($this->env, $this->env->getFunction('create_pagination')->getCallable()(), "html", null, true);
echo "
";
}
/**
* @codeCoverageIgnore
*/
public function getTemplateName()
{
return "form/result.html.twig";
}
/**
* @codeCoverageIgnore
*/
public function isTraitable()
{
return false;
}
/**
* @codeCoverageIgnore
*/
public function getDebugInfo()
{
return array ( 68 => 9, 64 => 8, 58 => 6, 54 => 5, 47 => 3, 36 => 1,);
}
public function getSourceContext()
{
return new Source("", "form/result.html.twig", "/home/kali/php/untitled/views/form/result.html.twig");
}
}

7
composer.json Normal file → Executable file
View File

@ -14,6 +14,11 @@
"require": {
"twbs/bootstrap": "5.0.2",
"itguild/php-cg-select-v2": "^0.1.0",
"craft-group/phroute": "^2.1"
"craft-group/phroute": "^2.1",
"twig/twig": "^3.0",
"illuminate/database": "^11.0",
"vlucas/phpdotenv": "^5.6",
"illuminate/filesystem": "^11.1",
"rakit/validation": "^1.4"
}
}

1974
composer.lock generated Normal file → Executable file

File diff suppressed because it is too large Load Diff

30
console.php Executable file
View File

@ -0,0 +1,30 @@
<?php
use itguild\forms\migrations\UserMigration;
use Illuminate\Filesystem\Filesystem;
const ROOT_PATH = __DIR__;
require_once "vendor/autoload.php";
require_once "bootstrap/db.php";
//$fileSystem = new Filesystem();
//
//$migration = new \Illuminate\Database\Migrations\MigrationCreator($fileSystem, "migrations/stubs");
//
////try {
//// $migration->create("some", "migrations", "my");
////} catch (Exception $e) {
//// var_dump($e->getMessage());
////}
//$rep = new \Illuminate\Database\Migrations\DatabaseMigrationRepository();
//$migrator = new \Illuminate\Database\Migrations\Migrator()
//UserMigration::up();
//\itguild\forms\migrations\FormsMigration::up();
//\itguild\forms\migrations\InputsTypeMigration::up();
//\itguild\forms\migrations\FormsInputMigration::up();
//\itguild\forms\migrations\FormsResMigration::up();
//\itguild\forms\migrations\InputsValueMigrations::up();

0
example.php Normal file → Executable file
View File

0
example_json.php Normal file → Executable file
View File

30
form.json Normal file → Executable file
View File

@ -10,7 +10,9 @@
"placeholder": "Email",
"id": "emailId",
"label": {
"title": "Email", "for": "emailId", "class": "form-label"
"title": "Email",
"for": "emailId",
"class": "form-label"
},
"class": "form-control"
},
@ -27,10 +29,16 @@
"class": "form-control",
"id": "cityId",
"label": {
"title": "Выберите город", "for": "cityId", "class": "form-label"
"title": "Выберите город",
"for": "cityId",
"class": "form-label"
},
"value": 2,
"options": {"1": "Москва", "2": "Донецк", "3": "Ростов"}
"options": {
"1": "Москва",
"2": "Донецк",
"3": "Ростов"
}
},
{
"type": "textArea",
@ -44,7 +52,9 @@
"class": "",
"id": "agreeId",
"label": {
"title": "Согласен с правилами", "for": "agreeId", "class": "form-label"
"title": "Согласен с правилами",
"for": "agreeId",
"class": "form-label"
}
},
{
@ -55,3 +65,15 @@
}
]
}
{
"meta": {
"perpage": 3,
"actions": ["view", "edit", "delete"],
"fillable": ["description", "phone", "telega", "city"],
"status" : 1
},
"params": {
"class": "form-control",
"id": "form"
}
}

31
index.php Normal file → Executable file
View File

@ -2,18 +2,43 @@
ini_set("display_errors", 1);
error_reporting(-1);
const ROOT_PATH = __DIR__;
const BASE_URL = "http://forms.local";
const VIEW_PATH = __DIR__ . "/views";
const VIEW_CACHE_PATH = __DIR__ . "/compilation_cache";
require_once "vendor/autoload.php";
require_once "bootstrap/db.php";
use Phroute\Phroute\RouteCollector;
$router = new RouteCollector();
$router->get('/', [\itguild\forms\app\controllers\Main::class, 'indexAction']);
$router->get('/example', [\itguild\forms\app\controllers\Main::class, 'exampleAction']);
$router->get('/', [\itguild\forms\app\controllers\MainController::class, 'indexAction']);
$router->get('/example', [\itguild\forms\app\controllers\MainController::class, 'exampleAction']);
$router->get('/create-user', [\itguild\forms\app\controllers\UserController::class, 'createUserAction']);
$router->get('/get-user/{id}', [\itguild\forms\app\controllers\UserController::class, 'getUserAction']);
$router->get("/form/{id}", [\itguild\forms\app\controllers\FormController::class, "indexAction"]);
$router->get("/form-input/{id}", [\itguild\forms\app\controllers\FormInputController::class, "indexAction"]);
$router->get("/form-res/{id}", [\itguild\forms\app\controllers\FormResController::class, "indexAction"]);
$router->get("/input-type/{id}", [\itguild\forms\app\controllers\InputTypeController::class, "indexAction"]);
$router->get("/input-value/{id}", [\itguild\forms\app\controllers\InputValueController::class, "indexAction"]);
$router->post("/form-save/{id}", [\itguild\forms\app\controllers\FormController::class, "saveAction"]);
$router->get("/form-result/{id}/{page}?", [\itguild\forms\app\controllers\FormController::class, "resultAction"]);
$router->get("/form-item/{id}", [\itguild\forms\app\controllers\FormController::class, "viewAction"]);
$router->get("/form-delete/{id}", [\itguild\forms\app\controllers\FormController::class, "deleteAction"]);
$router->get("/form-edit/{id}", [\itguild\forms\app\controllers\FormController::class, "editAction"]);
$router->get("/admin/create-form", [\itguild\forms\app\controllers\AdminController::class, "createAction"]);
$router->post("/admin/save-form/", [\itguild\forms\app\controllers\AdminController::class, "saveFormAction"]);
$router->get("/admin/form-add-fields", [\itguild\forms\app\controllers\AdminController::class, "getFormAddFieldsAction"]);
$router->get("/admin/set-value-select", [\itguild\forms\app\controllers\AdminController::class, "getSelectValue"]);
$router->get("/admin/edit-form/{id}", [\itguild\forms\app\controllers\AdminController::class, "editFormAction"]);
$dispatcher = new Phroute\Phroute\Dispatcher($router->getData());
$response = $dispatcher->dispatch($_SERVER['REQUEST_METHOD'], parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH));
// Print out the value returned from the dispatched function
echo $response;

0
old_index.php Normal file → Executable file
View File

36
public/js/ajax.js Normal file
View File

@ -0,0 +1,36 @@
function getValueSelect(){
let selectValue = document.getElementById("selectID").value
let request = new XMLHttpRequest();
let button = document.getElementById("buttonAdd");
let count = parseInt(button.dataset.count) + 1;
button.dataset.count = count;
console.log(count);
request.open("GET", "/admin/set-value-select?value=" + selectValue + "&count=" + count, true)
request.addEventListener("load", () => {
let responseText = request.responseText;
let targetElement = document.getElementById("buttonAdd");
let divElement = document.createElement("div");
divElement.innerHTML = responseText;
targetElement.insertAdjacentElement("beforebegin", divElement);
let deleteButton = document.getElementById("deleteButton");
deleteButton.addEventListener("click", () => {
divElement.remove();
});
divElement.appendChild(deleteButton);
});
request.send()
}
document.addEventListener("DOMContentLoaded", function() {
let divElement = document.getElementsByClassName("form-block");
let deleteButton = document.getElementsByClassName("deleteButton");
console.log(deleteButton);
for(let i = 0; i < deleteButton.length; i++){
deleteButton[i].addEventListener("click", () => {
deleteButton[i].parentElement.remove();
});
}
});

15
public/style/main.css Normal file
View File

@ -0,0 +1,15 @@
.delete-button {
position: absolute;
top: 5px;
right: 5px;
text-decoration: none;
width: 20px;
height: 20px;
text-align: center;
vertical-align: baseline;
}
.form-block {
background-color: #bbbbbb;
position: relative;
}

2
routing.php Normal file → Executable file
View File

@ -8,4 +8,4 @@ use Phroute\Phroute\RouteCollector;
$router = new RouteCollector();
$router->get('/', [\itguild\forms\app\controllers\Main::class, 'indexAction']);
$router->get('/', [\itguild\forms\app\controllers\MainController::class, 'indexAction']);

5
src/ActiveForm.php Normal file → Executable file
View File

@ -4,6 +4,7 @@ namespace itguild\forms;
use itguild\forms\builders\ButtonBuilder;
use itguild\forms\builders\CheckBoxBuilder;
use itguild\forms\builders\HiddenBuilder;
use itguild\forms\builders\RadioButtonBuilder;
use itguild\forms\builders\SelectBuilder;
use itguild\forms\builders\TextAreaBuilder;
@ -12,6 +13,7 @@ use itguild\forms\debug\Debug;
use itguild\forms\inputs\BaseInput;
use itguild\forms\inputs\Button;
use itguild\forms\inputs\Checkbox;
use itguild\forms\inputs\Hidden;
use itguild\forms\inputs\RadioButton;
use itguild\forms\inputs\Select;
use itguild\forms\inputs\TextArea;
@ -61,6 +63,9 @@ class ActiveForm
elseif ($class === RadioButton::class){
$this->fieldObject = RadioButtonBuilder::build($name, $params);
}
elseif ($class === Hidden::class){
$this->fieldObject = HiddenBuilder::build($name, $params);
}
else {
$this->fieldObject = new $class($name, $params);
}

0
src/Form.php Normal file → Executable file
View File

22
src/JsonForm.php Normal file → Executable file
View File

@ -8,9 +8,11 @@ use itguild\forms\debug\Debug;
use itguild\forms\mappers\JsonInputMapper;
use itguild\forms\inputs\BaseInput;
use itguild\forms\ActiveForm;
use itguild\forms\traits\CreateParams;
class JsonForm
{
use CreateParams;
private $jsonData;
private $html = '';
@ -22,8 +24,21 @@ class JsonForm
}
public function beginForm($params = []): string
{
$paramsString = $this->createParams($params);
return "<form $paramsString >";
}
public function endForm(): string
{
return "</form>";
}
public function convertHTML(): void
{
$this->html .= $this->beginForm($this->jsonData['meta']);
foreach ($this->jsonData['data'] as $item) {
@ -47,7 +62,7 @@ class JsonForm
}
}
$this->html .= $this->endForm();
//return $this->fetch($html);
}
@ -66,4 +81,9 @@ class JsonForm
echo $this->html;
}
public function fetch(): string
{
return $this->html;
}
}

23
src/app/DTO/FormDTO.php Normal file
View File

@ -0,0 +1,23 @@
<?php
namespace itguild\forms\app\DTO;
use itguild\forms\app\core\CGDTO;
use itguild\forms\debug\Debug;
class FormDTO extends CGDTO
{
public string $title;
public $perPage;
public $id;
public string $view;
public string $edit;
public string $delete;
protected array $fillable = [
'title', 'id', 'perPage', 'view', 'edit', 'delete'
];
}

View File

@ -0,0 +1,200 @@
<?php
namespace itguild\forms\app\controllers;
use Illuminate\Database\Events\DatabaseBusy;
use itguild\forms\ActiveForm;
use itguild\forms\app\core\BaseController;
use itguild\forms\app\DTO\FormDTO;
use itguild\forms\app\models\FormInputModel;
use itguild\forms\app\models\FormModel;
use itguild\forms\app\models\InputTypeModel;
use itguild\forms\app\models\InputValueModel;
use itguild\forms\app\requests\CreateFormRequest;
use itguild\forms\core\cg_view\CgView;
/**
* @var \itguild\forms\ActiveForm $form ;
*/
use itguild\forms\core\CgRequest;
use itguild\forms\debug\Debug;
use itguild\forms\exceptions\CreateFormException;
use itguild\forms\exceptions\FieldTypeNotFound;
use itguild\forms\exceptions\FormNotFoundException;
use itguild\forms\Form;
use itguild\forms\helpers\TranslitorHelper;
use itguild\forms\inputs\Select;
use itguild\forms\inputs\TextInput;
use itguild\forms\inputs\TextArea;
use itguild\forms\JsonForm;
use Twig\TwigFunction;
class AdminController extends BaseController
{
public string $html;
public function createAction(): void
{
$this->cgView->layout = "/layouts/admin_layout.php";
$this->cgView->render("/admin/index.php", [
'title' => "Создать форму",
'form' => new ActiveForm(),
'dto' => new FormDTO(),
]);
}
/**
* @throws CreateFormException
*/
public function saveFormAction(): void
{
$request = new CreateFormRequest();
if (!$request->validate()) {
throw new CreateFormException("Validation error");
}
$title = $request->post('title');
$perPage = $request->post('perPage', 10);
$inputs = $request->post('InputForm', []);
$formId = $request->post('formId');
$actionView = $request->post("actionView");
$actionEdit = $request->post("actionEdit");
$actionDelete = $request->post("actionDelete");
$actions = [$actionView, $actionEdit, $actionDelete];
$resultArray = ['meta' => ['perpage' => $perPage, 'status' => "1", 'actions' => $actions], 'params' => ['class' => "form-control", 'id' => 'form']];
if ($formId) {
//FormModel::where('id', $formId)->update(['title' => $title, 'status' => FormModel::STATUS_ACTIVE, 'params' => json_encode($resultArray, true)]);
$form = FormModel::find($formId);
$form->title = $title;
$form->params = json_encode($resultArray, true);
$form->save();
FormInputModel::where('form_id', $form->id)->delete();
} else {
$form = FormModel::Create(['title' => $title, 'status' => FormModel::STATUS_ACTIVE, 'params' => json_encode($resultArray, true)]);
}
foreach ($inputs as $input) {
$name = TranslitorHelper::translit($input['name']);
$params = [
"name" => $name,
"class" => "form-control",
'placeholder' => $input['placeholder'] ?? null
];
if ($input['type'] == InputTypeModel::RADIO_TYPE) {
$radio = explode("\n", $input['radio']);
foreach ($radio as $key) {
$nameRadio = TranslitorHelper::translit($key);
$paramsRadio = [
"name" => $name,
"value" => $key,
'label' => ['title' => $key, 'for' => $key, "class" => 'form-label']
];
$formInput = FormInputModel::Create([
'form_id' => $form->id,
'input_type_id' => $input['type'],
'label' => $key,
'name' => $name,
'params' => json_encode($paramsRadio)
]);
}
} elseif ($input['type'] == InputTypeModel::SELECT_TYPE) {
$options = explode("\n", $input['options']);
$paramsRadio = [
"name" => $name,
'label' => ['title' => $input["name"], 'for' => $name, "class" => 'form-label']
];
$formInput = FormInputModel::Create([
'form_id' => $form->id,
'input_type_id' => $input['type'],
'label' => $input["name"],
'name' => $name,
'params' => json_encode($paramsRadio)
]);
foreach ($options as $option) {
InputValueModel::Create(['form_input_id' => $formInput->id, 'value' => $option]);
}
} else {
$formInput = FormInputModel::Create([
'form_id' => $form->id,
'input_type_id' => $input['type'],
'label' => $input['name'],
'name' => $name,
'params' => json_encode($params)
]);
}
}
$this->redirect("/form-result/" . $form->id);
}
public function getFormAddFieldsAction(): void
{
$this->cgView->render("/admin/_form_add_fields_ajax.php", ['form' => new ActiveForm()]);
}
public function getSelectValue(): void
{
$selectValue = $_GET["value"];
$countInput = $_GET["count"];
$form = new ActiveForm();
$viewName = InputTypeModel::getViewNameByTypeId($selectValue);
if (!$viewName) {
throw new FieldTypeNotFound($selectValue);
}
$this->cgView->render("/admin/field_type/$viewName.php", ['form' => new ActiveForm(), 'count' => $countInput]);
}
public function editFormAction($id)
{
$form = FormModel::find($id);
$dto = new FormDTO();
$formFields = $form->fields;
$formDataArr = $form->toArray();
$formArr = json_decode($formDataArr['params'], true);
$fillableRes = [];
$fillableRes['title'] = $formDataArr['title'];
$fillableRes['id'] = $formDataArr['id'];
foreach ($formArr['meta'] as $key => $value) {
if ($key == 'perpage') {
$fillableRes['perPage'] = (string)$value;
} else if ($key == "actions") {
foreach ($value as $item) {
$fillableRes[$item] = $item;
}
}
}
$dto->load($fillableRes);
if (!$form) {
throw new FormNotFoundException($id);
}
$this->cgView->layout = "/layouts/admin_layout.php";
$this->cgView->render("/admin/index.php", [
'title' => "Редактировать форму",
'form' => new ActiveForm(),
'dto' => $dto,
'fields' => $formFields,
]);
}
}

View File

@ -0,0 +1,340 @@
<?php
namespace itguild\forms\app\controllers;
use itguild\forms\app\core\BaseController;
use itguild\forms\app\models\FormModel;
use itguild\forms\app\models\FormResModel;
use itguild\forms\app\models\InputTypeModel;
use itguild\forms\app\models\InputValueModel;
use itguild\forms\builders\LabelBuilder;
use itguild\forms\debug\Debug;
use itguild\forms\exceptions\FormNotFoundException;
use itguild\forms\exceptions\FormResultNotFoundException;
use itguild\forms\Form;
use itguild\forms\JsonForm;
use itguild\forms\table\actionBtn\ToDeleteBtn;
use itguild\forms\table\actionBtn\ToEditBtn;
use itguild\forms\table\actionBtn\ToListBtn;
use itguild\forms\table\ListJsonTable;
use itguild\forms\table\Pagination;
use itguild\forms\table\ViewJsonTable;
use Twig\Error\LoaderError;
use Twig\Error\RuntimeError;
use Twig\Error\SyntaxError;
use Twig\TwigFunction;
class FormController extends BaseController
{
/**
* @throws SyntaxError
* @throws FormNotFoundException
* @throws RuntimeError
* @throws LoaderError
*/
public function indexAction($id): void
{
$form = FormModel::find($id);
if (!$form) {
throw new FormNotFoundException($id);
}
$formArr = $this->createFormArr($form);
$formArr['data'][] = ['type' => "button", 'typeInput' => "submit", "value" => "Отправить", "name" => "", "class" => "btn btn-primary"];
//Debug::dd($formArr);
$this->view->addFunction(new TwigFunction("create_form", function () use ($formArr) {
$form = new JsonForm(json_encode($formArr));
$form->convertHTML();
$form->render();
}));
echo $this->view->render('form/form.html.twig', ['title' => $form->title]);
}
public function saveAction($id): void
{
if (isset($_POST["form_res_id"])) {
$formResId = $_POST["form_res_id"];
unset($_POST["form_res_id"]);
FormResModel::where("id", $formResId)->update(["data" => json_encode($_POST)]);
} else {
$formRes = FormResModel::Create(['form_id' => $id, 'data' => json_encode($_POST),]);
$formResId = $formRes->id;
}
header('Location: ' . "/form-item/$formResId");
exit;
}
public function createFormAction()
{
$form = Form::Create(['title' => "dsds", 'status' => 1, 'params' => "",]);
}
public function resultAction($id, $page = 1): void
{
$meta = [];
$data = [];
$tableArr = [];
$columns = [];
$columnsToMod = [];
$form = FormModel::find($id);
$formParams = json_decode($form->params, true);
$perPage = $formParams['meta']['perpage'] ?? "10";
$fillable = $formParams["meta"]["fillable"] ?? null;
$actions = $formParams["meta"]["actions"] ?? null;
$offset = ($page - 1) * $perPage;
$countItems = FormResModel::where("status", 1)->where("form_id", $form->id)->count();
$table = FormResModel::where("form_id", $id)->where("status", FormResModel::STATUS_ACTIVE)->limit(3)->offset($offset)->get();
foreach ($table as $key => $item) {
$data[] = array_merge(json_decode($item->data, true), ["id" => $item->id]);
}
if ($form->fields) {
foreach ($form->fields as $field) {
if ($field->input_type_id === 6) {
$fillable = $formParams["meta"]["fillable"] ?? null;
$columnsToMod[] = $field->name;
}
$columns[$field->name] = $field->label;
}
}
$meta['title'] = "Form ID: " . $id;
$meta['columns'] = $columns;
$meta["perPage"] = $perPage;
$meta["fillable"] = $fillable;
$meta['params'] = ["class" => "table table-bordered", "border" => "1"];
$meta['currentPage'] = $page;
$meta['actions'] = $actions;
$meta['baseUrl'] = BASE_URL;
$tableArr["meta"] = $meta;
$tableArr["data"] = $data;
$tableRes = json_encode($tableArr);
$this->view->addFunction(new TwigFunction("create_table", function () use ($tableRes, $columnsToMod, $form, $countItems) {
$table = new ListJsonTable($tableRes);
$table->setBeforePrintCell(function ($column, $data) use ($columnsToMod, $form) {
if (in_array($column, $columnsToMod)) {
$res = InputValueModel::find($data);
return $res->value ?? "";
}
return $data;
});
$table->beforePrint(function () use($countItems){
return "<h5 class='display-10 fw-bold'>Количество записей: " . $countItems . "</h5>";
});
$table->create();
$table->render();
}));
$this->view->addFunction(new TwigFunction("create_pagination", function () use ($perPage, $page, $countItems, $form) {
$pagination = new Pagination($countItems, $perPage, $page, BASE_URL . "/form-result/" . $form->id);
$pagination->create();
$pagination->render();
}));
echo $this->view->render('form/result.html.twig', ['title' => $tableArr["meta"]["title"]]);
}
public function deleteAction($id): void
{
$item = FormResModel::find($id);
$item->update(["status" => FormResModel::STATUS_ARCHIVE]);
header('Location: ' . "/form-result/$item->form_id");
exit;
}
public function editAction($id): void
{
$res = FormResModel::find($id);
if (!$res) {
throw new FormResultNotFoundException($id);
}
$form = FormModel::find($res->form_id);
if (!$form) {
throw new FormNotFoundException($id);
}
$formArr = $this->createFormArr($form, $res);
$formArr["data"][] = ["type" => "hidden", "value" => $id, "name" => "form_res_id"];
$formArr['data'][] = ['type' => "button", 'typeInput' => "submit", "value" => "Редактировать", "name" => "", "class" => "btn btn-primary"];
//Debug::dd($formArr);
$this->view->addFunction(new TwigFunction("create_form", function () use ($formArr) {
$form = new JsonForm(json_encode($formArr));
$form->convertHTML();
$form->render();
}));
echo $this->view->render('form/form.html.twig', ['title' => $form->title]);
}
public function viewAction($id): void
{
$resultForm = FormResModel::find($id);
$formID = $resultForm->form_id;
$form = FormModel::find($formID);
$meta = [];
$columnsToMod = [];
$columns = [];
$resultData = $resultForm->data;
if ($form->fields) {
foreach ($form->fields as $field) {
if ($field->input_type_id === 6) {
$columnsToMod[] = $field->name;
}
$columns[$field->name] = $field->label;
}
}
$meta['title'] = "ITEM ID: " . $id;
$meta['columns'] = $columns;
$meta['params'] = ["class" => "table table-bordered", "border" => "1"];
$meta["actions"] = ["view", "edit", "delete"];
$tableArr["meta"] = $meta;
$tableArr["data"] = $resultForm;
$tableRes = json_encode($tableArr);
$this->view->addFunction(new TwigFunction("create_get_action", function () use ($tableRes, $columnsToMod, $form, $resultForm) {
$table = new ViewJsonTable($tableRes);
$table->setBeforePrintCell(function ($column, $data) use ($columnsToMod, $form) {
if (in_array($column, $columnsToMod)) {
$res = InputValueModel::find($data);
return $res->value ?? "";
}
return $data;
});
$table->beforeTable(function () use($form, $resultForm){
$btn = (new ToListBtn(BASE_URL, $form->id))->fetch();
$btn .= (new ToEditBtn(BASE_URL, $resultForm->id))->fetch();
$btn .= (new ToDeleteBtn(BASE_URL, $resultForm->id))->fetch();
return $btn;
});
$table->afterTable(function () use ($resultForm){
$timeCreate = "<h5 class='display-10'>Создано: " . $resultForm->created_at . "</h5>";
$timeUpdate = "<h5 class='display-10'>Обновлено: " . $resultForm->updated_at . "</h5>";;
return $timeCreate . $timeUpdate;
});
$table->create();
$table->render();
}));
echo $this->view->render('form/resultItem.html.twig', ['title' => $tableArr["meta"]["title"]]);
}
private function createFormArr(FormModel $form, FormResModel|false $formResult = false): array
{
// Инициализируем пустые массивы
$meta = [];
$formArr = [];
$formFieldsArr = [];
$resArr = [];
// Получение формы из БД и обработка мета данных формы
if ($formResult) {
$resArr = json_decode($formResult->data, true);
}
if (isset($form->params)) {
$allParams = json_decode($form->params, true);
$meta = array_merge($meta, $allParams['params']);
}
$meta['action'] = "/form-save/" . $form->id;
$meta['method'] = "POST";
$formArr['meta'] = $meta;
$formResults = FormResModel::where("form_id", $form->id)->where("id",);
// Обработка полей формы
if ($form->fields) {
foreach ($form->fields as $field) {
$options = [];
$fieldArr = [];
$params = [];
if ($field->inputValue) {
foreach ($field->inputValue as $value) {
$options[$value['id']] = $value['value'];
}
}
//Debug::dd($field->params);
if ($field->params) {
$fieldArr = array_merge($fieldArr, json_decode($field->params, true));
}
$fieldArr['name'] = $field->name ?? $fieldArr['name'];
if ($field->input_type_id === InputTypeModel::RADIO_TYPE) {
if (isset($resArr[$fieldArr['name']]) && $resArr[$fieldArr['name']] === $fieldArr['value']) {
$fieldArr['checked'] = "true";
}
}
if ($field->input_type_id === InputTypeModel::CHECKBOX_TYPE) {
if (isset($resArr[$fieldArr['name']]) && $resArr[$fieldArr['name']] === $fieldArr['value']) {
$fieldArr['checked'] = "true";
}
}
if ($formResult && $field->input_type_id !== InputTypeModel::RADIO_TYPE) {
$fieldArr['value'] = $resArr[$fieldArr['name']] ?? null;
}
$fieldArr['type'] = $field->inputType['type'] ? $field->inputType['type'] : "textInput";
$fieldArr['options'] = $options;
$fieldArr['label'] = ['title' => $field->label, 'for' => $fieldArr['name'], 'class' => 'form-label'];
$formArr['data'][] = $fieldArr;
}
}
return $formArr;
}
}

View File

@ -0,0 +1,16 @@
<?php
namespace itguild\forms\app\controllers;
use itguild\forms\app\core\BaseController;
use itguild\forms\app\models\FormInputModel;
use itguild\forms\debug\Debug;
class FormInputController extends BaseController
{
public function indexAction($id)
{
Debug::prn(FormInputModel::find($id)->first());
}
}

View File

@ -0,0 +1,24 @@
<?php
namespace itguild\forms\app\controllers;
namespace itguild\forms\app\controllers;
use itguild\forms\app\core\BaseController;
use itguild\forms\app\models\FormResModel;
use itguild\forms\debug\Debug;
use Illuminate\Http\Request;
class FormResController extends BaseController
{
public function formSetRes($id, $data)
{
FormResModel::Create([
'form_id' => $id,
'data' => json_encode($data),
]);
return "Данные успешно сохранены в базе данных.";
}
}

View File

@ -0,0 +1,16 @@
<?php
namespace itguild\forms\app\controllers;
use itguild\forms\app\core\BaseController;
use itguild\forms\app\models\InputTypeModel;
use itguild\forms\debug\Debug;
class InputTypeController extends BaseController
{
public function indexAction($id)
{
Debug::prn(InputTypeModel::find($id)->first());
}
}

View File

@ -0,0 +1,16 @@
<?php
namespace itguild\forms\app\controllers;
use itguild\forms\app\core\BaseController;
use itguild\forms\app\models\InputValueModel;
use itguild\forms\debug\Debug;
class InputValueController extends BaseController
{
public function indexAction($id)
{
Debug::prn(InputValueModel::find($id)->first());
}
}

View File

@ -1,18 +0,0 @@
<?php
namespace itguild\forms\app\controllers;
class Main
{
public function indexAction(): void
{
echo 123;
}
public function exampleAction()
{
echo "example";
}
}

View File

@ -0,0 +1,30 @@
<?php
namespace itguild\forms\app\controllers;
use itguild\forms\app\core\BaseController;
use itguild\forms\debug\Debug;
use itguild\forms\JsonForm;
use Twig\TwigFunction;
class MainController extends BaseController
{
private $html;
public function indexAction(): void
{
$this->view->addFunction(new TwigFunction("create_form", function (){
$form = new JsonForm(file_get_contents("form.json"));
$form->convertHTML();
$form->render();
}));
echo $this->view->render('main/index.html.twig', ['title' => 'Заголовок', 'content' => ""]);
}
public function exampleAction()
{
echo "example";
}
}

View File

@ -0,0 +1,22 @@
<?php
namespace itguild\forms\app\controllers;
use itguild\forms\app\core\BaseController;
use itguild\forms\app\models\User;
use itguild\forms\debug\Debug;
class UserController extends BaseController
{
public function createUserAction()
{
$user = User::Create([ 'name' => "Ahmed Khan", 'email' => "ahmed.khan@lbs.com", 'password' => password_hash("ahmedkhan",PASSWORD_BCRYPT), ]);
}
public function getUserAction($id)
{
Debug::prn(User::find(1)->first()->email);
}
}

31
src/app/core/BaseController.php Executable file
View File

@ -0,0 +1,31 @@
<?php
namespace itguild\forms\app\core;
use itguild\forms\core\cg_view\CgView;
use JetBrains\PhpStorm\NoReturn;
class BaseController
{
protected \Twig\Environment $view;
protected CgView $cgView;
public function __construct()
{
$loader = new \Twig\Loader\FilesystemLoader(VIEW_PATH);
$this->view = new \Twig\Environment($loader, [
'cache' => VIEW_CACHE_PATH,
]);
$this->cgView = new CgView();
$this->cgView->viewPath = VIEW_PATH;
}
#[NoReturn] protected function redirect(string $url, int $code = 301): void
{
header('Location: ' . $url, true, $code);
exit;
}
}

37
src/app/core/CGDTO.php Normal file
View File

@ -0,0 +1,37 @@
<?php
namespace itguild\forms\app\core;
use itguild\forms\debug\Debug;
class CGDTO
{
protected array $fillable = [];
public function load(array $params): void
{
foreach ($this->fillable as $item) {
if (isset($params[$item])) {
$this->$item = $params[$item];
}
}
}
public function get(string $name)
{
if (!empty($this->$name)) {
return $this->$name;
}
return null;
}
public function set(string $name, string $value): void
{
$this->$name = $value;
}
}

View File

@ -0,0 +1,28 @@
<?php
namespace itguild\forms\app\models;
use Illuminate\Database\Eloquent\Model;
class FormInputModel extends Model
{
protected $table = "form_input";
protected $fillable = [
'form_id', 'input_type_id', 'label', 'name', 'params', 'priority', 'inputType'
];
protected $hidden = [
];
public function inputType(): \Illuminate\Database\Eloquent\Relations\HasOne
{
return $this->hasOne(InputTypeModel::class, "id", "input_type_id");
}
public function inputValue()
{
return $this->hasMany(InputValueModel::class, "form_input_id", "id");
}
}

View File

@ -0,0 +1,25 @@
<?php
namespace itguild\forms\app\models;
use Illuminate\Database\Eloquent\Model;
class FormModel extends Model
{
const STATUS_ACTIVE = 1;
const STATUS_ARCHIVE = 2;
protected $table = "form";
protected $fillable = [
'title', 'status', 'params'
];
protected $hidden = [
];
public function fields()
{
return $this->hasMany(FormInputModel::class, "form_id", "id")->orderBy("priority");
}
}

View File

@ -0,0 +1,20 @@
<?php
namespace itguild\forms\app\models;
use Illuminate\Database\Eloquent\Model;
class FormResModel extends Model
{
const STATUS_ACTIVE = 1;
const STATUS_ARCHIVE = 2;
protected $table = "form_res";
protected $fillable = [
'form_id', 'data', 'status'
];
protected $hidden = [
];
}

View File

@ -0,0 +1,39 @@
<?php
namespace itguild\forms\app\models;
use Illuminate\Database\Eloquent\Model;
class InputTypeModel extends Model
{
const SELECT_TYPE = 6;
const INPUT_TEXT_TYPE = 2;
const TEXT_AREA_TYPE = 3;
const BUTTON_TYPE = 5;
const CHECKBOX_TYPE = 1;
const RADIO_TYPE = 4;
protected $table = "input_type";
protected $fillable = [
'type', 'name', 'status'
];
protected $hidden = [
];
public static function getViewNameByTypeId(int $id): ?string
{
$fields = [
1 => '_checkBox',
2 => '_text_input',
3 => '_textarea',
4 => '_radioButton',
5 => '_button',
6 => '_select'
];
return $fields[$id] ?? null;
}
}

View File

@ -0,0 +1,18 @@
<?php
namespace itguild\forms\app\models;
use Illuminate\Database\Eloquent\Model;
class InputValueModel extends Model
{
protected $table = "input_value";
protected $fillable = [
'form_input_id', 'value'
];
protected $hidden = [
];
}

19
src/app/models/User.php Executable file
View File

@ -0,0 +1,19 @@
<?php
namespace itguild\forms\app\models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
protected $table = "user";
protected $fillable = [
'name', 'email', 'password','userimage'
];
protected $hidden = [
'password', 'remember_token',
];
}

View File

@ -0,0 +1,20 @@
<?php
namespace itguild\forms\app\requests;
use itguild\forms\core\CgRequest;
class CreateFormRequest extends CgRequest
{
public function rules(): array
{
return [
'formId' => 'numeric',
'title' => 'required|min:5',
'perPage' => 'numeric',
'InputForm' => 'required|array',
];
}
}

View File

@ -0,0 +1,15 @@
<?php
namespace itguild\forms\app\services;
class InputTypeService
{
/**
* @return mixed
*/
public static function getInputTypes(): array
{
return \itguild\forms\app\models\InputTypeModel::where("status", 1)->pluck('name', 'id')->toArray();
}
}

View File

@ -0,0 +1,14 @@
<?php
namespace itguild\forms\app\services;
class InputValueService
{
/**
* @return mixed
*/
public static function getInputValuesById(int $inputId): array
{
return \itguild\forms\app\models\InputValueModel::where("form_input_id", $inputId)->pluck('value', 'id')->toArray();
}
}

0
src/builders/Builder.php Normal file → Executable file
View File

4
src/builders/ButtonBuilder.php Normal file → Executable file
View File

@ -8,9 +8,11 @@ class ButtonBuilder
public static function build(string $name, array $params = [])
{
$value = $params['value'] ?? null;
$typeInput = $params['typeInput'] ?? null;
unset($params['value']);
unset($params['typeInput']);
return new Button(name: $name, value: $value, paramsArray: $params);
return new Button(name: $name, value: $value, typeInput: $typeInput, paramsArray: $params);
}
}

0
src/builders/CheckBoxBuilder.php Normal file → Executable file
View File

View File

@ -0,0 +1,17 @@
<?php
namespace itguild\forms\builders;
use itguild\forms\inputs\Checkbox;
use itguild\forms\inputs\Hidden;
class HiddenBuilder
{
public static function build(string $name, array $params = []): Hidden
{
$value = $params['value'] ?? "";
unset($params['value']);
return new Hidden(name: $name, value: $value, paramsArray: $params);
}
}

0
src/builders/LabelBuilder.php Normal file → Executable file
View File

0
src/builders/RadioButtonBuilder.php Normal file → Executable file
View File

0
src/builders/SelectBuilder.php Normal file → Executable file
View File

0
src/builders/TextAreaBuilder.php Normal file → Executable file
View File

0
src/builders/TextInputBuilder.php Normal file → Executable file
View File

226
src/core/CgRequest.php Normal file
View File

@ -0,0 +1,226 @@
<?php
namespace itguild\forms\core;
use AllowDynamicProperties;
use Rakit\Validation\Validator;
#[AllowDynamicProperties]
class CgRequest
{
/**
* @var string $host Абсолютный адрес сервера
*/
public $host;
/**
* @var array $headers Заголовки запроса
*/
public $headers;
/**
* @var array
*/
public $data = [];
/**
* @var array
*/
public $errors = [];
public function __construct()
{
$this->headers = $this->getRequestHeaders();
$this->load();
}
/**
* @return array
*/
public function rules()
{
return [];
}
/**
* @return array
*/
public function messages()
{
return [];
}
/**
* Возвращает абсолютный адрес сервера.
* @return string
*/
public function getHost(): string
{
if ($this->host !== null) {
return $this->host;
}
$http = $this->getIsSecure() ? 'https' : 'http';
if ($this->headerExist('Host')) {
$this->host = $http . '://' . $this->getHeader('Host');
} elseif (isset($_SERVER['SERVER_NAME'])) {
$this->host = $http . '://' . $_SERVER['SERVER_NAME'];
}
return $this->host;
}
/**
* Возвращает true если шифрование https, иначе false.
* @return bool
*/
public function getIsSecure(): bool
{
if (isset($_SERVER['HTTPS']) && (strcasecmp($_SERVER['HTTPS'], 'on') === 0 || $_SERVER['HTTPS'] == 1)) {
return true;
}
return false;
}
/**
* Проверяет был ли передан заголовок запроса.
* @return bool
*/
public function headerExist($header): bool
{
return isset($this->headers[$header]);
}
/**
* Возвращает заголовок запроса
* @param string $header Заголовок.
* @param mixed $defaultValue Значение если, параметр не передан.
* @return mixed|null
*/
public function getHeader($header, $defaultValue = null)
{
return $this->headers[$header] ?? $defaultValue;
}
/**
* Возвращает GET - параметр.
* @param string $param Параметр.
* @param mixed $defaultValue Значение если, параметр не передан.
* @return mixed
*/
public function get($param = null, $defaultValue = null)
{
if (is_null($param)) {
return $_GET;
}
return $_GET[$param] ?? $defaultValue;
}
/**
* Возвращает POST - параметр.
* @param string $param Параметр.
* @param mixed $defaultValue Значение если, параметр не передан.
* @return mixed
*/
public function post($param = null, $defaultValue = null)
{
if (is_null($param)) {
return $_POST;
}
return $_POST[$param] ?? $defaultValue;
}
/**
* Был ли POST - запрос.
* @return bool
*/
public function isPost(): bool
{
return ($_SERVER['REQUEST_METHOD'] === 'POST');
}
/**
* Был ли GET - запрос.
* @return bool
*/
public function isGet(): bool
{
return ($_SERVER['REQUEST_METHOD'] === 'GET');
}
/**
* Загружаем свойсва
*/
public function load(): void
{
if (!empty($_REQUEST)) {
foreach ($_REQUEST as $key => $item) {
$this->{$key} = $item;
$this->data[$key] = $item;
}
}
}
/**
* @return bool
*/
public function validate()
{
if (!empty($this->data)) {
$valid = new Validator();
$validation = $valid->make($this->data, $this->rules());
$validation->setMessages($this->messages());
$validation->validate();
if ($validation->fails()) {
$this->errors = $validation->errors();
return false;
}
}
return true;
}
/**
* @return array
*/
public function getMessagesArray()
{
$msgs = [];
if($this->errors){
foreach ($this->errors->toArray() as $item){
$msgs[] = array_values($item)[0];
}
}
return $msgs;
}
/**
* @return array
*/
protected function getRequestHeaders()
{
$headers = array();
foreach ($_SERVER as $key => $value) {
if (substr($key, 0, 5) <> 'HTTP_') {
continue;
}
$header = str_replace(' ', '-', ucwords(str_replace('_', ' ', strtolower(substr($key, 5)))));
$headers[$header] = $value;
}
return $headers;
}
}

View File

@ -0,0 +1,61 @@
<?php
namespace itguild\forms\core\cg_view;
use itguild\forms\debug\Debug;
class CgView
{
public string $viewPath = '';
public bool|string $layout = false;
public function __construct()
{
}
public function render(string $view, array $data = []): void
{
$content = $this->createContent($view, $data);
echo $content;
}
public function fetch(string $view, array $data = []): false|string
{
$content = $this->createContent($view, $data);
return $content;
}
private function createContent(string $view, array $data = []): false|string
{
ob_start();
$cgView = new self();
$cgView->viewPath = $this->viewPath;
foreach ($data as $key => $datum){
${"$key"} = $datum;
}
include ($this->viewPath . $view);
$content = ob_get_contents();
ob_end_clean ();
ob_start();
$file_content = $content;
if ($this->layout){
if (file_exists($this->viewPath . $this->layout)){
include ($this->viewPath . $this->layout);
$file_content = ob_get_contents();
}
}
ob_end_clean ();
return $file_content;
}
}

0
src/debug/Debug.php Normal file → Executable file
View File

View File

@ -0,0 +1,11 @@
<?php
namespace itguild\forms\exceptions;
class CreateFormException extends \Exception
{
function __construct(string $msg)
{
$this->message = "Create form error: " . $msg;
}
}

View File

@ -0,0 +1,13 @@
<?php
namespace itguild\forms\exceptions;
class FieldTypeNotFound extends \Exception
{
function __construct(string $type)
{
$this->message = "Тип поля $type не найден";
}
}

View File

@ -0,0 +1,11 @@
<?php
namespace itguild\forms\exceptions;
class FormNotFoundException extends \Exception
{
function __construct($formId)
{
$this -> message = "Форма $formId не найдена";
}
}

View File

@ -0,0 +1,11 @@
<?php
namespace itguild\forms\exceptions;
class FormResultNotFoundException extends \Exception
{
function __construct($id)
{
$this -> message = "Ответ формы $id не найдена";
}
}

View File

@ -0,0 +1,22 @@
<?php
namespace itguild\forms\helpers;
class TranslitorHelper
{
public static function translit($str){
$russian = array('А', 'Б', 'В', 'Г', 'Д', 'Е', 'Ё', 'Ж', 'З',
'И', 'Й', 'К', 'Л', 'М', 'Н', 'О', 'П', 'Р', 'С', 'Т', 'У',
'Ф', 'Х', 'Ц', 'Ч', 'Ш', 'Щ', 'Ъ', 'Ы', 'Ь', 'Э', 'Ю', 'Я',
'а', 'б', 'в', 'г', 'д', 'е', 'ё', 'ж', 'з', 'и', 'й', 'к',
'л', 'м', 'н', 'о', 'п', 'р', 'с', 'т', 'у', 'ф', 'х', 'ц',
'ч', 'ш', 'щ', 'ъ', 'ы', 'ь', 'э', 'ю', 'я', ' ');
$translit = array('A', 'B', 'V', 'G', 'D', 'E', 'E', 'Gh', 'Z',
'I', 'Y', 'K', 'L', 'M', 'N', 'O', 'P', 'R', 'S', 'T', 'U', 'F',
'H', 'C', 'Ch', 'Sh', 'Sch', 'Y', 'Y', 'Y', 'E', 'Yu', 'Ya', 'a',
'b', 'v', 'g', 'd', 'e', 'e', 'gh', 'z', 'i', 'y', 'k', 'l', 'm',
'n', 'o', 'p', 'r', 's', 't', 'u', 'f', 'h', 'c', 'ch', 'sh', 'sch',
'y', 'y', 'y', 'e', 'yu', 'ya', '_');
return str_replace($russian, $translit, $str);
}
}

0
src/inputs/BaseInput.php Normal file → Executable file
View File

11
src/inputs/Button.php Normal file → Executable file
View File

@ -9,7 +9,7 @@ use itguild\forms\inputs\BaseInput;
class Button extends BaseInput
{
use CreateParams;
private $typeInput;
private string $name;
private string $value;
private array $paramsArray;
@ -19,8 +19,9 @@ class Button extends BaseInput
* @param string $value
* @param array $paramsArray
*/
public function __construct(string $name, string $value, array $paramsArray = [])
public function __construct(string $name, string $value, $typeInput, array $paramsArray = [])
{
$this->typeInput = $typeInput;
$this->name = $name;
$this->paramsArray = $paramsArray;
$this->value = $value;
@ -34,7 +35,7 @@ class Button extends BaseInput
{
$paramsString = $this->createParams($this->paramsArray);
$label = "";
$button = "<input type='button' value='$this->value' name='$this->name' $paramsString>";
$button = "<input type='$this->typeInput' value='$this->value' name='$this->name' $paramsString>";
$this->createLabel();
@ -50,9 +51,9 @@ class Button extends BaseInput
* @param array $paramsArray
* @return void
*/
public static function build(string $name, string $value, array $paramsArray = []): void
public static function build( string $name, string $value, string $typeInput, array $paramsArray = []): void
{
$button = new self($name, $value, $paramsArray);
$button = new self($name, $value, $typeInput, $paramsArray);
$button->create()->render();
}

0
src/inputs/Checkbox.php Normal file → Executable file
View File

60
src/inputs/Hidden.php Normal file
View File

@ -0,0 +1,60 @@
<?php
namespace itguild\forms\inputs;
use itguild\forms\templates\Simple\SimpleTemplate;
use itguild\forms\traits\CreateParams;
class Hidden extends BaseInput
{
use CreateParams;
private string $name;
private string $value;
private array $paramsArray;
/**
* @param string $name
* @param string $value
* @param array $paramsArray
*/
public function __construct(string $name, string $value = '', array $paramsArray = [])
{
$this->name = $name;
$this->value = $value;
$this->paramsArray = $paramsArray;
$this->inputTemplate = new SimpleTemplate();
}
/**
* @return $this
*/
public function create(): self
{
$paramsString = $this->createParams($this->paramsArray);
$hidden = "<input name='$this->name' type='hidden' value='$this->value' $paramsString >";
$label = "";
$this->createLabel();
$this->html = str_replace('{input}', $hidden, $this->inputTemplate->getInputTemplate());
$this->html = str_replace('{label}', $this->labelString, $this->html);
return $this;
}
/**
* @param string $name
* @param string $value
* @param array $paramsArray
* @return void
*/
public static function build(string $name, string $value, array $paramsArray): void
{
$hidden = new self($name, $value, $paramsArray);
$hidden->create()->render();
}
}

12
src/inputs/Label.php Normal file → Executable file
View File

@ -4,6 +4,7 @@ namespace itguild\forms\inputs;
use itguild\forms\traits\CreateParams;
use itguild\forms\inputs\BaseInput;
class Label extends BaseInput
{
use CreateParams;
@ -36,6 +37,14 @@ class Label extends BaseInput
}
/**
* @return string
*/
public function getHtml(): string
{
return $this->html;
}
/**
* @param string $title
* @param array $paramsArray
@ -45,9 +54,6 @@ class Label extends BaseInput
{
$label = new self($title, $paramsArray);
$label->create()->render();
}
}

8
src/inputs/RadioButton.php Normal file → Executable file
View File

@ -31,11 +31,11 @@ class RadioButton extends BaseInput
$optionsString = $this->createOption($this->options, $this->value);
$radioButton = "<input name='$this->name' type='radio' $paramsString>$optionsString";
$label = "";
if($this->hasLabel == true) {
$label = "<label >$this->labelTitle</label>";
}
$this->createLabel();
$this->html = str_replace('{input}', $radioButton, $this->inputTemplate->getInputTemplate());
$this->html = str_replace('{label}', $label, $this->html);
$this->html = str_replace('{label}', $this->labelString, $this->html);
return $this;
}

0
src/inputs/Select.php Normal file → Executable file
View File

0
src/inputs/TextArea.php Normal file → Executable file
View File

0
src/inputs/TextInput.php Normal file → Executable file
View File

2
src/mappers/JsonInputMapper.php Normal file → Executable file
View File

@ -5,6 +5,7 @@ namespace itguild\forms\mappers;
use itguild\forms\builders\Builder;
use itguild\forms\builders\ButtonBuilder;
use itguild\forms\builders\CheckBoxBuilder;
use itguild\forms\builders\HiddenBuilder;
use itguild\forms\builders\LabelBuilder;
use itguild\forms\builders\RadioButtonBuilder;
use itguild\forms\builders\SelectBuilder;
@ -23,6 +24,7 @@ class JsonInputMapper
"select" => SelectBuilder::class,
"button" => ButtonBuilder::class,
"checkbox" => CheckBoxBuilder::class,
"hidden" => HiddenBuilder::class,
];
}

View File

@ -0,0 +1,36 @@
<?php
namespace itguild\forms\migrations;
use Illuminate;
use Illuminate\Database\Schema\Blueprint;
class FormsInputMigration extends Illuminate\Database\Migrations\Migration
{
public static function up(): void
{
Illuminate\Database\Capsule\Manager::schema()->create("form_input", function (Blueprint $table) {
$table->id("id");
$table->unsignedBigInteger('form_id');
$table->unsignedBigInteger('input_type_id');
$table->string('label');
$table->string('name');
$table->text('params');
$table->integer(11)->default(1);
$table->timestamps();
$table->index('form_id');
$table->index('input_type_id');
$table->foreign('form_id', 'fk_form_input_form')->references('id')->on('form');
$table->foreign('input_type_id', 'fk_form_input_input_type')->references('id')->on('input_type');
});
}
public static function down(): void
{
Illuminate\Database\Capsule\Manager::schema()->drop("form_input");
}
}

View File

@ -0,0 +1,31 @@
<?php
namespace itguild\forms\migrations;
use Illuminate;
class FormsMigration
{
public static function up(): void
{
Illuminate\Database\Capsule\Manager::schema()->create("form", function ($table) {
$table->id('id');
$table->string('title');
$table->integer('status');
$table->text('params')->nullable();
$table->timestamps();
});
}
public static function get()
{
return DB::forms('form_input')-> get();
}
public static function down(): void
{
Illuminate\Database\Capsule\Manager::schema()->drop("form");
}
}

View File

@ -0,0 +1,28 @@
<?php
namespace itguild\forms\migrations;
use Illuminate;
class FormsResMigration
{
public static function up(): void
{
Illuminate\Database\Capsule\Manager::schema()->create("form_res", function ($table) {
$table->id('id');
$table->unsignedBigInteger('form_id');
$table->json('data');
$table->timestamps();
$table->foreign('form_id', 'fk_form_form')->references('id')->on('form');
});
}
public static function down(): void
{
Illuminate\Database\Capsule\Manager::schema()->drop("form_res");
}
}

View File

@ -0,0 +1,25 @@
<?php
namespace itguild\forms\migrations;
use Illuminate;
class InputsTypeMigration
{
public static function up(): void
{
Illuminate\Database\Capsule\Manager::schema()->create("input_type", function ($table) {
$table->id('id');
$table->string('type');
$table->string('name');
$table->integer('status');
});
}
public static function down(): void
{
Illuminate\Database\Capsule\Manager::schema()->drop("input_type");
}
}

View File

@ -0,0 +1,28 @@
<?php
namespace itguild\forms\migrations;
use Illuminate;
class InputsValueMigrations
{
public static function up(): void
{
Illuminate\Database\Capsule\Manager::schema()->create("input_value", function ($table) {
$table->id('id');
$table->unsignedBigInteger('form_input_id');
$table->string('value');
$table->timestamps();
$table->foreign('form_input_id', 'fk_form_input')->references('id')->on('form_input');
});
}
public static function down(): void
{
Illuminate\Database\Capsule\Manager::schema()->drop("input_value");
}
}

View File

@ -0,0 +1,30 @@
<?php
namespace itguild\forms\migrations;
use Illuminate;
class UserMigration
{
public static function up(): void
{
Illuminate\Database\Capsule\Manager::schema()->create("user", function ($table) {
$table->increments('id');
$table->string('name');
$table->string('email')->unique();
$table->string('password');
$table->string('userimage')->nullable();
$table->string('api_key')->nullable()->unique();
$table->rememberToken();
$table->timestamps();
});
}
public static function down(): void
{
Illuminate\Database\Capsule\Manager::schema()->drop("user");
}
}

View File

@ -0,0 +1,20 @@
<?php
namespace itguild\forms\table\ActionColumn;
abstract class ActionColumn
{
protected string $baseUrl;
protected string $prefix;
protected int $id;
public function __construct(string $baseUrl, int $id)
{
$this->baseUrl = $baseUrl;
$this->id = $id;
}
abstract public function fetch();
}

View File

@ -0,0 +1,14 @@
<?php
namespace itguild\forms\table\ActionColumn;
class DeleteActionColumn extends ActionColumn
{
protected string $prefix = "/form-delete/";
public function fetch(): string
{
$link = $this->baseUrl . $this->prefix . $this->id;
return " <a href='$link' class='btn btn-danger'>Удалить</a> ";
}
}

View File

@ -0,0 +1,16 @@
<?php
namespace itguild\forms\table\ActionColumn;
class EditActionColumn extends ActionColumn
{
protected string $prefix = "/form-edit/";
public function fetch(): string
{
$link = $this->baseUrl . $this->prefix . $this->id;
return " <a href='$link' class='btn btn-primary'>Редактировать</a> ";
}
}

View File

@ -0,0 +1,14 @@
<?php
namespace itguild\forms\table\ActionColumn;
class ViewActionColumn extends ActionColumn
{
protected string $prefix = "/form-item/";
public function fetch(): string
{
$link = $this->baseUrl . $this->prefix . $this->id;
return " <a href='$link' class='btn btn-primary'>Просмотр</a> ";
}
}

184
src/table/ListJsonTable.php Normal file
View File

@ -0,0 +1,184 @@
<?php
namespace itguild\forms\table;
use itguild\forms\debug\Debug;
use itguild\forms\table\ActionColumn\DeleteActionColumn;
use itguild\forms\table\ActionColumn\EditActionColumn;
use itguild\forms\table\ActionColumn\ViewActionColumn;
use itguild\forms\traits\CreateParams;
use itguild\forms\widgets\BaseWidget;
class ListJsonTable
{
use CreateParams;
private string $html = '';
private string $json;
private int $count = 0;
private \Closure|false $beforePrintCell;
private \Closure|false $beforePrint;
private string $baseUrl;
private array $data;
private array $actionsArray = [];
public function __construct(string $json)
{
$this->beforePrintCell = false;
$this->json = $json;
$this->data = json_decode($this->json, true);
$this->baseUrl = $this->data['meta']['baseUrl'] ?? null;
$this->setActions();
}
public function beginTable(): void
{
$paramsStr = $this->createParams($this->data['meta']['params']);
$hook = $this->beforePrint;
$this->html .= $hook();
$this->html .= "<table $paramsStr>";
}
public function beforePrint(\Closure $closure): void
{
$this->beforePrint = $closure;
}
public function createThead(): void
{
if (!isset($this->data['meta']['columns'])) {
return;
}
$this->html .= "<thead><tr>";
$this->html .= "<th>" . "ID" . "</th>";
foreach ($this->data['meta']['columns'] as $key => $column) {
if ($this->is_fillable($key)) {
$this->html .= "<th>" . $column . "</th>";
}
}
$this->html .= "<th>Действия</th></th></tr></thead>";
}
public function createTbody(): void
{
if ($this->data['data']) {
$this->count = $this->data["meta"]["perPage"] * ($this->data['meta']["currentPage"] - 1);
foreach ($this->data['data'] as $col) {
$this->html .= "<tr>";
$this->count += 1;
$this->html .= '<td><a href=' . $this->baseUrl . "/form-item/" . $col["id"] . '>' . $this->count . '</a></td>';
foreach ($col as $key => $row) {
if ($this->issetColumn($key) and $this->is_fillable($key)) {
if ($this->beforePrintCell) {
$hook = $this->beforePrintCell;
$row = $hook($key, $row);
}
$this->html .= "<td>" . $row . "</td>";
}
}
$actions = $this->getActions($col["id"]);
$this->html .= "<td>$actions</td></tr>";
}
}
}
private function setActions(): void
{
if (isset($this->data['meta']['actions'])) {
foreach ($this->data['meta']['actions'] as $action) {
switch ($action) {
case 'view':
$this->actionsArray[] = ViewActionColumn::class;
break;
case 'delete':
$this->actionsArray[] = DeleteActionColumn::class;
break;
case 'edit':
$this->actionsArray[] = EditActionColumn::class;
break;
}
}
}
}
private function issetColumn($column)
{
if (isset($this->data['meta']['columns'])) {
foreach ($this->data['meta']['columns'] as $key => $currentColumn) {
if ($key === $column) {
return true;
}
}
}
return false;
}
private function is_fillable($column): bool
{
if (isset($this->data['meta']['fillable'])){
if (in_array($column, $this->data['meta']['fillable'])) {
return true;
}
}
else{
return true;
}
return false;
}
private function getActions(int $id): string
{
$actions = "";
foreach ($this->actionsArray as $item) {
$objItem = new $item($this->baseUrl, $id);
$actions .= $objItem->fetch();
}
return $actions;
}
public function create()
{
$this->beginTable();
$this->createThead();
$this->createTbody();
$this->endTable();
}
public function tableAction($json): void
{
$tableJson = json_decode($json, true);
foreach ($tableJson as $key => $value) {
echo "<tr>";
echo "<td>" . $key . "</td>";
echo "<td>" . $value . "</td>";
echo "</tr>";
}
}
public function endTable(): void
{
$this->html .= "</table>";
}
public function render(): void
{
echo $this->html;
}
public function setBeforePrintCell(\Closure $closure): void
{
$this->beforePrintCell = $closure;
}
}

69
src/table/Pagination.php Normal file
View File

@ -0,0 +1,69 @@
<?php
namespace itguild\forms\table;
use itguild\forms\widgets\BaseWidget;
class Pagination
{
private string $html = "";
private int $perPage = 10;
private int $countItem;
private int $currentPage = 1;
private int $countPages;
private string $baseUrl;
public function __construct($countItem, $perPage, $currentPage, $baseUrl)
{
$this->countItem = $countItem;
$this->perPage = $perPage;
$this->currentPage = $currentPage;
$this->baseUrl = $baseUrl;
$this->countPages = ceil($this->countItem / $perPage);
}
public function create()
{
$prev = $this->currentPage - 1 >= 1 ? $this->currentPage - 1 : null;
$next = $this->currentPage + 1 <= $this->countPages ? $this->currentPage + 1 : null;
$btns = $prev ? "<li class='page-item'><a class='page-link' href='$this->baseUrl/$prev'>$prev</a></li>" : "";
$btns .= "<li class='page-item'><a class='page-link active' href='#'>$this->currentPage</a></li>";
$btns .= $next ? "<li class='page-item'><a class='page-link' href='$this->baseUrl/$next'>$next</a></li>" : "";
$this->html = str_replace('{btns}', $btns, $this->getTemplate());
$this->html = str_replace('{previous_link}', $this->baseUrl . "/1", $this->html);
$this->html = str_replace('{next_link}', $this->baseUrl . "/" . $this->countPages, $this->html);
}
public function render(): void
{
echo $this->html;
}
public function fetch()
{
return $this->html;
}
private function getTemplate()
{
return '<nav aria-label="Page navigation example">
<ul class="pagination">
<li class="page-item">
<a class="page-link" href="{previous_link}" aria-label="Previous">
<span aria-hidden="true">&laquo;</span>
</a>
</li>
{btns}
<li class="page-item">
<a class="page-link" href="{next_link}" aria-label="Next">
<span aria-hidden="true">&raquo;</span>
</a>
</li>
</ul>
</nav>';
}
}

108
src/table/ViewJsonTable.php Normal file
View File

@ -0,0 +1,108 @@
<?php
namespace itguild\forms\table;
use itguild\forms\traits\CreateParams;
use itguild\forms\widgets\BaseWidget;
class ViewJsonTable
{
use CreateParams;
private array $data;
private string $html = "";
private string $json;
private \Closure|false $beforePrintCell;
private \Closure|false $beforePrintTable;
private \Closure|false $afterPrintTable;
private array $dataJson;
public function __construct($json)
{
$this->json = $json;
$this->data = json_decode($this->json, true);
$this->dataJson = json_decode($this->data['data']['data'], true);
}
public function beginTable(): void
{
$paramsStr = $this->createParams($this->data['meta']['params']);
$hook = $this->beforePrintTable;
$this->html = $hook();
$this->html .= "<table $paramsStr>";
}
public function createColum(): string
{
foreach ($this->data['meta']['columns'] as $key => $column){
if ($this->issetColumn($key)){
if ($this->beforePrintCell){
$hook = $this->beforePrintCell;
$this->dataJson[$key] = $hook($key, $this->dataJson[$key]);
}
$this->html .= "<tr><th>" . $column . ": </th><td>" . $this->dataJson[$key] . "</td></tr>";
}
}
return $this->html;
}
private function issetColumn($column)
{
if (isset($this->data['meta']['columns'])){
foreach ($this->data['meta']['columns'] as $key => $currentColumn){
if ($key === $column){
return true;
}
}
}
return false;
}
public function endTable()
{
$this->html .= "</table>";
$hookAfter = $this->afterPrintTable;
$this->html .= $hookAfter();
}
public function create()
{
$this->beginTable();
$this->createColum();
$this->endTable();
}
public function beforeTable(\Closure $closure): void
{
$this->beforePrintTable = $closure;
}
public function afterTable(\Closure $closure): void
{
$this->afterPrintTable = $closure;
}
public function render()
{
echo $this->html;
}
public function setBeforePrintCell(\Closure $closure): void
{
$this->beforePrintCell = $closure;
}
}

View File

@ -0,0 +1,22 @@
<?php
namespace itguild\forms\table\actionBtn;
abstract class ActionBtn
{
protected string $baseUrl;
protected string $prefix;
protected int $id;
public function __construct(string $baseUrl, int $id)
{
$this->baseUrl = $baseUrl;
$this->id = $id;
return $this;
}
abstract public function fetch();
}

View File

@ -0,0 +1,13 @@
<?php
namespace itguild\forms\table\actionBtn;
class ToDeleteBtn extends ActionBtn
{
protected string $prefix = "/form-delete/";
public function fetch(): string
{
return "<a class='btn btn-danger' href='$this->baseUrl$this->prefix$this->id' style='margin: 3px'>Удалить</a>";
}
}

View File

@ -0,0 +1,13 @@
<?php
namespace itguild\forms\table\actionBtn;
class ToEditBtn extends ActionBtn
{
protected string $prefix = "/form-edit/";
public function fetch(): string
{
return "<a class='btn btn-warning' href='$this->baseUrl$this->prefix$this->id' style='margin: 3px'>Редактировать</a>";
}
}

View File

@ -0,0 +1,13 @@
<?php
namespace itguild\forms\table\actionBtn;
class ToListBtn extends ActionBtn
{
protected string $prefix = "/form-result/";
public function fetch(): string
{
return "<a class='btn btn-primary' href='$this->baseUrl$this->prefix$this->id' style='margin: 3px'>Список</a>";
}
}

0
src/templates/Simple/SimpleTemplate.php Normal file → Executable file
View File

0
src/templates/Template.php Normal file → Executable file
View File

0
src/templates/bootstrap5/Bootstrap5Template.php Normal file → Executable file
View File

2
src/traits/CreateOption.php Normal file → Executable file
View File

@ -13,7 +13,7 @@ trait CreateOption
{
$optionsString = "";
foreach ($options as $val => $title){
$selected = $value === $val ? "selected" : "";
$selected = (int)$value === $val ? "selected" : "";
$optionsString .= "<option $selected value='$val'>$title</option>";
}
return $optionsString;

6
src/traits/CreateParams.php Normal file → Executable file
View File

@ -2,6 +2,8 @@
namespace itguild\forms\traits;
use itguild\forms\debug\Debug;
trait CreateParams
{
@ -13,7 +15,9 @@ trait CreateParams
{
$paramsString = "";
foreach($data as $key => $param){
$paramsString .= $key . "='" . $param . "'";
if(is_string($param)){
$paramsString .= $key . "='" . $param . "'";
}
}
return $paramsString;

View File

@ -0,0 +1,32 @@
<?php
namespace itguild\forms\widgets;
use itguild\forms\core\cg_view\CgView;
abstract class BaseWidget
{
protected CgView $cgView;
public function __construct()
{
$this->cgView = new CgView();
$this->cgView->viewPath = VIEW_PATH;
}
/**
* @return self
*/
public static function create(): BaseWidget
{
return new static();
}
/**
* @param array $data
* @return mixed
*/
abstract public function run(array $data = []);
}

View File

@ -0,0 +1,63 @@
<?php
/**
* @var \itguild\forms\ActiveForm $form
* @var \itguild\forms\app\DTO\FormDTO $dto
* @var \itguild\forms\core\cg_view\CgView $cgView
*/
namespace itguild\forms\widgets;
use Illuminate\Database\Eloquent\Collection;
use itguild\forms\app\models\InputTypeModel;
use itguild\forms\ActiveForm;
use itguild\forms\app\services\InputValueService;
use itguild\forms\debug\Debug;
class FormFieldBlockWidget extends BaseWidget
{
public function run(array $data = []): void
{
foreach ($this->prepare($data['fields']) as $field) {
$this->cgView->render('/admin/field_type/' . $field['view_name'] . ".php", $field);
}
}
private function prepare(Collection $rawFields): array
{
$fields = [];
$i = 0;
foreach ($rawFields as $field) {
$params = json_decode($field['params'], true);
$viewName = \itguild\forms\app\models\InputTypeModel::getViewNameByTypeId($field['input_type_id']);
if (!isset($fields[$field['name']])) {
$fields[$field['name']] = [
'name' => $field['name'],
'form' => new ActiveForm(),
'view_name' => $viewName,
'count' => $i,
];
}
if ($field['input_type_id'] == InputTypeModel::RADIO_TYPE) {
if (isset($fields[$field['name']]['value'])) {
$fields[$field['name']]['value'] .= "\n" . $params['value'];
} else {
$fields[$field['name']]['value'] = $params['value'];
}
} elseif ($field['input_type_id'] == InputTypeModel::SELECT_TYPE) {
$fields[$field['name']]['value'] = implode("\n", InputValueService::getInputValuesById($field['id']));
} else {
$fields[$field['name']]['value'] = $params['value'] ?? null;
$fields[$field['name']]['placeholder'] = $params['placeholder'] ?? null;
}
$i++;
}
return $fields;
}
}

15
table.json Normal file
View File

@ -0,0 +1,15 @@
{
"meta": {
"title": "forma 1",
"columns": {
"email": "Email",
"description": "Описание 1",
"description2": "Описание 2"
},
"params": {"class": "table table-bordered", "border": "1"}
},
"data": [
{"email":"fas@mail.ru","description":"fafdgdfs","description2":"ffdghdas"},
]
}

View File

@ -0,0 +1,29 @@
<?php
/**
*
* @var ActiveForm $form
*
*/
use itguild\forms\ActiveForm;
use itguild\forms\inputs\Select;
use itguild\forms\inputs\TextArea;
use itguild\forms\inputs\TextInput;
$form->field(Select::class, name: "selectItem", params: [
'class' => "form-control", "options" => ["textInput", "textArea", "checkBox", "button", "radioButton", "select", "label"]
])
->setLabel("Выберите тип инпута")
->render();
$form->field(TextInput::class, name: "name", params: [
'class' => "form-control",
'placeholder' => 'Name'
])
->setLabel("Имя поля")
->render();
$form->field(TextInput::class, name: "value", params: [
'class' => "form-control",
'placeholder' => 'Значение value'
])
->setLabel("Значение")
->render();

View File

@ -0,0 +1 @@
<a href="#" class="delete-button btn-danger deleteButton">X</a>

View File

@ -0,0 +1,24 @@
<div class="form-block form-control">
<b><p>Кнопка</p></b>
<?php
/**
*
* @var \itguild\forms\ActiveForm $form
* @var integer $count
* @var integer $name
* @var \itguild\forms\core\cg_view\CgView $cgView
*/
use itguild\forms\inputs\Checkbox;
use itguild\forms\inputs\TextInput;
$form->field(TextInput::class, name: "InputForm[$count][name]", params: ['class' => "form-control",
'placeholder' => "Наименование поля", 'value' => $name ?? null])->setLabel("Наименование поля (например \"Телефон\")")->render();
$form->field(Checkbox::class, name: "InputForm[$count][required]", params:['value' => '1'])->setLabel("Обязательное")->render();
$form->field(\itguild\forms\inputs\Hidden::class, name: "InputForm[$count][type]", params: ['value' => '5'])->render();
$cgView->render("/admin/additional_elements/_delete_field_box_button.php", []);
?>
</div>

View File

@ -0,0 +1,22 @@
<div class="form-block form-control">
<b><p>Чекбокс</p></b>
<?php
/**
*
* @var \itguild\forms\ActiveForm $form
* @var integer $count
* @var integer $name
* @var \itguild\forms\core\cg_view\CgView $cgView
*/
use itguild\forms\inputs\Checkbox;
use itguild\forms\inputs\TextInput;
$form->field(TextInput::class, name: "InputForm[$count][name]", params: ['class' => "form-control",
'placeholder' => "Наименование", 'value' => $name ?? null])->setLabel("Наименование (например \"Телефон\")")->render();
$form->field(Checkbox::class, name: "InputForm[$count][required]", params:['value' => '1'])->setLabel("Обязательное")->render();
$form->field(\itguild\forms\inputs\Hidden::class, name: "InputForm[$count][type]", params: ['value' => '1'])->render();
$cgView->render("/admin/additional_elements/_delete_field_box_button.php", []);
?>
</div>

Some files were not shown because too many files have changed in this diff Show More