Compare commits
11
Commits
67484d79f9
..
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
11fee552c5 | ||
|
|
e70a98e7b9 | ||
|
|
47271d9413 | ||
|
|
207d793b07 | ||
|
|
448edb8671 | ||
|
|
4c2e56dd4c | ||
|
|
2b6ebbf17d | ||
|
|
1ab56ef3c4 | ||
|
|
218eeff1ad | ||
|
|
af604aa607 | ||
|
|
d8b103fe33 |
+5
-5
@@ -1,9 +1,9 @@
|
||||
{
|
||||
"id": "bx.null",
|
||||
"prefix": "bx_null",
|
||||
"namespace": "Bx\\Null",
|
||||
"gitUrl": "https://bitbucket.org/bellord13/bx.null/",
|
||||
"id": "bx.nullable",
|
||||
"prefix": "bx_nullable",
|
||||
"namespace": "Bx\\Nullable",
|
||||
"repo": "https://gitea.ixrs.ru/bellord/bx.nullable.git",
|
||||
"version": "1.0.0",
|
||||
"date": "2024-01-01 00:00:00",
|
||||
"date": "2026-01-01 00:00:00",
|
||||
"deps": ["wt.core"]
|
||||
}
|
||||
@@ -0,0 +1,199 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Wt\Core\App;
|
||||
|
||||
use RecursiveDirectoryIterator;
|
||||
use RecursiveIteratorIterator;
|
||||
use UnexpectedValueException;
|
||||
|
||||
/**
|
||||
* Class ModuleCloner
|
||||
*
|
||||
* Обеспечивает функционал клонирования Bitrix модулей с автоматической
|
||||
* заменой идентификаторов и пространств имен.
|
||||
*/
|
||||
class ModuleCloner
|
||||
{
|
||||
protected array $excludePatterns = [
|
||||
'/\.git$/',
|
||||
'/\.module\.json/',
|
||||
'/clone\.php/',
|
||||
'/ModuleCloner\.php/',
|
||||
'/readme\.md/',
|
||||
'/src\/\.env$/',
|
||||
'/src\/config\.php$/',
|
||||
];
|
||||
|
||||
public function __construct(
|
||||
private readonly ModuleEntity $sourceEntity,
|
||||
private readonly ModuleEntity $targetEntity
|
||||
) {}
|
||||
|
||||
/**
|
||||
* Основной метод клонирования модуля.
|
||||
*
|
||||
* @throws UnexpectedValueException
|
||||
*/
|
||||
public function clone(): void
|
||||
{
|
||||
$this->copyStructure();
|
||||
$this->fixContent();
|
||||
}
|
||||
|
||||
/**
|
||||
* Копирует структуру папок и файлов из источника в цель.
|
||||
*/
|
||||
protected function copyStructure(): void
|
||||
{
|
||||
$this->copyFolderSafe(
|
||||
$this->sourceEntity->getPath(),
|
||||
$this->targetEntity->getPath()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Рекурсивное копирование папки с фильтрацией и динамическим переименованием.
|
||||
*/
|
||||
protected function copyFolderSafe(string $source, string $destination): void
|
||||
{
|
||||
if ($this->shouldExclude($source)) {
|
||||
echo "Skip: $source" . PHP_EOL;
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_dir($source)) {
|
||||
$destination = $this->ensureDirectory($destination);
|
||||
if ($destination === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
$dir = dir($source);
|
||||
while (false !== ($entry = $dir->read())) {
|
||||
if ($entry !== '.' && $entry !== '..') {
|
||||
$srcPath = $source . DIRECTORY_SEPARATOR . $entry;
|
||||
$dstPath = $destination . DIRECTORY_SEPARATOR . $entry;
|
||||
|
||||
$dstPath = $this->renamePathSegment($dstPath);
|
||||
|
||||
$this->copyFolderSafe($srcPath, $dstPath);
|
||||
}
|
||||
}
|
||||
$dir->close();
|
||||
} else {
|
||||
$this->copyFileSafe($source, $destination);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Копирует файл с сохранением времени модификации.
|
||||
*/
|
||||
protected function copyFileSafe(string $source, string $destination): void
|
||||
{
|
||||
$time = filemtime($source);
|
||||
if (file_exists($destination) && filemtime($destination) >= $time) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (copy($source, $destination)) {
|
||||
touch($destination, $time);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Создает директорию, если она отсутствует.
|
||||
*/
|
||||
protected function ensureDirectory(string $path): ?string
|
||||
{
|
||||
if (file_exists($path)) {
|
||||
if (is_dir($path)) {
|
||||
return $path;
|
||||
}
|
||||
unlink($path);
|
||||
}
|
||||
return mkdir($path, 0777, true) ? $path : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Выполняет массовую замену строк в PHP файлах целевого модуля.
|
||||
*/
|
||||
protected function fixContent(): void
|
||||
{
|
||||
$iterator = new RecursiveIteratorIterator(
|
||||
new RecursiveDirectoryIterator($this->targetEntity->getPath()),
|
||||
RecursiveIteratorIterator::LEAVES_ONLY
|
||||
);
|
||||
|
||||
foreach ($iterator as $file) {
|
||||
if ($file->isFile() && $file->getExtension() === 'php') {
|
||||
$path = $file->getPathname();
|
||||
$content = file_get_contents($path);
|
||||
$original = $content;
|
||||
|
||||
$replacements = $this->getReplacements();
|
||||
foreach ($replacements as $search => $replace) {
|
||||
$content = str_replace($search, $replace, $content);
|
||||
}
|
||||
|
||||
if ($original !== $content) {
|
||||
file_put_contents($path, $content);
|
||||
echo "Fixed: $path" . PHP_EOL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Формирует карту замен на основе сущностей модулей.
|
||||
*/
|
||||
protected function getReplacements(): array
|
||||
{
|
||||
$s = $this->sourceEntity;
|
||||
$t = $this->targetEntity;
|
||||
|
||||
$productS = ucfirst($s->getProductCode());
|
||||
$productT = ucfirst($t->getProductCode());
|
||||
$companyS = ucfirst($s->getCompanyCode());
|
||||
$companyT = ucfirst($t->getCompanyCode());
|
||||
|
||||
return [
|
||||
$s->getLangPrefix() => $t->getLangPrefix(),
|
||||
$s->getId() => $t->getId(),
|
||||
$s->getPrefix() => $t->getPrefix(),
|
||||
$s->getNamespace() => $t->getNamespace(),
|
||||
"$productS: $productS" => "$productT: $productT",
|
||||
$productS => $productT,
|
||||
$companyS => $companyT,
|
||||
$s->getProductCode() => $t->getProductCode(),
|
||||
$s->getCompanyCode() => $t->getCompanyCode(),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Переименовывает сегменты пути (папки) в соответствии с именами модулей.
|
||||
*/
|
||||
protected function renamePathSegment(string $path): string
|
||||
{
|
||||
$sourceLast = collect(explode('.', $this->sourceEntity->getId()))->last();
|
||||
$targetLast = collect(explode('.', $this->targetEntity->getId()))->last();
|
||||
|
||||
$path = str_replace(ucfirst($sourceLast), ucfirst($targetLast), $path);
|
||||
$path = str_replace(strtolower($sourceLast), strtolower($targetLast), $path);
|
||||
|
||||
return $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Проверяет, должен ли файл/папка быть исключен из копирования.
|
||||
*/
|
||||
protected function shouldExclude(string $path): bool
|
||||
{
|
||||
foreach ($this->excludePatterns as $pattern) {
|
||||
if (preg_match($pattern, $path)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
+12
-12
@@ -2,22 +2,22 @@
|
||||
|
||||
IncludeModuleLangFile(__FILE__);
|
||||
|
||||
return array(
|
||||
'MAIN' => array(
|
||||
return [
|
||||
'MAIN' => [
|
||||
'TITLE' => GetMessage('MAIN_OPTIONS_PARAMETERS'),
|
||||
'THEME' => 'Y',
|
||||
'OPTIONS' => array(
|
||||
'OPTIONS' => [
|
||||
|
||||
),
|
||||
),
|
||||
'TEST' => array(
|
||||
],
|
||||
],
|
||||
'TEST' => [
|
||||
'TITLE' => 'test',
|
||||
'OPTIONS' => array(
|
||||
'TEST' => array(
|
||||
'OPTIONS' => [
|
||||
'TEST' => [
|
||||
'TITLE' => 'test_setting',
|
||||
'TYPE' => 'text',
|
||||
'DEFAULT' => '',
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
@@ -3,7 +3,7 @@
|
||||
require_once($_SERVER['DOCUMENT_ROOT'].'/bitrix/modules/main/include/prolog_admin_before.php');
|
||||
require($_SERVER['DOCUMENT_ROOT'].'/bitrix/modules/main/include/prolog_admin_after.php');
|
||||
|
||||
$adminPage = new \Wt\Core\Admin\SiteSettingsAdminPage('bx.null', 'main');
|
||||
$adminPage = new \Wt\Core\Admin\SiteSettingsAdminPage('bx.nullable', 'main');
|
||||
$adminPage->render();
|
||||
|
||||
require($_SERVER['DOCUMENT_ROOT'].'/bitrix/modules/main/include/epilog_admin.php');
|
||||
@@ -1,5 +1,2 @@
|
||||
<?
|
||||
<?php
|
||||
$MESS['MAIN_OPTIONS_PARAMETERS'] = 'Общие';
|
||||
$MESS['LOGO_IMAGE'] = 'Логотип сайта';
|
||||
$MESS['CACHE_OPTIONS'] = 'Кеш';
|
||||
$MESS['CACHE_STORAGE'] = 'Место хранения кеша';
|
||||
+1
-1
@@ -8,4 +8,4 @@ Loc::loadMessages(__FILE__);
|
||||
|
||||
return (new GlobalMenuItem())
|
||||
->setSort(10)
|
||||
->setTitle('Null Main');
|
||||
->setTitle('Nullable Main');
|
||||
+4
-4
@@ -1,17 +1,17 @@
|
||||
<?php
|
||||
|
||||
use Bx\Null\ORM\NullTable;
|
||||
use Bx\Nullable\ORM\NullableTable;
|
||||
use Wt\Core\Admin\TableAdminPage;
|
||||
|
||||
|
||||
require_once($_SERVER['DOCUMENT_ROOT'].'/bitrix/modules/main/include/prolog_admin.php');
|
||||
|
||||
/**
|
||||
* @var $ormTable NullTable
|
||||
* @var NullableTable $ormTable
|
||||
*/
|
||||
$ormTable = resolve(NullTable::class);
|
||||
$ormTable = resolve(NullableTable::class);
|
||||
|
||||
$tableAdminPage = new TableAdminPage($ormTable, $_REQUEST, '/bitrix/admin/bx_null.main.null_table.row.php');
|
||||
$tableAdminPage = new TableAdminPage($ormTable, $_REQUEST, '/bitrix/admin/bx_nullable.main.nullable_table.row.php');
|
||||
$tableAdminPage
|
||||
->checkPermission()
|
||||
->start()
|
||||
+1
-1
@@ -1,2 +1,2 @@
|
||||
<?
|
||||
<?php
|
||||
$MESS['CONTEXT_PROFILE_DELETE_CONFIRM'] = 'Удалить %s?';
|
||||
@@ -7,7 +7,8 @@ Loc::loadMessages(__FILE__);
|
||||
|
||||
|
||||
return (new GlobalMenuItem())
|
||||
->setVisible(false)
|
||||
->setSort(1300)
|
||||
->setTitle('Null Table')
|
||||
->setTitle('Nullable Table')
|
||||
->setIcon('iblock_menu_icon_iblocks')
|
||||
->setUrl();
|
||||
+5
-8
@@ -1,20 +1,17 @@
|
||||
<?
|
||||
<?php
|
||||
|
||||
use Bx\Null\ORM\NullTable;
|
||||
use Bx\Nullable\ORM\NullableTable;
|
||||
use Wt\Core\Admin\TableRowAdminPage;
|
||||
|
||||
|
||||
require_once($_SERVER['DOCUMENT_ROOT'].'/bitrix/modules/main/include/prolog_admin_before.php');
|
||||
require_once($_SERVER['DOCUMENT_ROOT'].'/bitrix/modules/main/include/prolog_admin_after.php');
|
||||
/**
|
||||
* @var $ormTable NullTable
|
||||
* @var NullableTable $ormTable
|
||||
*/
|
||||
$ormTable = resolve(NullTable::class);
|
||||
$ormTable = resolve(NullableTable::class);
|
||||
|
||||
$AdminPageTableRow = new TableRowAdminPage($ormTable, $_REQUEST, '/bitrix/admin/bx_null.main.null_table.php');
|
||||
$AdminPageTableRow = new TableRowAdminPage($ormTable, $_REQUEST, '/bitrix/admin/bx_nullable.main.nullable_table.php');
|
||||
$AdminPageTableRow->checkPermission();
|
||||
$AdminPageTableRow->start();
|
||||
|
||||
\CJSCore::Init('jquery');
|
||||
|
||||
require_once($_SERVER['DOCUMENT_ROOT'].'/bitrix/modules/main/include/epilog_admin.php');
|
||||
+1
-1
@@ -1,2 +1,2 @@
|
||||
<?
|
||||
<?php
|
||||
$MESS['MAIN_OPTIONS_PARAMETERS'] = 'Общие';
|
||||
+1
-1
@@ -7,7 +7,7 @@ Loc::loadMessages(__FILE__);
|
||||
|
||||
return (new GlobalMenuItem())
|
||||
->setSort(1400)
|
||||
->setTitle('Null Table Row')
|
||||
->setTitle('Nullable Table Row')
|
||||
->setIcon('default_menu_icon')
|
||||
->setVisible(false)
|
||||
->setUrl();
|
||||
@@ -5,39 +5,39 @@ use Wt\Core\Admin\SiteSettingsAdminPage;
|
||||
IncludeModuleLangFile(__FILE__);
|
||||
|
||||
/**
|
||||
* @var $this SiteSettingsAdminPage
|
||||
* @var SiteSettingsAdminPage $this
|
||||
*/
|
||||
|
||||
return array(
|
||||
'MAIN' => array(
|
||||
return [
|
||||
'MAIN' => [
|
||||
'TITLE' => 'Общие сведения',
|
||||
'OPTIONS' => array(
|
||||
'ENABLE' => array(
|
||||
'OPTIONS' => [
|
||||
'ENABLE' => [
|
||||
'TITLE' => 'Enable module',
|
||||
'TYPE' => 'checkbox',
|
||||
'DEFAULT' => 'N',
|
||||
'HINT' => '',
|
||||
),
|
||||
'CONFIG' => array(
|
||||
],
|
||||
'CONFIG' => [
|
||||
'TITLE' => 'Конфигурационные данные',
|
||||
'HINT' => '',
|
||||
'TYPE' => 'content',
|
||||
'INCLUDEFILE' => \Wt\Core\Tools::removeDocRoot(__DIR__ . '/include/config.php'),
|
||||
'SHOW_EDIT_BUTTON' => 'N',
|
||||
'DEFAULT' => '',
|
||||
),
|
||||
),
|
||||
),
|
||||
'DOCS' => array(
|
||||
],
|
||||
],
|
||||
],
|
||||
'DOCS' => [
|
||||
'TITLE' => 'Docs',
|
||||
'OPTIONS' => array(
|
||||
'DOCUMENTATION' => array(
|
||||
'OPTIONS' => [
|
||||
'DOCUMENTATION' => [
|
||||
'TITLE' => 'Documentation',
|
||||
'TYPE' => 'content',
|
||||
'INCLUDEFILE' => \Wt\Core\Tools::removeDocRoot(__DIR__ . '/include/documentation.php'),
|
||||
'SHOW_EDIT_BUTTON' => 'N',
|
||||
'DEFAULT' => '',
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/**
|
||||
* @var $this Wt\Core\Admin\Templater
|
||||
* @var Wt\Core\Admin\Templater $this
|
||||
*/
|
||||
$moduleId = $this->getAdminPage()->getModuleId();
|
||||
$app = app()::getInstance($moduleId);
|
||||
@@ -9,9 +9,41 @@ $data['env'] = $app->env();
|
||||
|
||||
|
||||
?>
|
||||
<table cellpadding="5" border="1" style="border-collapse: collapse; width: 100%">
|
||||
<?
|
||||
foreach ($data as $key => $value) {
|
||||
?><tr><td><?= $key ?></td><td><?= $value ?></td></tr><?
|
||||
}
|
||||
?></table><?
|
||||
<table cellpadding="5" border="1" style="border-collapse: collapse; width: 100%">
|
||||
<?php
|
||||
foreach ($data as $key => $value) {
|
||||
?><tr><td><?= $key ?></td><td><?= $value ?></td></tr><?php
|
||||
}
|
||||
?></table>
|
||||
<br><?php
|
||||
|
||||
?><table cellpadding="5" border="1" style="border-collapse: collapse; width: 100%">
|
||||
<tr>
|
||||
<?php
|
||||
$initPhpSrc = getLocalPath('php_interface/init.php', BX_PERSONAL_ROOT);
|
||||
$src = $app->module()->getSrc();
|
||||
$html = "<div style=\"font-family: monospace; font-size: 0.9em; white-space: pre; color: grey;\">if(file_exists(\$_SERVER['DOCUMENT_ROOT'] . '$src/init.php'))
|
||||
include_once \$_SERVER['DOCUMENT_ROOT'] . '$src/init.php';</div>";
|
||||
?>
|
||||
<td>
|
||||
<?=$this->getCheckTemplate($app->isIncludeFileToInitPhp())?>
|
||||
</td>
|
||||
<td>
|
||||
Модуль подключен в init.php
|
||||
</td>
|
||||
<td width="50%">
|
||||
<?php
|
||||
if($initPhpSrc){
|
||||
?><a target="_blank" href="/bitrix/admin/fileman_file_edit.php?path=<?=urlencode($initPhpSrc)?>&full_src=Y">
|
||||
<?=$initPhpSrc?>
|
||||
</a><?php
|
||||
} else {
|
||||
?>init.php отсутствует<?php
|
||||
}
|
||||
?>
|
||||
<br>
|
||||
<?=$html?>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
@@ -1,18 +1,9 @@
|
||||
<?php
|
||||
|
||||
|
||||
use Wt\Core\Admin\TableAdminPage;
|
||||
|
||||
|
||||
require_once($_SERVER['DOCUMENT_ROOT'].'/bitrix/modules/main/include/prolog_admin_before.php');
|
||||
require($_SERVER['DOCUMENT_ROOT']. '/bitrix/modules/main/include/prolog_admin_after.php');
|
||||
|
||||
|
||||
CJSCore::Init('jquery');
|
||||
CAjax::Init();
|
||||
|
||||
require($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_admin_after.php");
|
||||
|
||||
$adminPage = new \Wt\Core\Admin\SiteSettingsAdminPage('bx.null', 'main.settings');
|
||||
$adminPage = new \Wt\Core\Admin\SiteSettingsAdminPage('bx.nullable', 'main.settings');
|
||||
$adminPage->render();
|
||||
|
||||
require($_SERVER['DOCUMENT_ROOT'].'/bitrix/modules/main/include/epilog_admin.php');
|
||||
@@ -1,2 +1,2 @@
|
||||
<?
|
||||
<?php
|
||||
$MESS['CONTEXT_PROFILE_DELETE_CONFIRM'] = 'Удалить %s?';
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
use \Bitrix\Main\Localization\Loc;
|
||||
use Bitrix\Main\Localization\Loc;
|
||||
use Wt\Core\Admin\GlobalMenuItem;
|
||||
|
||||
Loc::loadMessages(__FILE__);
|
||||
|
||||
@@ -1,63 +1,35 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Wt\Core\App\ModuleCloner;
|
||||
|
||||
require './../wt.core/include.php';
|
||||
require './ModuleCloner.php';
|
||||
|
||||
$curPath = __DIR__;
|
||||
$newPath = realpath($argv[1]);
|
||||
$newEntity = __getModuleEntity($newPath);
|
||||
$nullEntity = __getModuleEntity(__DIR__);
|
||||
|
||||
function copy_folder($d1, $d2, $upd = true, $force = true, $exclude = []) {
|
||||
if ( is_dir( $d1 ) ) {
|
||||
$d2 = mkdir_safe( $d2, $force );
|
||||
if (!$d2) {
|
||||
fs_log("!!fail $d2");
|
||||
return;
|
||||
}
|
||||
$d = dir( $d1 );
|
||||
while ( false !== ( $entry = $d->read() ) ) {
|
||||
if ( $entry != '.' && $entry != '..' )
|
||||
copy_folder( "$d1/$entry", "$d2/$entry", $upd, $force );
|
||||
}
|
||||
$d->close();
|
||||
}
|
||||
else {
|
||||
$ok = copy_safe( $d1, $d2, $upd );
|
||||
$ok = ($ok) ? "ok-- " : " -- ";
|
||||
fs_log("{$ok}$d1");
|
||||
}
|
||||
} //function copy_folder
|
||||
|
||||
function mkdir_safe( $dir, $force ) {
|
||||
if (file_exists($dir)) {
|
||||
if (is_dir($dir)) return $dir;
|
||||
else if (!$force) return false;
|
||||
unlink($dir);
|
||||
}
|
||||
return (mkdir($dir, 0777, true)) ? $dir : false;
|
||||
} //function mkdir_safe
|
||||
|
||||
function copy_safe ($f1, $f2, $upd) {
|
||||
$time1 = filemtime($f1);
|
||||
if (file_exists($f2)) {
|
||||
$time2 = filemtime($f2);
|
||||
if ($time2 >= $time1 && $upd) return false;
|
||||
}
|
||||
$ok = copy($f1, $f2);
|
||||
if ($ok) touch($f2, $time1);
|
||||
return $ok;
|
||||
} //function copy_safe
|
||||
|
||||
function fs_log($str) {
|
||||
return;
|
||||
$log = fopen("./fs_log.txt", "a");
|
||||
$time = date("Y-m-d H:i:s");
|
||||
fwrite($log, "$str ($time)\n");
|
||||
fclose($log);
|
||||
if (!isset($argv[1])) {
|
||||
echo 'Error: Please provide the target module path as the first argument.' . PHP_EOL;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
try {
|
||||
$sourcePath = __DIR__;
|
||||
$targetPath = realpath($argv[1]);
|
||||
|
||||
echo $newEntity->getId() . PHP_EOL;
|
||||
if ($targetPath === false) {
|
||||
throw new InvalidArgumentException("Invalid target path: {$argv[1]}");
|
||||
}
|
||||
|
||||
$targetEntity = __getModuleEntity($targetPath);
|
||||
$sourceEntity = __getModuleEntity($sourcePath);
|
||||
|
||||
copy_folder($nullEntity->getDir(), $newEntity->getDir());
|
||||
echo "Cloning {$sourceEntity->getId()} -> {$targetEntity->getId()}..." . PHP_EOL;
|
||||
|
||||
$cloner = new ModuleCloner($sourceEntity, $targetEntity);
|
||||
$cloner->clone();
|
||||
|
||||
echo 'Success: Module cloned successfully.' . PHP_EOL;
|
||||
} catch (Throwable $e) {
|
||||
echo 'Critical Error: ' . $e->getMessage() . PHP_EOL;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
+122
@@ -0,0 +1,122 @@
|
||||
<?php
|
||||
|
||||
use Wt\Core\App\ModuleEntity;
|
||||
|
||||
require './../wt.core/include.php';
|
||||
|
||||
$curPath = __DIR__;
|
||||
$newPath = realpath($argv[1]);
|
||||
$newEntity = __getModuleEntity($newPath);
|
||||
$nullableEntity = __getModuleEntity(__DIR__);
|
||||
|
||||
function copy_folder_safe($d1, $d2, $upd = true, $force = true, $exclude = [], $handler = null) {
|
||||
$cm = 0;
|
||||
preg_filter($exclude, $exclude, $d1, -1, $cm);
|
||||
if($cm){
|
||||
echo 'skip ' . $d1 . PHP_EOL;
|
||||
return;
|
||||
}
|
||||
if(is_callable($handler)){
|
||||
call_user_func_array($handler, [$d1, &$d2]);
|
||||
}
|
||||
if ( is_dir( $d1 ) ) {
|
||||
$d2 = mkdir_safe( $d2, $force );
|
||||
if (!$d2) {
|
||||
return;
|
||||
}
|
||||
$d = dir( $d1 );
|
||||
while ( false !== ( $entry = $d->read() ) ) {
|
||||
if ( $entry != '.' && $entry != '..' )
|
||||
copy_folder_safe( "$d1/$entry", "$d2/$entry", $upd, $force, $exclude, $handler);
|
||||
}
|
||||
$d->close();
|
||||
}
|
||||
else {
|
||||
$ok = copy_safe( $d1, $d2, $upd );
|
||||
}
|
||||
}
|
||||
|
||||
function mkdir_safe( $dir, $force ) {
|
||||
if (file_exists($dir)) {
|
||||
if (is_dir($dir)) return $dir;
|
||||
elseif (!$force) return false;
|
||||
unlink($dir);
|
||||
}
|
||||
return (mkdir($dir, 0777, true)) ? $dir : false;
|
||||
}
|
||||
|
||||
function copy_safe ($f1, $f2, $upd) {
|
||||
$time1 = filemtime($f1);
|
||||
if (file_exists($f2)) {
|
||||
$time2 = filemtime($f2);
|
||||
if ($time2 >= $time1 && $upd) return false;
|
||||
}
|
||||
$ok = copy($f1, $f2);
|
||||
if ($ok) touch($f2, $time1);
|
||||
return $ok;
|
||||
}
|
||||
|
||||
function fs_log($str) {
|
||||
return;
|
||||
$log = fopen('./fs_log.txt', 'a');
|
||||
$time = date('Y-m-d H:i:s');
|
||||
fwrite($log, "$str ($time)\n");
|
||||
fclose($log);
|
||||
}
|
||||
|
||||
function _fix(ModuleEntity $newEntity, ModuleEntity $nullableEntity){
|
||||
$d = new RecursiveDirectoryIterator( $newEntity->getPath() );
|
||||
foreach( new RecursiveIteratorIterator( $d, 1 ) as $path ){
|
||||
if( is_file( $path ) && str_ends_with($path, '.php')){
|
||||
$orig_file = file_get_contents($path);
|
||||
|
||||
$new_file = $orig_file;
|
||||
$cr = 0;
|
||||
$new_file = str_replace($nullableEntity->getLangPrefix(), $newEntity->getLangPrefix(), $new_file, $cr);
|
||||
$new_file = str_replace($nullableEntity->getId(), $newEntity->getId(), $new_file, $cr);
|
||||
$new_file = str_replace($nullableEntity->getPrefix(), $newEntity->getPrefix(), $new_file, $cr);
|
||||
$new_file = str_replace($nullableEntity->getNamespace(), $newEntity->getNamespace(), $new_file, $cr);
|
||||
|
||||
$new_file = str_replace(
|
||||
ucfirst($nullableEntity->getProductCode()) . ': ' . ucfirst($nullableEntity->getProductCode()),
|
||||
ucfirst($newEntity->getProductCode()) . ': ' . ucfirst($newEntity->getProductCode()),
|
||||
$new_file,
|
||||
$cr
|
||||
);
|
||||
|
||||
$new_file = str_replace(ucfirst($nullableEntity->getProductCode()), ucfirst($newEntity->getProductCode()), $new_file, $cr);
|
||||
$new_file = str_replace(ucfirst($nullableEntity->getCompanyCode()), ucfirst($newEntity->getCompanyCode()), $new_file, $cr);
|
||||
$new_file = str_replace($nullableEntity->getProductCode(), $newEntity->getProductCode(), $new_file, $cr);
|
||||
$new_file = str_replace($nullableEntity->getCompanyCode(), $newEntity->getCompanyCode(), $new_file, $cr);
|
||||
|
||||
|
||||
|
||||
echo $cr . ' ' .$path . PHP_EOL;
|
||||
|
||||
if($orig_file != $new_file){
|
||||
file_put_contents($path, $new_file);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
echo $newEntity->getId() . PHP_EOL;
|
||||
|
||||
|
||||
copy_folder_safe($nullableEntity->getPath(), $newEntity->getPath(), true, true, [
|
||||
'/\.git$/',
|
||||
'/\.module\.json/',
|
||||
'/clone\.php/',
|
||||
'/readme\.md/',
|
||||
'/src\/\.env$/',
|
||||
'/src\/config\.php$/',
|
||||
], function ($d1, &$d2) use ($nullableEntity, $newEntity){
|
||||
$lastModuleName = collect(explode('.', $newEntity->fields()->id))->last();
|
||||
$lastNullableModuleName = collect(explode('.', $nullableEntity->fields()->id))->last();
|
||||
|
||||
|
||||
$d2 = str_replace(ucfirst($lastNullableModuleName), ucfirst($lastModuleName), $d2, $cr);
|
||||
$d2 = str_replace(strtolower($lastNullableModuleName), strtolower($lastModuleName), $d2, $cr);
|
||||
});
|
||||
|
||||
_fix($newEntity, $nullableEntity);
|
||||
+15
-1
@@ -2,6 +2,20 @@
|
||||
|
||||
return [
|
||||
'MainAbstractFactory' => [
|
||||
'Bx\Null\Factory\NullFactory' => ['cache' => ['hit'], 'is_collection_query' => true],
|
||||
'Bx\Nullable\Factory\NullableFactory' => ['cache' => ['hit'], 'is_collection_query' => true],
|
||||
],
|
||||
'events' => [
|
||||
'main:OnPageStart' => [
|
||||
['Bx\Nullable\Handlers\Autoloader', 'onPageStart'],
|
||||
],
|
||||
'main:OnProlog' => [
|
||||
['Bx\Nullable\Handlers\Autoloader', 'onProlog'],
|
||||
],
|
||||
'main:OnEpilog' => [
|
||||
['Bx\Nullable\Handlers\Autoloader', 'onEpilog'],
|
||||
],
|
||||
'main:OnBeforeProlog' => [
|
||||
['Bx\Nullable\Handlers\Autoloader', 'onBeforeProlog'],
|
||||
],
|
||||
],
|
||||
];
|
||||
+3
-4
@@ -1,12 +1,11 @@
|
||||
<?php
|
||||
|
||||
use Bx\Null\App\App;
|
||||
use Bx\Nullable\App\App;
|
||||
|
||||
/**
|
||||
* @return App
|
||||
* @throws null
|
||||
*/
|
||||
function nullApp() {
|
||||
$app = App::getInstance('bx.null');
|
||||
return $app;
|
||||
function nullableApp() {
|
||||
return App::getInstance('bx.nullable');
|
||||
}
|
||||
+47
-24
@@ -1,19 +1,20 @@
|
||||
<?
|
||||
<?php
|
||||
|
||||
use Bitrix\Main\EventManager;
|
||||
use Bitrix\Main\Loader;
|
||||
|
||||
IncludeModuleLangFile(__FILE__);
|
||||
|
||||
class bx_null extends \CModule
|
||||
class bx_nullable extends \CModule
|
||||
{
|
||||
public $module = [];
|
||||
var $MODULE_GROUP_RIGHTS = 'Y';
|
||||
public $MODULE_GROUP_RIGHTS = 'Y';
|
||||
|
||||
function __construct()
|
||||
public function __construct()
|
||||
{
|
||||
$module = [];
|
||||
if(file_exists(__DIR__.'/../.module.json')){
|
||||
$module = json_decode(file_get_contents(__DIR__.'/../.module.json'), true);
|
||||
if (file_exists(__DIR__ . '/../.module.json')) {
|
||||
$module = json_decode(file_get_contents(__DIR__ . '/../.module.json'), true);
|
||||
}
|
||||
|
||||
$this->module = $module;
|
||||
@@ -25,32 +26,32 @@ class bx_null extends \CModule
|
||||
$langPrefix = $module['prefix'];
|
||||
|
||||
$this->PARTNER_NAME = GetMessage("{$langPrefix}_partner_name");
|
||||
$this->PARTNER_URI = GetMessage("{$langPrefix}_partner_uri");
|
||||
$this->PARTNER_URI = GetMessage("{$langPrefix}_partner_uri");
|
||||
$this->MODULE_NAME = GetMessage("{$langPrefix}_module_name");
|
||||
$this->MODULE_DESCRIPTION = GetMessage("{$langPrefix}_module_description");
|
||||
}
|
||||
|
||||
|
||||
function DoInstall()
|
||||
public function DoInstall()
|
||||
{
|
||||
global $DOCUMENT_ROOT, $APPLICATION;
|
||||
global $APPLICATION;
|
||||
|
||||
if(is_array($this->module['deps'])){
|
||||
foreach ($this->module['deps'] as $moduleId){
|
||||
if (!\Bitrix\Main\Loader::includeModule($moduleId)) {
|
||||
if (is_array($this->module['deps'])) {
|
||||
foreach ($this->module['deps'] as $moduleId) {
|
||||
if (!Loader::includeModule($moduleId)) {
|
||||
$APPLICATION->ThrowException("Module {$moduleId} not installed!");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!CheckVersion(PHP_VERSION, "5.4.0")) {
|
||||
$APPLICATION->ThrowException('Php version required more 5.4.0');
|
||||
if (!(version_compare(PHP_VERSION, '8.0.0') >= 0)) {
|
||||
$APPLICATION->ThrowException('Php version required more 8.0.0');
|
||||
return false;
|
||||
}
|
||||
|
||||
RegisterModule($this->MODULE_ID);
|
||||
RegisterModuleDependences("main", "OnPageStart", $this->MODULE_ID);
|
||||
RegisterModuleDependences('main', 'OnPageStart', $this->MODULE_ID);
|
||||
$this->InstallEvents();
|
||||
$this->InstallCatalogExport();
|
||||
|
||||
@@ -58,37 +59,59 @@ class bx_null extends \CModule
|
||||
return true;
|
||||
}
|
||||
|
||||
function DoUninstall()
|
||||
public function DoUninstall()
|
||||
{
|
||||
global $DOCUMENT_ROOT, $APPLICATION;
|
||||
global $APPLICATION;
|
||||
UnRegisterModule($this->MODULE_ID);
|
||||
UnRegisterModuleDependences("main", "OnPageStart", $this->MODULE_ID, "", "");
|
||||
UnRegisterModuleDependences('main', 'OnPageStart', $this->MODULE_ID, '', '');
|
||||
$this->UnInstallEvents();
|
||||
$this->UnInstallCatalogExport();
|
||||
return true;
|
||||
}
|
||||
|
||||
function InstallCatalogExport()
|
||||
public function InstallCatalogExport()
|
||||
{
|
||||
if(is_dir(__DIR__."/catalog_export") && \Bitrix\Main\Loader::includeModule('catalog')){
|
||||
CopyDirFiles(__DIR__."/catalog_export", $_SERVER["DOCUMENT_ROOT"].CATALOG_PATH2EXPORTS, true, true);
|
||||
if (is_dir(__DIR__ . '/catalog_export') && Loader::includeModule('catalog')) {
|
||||
CopyDirFiles(__DIR__ . '/catalog_export', $_SERVER['DOCUMENT_ROOT'] . CATALOG_PATH2EXPORTS, true, true);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function UnInstallCatalogExport()
|
||||
public function UnInstallCatalogExport()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
function InstallEvents()
|
||||
public function InstallEvents()
|
||||
{
|
||||
if (class_exists('\Bitrix\Main\EventManager')) {
|
||||
$eventManager = EventManager::getInstance();
|
||||
// $eventManager->registerEventHandler(
|
||||
// 'main',
|
||||
// 'OnPageStart',
|
||||
// $this->MODULE_ID,
|
||||
// 'Bx\Nullable\Handler\Handler',
|
||||
// 'exec',
|
||||
// 100
|
||||
// );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function UnInstallEvents()
|
||||
public function UnInstallEvents()
|
||||
{
|
||||
if (class_exists('\Bitrix\Main\EventManager')) {
|
||||
$eventManager = \Bitrix\Main\EventManager::getInstance();
|
||||
// $eventManager->unRegisterEventHandler(
|
||||
// 'main',
|
||||
// 'OnPageStart',
|
||||
// $this->MODULE_ID,
|
||||
// 'Bx\Nullable\Handler\Handler',
|
||||
// 'exec'
|
||||
// );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
<?
|
||||
$MESS ['bx_null_partner_name'] = 'CoreLion';
|
||||
$MESS ['bx_null_partner_uri'] = 'https://corelion.ru/';
|
||||
$MESS ['bx_null_module_name'] = 'Bx: Null';
|
||||
$MESS ['bx_null_module_description'] = 'Null module';
|
||||
<?php
|
||||
$MESS ['bx_nullable_partner_name'] = 'CoreLion';
|
||||
$MESS ['bx_nullable_partner_uri'] = 'https://corelion.ru/';
|
||||
$MESS ['bx_nullable_module_name'] = 'Bx: Nullable';
|
||||
$MESS ['bx_nullable_module_description'] = 'Nullable module';
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace Bx\Nullable\AbstractFactory;
|
||||
|
||||
use Wt\Core\AbstractFactory\AAbstractFactory;
|
||||
use Bx\Nullable\Factory\NullableFactory;
|
||||
|
||||
class MainAbstractFactory extends AAbstractFactory
|
||||
{
|
||||
/**
|
||||
* @return NullableFactory
|
||||
*/
|
||||
public function getNullableFactory()
|
||||
{
|
||||
return $this->getFactoryInstance(NullableFactory::class);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,12 +1,10 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Bx\Null\Ajax;
|
||||
|
||||
namespace Bx\Nullable\Ajax;
|
||||
|
||||
use Wt\Core\Ajax\AAjaxHandler;
|
||||
|
||||
class BxNull extends AAjaxHandler
|
||||
class BxNullable extends AAjaxHandler
|
||||
{
|
||||
public function ajaxStart()
|
||||
{
|
||||
@@ -15,7 +13,7 @@ class BxNull extends AAjaxHandler
|
||||
|
||||
public function test()
|
||||
{
|
||||
$this->getResponse()->addData(['method' => 'test', 'version' => nullApp()->module()->getVersion()]);
|
||||
$this->getResponse()->addData(['method' => 'test', 'version' => app()::getInstance('bx.nullable')->module()->getVersion()]);
|
||||
return $this->getResponse();
|
||||
}
|
||||
}
|
||||
@@ -1,18 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace Bx\Nullable\App;
|
||||
|
||||
namespace Bx\Null\App;
|
||||
|
||||
|
||||
use Bx\Null\Facade\DefaultDefines;
|
||||
use Bx\Null\Facade\Defines;
|
||||
use Bx\Null\Facade\DefaultServiceFacade;
|
||||
use Bx\Null\Facade\ServiceFacade;
|
||||
use Bx\Null\Facade\DefaultFactoryFacade;
|
||||
use Bx\Null\Facade\FactoryFacade;
|
||||
use Bx\Nullable\Facade\DefaultDefines;
|
||||
use Bx\Nullable\Facade\Defines;
|
||||
use Bx\Nullable\Facade\DefaultServiceFacade;
|
||||
use Bx\Nullable\Facade\ServiceFacade;
|
||||
use Bx\Nullable\Facade\DefaultFactoryFacade;
|
||||
use Bx\Nullable\Facade\FactoryFacade;
|
||||
|
||||
class App extends \Wt\Core\App\App
|
||||
{
|
||||
protected $includeFileToInitPhp;
|
||||
|
||||
/**
|
||||
* @param string $factoryName
|
||||
* @return FactoryFacade | DefaultFactoryFacade
|
||||
@@ -39,4 +39,13 @@ class App extends \Wt\Core\App\App
|
||||
{
|
||||
return parent::defines();
|
||||
}
|
||||
|
||||
public function isIncludeFileToInitPhp($value = null)
|
||||
{
|
||||
if(is_null($value)){
|
||||
return $this->includeFileToInitPhp;
|
||||
}
|
||||
$this->includeFileToInitPhp = $value;
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
|
||||
namespace Bx\Nullable\Collection;
|
||||
|
||||
use Wt\Core\Collection\AEntityCollection;
|
||||
use Bx\Nullable\Entity\NullableEntity;
|
||||
|
||||
class NullableCollection extends AEntityCollection
|
||||
{
|
||||
|
||||
/**
|
||||
* @param $xmlId
|
||||
* @return NullableEntity
|
||||
* @deprecated
|
||||
*/
|
||||
public function &getByXmlId($xmlId)
|
||||
{
|
||||
return parent::getByXmlId($xmlId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $id
|
||||
* @param null $default
|
||||
* @return NullableEntity|null
|
||||
*/
|
||||
public function &get($id, $default = null)
|
||||
{
|
||||
return parent::get($id, $default);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return NullableEntity
|
||||
*/
|
||||
public function &first(callable $callback = null, $default = null)
|
||||
{
|
||||
return parent::first($callback, $default);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return NullableEntity
|
||||
*/
|
||||
public function &last()
|
||||
{
|
||||
return parent::last();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return NullableEntity
|
||||
*/
|
||||
public function shift()
|
||||
{
|
||||
return parent::shift();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return NullableEntity
|
||||
*/
|
||||
public function pop()
|
||||
{
|
||||
return parent::pop();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return NullableCollection|NullableEntity[]
|
||||
*/
|
||||
public function filter($callback = null)
|
||||
{
|
||||
return parent::filter($callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return NullableEntity[]
|
||||
*/
|
||||
public function all()
|
||||
{
|
||||
return parent::all();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace Bx\Nullable\Entity;
|
||||
|
||||
use Bx\Nullable\IFields\NullableFields;
|
||||
use Bx\Nullable\Factory\NullableFactory;
|
||||
use Wt\Core\Entity\AEntity;
|
||||
|
||||
class NullableEntity extends AEntity
|
||||
{
|
||||
/**
|
||||
* @return NullableFactory
|
||||
*/
|
||||
public function getFactory()
|
||||
{
|
||||
return parent::getFactory();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return NullableFields
|
||||
*/
|
||||
public function fields()
|
||||
{
|
||||
return parent::fields();
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,6 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Bx\Null\Facade;
|
||||
|
||||
namespace Bx\Nullable\Facade;
|
||||
|
||||
use Wt\Core\App\ADefines;
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace Bx\Nullable\Facade;
|
||||
|
||||
namespace Bx\Null\Facade;
|
||||
|
||||
|
||||
use Bx\Null\AbstractFactory\MainAbstractFactory;
|
||||
use Bx\Nullable\AbstractFactory\MainAbstractFactory;
|
||||
use Wt\Core\Facade\AFacade;
|
||||
|
||||
class DefaultFactoryFacade extends AFacade
|
||||
@@ -1,8 +1,6 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Bx\Null\Facade;
|
||||
|
||||
namespace Bx\Nullable\Facade;
|
||||
|
||||
use Wt\Core\Facade\AFacade;
|
||||
|
||||
@@ -1,44 +1,42 @@
|
||||
<?php
|
||||
|
||||
namespace Bx\Nullable\Factory;
|
||||
|
||||
namespace Bx\Null\Factory;
|
||||
|
||||
|
||||
use Bx\Null\Collection\NullCollection;
|
||||
use Bx\Null\Entity\NullEntity;
|
||||
use Bx\Null\ORM\NullTable;
|
||||
use Bx\Nullable\Collection\NullableCollection;
|
||||
use Bx\Nullable\Entity\NullableEntity;
|
||||
use Bx\Nullable\ORM\NullableTable;
|
||||
use Wt\Core\Factory\AFactory;
|
||||
use Wt\Core\Factory\AORMFactory;
|
||||
|
||||
class NullFactory extends AORMFactory
|
||||
class NullableFactory extends AORMFactory
|
||||
{
|
||||
|
||||
/**
|
||||
* @return string|NullTable
|
||||
* @return string|NullableTable
|
||||
*/
|
||||
protected function __getDataManagerClass()
|
||||
{
|
||||
return NullTable::class;
|
||||
return NullableTable::class;
|
||||
}
|
||||
|
||||
public function __getEntityClass()
|
||||
{
|
||||
return NullEntity::class;
|
||||
return NullableEntity::class;
|
||||
}
|
||||
|
||||
public function __getCachePrefix()
|
||||
{
|
||||
return 'bx_null';
|
||||
return 'bx_nullable';
|
||||
}
|
||||
|
||||
public function __getCollectionClass()
|
||||
{
|
||||
return NullCollection::class;
|
||||
return NullableCollection::class;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $id
|
||||
* @return NullEntity
|
||||
* @return NullableEntity
|
||||
*/
|
||||
public function getEntityById($id)
|
||||
{
|
||||
@@ -51,24 +49,24 @@ class NullFactory extends AORMFactory
|
||||
* @param array $select
|
||||
* @param null $limit
|
||||
* @param null $offset
|
||||
* @return NullCollection|NullEntity[]
|
||||
* @return NullableCollection|NullableEntity[]
|
||||
*/
|
||||
public function getCollection($filter = [], $order = [], $select = [], $limit = null, $offset = null)
|
||||
{
|
||||
return parent::getCollection($filter, $order, $select, $limit, $offset); // TODO: Change the autogenerated stub
|
||||
return parent::getCollection($filter, $order, $select, $limit, $offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $arIds
|
||||
* @return NullCollection|NullEntity[]
|
||||
* @return NullableCollection|NullableEntity[]
|
||||
*/
|
||||
public function getEntityByIds(array $arIds)
|
||||
{
|
||||
return parent::getEntityByIds($arIds); // TODO: Change the autogenerated stub
|
||||
return parent::getEntityByIds($arIds);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return NullTable
|
||||
* @return NullableTable
|
||||
*/
|
||||
public function getDataManager()
|
||||
{
|
||||
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace Bx\Nullable\Handlers;
|
||||
|
||||
class Autoloader
|
||||
{
|
||||
public static function onPageStart(){}
|
||||
public static function onBeforeProlog(){}
|
||||
public static function onProlog(){}
|
||||
public static function onEpilog(){}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace Bx\Nullable\IFields;
|
||||
|
||||
use Wt\Core\Interfaces\IFields;
|
||||
|
||||
class NullableFields implements IFields
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace Bx\Nullable\Interfaces;
|
||||
|
||||
interface ITest
|
||||
{
|
||||
|
||||
}
|
||||
@@ -1,39 +1,38 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Bx\Null\ORM;
|
||||
|
||||
namespace Bx\Nullable\ORM;
|
||||
|
||||
use Bitrix\Main\ORM\Fields\DatetimeField;
|
||||
use Bitrix\Main\Type\DateTime;
|
||||
use Exception;
|
||||
use Wt\Core\ORM\ADataManager;
|
||||
|
||||
class NullTable extends ADataManager
|
||||
class NullableTable extends ADataManager
|
||||
{
|
||||
|
||||
public static function getTitle()
|
||||
{
|
||||
return 'Null Title';
|
||||
return 'Nullable Title';
|
||||
}
|
||||
|
||||
public static function getRowTitle()
|
||||
{
|
||||
return 'Null Row Title';
|
||||
return 'Nullable Row Title';
|
||||
}
|
||||
|
||||
public static function getRowDescription()
|
||||
{
|
||||
return 'Null Row Description';
|
||||
return 'Nullable Row Description';
|
||||
}
|
||||
|
||||
public static function getTableName()
|
||||
{
|
||||
return 'bx_null_table';
|
||||
return 'bx_nullable_table';
|
||||
}
|
||||
|
||||
public static function getMap()
|
||||
{
|
||||
return array(
|
||||
return [
|
||||
'ID' => new \Bitrix\Main\Entity\IntegerField('ID', [
|
||||
'primary' => true,
|
||||
'autocomplete' => true,
|
||||
@@ -47,39 +46,39 @@ class NullTable extends ADataManager
|
||||
'title' => 'UpdatedAt',
|
||||
'user_edit' => false,
|
||||
]),
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $id
|
||||
* @param array $fields
|
||||
* @param $primary
|
||||
* @param array $data
|
||||
* @return \Bitrix\Main\ORM\Data\UpdateResult
|
||||
* @throws \Bitrix\Main\ObjectException
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function update($id, array $fields)
|
||||
public static function update($primary, array $data)
|
||||
{
|
||||
foreach (static::getEntity()->getFields() as $field){
|
||||
if(is_a($field, DatetimeField::class)){
|
||||
if(isset($fields[$field->getName()]) && !is_a($fields[$field->getName()], DateTime::class)) {
|
||||
$fields[$field->getName()] = new \Bitrix\Main\Type\DateTime($fields[$field->getName()]);
|
||||
if(isset($data[$field->getName()]) && !is_a($data[$field->getName()], DateTime::class)) {
|
||||
$data[$field->getName()] = new \Bitrix\Main\Type\DateTime($data[$field->getName()]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$fields = array_merge($fields, [
|
||||
$data = array_merge($data, [
|
||||
'UPDATED_AT' => new \Bitrix\Main\Type\DateTime(), // date(CDatabase::DateFormatToPHP(FORMAT_DATETIME))
|
||||
]);
|
||||
unset($fields['CREATED_AT']);
|
||||
unset($data['CREATED_AT']);
|
||||
|
||||
$result = parent::update($id, $fields);
|
||||
return $result;
|
||||
return parent::update($primary, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $fields
|
||||
* @return \Bitrix\Main\ORM\Data\AddResult
|
||||
* @throws \Bitrix\Main\ObjectException
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function add(array $fields)
|
||||
{
|
||||
@@ -88,7 +87,6 @@ class NullTable extends ADataManager
|
||||
'UPDATED_AT' => new \Bitrix\Main\Type\DateTime(),
|
||||
]);
|
||||
|
||||
$result = parent::add($fields);
|
||||
return $result;
|
||||
return parent::add($fields);
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace Bx\Nullable\Providers;
|
||||
|
||||
namespace Bx\Null\Providers;
|
||||
|
||||
|
||||
use Bx\Null\AbstractFactory\MainAbstractFactory;
|
||||
use Bx\Nullable\AbstractFactory\MainAbstractFactory;
|
||||
use Wt\Core\Interfaces\IApp;
|
||||
use Wt\Core\Interfaces\IServiceProvider;
|
||||
|
||||
@@ -16,7 +14,7 @@ class DefaultFactoryProvider implements IServiceProvider
|
||||
$serviceContainer = $app->container();
|
||||
|
||||
/**
|
||||
* @var $mainAbstractFactory MainAbstractFactory
|
||||
* @var MainAbstractFactory $mainAbstractFactory
|
||||
*/
|
||||
$mainAbstractFactory = $serviceContainer->make(MainAbstractFactory::class, [$config->get('MainAbstractFactory', [])]);
|
||||
$serviceContainer->singleton($app->module()->getId().':mainAbstractFactory', $mainAbstractFactory);
|
||||
@@ -1,8 +1,6 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Bx\Null\Providers;
|
||||
|
||||
namespace Bx\Nullable\Providers;
|
||||
|
||||
use Wt\Core\Interfaces\IApp;
|
||||
use Wt\Core\Providers\ADefaultServiceProvider;
|
||||
@@ -1,20 +0,0 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Bx\Null\AbstractFactory;
|
||||
|
||||
|
||||
use Wt\Core\AbstractFactory\AAbstractFactory;
|
||||
use Bx\Null\Factory\NullFactory;
|
||||
|
||||
class MainAbstractFactory extends AAbstractFactory
|
||||
{
|
||||
/**
|
||||
* @return NullFactory
|
||||
*/
|
||||
public function getNullFactory()
|
||||
{
|
||||
return $this->getFactoryInstance(NullFactory::class);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Bx\Null\Collection;
|
||||
|
||||
|
||||
use Wt\Core\Collection\AEntityCollection;
|
||||
use Bx\Null\Entity\NullEntity;
|
||||
|
||||
class NullCollection extends AEntityCollection
|
||||
{
|
||||
|
||||
/**
|
||||
* @param $xmlId
|
||||
* @return NullEntity
|
||||
*/
|
||||
public function &getByXmlId($xmlId)
|
||||
{
|
||||
return parent::getByXmlId($xmlId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $id
|
||||
* @param null $default
|
||||
* @return NullEntity|null
|
||||
*/
|
||||
public function &get($id, $default = null)
|
||||
{
|
||||
return parent::get($id, $default); // TODO: Change the autogenerated stub
|
||||
}
|
||||
|
||||
/**
|
||||
* @return NullEntity
|
||||
*/
|
||||
public function &first()
|
||||
{
|
||||
return parent::first(); // TODO: Change the autogenerated stub
|
||||
}
|
||||
|
||||
/**
|
||||
* @return NullEntity
|
||||
*/
|
||||
public function &last()
|
||||
{
|
||||
return parent::last(); // TODO: Change the autogenerated stub
|
||||
}
|
||||
|
||||
/**
|
||||
* @return NullEntity
|
||||
*/
|
||||
public function shift()
|
||||
{
|
||||
return parent::shift(); // TODO: Change the autogenerated stub
|
||||
}
|
||||
|
||||
/**
|
||||
* @return NullEntity
|
||||
*/
|
||||
public function pop()
|
||||
{
|
||||
return parent::pop(); // TODO: Change the autogenerated stub
|
||||
}
|
||||
|
||||
/**
|
||||
* @return NullEntity[]
|
||||
*/
|
||||
public function all()
|
||||
{
|
||||
return parent::all(); // TODO: Change the autogenerated stub
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Bx\Null\Entity;
|
||||
|
||||
|
||||
use Bx\Null\IFields\NullFields;
|
||||
use Wt\Core\Entity\AEntity;
|
||||
use Wt\Core\Supports\Entity;
|
||||
|
||||
class NullEntity extends AEntity
|
||||
{
|
||||
/**
|
||||
* @return NullFields
|
||||
*/
|
||||
public function fields()
|
||||
{
|
||||
return parent::fields();
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Bx\Null\IFields;
|
||||
|
||||
|
||||
use Wt\Core\Interfaces\IFields;
|
||||
|
||||
class NullFields implements IFields
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
# 🛠️ Инструкция по созданию и настройке модулей
|
||||
|
||||
## 📁 Структура директорий
|
||||
|
||||
```text
|
||||
└── 📁 local/
|
||||
└── 📁 modules/
|
||||
├── 📁 bx.nullable/
|
||||
│ └── 📄 clone.php
|
||||
├── 📁 comp.dev/
|
||||
│ └── 📄 .module.json
|
||||
└── 📁 wt.core/
|
||||
```
|
||||
|
||||
## 🚀 Пошаговое руководство
|
||||
|
||||
1. **Создайте папку** с вашим новым модулем в директории `local/modules/`.
|
||||
2. **Скопируйте и настройте** конфигурационный файл `.module.json` внутри созданной папки.
|
||||
3. **Запустите скрипт клонирования**, выполнив команду в терминале:
|
||||
```bash
|
||||
php -f local/modules/bx.nullable/clone.php ../путь_к_новому_модулю
|
||||
```
|
||||
## 📄 Пример файла `.module.json`
|
||||
|
||||
Ниже представлен шаблон конфигурации для модуля:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "comp.dev",
|
||||
"prefix": "comp_dev",
|
||||
"namespace": "Comp\\Dev",
|
||||
"repo": "git@git.ru:author/comp.dev.git",
|
||||
"version": "1.0.0",
|
||||
"date": "2026-01-01 00:00:00",
|
||||
"deps": ["wt.core"]
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1 @@
|
||||
local
|
||||
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
/**
|
||||
* @var array $config
|
||||
*/
|
||||
return [
|
||||
'providers' => [],
|
||||
];
|
||||
Reference in New Issue
Block a user