├── .gitignore
├── README.md
├── mycomponent
├── build
│ ├── build.models.php
│ ├── build.package.php
│ ├── build.schema.php
│ ├── config
│ │ ├── config.inc.php
│ │ └── version.php
│ ├── data
│ │ ├── README.md
│ │ ├── setup.options.php
│ │ ├── setup.requires.php
│ │ ├── transport.chunks.php
│ │ ├── transport.events.php
│ │ ├── transport.menu.php
│ │ ├── transport.plugins.php
│ │ ├── transport.settings.php
│ │ ├── transport.snippets.php
│ │ ├── transport.templates.php
│ │ └── transport.tvs.php
│ ├── data_static
│ │ ├── README.md
│ │ ├── setup.options.php
│ │ ├── transport.chunks.php
│ │ ├── transport.menu.php
│ │ ├── transport.plugins.php
│ │ ├── transport.settings.php
│ │ ├── transport.snippets.php
│ │ ├── transport.templates.php
│ │ └── transport.tvs.php
│ ├── resolvers
│ │ ├── resolver.tables.php
│ │ └── resolvers.php
│ └── templates
│ │ ├── changelog.item.txt
│ │ └── readme.txt
└── copy-from-www.php
└── tools
├── modxbuilder.class.php
└── xpdogenerator.class.php
/.gitignore:
--------------------------------------------------------------------------------
1 | /mycomponent/core
2 | /omtestimonials
3 | .idea
4 | .DS_Store
5 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Набор скриптов для автоматической генерации xPDO моделей и сборки компонента MODx.
2 |
3 | Работает только с mySQL, так как используется информация из базы данных information_schema.
4 |
5 | ## Установка
6 |
7 | По-умолчанию папка modxbuilder должна располагаться в каталоге на уровень выше вашей корневой папки сайта (www).
8 |
9 | ```
10 | .
11 | |-modxbuilder
12 | | |-mycomponent
13 | | | |-build
14 | | |
15 | | |-tools
16 | |
17 | |-www
18 | |-assets
19 | |-connectors
20 | |-core
21 | |-manager
22 | |-config.core.php
23 | |-index.php
24 | ```
25 |
26 | После того, как вы склонировали репозиторий в папку modxbuilder, можно приступать к работе
27 |
28 | ## Определяем имя компонента, префикс классов и префикс таблиц
29 |
30 | Перед тем как создавать свои таблицы в БД, необходимо определиться с названием вашего расширения, префиксом таблиц и префиксом генерируемых классов
31 |
32 | Например, вы хотите назвать ваш компонент `yourcomponent`, префикс классов `your`, префикс таблиц `your_`:
33 |
34 | 1. Переименуйте папку `modxbuilder/mycomponent` в `modxbuilder/yourcomponent`
35 | 2. Откройте файл `modxbuilder/yourcomponent/build/config/build.config.php` и укажите соответствующие значения в переменных `real_package_name` `package_name` `package_table_prefix` `package_class_prefix`
36 |
37 | ## Создание пользовательских таблиц
38 |
39 | Создайте в вашей базе данных таблицу(-ы) с именем в формате:
40 |
41 | ```
42 | [глобальный_префикс][префикс_ваших_таблиц][имя_таблицы]
43 | ```
44 |
45 | Например:
46 |
47 | ```
48 | modx_your_books
49 | ```
50 |
51 | При создании таблицы вы можете явно указать класс будущей модели через поле комментария к таблице. Если его не указать, то имя класса будет сформировано
52 | автоматически из названия таблицы. В нашем случае имя класса будет yourBooks.
53 |
54 | Поскольку books - это множественное число, то вы, вероятно, хотели бы, чтобы ваш класс назывался yourBook. Выхода из этой ситуации два:
55 |
56 | 1. Изменить название таблицы на modx_your_book
57 | 2. Указать в комментариях к таблице modx_your_book значение yourBook. В этом случае, независимо от названия таблицы (после modx_your_) имя вашей модели
58 | будет четко указано - yourBook
59 |
60 | ## Генерация первичной xml-схемы
61 |
62 | После того, как вы создали все необходимые таблицы с префиксом modx_your_ (или другим, выбранным вами), запускаем скрипт `modxbuilder/[имя_компонента]/build/build.schema.php`
63 |
64 | При успешном выполнении скрипта, вы получите файл `modxbuilder/[имя_компонента]/core/components/[имя_компонента]/model/schema/[имя_компонента].mysql.schema.new.xml`
65 |
66 | ## Создание основной xml-схемы
67 |
68 | После того, как вы получили файл первичной схемы, вам необходимо скопировать содержимое файла `modxbuilder/[имя_компонента]/core/components/[имя_компонента]/model/schema/[имя_компонента].mysql.schema.new.xml`
69 | в файл `modxbuilder/[имя_компонента]/core/components/[имя_компонента]/model/schema/[имя_компонента].mysql.schema.xml`.
70 |
71 | При необходимости, дополните содержимое файла `modxbuilder/[имя_компонента]/core/components/[имя_компонента]/model/schema/[имя_компонента].mysql.schema.xml`
72 | дополнительной информацией о связях между таблицами и полями валидации.
73 |
74 | [Подробнее об описании связей между моделями](https://docs.modx.com/xpdo/2.x/getting-started/creating-a-model-with-xpdo/defining-a-schema/defining-relationships)
75 |
76 | [Подробнее о правилах валидации моделей](https://docs.modx.com/xpdo/2.x/getting-started/creating-a-model-with-xpdo/defining-a-schema/validation-rules-in-your-schema)
77 |
78 | ## Генерация моделей
79 |
80 | После того, как вы добавили содержимое в файл `modxbuilder/[имя_компонента]/core/components/[имя_компонента]/model/schema/[имя_компонента].mysql.schema.xml`
81 | запустите скрипт `modxbuilder/[имя_компонента]/build/build.models.php`.
82 |
83 | После успешного запуска вашего скрипта в папке `modxbuilder/[имя_компонента]/core/components/[имя_компонента]/model/[имя_компонента]/` появятся все
84 | сгенерированные файлы моделей и маппинги mysql.
85 |
86 | ## Использование моделей в проекте
87 |
88 | Как вы заметили, вся описанная выше работа изолирована в каталоге `modxbuilder/[имя_компонента]`. Для дальнейшего использования
89 | ваших моделей в проекте, вам необходимо:
90 |
91 | 1. Если сборка производится впервые и в папке www/core/components еще нет папки с вашим компонентом, то просто скопируйте содержимое каталога
92 | `modxbuilder/[имя_компонента]/core/components/` в каталог `www/core/components/`
93 | 2. Если сборка производится не впервые и в процессе разработки файлы в каталоге `www/core/components/[имя_компонента]/` претерпели ряд изменений, таких, например, как
94 | описание дополнительных методов внутри моделей или создание дополнительных классов, не связанных с базой данных, то вам необходимо только лишь переносить изменения из
95 | каталога `modxbuilder/[имя_компонента]/core/components/[имя_компонента]/` в каталог `www/core/components/[имя_компонента]`. Удобнее всего это делать при помощи функции сравнения каталогов в phpStorm.
96 |
97 | ## Сборщик пакетов
98 |
99 | Скрипт сборки пакета `modxbuilder/[имя_компонента]/build.package.php`
100 |
101 | Подробная инструкция в разработке...
--------------------------------------------------------------------------------
/mycomponent/build/build.models.php:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env php
2 | initialize('mgr');
19 | $modx->setLogLevel(modX::LOG_LEVEL_INFO);
20 | $modx->setLogTarget(XPDO_CLI_MODE ? 'ECHO' : 'HTML');
21 |
22 | $modxBuilder = new modxBuilder($modx,$buildConfig);
23 |
24 | //Парсим схему и генерируем модели и map.inc-файлы
25 | $modxBuilder->parseSchema();
--------------------------------------------------------------------------------
/mycomponent/build/build.package.php:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env php
2 | initialize('mgr');
19 | $modx->setLogLevel(modX::LOG_LEVEL_INFO);
20 | $modx->setLogTarget(XPDO_CLI_MODE ? 'ECHO' : 'HTML');
21 |
22 | $modxBuilder = new modxBuilder($modx,$buildConfig);
23 |
24 | //Сборка компонента
25 | $modxBuilder->buildComponent();
--------------------------------------------------------------------------------
/mycomponent/build/build.schema.php:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env php
2 | initialize('mgr');
19 | $modx->setLogLevel(modX::LOG_LEVEL_INFO);
20 | $modx->setLogTarget(XPDO_CLI_MODE ? 'ECHO' : 'HTML');
21 |
22 | $modxBuilder = new modxBuilder($modx,$buildConfig);
23 |
24 | //Здесь мы генерируем xml схему
25 | $modxBuilder->writeSchema(true,true,false);
--------------------------------------------------------------------------------
/mycomponent/build/config/config.inc.php:
--------------------------------------------------------------------------------
1 | "MyComponent",
13 | //name for folder
14 | "package_name" => "mycomponent",
15 | "package_version" => "0.1",
16 | "package_release" => "",
17 | "package_table_prefix" => "my_",
18 | "package_class_prefix" => "my",
19 |
20 | "regenerate_schema" => true,
21 | //switch to false if you don't need to rewrite your class-files
22 | "regenerate_classes" => true,
23 | //switch to false if you don't need to rewrite your map.inc-files
24 | "regenerate_maps" => true,
25 |
26 | "modx_root" => $modxRoot,
27 | "builder_root" => $builderRoot,
28 | "tools_root" => $builderRoot . "tools/",
29 | );
30 |
31 | $builderComponentRoot = $buildConfig["builder_root"] . $buildConfig['package_name'] . '/';
32 |
33 | $sources = array();
34 |
35 | if (COMPONENT_BUILD)
36 | {
37 | $buildConfig = array_merge($buildConfig, array(
38 | "root" => $root,
39 | "build" => $builderComponentRoot . "build/",
40 | "resolvers" => $builderComponentRoot . "build/resolvers/",
41 | "data" => $builderComponentRoot . "build/data/",
42 |
43 | "source_core" => $modxRoot . "core/components/{$buildConfig['package_name']}/",
44 | "source_lexicon" => $modxRoot . "core/components/{$buildConfig['package_name']}/lexicon/",
45 | "source_assets" => $modxRoot . "assets/components/{$buildConfig['package_name']}/",
46 | "source_docs" => $modxRoot . "core/components/{$buildConfig['package_name']}/docs/",
47 |
48 | "package_dir" => $builderComponentRoot . "core/components/{$buildConfig['package_name']}",
49 | "model_dir" => $builderComponentRoot . "core/components/{$buildConfig['package_name']}/model",
50 | "class_dir" => $builderComponentRoot . "core/components/{$buildConfig['package_name']}/model/{$buildConfig['package_name']}",
51 | "schema_dir" => $builderComponentRoot . "core/components/{$buildConfig['package_name']}/model/schema",
52 | "mysql_class_dir" => $builderComponentRoot . "core/components/{$buildConfig['package_name']}/model/{$buildConfig['package_name']}/mysql",
53 |
54 | //It's a main file we edit
55 | "xml_schema_file" => $builderComponentRoot . "core/components/{$buildConfig['package_name']}/model/schema/{$buildConfig['package_name']}.mysql.schema.xml",
56 |
57 | //It's a new file generated automatically. We will transfer new code to file above
58 | "new_xml_schema_file" => $builderComponentRoot . "core/components/{$buildConfig['package_name']}/model/schema/{$buildConfig['package_name']}.mysql.schema.new.xml"
59 | ));
60 | }
61 | else
62 | {
63 | $buildConfig = array_merge($buildConfig, array(
64 | "root" => $root,
65 | "build" => $builderComponentRoot . "build/",
66 | "resolvers" => $builderComponentRoot . "build/resolvers/",
67 | "data" => $builderComponentRoot . "build/data/",
68 |
69 | "source_core" => $modxRoot . "core/components/{$buildConfig['package_name']}/",
70 | "source_lexicon" => $modxRoot . "core/components/{$buildConfig['package_name']}/lexicon/",
71 | "source_assets" => $modxRoot . "assets/components/{$buildConfig['package_name']}/",
72 | "source_docs" => $modxRoot . "core/components/{$buildConfig['package_name']}/docs/",
73 |
74 | "package_dir" => $root . "core/components/{$buildConfig['package_name']}",
75 | "model_dir" => $root . "core/components/{$buildConfig['package_name']}/model",
76 | "class_dir" => $root . "core/components/{$buildConfig['package_name']}/model/{$buildConfig['package_name']}",
77 | "schema_dir" => $root . "core/components/{$buildConfig['package_name']}/model/schema",
78 | "mysql_class_dir" => $root . "core/components/{$buildConfig['package_name']}/model/{$buildConfig['package_name']}/mysql",
79 |
80 | //It's a main file we edit
81 | "xml_schema_file" => $root . "core/components/{$buildConfig['package_name']}/model/schema/{$buildConfig['package_name']}.mysql.schema.xml",
82 |
83 | //It's a new file generated automatically. We will transfer new code to file above
84 | "new_xml_schema_file" => $root . "core/components/{$buildConfig['package_name']}/model/schema/{$buildConfig['package_name']}.mysql.schema.new.xml"
85 | ));
86 | }
87 |
88 | //Объявляем базовые константы
89 | define("MODX_CORE_PATH", $modxRoot . "core/");
90 | define("MODX_BASE_PATH", $modxRoot);
91 | define('MODX_BASE_URL', '/');
92 |
93 | unset($root,$modxRoot,$builderRoot,$builderComponentRoot);
94 |
95 | return $buildConfig;
96 |
--------------------------------------------------------------------------------
/mycomponent/build/config/version.php:
--------------------------------------------------------------------------------
1 | 0,
5 | 'major' => 0,
6 | 'minor' => 0,
7 | );
8 |
--------------------------------------------------------------------------------
/mycomponent/build/data/README.md:
--------------------------------------------------------------------------------
1 | Данный каталог используется для хранения данных об объектах компонента в
2 | динамичном виде, то есть данные будут браться из базы данных проекта, на
3 | котором данный компонент уже развернут
--------------------------------------------------------------------------------
/mycomponent/build/data/setup.options.php:
--------------------------------------------------------------------------------
1 | 'someValue',
12 | );
13 | switch ($options[xPDOTransport::PACKAGE_ACTION]) {
14 | case xPDOTransport::ACTION_INSTALL:
15 | case xPDOTransport::ACTION_UPGRADE:
16 | /*
17 | $setting = $modx->getObject('modSystemSetting',array('key' => 'mypkg.someKey'));
18 | if ($setting != null) { $values['someKey'] = $setting->get('value'); }
19 | unset($setting);
20 | */
21 | break;
22 | case xPDOTransport::ACTION_UNINSTALL: break;
23 | }
24 |
25 | $output = '';
26 | /*
27 | $output = '
28 |
29 | */
30 |
31 | return $output;
--------------------------------------------------------------------------------
/mycomponent/build/data/setup.requires.php:
--------------------------------------------------------------------------------
1 | '>=2.8.2'
6 | );
--------------------------------------------------------------------------------
/mycomponent/build/data/transport.chunks.php:
--------------------------------------------------------------------------------
1 | modx->getObject('modCategory',array(
12 | 'category' => $categoryName
13 | ));
14 |
15 | if(!$mainCategory) return $chunks;
16 |
17 | /** @var modChunk[] $realChunks */
18 | $realChunks = $mainCategory->getMany('Chunks');
19 |
20 | if(!$realChunks) return $chunks;
21 |
22 | foreach($realChunks as $realChunk){
23 | /** @var modChunk $chunk */
24 | $chunk = $this->modx->newObject('modChunk');
25 | $chunkData = $realChunk->toArray();
26 | $chunkData['id'] = 0;
27 | //TODO remove comment if you want to make your chunks static
28 | //$chunkData['static'] = 1;
29 | $chunk->fromArray($chunkData);
30 | $chunks[] = $chunk;
31 | }
32 |
33 | unset($realChunks,$chunkData);
34 |
35 | return $chunks;
--------------------------------------------------------------------------------
/mycomponent/build/data/transport.events.php:
--------------------------------------------------------------------------------
1 | modx->getCollection('modEvent', array(
11 | 'groupname' => $categoryName
12 | ));
13 |
14 | if(!$realEvents) return $events;
15 |
16 | /** @var modEvent[] $realEvents */
17 | foreach($realEvents as $realEvent){
18 | /** @var modEvent $event */
19 | $event = $this->modx->newObject('modEvent');
20 | $eventData = $realEvent->toArray();
21 | $event->fromArray($eventData,'',true);
22 | $events[] = $event;
23 | }
24 |
25 | unset($realEvents,$eventData);
26 |
27 | return $events;
28 |
--------------------------------------------------------------------------------
/mycomponent/build/data/transport.menu.php:
--------------------------------------------------------------------------------
1 | modx->getCollection('modMenu',array(
11 | 'namespace' => $namespace
12 | ));
13 |
14 | if(!$realMenus) return $menus;
15 |
16 | /** @var modMenu[] $realMenus */
17 | foreach($realMenus as $realMenu){
18 | /** @var modMenu $menu */
19 | $menu = $this->modx->newObject('modMenu');
20 | $menuData = $realMenu->toArray();
21 | $menu->fromArray($menuData,'',true);
22 | $menus[] = $menu;
23 | }
24 |
25 | unset($realMenus,$menuData);
26 |
27 | return $menus;
--------------------------------------------------------------------------------
/mycomponent/build/data/transport.plugins.php:
--------------------------------------------------------------------------------
1 | modx->getObject('modCategory',array(
13 | 'category' => $categoryName
14 | ));
15 |
16 | if(!$mainCategory) return $plugins;
17 |
18 | /** @var modPlugin[] $realPlugins */
19 | $realPlugins = $mainCategory->getMany('Plugins');
20 |
21 | if(!$realPlugins) return $plugins;
22 |
23 | foreach($realPlugins as $realPlugin){
24 | /** @var modPluginEvent[] $pluginEvents */
25 | if($pluginEvents = $realPlugin->getMany('PluginEvents')){
26 | foreach($pluginEvents as &$pluginEvent){
27 | $pluginEvent->set('pluginid', 0);
28 | }
29 | }
30 |
31 | /** @var modPlugin $plugin */
32 | $plugin = $this->modx->newObject('modPlugin');
33 | $pluginData = $realPlugin->toArray();
34 | $pluginData['id'] = 0;
35 | //TODO remove comment if you want make your plugin static
36 | //$pluginData['static'] = 1;
37 | $plugin->fromArray($pluginData);
38 | $plugin->addMany($pluginEvents);
39 | $plugins[] = $plugin;
40 | }
41 |
42 | unset($realPlugins,$pluginData);
43 |
44 | return $plugins;
--------------------------------------------------------------------------------
/mycomponent/build/data/transport.settings.php:
--------------------------------------------------------------------------------
1 | modx->getCollection('modSystemSetting',array(
11 | 'namespace' => $namespace
12 | ));
13 |
14 | if(!$realSettings) return $settings;
15 |
16 | /** @var modSystemSetting[] $realSettings */
17 | foreach($realSettings as $realSetting){
18 | /** @var modSystemSetting $setting */
19 | $setting = $this->modx->newObject('modSystemSetting');
20 | $settingData = $realSetting->toArray();
21 | $setting->fromArray($settingData,'',true);
22 | $settings[] = $setting;
23 | }
24 |
25 | unset($realSettings,$settingData);
26 |
27 | return $settings;
--------------------------------------------------------------------------------
/mycomponent/build/data/transport.snippets.php:
--------------------------------------------------------------------------------
1 | modx->getObject('modCategory',array(
12 | 'category' => $categoryName
13 | ));
14 |
15 | if(!$mainCategory) return $snippets;
16 |
17 | /** @var modSnippet[] $realSnippets */
18 | $realSnippets = $mainCategory->getMany('Snippets');
19 |
20 | if(!$realSnippets) return $snippets;
21 |
22 | foreach($realSnippets as $realSnippet){
23 | /** @var modSnippet $snippet */
24 | $snippet = $this->modx->newObject('modSnippet');
25 | $snippetData = $realSnippet->toArray();
26 | $snippetData['id'] = 0;
27 | //TODO remove comment if you want to make your snippets static
28 | //$snippetData['static'] = 1;
29 | $snippet->fromArray($snippetData);
30 | $snippets[] = $snippet;
31 | }
32 |
33 | unset($realSnippets,$snippetData);
34 |
35 | return $snippets;
--------------------------------------------------------------------------------
/mycomponent/build/data/transport.templates.php:
--------------------------------------------------------------------------------
1 | modx->getObject('modCategory',array(
12 | 'category' => $categoryName
13 | ));
14 |
15 | if(!$mainCategory) return $templates;
16 |
17 | /** @var modTemplate[] $realTemplates */
18 | $realTemplates = $mainCategory->getMany('Templates');
19 | if(!$realTemplates) return $templates;
20 |
21 | foreach($realTemplates as $realTemplate){
22 | /** @var modTemplate $template */
23 | $template = $this->modx->newObject('modTemplate');
24 | $templateData = $realTemplate->toArray();
25 | $templateData['id'] = 0;
26 | //TODO remove comment if you want to make templates static
27 | //$templateData['static'] = 1;
28 | $template->fromArray($templateData);
29 | $templates[] = $template;
30 | }
31 |
32 | unset($realTemplates,$templateData);
33 |
34 | return $templates;
--------------------------------------------------------------------------------
/mycomponent/build/data/transport.tvs.php:
--------------------------------------------------------------------------------
1 | modx->getObject('modCategory',array(
12 | 'category' => $categoryName
13 | ));
14 |
15 | if(!$mainCategory) return $templateVars;
16 |
17 | /** @var modTemplateVar[] $realTemplateVars */
18 | $realTemplateVars = $mainCategory->getMany('TemplateVars');
19 |
20 | if(!$realTemplateVars) return $templateVars;
21 |
22 | foreach($realTemplateVars as $realTemplateVar){
23 | /** @var modTemplateVarTemplate $templateVarTemplates */
24 | $templateVarTemplates = $realTemplateVar->getMany('TemplateVarTemplates');
25 |
26 | /** @var modTemplateVar $templateVar */
27 | $templateVar = $this->modx->newObject('modTemplateVar');
28 | $templateVarData = $realTemplateVar->toArray();
29 | $templateVarData['id'] = 0;
30 | $templateVar->fromArray($templateVarData);
31 | $templateVar->addMany($templateVarTemplates);
32 | $templateVars[] = $templateVar;
33 | }
34 |
35 | unset($realTemplateVars,$templateVarData);
36 |
37 | return $templateVars;
--------------------------------------------------------------------------------
/mycomponent/build/data_static/README.md:
--------------------------------------------------------------------------------
1 | Данный каталог используется для хранения данных об объектах компонента в
2 | статичном виде, то есть описанном в файлах
--------------------------------------------------------------------------------
/mycomponent/build/data_static/setup.options.php:
--------------------------------------------------------------------------------
1 | 'someValue',
12 | );
13 | switch ($options[xPDOTransport::PACKAGE_ACTION]) {
14 | case xPDOTransport::ACTION_INSTALL:
15 | case xPDOTransport::ACTION_UPGRADE:
16 | /*
17 | $setting = $modx->getObject('modSystemSetting',array('key' => 'mypkg.someKey'));
18 | if ($setting != null) { $values['someKey'] = $setting->get('value'); }
19 | unset($setting);
20 | */
21 | break;
22 | case xPDOTransport::ACTION_UNINSTALL: break;
23 | }
24 |
25 | $output = '';
26 | /*
27 | $output = '
28 |
29 | */
30 |
31 | return $output;
--------------------------------------------------------------------------------
/mycomponent/build/data_static/transport.chunks.php:
--------------------------------------------------------------------------------
1 | modx->newObject('modChunk');
8 | $chunk->fromArray(array(
9 | 'id' => 0,
10 | 'name' => 'exampleChunk',
11 | 'description' => 'exampleDescription',
12 | 'snippet' => 'exampleContent. You can get content from file by file_get_contents()',
13 | 'static' => 0,
14 | 'source' => 1,
15 | 'static_file' => "core/components/{$this->config['package_name']}/elements/chunks/exampleChunk.tpl",
16 | ), '', true, true);
17 | $chunks[] = $chunk;
18 | unset($chunk);
19 | return $chunks;
--------------------------------------------------------------------------------
/mycomponent/build/data_static/transport.menu.php:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/azernov/modxbuilder/130c83e1a630c0af6078b3cd2bcdc8ca5fcacd06/mycomponent/build/data_static/transport.menu.php
--------------------------------------------------------------------------------
/mycomponent/build/data_static/transport.plugins.php:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/azernov/modxbuilder/130c83e1a630c0af6078b3cd2bcdc8ca5fcacd06/mycomponent/build/data_static/transport.plugins.php
--------------------------------------------------------------------------------
/mycomponent/build/data_static/transport.settings.php:
--------------------------------------------------------------------------------
1 | modx->newObject('modSystemSetting');
8 | $setting->fromArray(
9 | array(
10 | 'key' => 'test_setting',
11 | 'namespace' => $this->config['package_name'],
12 | 'xtype' => 'textfield',
13 | 'value' => 'test_value',
14 | 'area' => 'mycmp_main',
15 | ),'',true,true);
16 | $settings[] = $setting;
17 | unset($setting);
18 | return $settings;
--------------------------------------------------------------------------------
/mycomponent/build/data_static/transport.snippets.php:
--------------------------------------------------------------------------------
1 | modx->newObject('modSnippet');
9 |
10 | $snippetContent = 'return date("Y-m-d");';
11 | //Удаляем fromArray(array(
16 | 'id' => 0,
17 | 'name' => 'testSnippet',
18 | 'description' => 'test description',
19 | 'snippet' => $snippetContent,
20 | 'static' => 0,
21 | 'source' => 1,
22 | 'static_file' => "core/components/{$this->config['package_name']}/elements/snippets/testSnippet.php",
23 | ), '', true, true);
24 |
25 | $snippet->setProperties(array(
26 | array(
27 | 'name' => 'test_snippet_property1',
28 | 'desc' => 'mycmp_prop_test_snippet_property_1',
29 | 'lexicon' => 'mycmp:default',
30 | )
31 | ));
32 | $snippets[] = $snippet;
33 | unset($snippet,$snippetContent);
34 | return $snippets;
--------------------------------------------------------------------------------
/mycomponent/build/data_static/transport.templates.php:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/azernov/modxbuilder/130c83e1a630c0af6078b3cd2bcdc8ca5fcacd06/mycomponent/build/data_static/transport.templates.php
--------------------------------------------------------------------------------
/mycomponent/build/data_static/transport.tvs.php:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/azernov/modxbuilder/130c83e1a630c0af6078b3cd2bcdc8ca5fcacd06/mycomponent/build/data_static/transport.tvs.php
--------------------------------------------------------------------------------
/mycomponent/build/resolvers/resolver.tables.php:
--------------------------------------------------------------------------------
1 | xpdo) {
8 | $modx =& $object->xpdo;
9 |
10 | //TODO put your package name here
11 | $packageName = 'mycomponent';
12 | $modelPath = $modx->getOption($packageName.'.core_path',null,$modx->getOption('core_path').'components/'.$packageName.'/').'model/';
13 | $modx->addPackage($packageName,$modelPath);
14 | $manager = $modx->getManager();
15 |
16 | switch ($options[xPDOTransport::PACKAGE_ACTION]) {
17 | case xPDOTransport::ACTION_INSTALL:
18 | //TODO add your database related custom objects
19 | //$manager->createObjectContainer('myObjectClass');
20 | break;
21 | case xPDOTransport::ACTION_UPGRADE:
22 | break;
23 | case xPDOTransport::ACTION_UNINSTALL:
24 | //TODO add your database related custom objects
25 | //$manager->removeObjectContainer('myObjectClass');
26 | break;
27 | }
28 | }
29 | return true;
--------------------------------------------------------------------------------
/mycomponent/build/resolvers/resolvers.php:
--------------------------------------------------------------------------------
1 | [
4 | [
5 | 'source' => $this->config['source_core'],
6 | 'target' => "return MODX_CORE_PATH.'components/';",
7 | ],
8 | [
9 | 'source' => $this->config['source_assets'],
10 | 'target' => "return MODX_ASSETS_PATH.'components/';",
11 | ]
12 | ],
13 | 'php' => [
14 | [
15 | 'source' => $this->config['resolvers'].'resolver.tables.php'
16 | ]
17 | ]
18 | ];
--------------------------------------------------------------------------------
/mycomponent/build/templates/changelog.item.txt:
--------------------------------------------------------------------------------
1 | [[+real_package_name]] [[+package_version]]-[[+package_release]]
2 | ==========================================
3 | [[+input]]
4 |
5 |
--------------------------------------------------------------------------------
/mycomponent/build/templates/readme.txt:
--------------------------------------------------------------------------------
1 | --------------------
2 | Extra: [[+real_package_name]]
3 | --------------------
4 | Version: [[+package_version]]-[[+package_release]]
5 | Created: [[+package_created]]
6 | Updated: [[+package_updated]]
7 | Author: [[+package_author]]
8 | License: [[+package_license]]
9 |
10 | [[+package_description]]
11 |
--------------------------------------------------------------------------------
/mycomponent/copy-from-www.php:
--------------------------------------------------------------------------------
1 | modx = &$modx;
24 | $version = include($config['build'].'config/version.php');
25 | $this->config = array(
26 | //List default settings
27 | 'package_version' => implode('.', $version)
28 | );
29 | $this->config = array_merge($this->config, $config);
30 | }
31 |
32 | protected function getManager()
33 | {
34 | $this->modx->getManager();
35 | }
36 |
37 | protected function getGenerator()
38 | {
39 | if (!$this->generator)
40 | {
41 | //Подключаем наш класс генератора
42 | include_once $this->config['modx_root'] . 'core/xpdo/om/mysql/xpdogenerator.class.php';
43 | include_once($this->config['tools_root'] . "xpdogenerator.class.php");
44 | $manager = $this->modx->getManager();
45 | $this->generator = new xPDOGenerator_my($manager);
46 | }
47 | return $this->generator;
48 | }
49 |
50 | /**
51 | * @param bool $restrict_prefix - If you specify a table prefix, you probably want this set to 'true'. E.g. if you
52 | * have custom tables alongside the modx_xxx tables, restricting the prefix ensures
53 | * that you only generate classes/maps for the tables identified by the $this->config['package_table_prefix'].
54 | * @param bool $verbose - if true, will print status info.
55 | * @param bool $debug - if true, will include verbose debugging info, including SQL errors.
56 | */
57 | public function writeSchema($restrict_prefix = true, $verbose = true, $debug = true)
58 | {
59 | if (!defined('MODX_CORE_PATH'))
60 | {
61 | $this->modx->log(MODX_LOG_LEVEL_ERROR, 'Reverse Engineering Error! MODX_CORE_PATH not defined! Did you include the correct config file?');
62 | exit;
63 | }
64 |
65 | // A few variables used to track execution times.
66 | $mtime = microtime();
67 | $mtime = explode(' ', $mtime);
68 | $mtime = $mtime[1] + $mtime[0];
69 | $tstart = $mtime;
70 |
71 | // Validations
72 | if (empty($this->config['package_name']))
73 | {
74 | $this->modx->log(MODX_LOG_LEVEL_ERROR, "Reverse Engineering Error! The package_name cannot be empty! Please adjust the configuration and try again.");
75 | exit;
76 | }
77 |
78 | // Create directories if necessary
79 | $dirs = array($this->config["package_dir"], $this->config["schema_dir"], $this->config["mysql_class_dir"], $this->config["class_dir"]);
80 |
81 | foreach ($dirs as $d)
82 | {
83 | if (!file_exists($d))
84 | {
85 | if (!mkdir($d, 0777, true))
86 | {
87 | $this->modx->log(MODX_LOG_LEVEL_ERROR, sprintf('Reverse Engineering Error! Error creating %s. Create the directory (and its parents) and try again.', $d));
88 | exit;
89 | }
90 | }
91 | if (!is_writable($d))
92 | {
93 | $this->modx->log(MODX_LOG_LEVEL_ERROR, sprintf('Reverse Engineering Error! The %s directory is not writable by PHP. Adjust the permissions and try again.', $d));
94 | exit;
95 | }
96 | }
97 |
98 | if ($verbose)
99 | {
100 | $this->modx->log(MODX_LOG_LEVEL_INFO, sprintf('Ok: The necessary directories exist and have the correct permissions inside of %s', $this->config["package_dir"]));
101 | }
102 |
103 | // Delete/regenerate map files?
104 | if (file_exists($this->config["new_xml_schema_file"]) && !$this->config['regenerate_schema'] && $verbose)
105 | {
106 | $this->modx->log(MODX_LOG_LEVEL_INFO, sprintf('Ok: Using existing XML schema file: %s', $this->config["new_xml_schema_file"]));
107 | }
108 |
109 | // Set the package name and root path of that package
110 | $this->modx->setPackage($this->config['package_name'], $this->config["model_dir"].'/');
111 | $this->modx->setDebug($debug);
112 |
113 | //$generator = $manager->getGenerator(); // Станадртное получение mysql генератора
114 | $generator = $this->getGenerator();
115 | $generator->setClassPrefix($this->config['package_class_prefix']);
116 |
117 | //Use this to create an XML schema from an existing database
118 | if ($this->config['regenerate_schema'])
119 | {
120 | if (!file_exists($this->config['new_xml_schema_file']))
121 | {
122 | touch($this->config['new_xml_schema_file']);
123 | }
124 | $xml = $generator->writeSchema($this->config["new_xml_schema_file"], $this->config['package_name'], 'xPDOObject', '', $restrict_prefix, $this->config['package_table_prefix']);
125 | if ($verbose)
126 | {
127 | $this->modx->log(MODX_LOG_LEVEL_INFO, sprintf('Ok: XML schema file generated: %s', $this->config["new_xml_schema_file"]));
128 | }
129 | }
130 |
131 | $mtime = microtime();
132 | $mtime = explode(" ", $mtime);
133 | $mtime = $mtime[1] + $mtime[0];
134 | $tend = $mtime;
135 | $totalTime = ($tend - $tstart);
136 | $totalTime = sprintf("%2.4f s", $totalTime);
137 |
138 | if ($verbose)
139 | {
140 | $this->modx->log(MODX_LOG_LEVEL_INFO, "Finished! Execution time: {$totalTime}");
141 |
142 | if ($this->config['regenerate_schema'])
143 | {
144 | $this->modx->log(MODX_LOG_LEVEL_INFO, "If you need to define aggregate/composite relationships in your XML schema file, be sure to regenerate your class files.");
145 | }
146 | }
147 | }
148 |
149 | public function parseSchema($verbose = true)
150 | {
151 | $this->modx->loadClass('transport.modPackageBuilder', '', false, true);
152 | $this->modx->setLogLevel(modX::LOG_LEVEL_INFO);
153 | $this->modx->setLogTarget(XPDO_CLI_MODE ? 'ECHO' : 'HTML');
154 |
155 | if (!is_dir($this->config['model_dir']))
156 | {
157 | $this->modx->log(modX::LOG_LEVEL_ERROR, 'Model directory not found!');
158 | die();
159 | }
160 | if (!file_exists($this->config['xml_schema_file']))
161 | {
162 | $this->modx->log(modX::LOG_LEVEL_ERROR, 'Schema file not found!');
163 | die();
164 | }
165 |
166 | // Use this to generate classes from your schema
167 | if ($this->config['regenerate_classes'])
168 | {
169 | $this->modx->log(MODX_LOG_LEVEL_INFO, 'Attempting to remove/regenerate class files...');
170 | modxBuilder::deleteClassFiles($this->config["class_dir"], $verbose);
171 | modxBuilder::deleteClassFiles($this->config["mysql_class_dir"], $verbose);
172 | }
173 |
174 | // Use this to generate maps from your schema
175 | if ($this->config['regenerate_maps'])
176 | {
177 | if ($verbose)
178 | {
179 | $this->modx->log(MODX_LOG_LEVEL_INFO, 'Attempting to remove/regenerate map files...');
180 | }
181 | modxBuilder::deleteMapFiles($this->config["mysql_class_dir"], $verbose);
182 | }
183 |
184 | $this->getGenerator()->parseSchema($this->config["xml_schema_file"], $this->config["model_dir"] . "/");
185 |
186 | $this->modx->log(modX::LOG_LEVEL_INFO, 'Done!');
187 | }
188 |
189 | public function getPackageBulder(){
190 | if(!$this->builder){
191 | //Подгружаем класс для сборки пакетов
192 | $this->modx->loadClass('transport.modPackageBuilder', '', false, true);
193 | $this->builder = new modPackageBuilder($this->modx);
194 | }
195 | return $this->builder;
196 | }
197 |
198 | /**
199 | * @param modCategory $category
200 | * @param array $snippets
201 | * @param array $attr
202 | * @param bool $updateObject
203 | * @return bool
204 | */
205 | public function addSnippetsToCategory(&$category,$snippets,&$attr,$updateObject = true){
206 | $attr[xPDOTransport::RELATED_OBJECT_ATTRIBUTES]['Snippets'] = array(
207 | xPDOTransport::PRESERVE_KEYS => true,
208 | xPDOTransport::UPDATE_OBJECT => $updateObject,
209 | xPDOTransport::UNIQUE_KEY => 'name',
210 | );
211 | return $category->addMany($snippets);
212 | }
213 |
214 | /**
215 | * @param modCategory $category
216 | * @param array modChunk[] $chunks
217 | * @param array $attr
218 | * @param bool $updateObject
219 | * @return bool
220 | */
221 | public function addChunksToCategory(&$category,$chunks,&$attr,$updateObject = true){
222 | $attr[xPDOTransport::RELATED_OBJECT_ATTRIBUTES]['Chunks'] = array(
223 | xPDOTransport::PRESERVE_KEYS => true,
224 | xPDOTransport::UPDATE_OBJECT => $updateObject,
225 | xPDOTransport::UNIQUE_KEY => 'name',
226 | );
227 | return $category->addMany($chunks);
228 | }
229 |
230 | /**
231 | * @param modCategory $category
232 | * @param array modTemplate[] $templates
233 | * @param array $attr
234 | * @param bool $updateObject
235 | * @return bool
236 | */
237 | public function addTemplatesToCategory(&$category,$templates,&$attr,$updateObject = true){
238 | $attr[xPDOTransport::RELATED_OBJECT_ATTRIBUTES]['Templates'] = array(
239 | xPDOTransport::PRESERVE_KEYS => true,
240 | xPDOTransport::UPDATE_OBJECT => $updateObject,
241 | xPDOTransport::UNIQUE_KEY => 'templatename',
242 | );
243 | return $category->addMany($templates);
244 | }
245 |
246 | /**
247 | * @param modCategory $category
248 | * @param array modPlugin[] $templates
249 | * @param array $attr
250 | * @param bool $updateObject
251 | * @return bool
252 | */
253 | public function addPluginsToCategory(&$category, $plugins, &$attr, $updateObject = true){
254 | $attr[xPDOTransport::RELATED_OBJECT_ATTRIBUTES]['Plugins'] = array(
255 | xPDOTransport::PRESERVE_KEYS => true,
256 | xPDOTransport::UPDATE_OBJECT => $updateObject,
257 | xPDOTransport::UNIQUE_KEY => 'name',
258 | xPDOTransport::RELATED_OBJECTS => true,
259 | xPDOTransport::RELATED_OBJECT_ATTRIBUTES => array(
260 | 'PluginEvents' => array(
261 | xPDOTransport::PRESERVE_KEYS => true,
262 | xPDOTransport::UPDATE_OBJECT => $updateObject,
263 | xPDOTransport::UNIQUE_KEY => ['pluginid', 'event'],
264 | )
265 | )
266 | );
267 | return $category->addMany($plugins);
268 | }
269 |
270 | /**
271 | * @param modCategory $category
272 | * @param array modTemplateVar[] $tvs
273 | * @param array $attr
274 | * @param bool $updateObject
275 | * @return bool
276 | */
277 | public function addTVsToCategory(&$category, $tvs, &$attr, $updateObject = true){
278 | $attr[xPDOTransport::RELATED_OBJECT_ATTRIBUTES]['TemplateVars'] = array(
279 | xPDOTransport::PRESERVE_KEYS => true,
280 | xPDOTransport::UPDATE_OBJECT => $updateObject,
281 | xPDOTransport::UNIQUE_KEY => 'name',
282 | xPDOTransport::RELATED_OBJECTS => true,
283 | xPDOTransport::RELATED_OBJECT_ATTRIBUTES => array(
284 | 'TemplateVarTemplates' => array(
285 | xPDOTransport::PRESERVE_KEYS => true,
286 | xPDOTransport::UPDATE_OBJECT => $updateObject,
287 | xPDOTransport::UNIQUE_KEY => ['tmplvarid','templateid'],
288 | )
289 | )
290 | );
291 | return $category->addMany($tvs);
292 | }
293 |
294 | /**
295 | * @param modTransportVehicle $vehicle
296 | * @param array $resolvers
297 | * @return int
298 | */
299 | public function addResolvers(&$vehicle,$resolvers){
300 | $cnt = 0;
301 | foreach($resolvers as $type => $resolver){
302 | if(isset($resolver['source']))
303 | {
304 | $cnt++;
305 | $vehicle->resolve($type,$resolver);
306 | }
307 | else{
308 | foreach($resolver as $resolverItem){
309 | $cnt++;
310 | $vehicle->resolve($type,$resolverItem);
311 | }
312 | }
313 | }
314 | return $cnt;
315 | }
316 |
317 | /**
318 | * @param modSystemSetting[] $settings
319 | * @param array $attr
320 | * @param bool $updateObject
321 | * @return bool
322 | */
323 | public function addSystemSettings($settings,$attr = array(), $updateObject = false){
324 | $noError = true;
325 |
326 | $sysSettingsAttr = array_merge(array(
327 | xPDOTransport::UNIQUE_KEY => 'key',
328 | xPDOTransport::PRESERVE_KEYS => true,
329 | xPDOTransport::UPDATE_OBJECT => $updateObject,
330 | ),$attr);
331 | foreach ($settings as $setting) {
332 | $vehicle = $this->builder->createVehicle($setting,$sysSettingsAttr);
333 | $noError = $noError && $this->builder->putVehicle($vehicle);
334 | }
335 | return $noError;
336 | }
337 |
338 | /**
339 | * @param modEvent[] $events
340 | * @param array $attr
341 | * @param bool $updateObject
342 | * @return bool
343 | */
344 | public function addSystemEvents($events, $attr = array(), $updateObject = false){
345 | $noError = true;
346 |
347 | $sysSettingsAttr = array_merge(array(
348 | xPDOTransport::UNIQUE_KEY => 'name',
349 | xPDOTransport::PRESERVE_KEYS => true,
350 | xPDOTransport::UPDATE_OBJECT => $updateObject,
351 | ),$attr);
352 | foreach ($events as $event) {
353 | $vehicle = $this->builder->createVehicle($event,$sysSettingsAttr);
354 | $noError = $noError && $this->builder->putVehicle($vehicle);
355 | }
356 | return $noError;
357 | }
358 |
359 | /**
360 | * @param modMenu[] $menus
361 | * @param array $attr
362 | * @param bool $updateObject
363 | * @return bool
364 | */
365 | public function addMenus($menus,$attr = array(), $updateObject = true){
366 | $noError = true;
367 |
368 | $menuSettingsArray = array_merge(array(
369 | xPDOTransport::UNIQUE_KEY => 'text',
370 | xPDOTransport::PRESERVE_KEYS => true,
371 | xPDOTransport::UPDATE_OBJECT => $updateObject,
372 | ),$attr);
373 | foreach ($menus as $menu) {
374 | $vehicle = $this->builder->createVehicle($menu,$menuSettingsArray);
375 | $noError = $noError && $this->builder->putVehicle($vehicle);
376 | }
377 | return $noError;
378 | }
379 |
380 | public function addPackageAttributes(){
381 | $attrs = array();
382 | if(file_exists($this->config['source_docs'] . 'changelog.txt')){
383 | $attrs['changelog'] = file_get_contents($this->config['source_docs'] . 'changelog.txt');
384 | }
385 | if(file_exists($this->config['source_docs'] . 'license.txt')){
386 | $attrs['license'] = file_get_contents($this->config['source_docs'] . 'license.txt');
387 | }
388 | if(file_exists($this->config['source_docs'] . 'readme.txt')){
389 | $attrs['readme'] = file_get_contents($this->config['source_docs'] . 'readme.txt');
390 | }
391 | if(file_exists($this->config['data'] . 'setup.options.php')){
392 | $attrs['setup-options'] = array('source' => $this->config['data'] . 'setup.options.php');
393 | }
394 | if(file_exists($this->config['data'] . 'setup.requires.php')){
395 | $requires = include $this->config['data'] . 'setup.requires.php';
396 | if(!empty($requires)){
397 | $attrs['requires'] = $requires;
398 | }
399 | }
400 | $this->builder->setPackageAttributes($attrs);
401 | }
402 |
403 | public function buildComponent()
404 | {
405 | $this->updateVersionAndDocs();
406 |
407 | $this->getPackageBulder();
408 | $this->builder->createPackage(str_replace(' ','',$this->config['real_package_name']), $this->config['package_version'], $this->config['package_release']);
409 | $namespace = $this->config['package_name'];
410 | $this->modx->log(xPDO::LOG_LEVEL_INFO,'Registering new namespace: '.$namespace);
411 | $this->builder->registerNamespace($this->config['package_name'], false, true, "{core_path}components/{$this->config['package_name']}/");
412 |
413 | // Create new category for chunks and snippets
414 | $categoryName = $this->config['real_package_name'];
415 | $this->modx->log(xPDO::LOG_LEVEL_INFO,'Creating new category: '.$categoryName);
416 |
417 | /** @var modCategory $category */
418 | $category= $this->modx->newObject('modCategory');
419 | $category->set('category',$this->config['real_package_name']);
420 |
421 | // Define attributes for category transport
422 | $categoryAttr = array(
423 | xPDOTransport::UNIQUE_KEY => 'category',
424 | xPDOTransport::PRESERVE_KEYS => false,
425 | xPDOTransport::UPDATE_OBJECT => true,
426 | xPDOTransport::RELATED_OBJECTS => true,
427 | );
428 |
429 | //Define snippets
430 | /** @var modSnippet $snippets */
431 | $snippets = include $this->config['data'] . 'transport.snippets.php';
432 | if (!is_array($snippets)){
433 | $this->modx->log(modX::LOG_LEVEL_INFO, 'Are snippets empty? Skip them');
434 | }
435 | elseif($this->addSnippetsToCategory($category,$snippets,$categoryAttr)){
436 | $this->modx->log(modX::LOG_LEVEL_INFO, 'Added snippets: ' . count($snippets) . '.');
437 | }
438 |
439 |
440 | //Define chunks
441 | /** @var modChunk[] $chunks */
442 | $chunks = include $this->config['data'] . 'transport.chunks.php';
443 | if (!is_array($chunks)){
444 | $this->modx->log(modX::LOG_LEVEL_INFO, 'Are chunks empty? Skip them');
445 | }
446 | elseif($this->addChunksToCategory($category,$chunks,$categoryAttr)){
447 | $this->modx->log(modX::LOG_LEVEL_INFO, 'Added chunks: ' . count($chunks) . '.');
448 | }
449 |
450 | //Define templates
451 | /** @var modTemplate[] $templates */
452 | $templates = include $this->config['data'] . 'transport.templates.php';
453 | if (!is_array($templates)){
454 | $this->modx->log(modX::LOG_LEVEL_INFO, 'Are templates empty? Skip them');
455 | }
456 | elseif($this->addTemplatesToCategory($category,$templates,$categoryAttr)){
457 | $this->modx->log(modX::LOG_LEVEL_INFO, 'Added templates: ' . count($templates) . '.');
458 | }
459 |
460 | //Define tvs
461 | /** @var modTemplateVar[] $tvs */
462 | $tvs = include $this->config['data'] . 'transport.tvs.php';
463 | if (!is_array($tvs))
464 | {
465 | $this->modx->log(modX::LOG_LEVEL_INFO, 'Are template variables empty? Skip them');
466 | }
467 | elseif ($this->addTVsToCategory($category, $tvs, $categoryAttr, true))
468 | {
469 | $this->modx->log(modX::LOG_LEVEL_INFO, 'Added template variables: ' . count($tvs) . '.');
470 | }
471 |
472 | /*if (isset($templates) && is_array($templates))
473 | {
474 | foreach ($templates as $template)
475 | {
476 | //TODO add tvs to templates
477 | }
478 | }*/
479 |
480 | //Define plugins
481 | $plugins = include $this->config['data'] . 'transport.plugins.php';
482 | if (!is_array($plugins)){
483 | $this->modx->log(modX::LOG_LEVEL_INFO, 'Are plugins empty? Skip them');
484 | }
485 | elseif($this->addPluginsToCategory($category,$plugins,$categoryAttr)){
486 | $this->modx->log(modX::LOG_LEVEL_INFO, 'Added plugins: ' . count($plugins) . '.');
487 | }
488 |
489 | $vehicle = $this->builder->createVehicle($category,$categoryAttr);
490 | $this->builder->putVehicle($vehicle);
491 |
492 | //Define file resolvers
493 | $resolvers = include $this->config['resolvers'] . 'resolvers.php';
494 | if(!is_array($resolvers)){
495 | $this->modx->log(modX::LOG_LEVEL_INFO,'Are file resolvers empty? Skip them');
496 | }
497 | else{
498 | $count = $this->addResolvers($vehicle,$resolvers);
499 | $this->modx->log(modX::LOG_LEVEL_INFO, 'Added resolvers: ' . $count . '.');
500 | }
501 |
502 | $this->builder->putVehicle($vehicle);
503 |
504 | //Define system settings
505 | $settings = include $this->config['data'].'transport.settings.php';
506 | if (!is_array($settings)) {
507 | $this->modx->log(modX::LOG_LEVEL_ERROR,'Are system settings empty? Skip them');
508 | } else {
509 | $this->addSystemSettings($settings);
510 | $this->modx->log(modX::LOG_LEVEL_INFO,'Added system settings: '.count($settings).'.');
511 | }
512 |
513 | //Define system events
514 | $events = include $this->config['data'].'transport.events.php';
515 | if (!is_array($events)) {
516 | $this->modx->log(modX::LOG_LEVEL_ERROR,'Are events empty? Skip them');
517 | } else {
518 | $this->addSystemEvents($events);
519 | $this->modx->log(modX::LOG_LEVEL_INFO,'Added system events: '.count($events).'.');
520 | }
521 |
522 | //Define menu items
523 | $menus = include $this->config['data'].'transport.menu.php';
524 | if (!is_array($menus)) {
525 | $this->modx->log(modX::LOG_LEVEL_ERROR,'Are menu items empty? Skip them');
526 | } else {
527 | $this->addMenus($menus);
528 | $this->modx->log(modX::LOG_LEVEL_INFO,'Added menu items: '.count($menus).'.');
529 | }
530 |
531 | $this->addPackageAttributes();
532 | $this->modx->log(modX::LOG_LEVEL_INFO,'Added package attributes!');
533 |
534 | //Start packing into zip
535 | $this->modx->log(modX::LOG_LEVEL_INFO,'Start packing into zip');
536 |
537 | if($this->builder->pack()){
538 | $this->modx->log(modX::LOG_LEVEL_INFO,'Packet was successfully packed!');
539 | }
540 | else{
541 | $this->modx->log(modX::LOG_LEVEL_ERROR,'Something went wrong... Error while packing into zip');
542 | }
543 | }
544 |
545 | public function updateVersionAndDocs(){
546 | //Апдейтим описание версии и changelog
547 | $versionFilePath = $this->config['build'].'config/version.php';
548 | $version = include($versionFilePath);
549 | $version['minor']++;
550 | file_put_contents($versionFilePath, "config['package_version'] = implode('.', $version);
553 |
554 | $readmeTemplate = file_get_contents($this->config['build'].'templates/readme.txt');
555 | $changeLogItemTemplate = file_get_contents($this->config['build'].'templates/changelog.item.txt');
556 |
557 | $readmeTemplate = $this->parseString($readmeTemplate, $this->config);
558 |
559 | $prompt = "What's new?:";
560 | $emptyLinesCount = 0;
561 | $inputContent = '';
562 | while($emptyLinesCount < 1){
563 | $line = readline($prompt);
564 | if(!empty($line)){
565 | $inputContent .= $line."\n";
566 | }
567 | else{
568 | $emptyLinesCount++;
569 | }
570 | }
571 |
572 | $changeLogItemTemplate = $this->parseString($changeLogItemTemplate, array_merge($this->config, [
573 | 'input' => $inputContent
574 | ]));
575 |
576 | file_put_contents($this->config['source_docs'].'readme.txt', $readmeTemplate);
577 | $this->filePrependContent($this->config['source_docs'].'changelog.txt', $changeLogItemTemplate);
578 | }
579 |
580 | protected function filePrependContent($filePath, $content){
581 | //if(!file_exists($filePath))
582 | $handle = fopen($filePath, "r+");
583 | $len = strlen($content);
584 | $finalLen = filesize($filePath) + $len;
585 | $cacheOld = fread($handle, $len);
586 | rewind($handle);
587 | $i = 1;
588 | while (ftell($handle) < $finalLen) {
589 | fwrite($handle, $content);
590 | $content = $cacheOld;
591 | $cacheOld = fread($handle, $len);
592 | fseek($handle, $i * $len);
593 | $i++;
594 | }
595 | fclose($handle);
596 | }
597 |
598 | protected function makePlaceholders(
599 | array $array = array(),
600 | $plPrefix = '',
601 | $prefix = '[[+',
602 | $suffix = ']]',
603 | $uncacheable = true
604 | )
605 | {
606 | $result = ['pl' => [], 'vl' => []];
607 |
608 | $uncached_prefix = str_replace('[[', '[[!', $prefix);
609 | foreach ($array as $k => $v) {
610 | if (is_array($v)) {
611 | $result = array_merge_recursive($result,
612 | $this->makePlaceholders($v, $plPrefix . $k . '.', $prefix, $suffix, $uncacheable));
613 | } else {
614 | $pl = $plPrefix . $k;
615 | $result['pl'][$pl] = $prefix . $pl . $suffix;
616 | $result['vl'][$pl] = $v;
617 | if ($uncacheable) {
618 | $result['pl']['!' . $pl] = $uncached_prefix . $pl . $suffix;
619 | $result['vl']['!' . $pl] = $v;
620 | }
621 | }
622 | }
623 |
624 | return $result;
625 | }
626 |
627 | protected function parseString($string, $settings){
628 | $pl1 = $this->makePlaceholders($settings, '', '{', '}', false);
629 | $pl2 = $this->makePlaceholders($settings, '', '[[+', ']]', false);
630 |
631 | return str_replace($pl1['pl'], $pl1['vl'],
632 | str_replace($pl2['pl'], $pl2['vl'], $string)
633 | );
634 | }
635 |
636 | /**
637 | * @param string $dir - a directory containing class files you wish to delete.
638 | * @param bool $verbose
639 | */
640 | public function deleteClassFiles($dir, $verbose = false)
641 | {
642 | $all_files = scandir($dir);
643 | foreach ($all_files as $f)
644 | {
645 | if (preg_match('#\.class\.php$#i', $f))
646 | {
647 | if (unlink("$dir/$f"))
648 | {
649 | if ($verbose)
650 | {
651 | $this->modx->log(MODX_LOG_LEVEL_INFO, sprintf('Deleted file: %s/%s', $dir, $f));
652 | }
653 | }
654 | else
655 | {
656 | $this->modx->log(MODX_LOG_LEVEL_ERROR, sprintf('Failed to delete file: %s/%s', $dir, $f));
657 | }
658 | }
659 | }
660 | }
661 |
662 | /**
663 | * @param string $dir - a directory containing map files you wish to delete.
664 | * @param bool $verbose
665 | */
666 | public function deleteMapFiles($dir, $verbose = false)
667 | {
668 | $all_files = scandir($dir);
669 | foreach ($all_files as $f)
670 | {
671 | if (preg_match('#\.map\.inc\.php$#i', $f))
672 | {
673 | if (unlink("$dir/$f"))
674 | {
675 | if ($verbose)
676 | {
677 | $this->modx->log(MODX_LOG_LEVEL_INFO, sprintf('Deleted file: %s/%s', $dir, $f));
678 | }
679 | }
680 | else
681 | {
682 | $this->modx->log(MODX_LOG_LEVEL_ERROR, sprintf('Failed to delete file: %s/%s', $dir, $f));
683 | }
684 | }
685 | }
686 | }
687 | }
688 |
--------------------------------------------------------------------------------
/tools/xpdogenerator.class.php:
--------------------------------------------------------------------------------
1 | classPrefix = $string;
23 | }
24 |
25 | /**
26 | * Gets a class name from a table name by splitting the string by _ and
27 | * capitalizing each token.
28 | *
29 | * Переопределяет родительскую функцию и добавляет префикс к названию класса
30 | *
31 | * @access public
32 | * @param string $string The table name to format.
33 | * @return string The formatted string.
34 | */
35 | public function getClassName($string) {
36 | if (is_string($string) && $strArray= explode('_', $string)) {
37 | $return= '';
38 | while (list($k, $v)= each($strArray)) {
39 | //Если мы обрезаем табличный префикс, то первый кусочек пропускаем
40 | if($this->restrictPrefix && $k==0) continue;
41 | $return.= strtoupper(substr($v, 0, 1)) . substr($v, 1) . '';
42 | }
43 | $string= $return;
44 | }
45 | return $this->classPrefix.trim($string);
46 | }
47 |
48 | /**
49 | * Write an xPDO XML Schema from your database.
50 | * Переписан механизм формирования имени класса.
51 | *
52 | * @param string $schemaFile The name (including path) of the schemaFile you
53 | * want to write.
54 | * @param string $package Name of the package to generate the classes in.
55 | * @param string $baseClass The class which all classes in the package will
56 | * extend; by default this is set to {@link xPDOObject} and any
57 | * auto_increment fields with the column name 'id' will extend {@link
58 | * xPDOSimpleObject} automatically.
59 | * @param string $tablePrefix The table prefix for the current connection,
60 | * which will be removed from all of the generated class and table names.
61 | * Specify a prefix when creating a new {@link xPDO} instance to recreate
62 | * the tables with the same prefix, but still use the generic class names.
63 | * @param boolean $restrictPrefix Only reverse-engineer tables that have the
64 | * specified tablePrefix; if tablePrefix is empty, this is ignored.
65 | * @return boolean True on success, false on failure.
66 | */
67 | public function writeSchema($schemaFile, $package= '', $baseClass= '', $tablePrefix= '', $restrictPrefix= false, $tablePrefixForSchema = '') {
68 | if (empty ($package))
69 | $package= $this->manager->xpdo->package;
70 | if (empty ($baseClass))
71 | $baseClass= 'xPDOObject';
72 | if (empty ($tablePrefix) || $tablePrefix == '')
73 | $tablePrefix= $this->manager->xpdo->config[xPDO::OPT_TABLE_PREFIX];
74 | $this->tablePrefix = $tablePrefixForSchema;
75 | $this->restrictPrefix = $restrictPrefix;
76 | $tablePrefix .= $tablePrefixForSchema;
77 | $schemaVersion = xPDO::SCHEMA_VERSION;
78 | $xmlContent = array();
79 | $xmlContent[] = "";
80 | $xmlContent[] = "
'; 562 | var_dump($this->map[$className]); 563 | echo '';*/ 564 | $newClass= false; 565 | $classDef['class']= $className; 566 | $classDef['class-lowercase']= strtolower($className); 567 | 568 | $classDef['phpdoc-vars'] = $this->generateClassPhpDoc($this->map[$className]); 569 | 570 | $classDef= array_merge($model, $classDef); 571 | $replaceVars= array (); 572 | foreach ($classDef as $varKey => $varValue) { 573 | if (is_scalar($varValue)) $replaceVars["[+{$varKey}+]"]= $varValue; 574 | } 575 | 576 | 577 | 578 | 579 | $fileContent= str_replace(array_keys($replaceVars), array_values($replaceVars), $this->classTemplate); 580 | if (is_dir($path)) { 581 | $fileName= $path . strtolower($className) . '.class.php'; 582 | if (!file_exists($fileName)) { 583 | if ($file= @ fopen($fileName, 'wb')) { 584 | if (!fwrite($file, $fileContent)) { 585 | $this->manager->xpdo->log(xPDO::LOG_LEVEL_ERROR, "Could not write to file: {$fileName}"); 586 | } 587 | $newClass= true; 588 | @fclose($file); 589 | } else { 590 | $this->manager->xpdo->log(xPDO::LOG_LEVEL_ERROR, "Could not open or create file: {$fileName}"); 591 | } 592 | } else { 593 | $newClass= false; 594 | $this->manager->xpdo->log(xPDO::LOG_LEVEL_INFO, "Skipping {$fileName}; file already exists.\nMove existing class files to regenerate them."); 595 | } 596 | } else { 597 | $this->manager->xpdo->log(xPDO::LOG_LEVEL_ERROR, "Could not open or create dir: {$path}"); 598 | } 599 | $fileContent= str_replace(array_keys($replaceVars), array_values($replaceVars), $this->getClassPlatformTemplate($platform)); 600 | if (is_dir($ppath)) { 601 | $fileName= $ppath . '/' . strtolower($className) . '.class.php'; 602 | if (!file_exists($fileName)) { 603 | if ($file= @ fopen($fileName, 'wb')) { 604 | if (!fwrite($file, $fileContent)) { 605 | $this->manager->xpdo->log(xPDO::LOG_LEVEL_ERROR, "Could not write to file: {$fileName}"); 606 | } 607 | @fclose($file); 608 | } else { 609 | $this->manager->xpdo->log(xPDO::LOG_LEVEL_ERROR, "Could not open or create file: {$fileName}"); 610 | } 611 | } else { 612 | $this->manager->xpdo->log(xPDO::LOG_LEVEL_INFO, "Skipping {$fileName}; file already exists.\nMove existing class files to regenerate them."); 613 | if ($newClassGeneration || $newClass) $this->manager->xpdo->log(xPDO::LOG_LEVEL_WARN, "IMPORTANT: {$fileName} already exists but you appear to have generated classes with an older xPDO version. You need to edit your class definition in this file to extend {$className} rather than {$classDef['extends']}."); 614 | } 615 | } else { 616 | $this->manager->xpdo->log(xPDO::LOG_LEVEL_ERROR, "Could not open or create dir: {$path}"); 617 | } 618 | } 619 | } 620 | 621 | /** 622 | * Generate phpdoc for model class 623 | * @param $classMap 624 | * @return string 625 | */ 626 | public function generateClassPhpDoc($classMap) 627 | { 628 | $doc = ''; 629 | $doc .= " * @package ".$classMap['package']."\n"; 630 | foreach($classMap['fieldMeta'] as $fieldName => $fieldData) 631 | { 632 | $doc .= " * @property ".$fieldData['phptype']." $".$fieldName."\n"; 633 | } 634 | 635 | if(isset($classMap['composites'])) 636 | { 637 | foreach($classMap['composites'] as $fieldName => $fieldData) 638 | { 639 | $brackets = $fieldData['cardinality'] == 'many' ? '[]' : ''; 640 | $doc .= " * @property ".$fieldData['class'].$brackets." $".$fieldName."\n"; 641 | } 642 | } 643 | 644 | if(isset($classMap['aggregates'])) 645 | { 646 | foreach($classMap['aggregates'] as $fieldName => $fieldData) 647 | { 648 | $brackets = $fieldData['cardinality'] == 'many' ? '[]' : ''; 649 | $doc .= " * @property ".$fieldData['class'].$brackets." $".$fieldName."\n"; 650 | } 651 | } 652 | $doc = trim($doc,"\n"); 653 | return $doc; 654 | } 655 | } 656 | --------------------------------------------------------------------------------