├── copy_this
└── modules
│ └── oxps
│ ├── modulegenerator
│ ├── core
│ │ ├── module.tpl
│ │ │ ├── module
│ │ │ │ ├── models
│ │ │ │ │ └── .gitkeep
│ │ │ │ ├── tests
│ │ │ │ │ └── .gitkeep
│ │ │ │ ├── views
│ │ │ │ │ ├── blocks
│ │ │ │ │ │ └── .gitkeep
│ │ │ │ │ ├── pages
│ │ │ │ │ │ └── .gitkeep
│ │ │ │ │ ├── widgets
│ │ │ │ │ │ └── .gitkeep
│ │ │ │ │ └── admin
│ │ │ │ │ │ ├── popups
│ │ │ │ │ │ └── .gitkeep
│ │ │ │ │ │ ├── en
│ │ │ │ │ │ └── oxpsmodule_lang.php.tpl
│ │ │ │ │ │ └── de
│ │ │ │ │ │ └── oxpsmodule_lang.php.tpl
│ │ │ │ ├── controllers
│ │ │ │ │ └── admin
│ │ │ │ │ │ └── .gitkeep
│ │ │ │ ├── components
│ │ │ │ │ └── widgets
│ │ │ │ │ │ └── .gitkeep
│ │ │ │ ├── docs
│ │ │ │ │ ├── install.sql
│ │ │ │ │ ├── uninstall.sql
│ │ │ │ │ └── README.txt
│ │ │ │ ├── out
│ │ │ │ │ └── pictures
│ │ │ │ │ │ └── picture.png
│ │ │ │ ├── translations
│ │ │ │ │ ├── en
│ │ │ │ │ │ └── oxpsmodule_lang.php.tpl
│ │ │ │ │ └── de
│ │ │ │ │ │ └── oxpsmodule_lang.php.tpl
│ │ │ │ ├── metadata.php.tpl
│ │ │ │ └── core
│ │ │ │ │ └── oxpsmodule.php.tpl
│ │ │ ├── oxpscomment.inc.php.tpl
│ │ │ ├── oxpsextendclass.php.tpl
│ │ │ ├── oxpswidgetclass.php.tpl
│ │ │ ├── oxpslistmodelclass.php.tpl
│ │ │ ├── oxpsmodelclass.php.tpl
│ │ │ ├── oxpscontrollerclass.php.tpl
│ │ │ └── oxpstestclass.php.tpl
│ │ ├── oxpsmodulegeneratorvalidator.php
│ │ ├── oxpsmodulegeneratorfilesystem.php
│ │ ├── oxpsmodulegeneratormodule.php
│ │ ├── oxpsmodulegeneratorrender.php
│ │ ├── oxpsmodulegeneratorsettings.php
│ │ ├── oxpsmodulegeneratorhelper.php
│ │ └── oxpsmodulegeneratoroxmodule.php
│ ├── out
│ │ ├── pictures
│ │ │ └── oxpsmodulegenerator.png
│ │ └── src
│ │ │ └── css
│ │ │ └── admin_oxpsmodulegenerator.css
│ ├── tests
│ │ ├── unit
│ │ │ ├── testdata
│ │ │ │ ├── testdata_remove.sql
│ │ │ │ └── testdata_add.sql
│ │ │ └── core
│ │ │ │ ├── oxpsModuleGeneratorModuleTest.php
│ │ │ │ ├── oxpsModuleGeneratorValidatorTest.php
│ │ │ │ ├── oxpsModuleGeneratorSettingsTest.php
│ │ │ │ ├── oxpsModuleGeneratorFileSystemTest.php
│ │ │ │ └── oxpsModuleGeneratorRenderTest.php
│ │ └── additional.inc.php
│ ├── docs
│ │ ├── CHANGELOG.txt
│ │ └── README.txt
│ ├── menu.xml
│ ├── metadata.php
│ ├── views
│ │ └── admin
│ │ │ ├── de
│ │ │ └── oxpsmodulegenerator_admin_de_lang.php
│ │ │ ├── en
│ │ │ └── oxpsmodulegenerator_admin_en_lang.php
│ │ │ └── admin_oxpsmodulegenerator.tpl
│ └── controllers
│ │ └── admin
│ │ └── admin_oxpsmodulegenerator.php
│ └── vendormetadata.php
├── .gitignore
├── composer.json
├── CHANGELOG.md
├── CONTRIBUTING.md
└── README.md
/copy_this/modules/oxps/modulegenerator/core/module.tpl/module/models/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/copy_this/modules/oxps/modulegenerator/core/module.tpl/module/tests/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/copy_this/modules/oxps/modulegenerator/core/module.tpl/module/views/blocks/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/copy_this/modules/oxps/modulegenerator/core/module.tpl/module/views/pages/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/copy_this/modules/oxps/modulegenerator/core/module.tpl/module/controllers/admin/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/copy_this/modules/oxps/modulegenerator/core/module.tpl/module/views/widgets/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/copy_this/modules/oxps/modulegenerator/core/module.tpl/module/components/widgets/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/copy_this/modules/oxps/modulegenerator/core/module.tpl/module/views/admin/popups/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/copy_this/modules/oxps/vendormetadata.php:
--------------------------------------------------------------------------------
1 | getTitle()}] module install SQL file --
2 | [{if $oModule->renderTasks()}]-- TODO: Add Your installation SQL here or delete the file --[{/if}]
3 |
--------------------------------------------------------------------------------
/copy_this/modules/oxps/modulegenerator/core/module.tpl/module/docs/uninstall.sql:
--------------------------------------------------------------------------------
1 | -- [{$oModule->getTitle()}] module uninstall SQL file --
2 | [{if $oModule->renderTasks()}]-- TODO: Add Your uninstall SQL here or delete the file --[{/if}]
3 |
--------------------------------------------------------------------------------
/copy_this/modules/oxps/modulegenerator/core/module.tpl/module/out/pictures/picture.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OXID-eSales/module_skeleton_generator/HEAD/copy_this/modules/oxps/modulegenerator/core/module.tpl/module/out/pictures/picture.png
--------------------------------------------------------------------------------
/copy_this/modules/oxps/modulegenerator/tests/unit/testdata/testdata_remove.sql:
--------------------------------------------------------------------------------
1 | -- Test data removal script
2 |
3 | -- Sample CMS snippet deletion
4 | DELETE FROM `oxcontents` WHERE `OXID` = 'oxpstestident';
5 |
6 | -- Model related test table
7 | DROP TABLE IF EXISTS `testspecial_offer`;
8 |
--------------------------------------------------------------------------------
/copy_this/modules/oxps/modulegenerator/docs/CHANGELOG.txt:
--------------------------------------------------------------------------------
1 | OXID Module Skeleton Generator changelog
2 | ========================================
3 |
4 | v0.5.0
5 | ------
6 | * First standalone release of the OXID Module Skeleton Generator
7 | * Formatted for OXID PSR coding standards and refactored
8 | * Covered with PHPUnit tests
9 | * Styles, translations and documentation adjusted
10 |
--------------------------------------------------------------------------------
/copy_this/modules/oxps/modulegenerator/core/module.tpl/oxpscomment.inc.php.tpl:
--------------------------------------------------------------------------------
1 | /**
2 | [{$oModule->getAuthorData('info')}]
3 | *
4 | * @category module
5 | * @package [{$oModule->getModuleFolderName()}]
6 | * @author [{$oModule->getAuthorData('name')}]
7 | * @link [{$oModule->getAuthorData('link')}]
8 | * @copyright (C) [{$oModule->getAuthorData('copy')}][{$smarty.now|date_format:"%Y"}]
9 | */
--------------------------------------------------------------------------------
/copy_this/modules/oxps/modulegenerator/menu.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/copy_this/modules/oxps/modulegenerator/core/module.tpl/module/translations/en/oxpsmodule_lang.php.tpl:
--------------------------------------------------------------------------------
1 | renderFileComment()}]
3 |
4 | $sLangName = 'English';
5 |
6 | $aLang = array(
7 | 'charset' => 'UTF-8',
8 |
9 | [{if $oModule->renderTasks()}]// TODO: Follow this pattern to add more translation. Delete this comment.
10 | [{/if}][{if $oModule->renderSamples()}]//'[{$oModule->getVendorPrefix(true)}]_[{$oModule->getModuleFolderName(true)}]_[KEY]' => 'Value',
11 | [{/if}]);
12 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Change Log for OXID Module Skeleton Generator
2 |
3 | All notable changes to this project will be documented in this file.
4 | The format is based on [Keep a Changelog](http://keepachangelog.com/)
5 | and this project adheres to [Semantic Versioning](http://semver.org/).
6 |
7 |
8 | ## [Unreleased]
9 |
10 | ### Added
11 |
12 | ### Changed
13 |
14 | ### Deprecated
15 |
16 | ### Removed
17 |
18 | ### Fixed
19 |
20 | ### Security
21 |
22 | [Unreleased]: https://github.com/OXID-eSales/module_skeleton_generator/compare/HEAD...HEAD
23 |
--------------------------------------------------------------------------------
/copy_this/modules/oxps/modulegenerator/core/module.tpl/module/translations/de/oxpsmodule_lang.php.tpl:
--------------------------------------------------------------------------------
1 | renderFileComment()}]
3 |
4 | $sLangName = 'Deutsch';
5 |
6 | $aLang = array(
7 | 'charset' => 'UTF-8', // Supports german language specific chars like: ä, ö. ß, etc.
8 |
9 | [{if $oModule->renderTasks()}]// TODO: Follow this pattern to add more translation. Delete this comment.
10 | [{/if}][{if $oModule->renderSamples()}]//'[{$oModule->getVendorPrefix(true)}]_[{$oModule->getModuleFolderName(true)}]_[KEY]' => '[TR - Value]',
11 | [{/if}]);
12 |
--------------------------------------------------------------------------------
/copy_this/modules/oxps/modulegenerator/tests/additional.inc.php:
--------------------------------------------------------------------------------
1 | "vendor/mymodule/core/myarticle.php",
18 | ));
19 |
--------------------------------------------------------------------------------
/copy_this/modules/oxps/modulegenerator/docs/README.txt:
--------------------------------------------------------------------------------
1 | ==Title==
2 | OXID Module Skeleton Generator
3 |
4 | ==Author==
5 | OXID Professional Services
6 |
7 | ==Prefix==
8 | oxps
9 |
10 | ==Shop Version==
11 | 5.0.x/4.7.x-5.2.x/4.9.x
12 |
13 | ==Version==
14 | 0.5.0
15 |
16 | ==Link==
17 | http://www.oxid-esales.com
18 |
19 | ==Mail==
20 | info@oxid-esales.com
21 |
22 | ==Description==
23 | Folders structure, empty classes and metadata generation for new OXID eShop modules.
24 |
25 | ==Installation==
26 | * Copy the content of `copy_this/` folder to OXID eShop root folder
27 | * Activate the module in administration area
28 | * Set eShop `modules/` folder writable while generating new modules
29 |
30 | ==Extend==
31 | * oxmodule
32 |
33 | ==Modules==
34 |
35 | ==Modified original templates==
36 |
37 | ==Uninstall==
38 | * Deactivate the module in administration area
39 | * Delete module folder
40 |
--------------------------------------------------------------------------------
/copy_this/modules/oxps/modulegenerator/core/module.tpl/module/docs/README.txt:
--------------------------------------------------------------------------------
1 | ==Title==
2 | [{$oModule->getTitle()}]
3 |
4 | ==Author==
5 | [{$oModule->getAuthorData('name')}]
6 |
7 | ==Prefix==
8 | [{$oModule->getVendorPrefix()}]
9 |
10 | ==Shop Version==
11 | 5.2.x/4.9.x
12 |
13 | ==Version==
14 | [{$oModule->getInitialVersion()}]
15 |
16 | ==Link==
17 | [{$oModule->getAuthorData('link')}]
18 |
19 | ==Mail==
20 | [{$oModule->getAuthorData('mail')}]
21 |
22 | ==Description==
23 | [{$oModule->getDescription()}]
24 |
25 | ==Installation==
26 | Activate the module in administration area.
27 |
28 | ==Extend==
29 | [{assign var="aExtendClasses" value=$oModule->getClassesToExtend()}]
30 | [{if $aExtendClasses}]
31 | [{foreach from=$aExtendClasses key="sExtendClass" item="mApplicationPath"}]
32 | * [{$sExtendClass}]
33 | [{/foreach}]
34 | [{else}]
35 |
36 | [{/if}]
37 |
38 | ==Modules==
39 |
40 | ==Modified original templates==
41 |
42 | ==Uninstall==
43 | Disable the module in administration area and delete module folder.
44 |
--------------------------------------------------------------------------------
/copy_this/modules/oxps/modulegenerator/tests/unit/testdata/testdata_add.sql:
--------------------------------------------------------------------------------
1 | -- Test data creation script
2 |
3 | -- Sample CMS snippet insertion
4 | INSERT INTO `oxcontents` (`OXID`, `OXLOADID`, `OXSHOPID`, `OXSNIPPET`, `OXTYPE`, `OXACTIVE`, `OXACTIVE_1`, `OXPOSITION`, `OXTITLE`, `OXCONTENT`, `OXTITLE_1`, `OXCONTENT_1`, `OXACTIVE_2`, `OXTITLE_2`, `OXCONTENT_2`, `OXACTIVE_3`, `OXTITLE_3`, `OXCONTENT_3`, `OXCATID`, `OXFOLDER`, `OXTERMVERSION`, `OXTIMESTAMP`) VALUES ('oxpstestident', 'oxpstestident', '1', '1', '0', '1', '1', '', 'Test', '
Hello,
World!
', 'Test', 'Hello,
World!
', '1', 'Test', 'Hello,
World!
', '1', '', 'Hello,
World!
', '30e44ab83fdee7564.23264141', '', '', CURRENT_TIMESTAMP);
5 |
6 | -- Model related test table
7 |
8 | --
9 | -- Table structure for table `testspecial_offer`
10 | --
11 |
12 | CREATE TABLE IF NOT EXISTS `testspecial_offer` (
13 | `OXID` char(32) COLLATE latin1_general_ci NOT NULL,
14 | PRIMARY KEY (`OXID`)
15 | ) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;
16 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | ###How to Contribute
2 |
3 | Before contributing for the first time, you must sign the Contributor License Agreement.
4 | You can find more information about it on the FAQ page OXID Contribution and Contributor Agreement FAQ:
5 | http://wiki.oxidforge.org/OXID_Contribution_and_Contributor_Agreement_FAQ
6 |
7 | First off, you have to fork current repository.
8 |
9 | Best practice:
10 | * Please leave the the branch names as they are.
11 | * If you want to fix a bug or develop a new feature, define an own branch in your repository. Name it e.g. "feature/foo" or "bug/bugname" for better traceability.
12 | * Change whatever you want and send a pull request back to the original branch.
13 |
14 | For more information about this, please see:
15 | http://codeinthehole.com/writing/pull-requests-and-other-good-practices-for-teams-using-github/
16 |
17 | You will find technical help with Git and GitHub on this place:
18 | https://help.github.com/
19 |
20 | When sending your pull request, please provide a clear, meaningful and detailed information about what your code is about and what it will do, best including a screen shot if possible.
21 |
--------------------------------------------------------------------------------
/copy_this/modules/oxps/modulegenerator/out/src/css/admin_oxpsmodulegenerator.css:
--------------------------------------------------------------------------------
1 | /* OXID Module Skeleton Generator - Admin Styles */
2 |
3 | div.box {
4 | border: none;
5 | height: 100% !important;
6 | padding: 0;
7 | }
8 |
9 | div#oxpsmodulegenerator div.export {
10 | width: 99%;
11 | padding: 0;
12 | }
13 |
14 | div#oxpsmodulegenerator div.export span {
15 | margin: 0 10px;
16 | }
17 |
18 | table.oxpsmodulegenerator-wrapper {
19 | border: 1px solid #000000;
20 | border-top: none;
21 | width: 99%;
22 | }
23 |
24 | table.oxpsmodulegenerator-wrapper td.edittext {
25 | padding: 5px 10px;
26 | }
27 |
28 | table.oxpsmodulegenerator-wrapper td.edittext-label {
29 | width: 180px;
30 | }
31 |
32 | div#oxpsmodulegenerator input[type="text"],
33 | div#oxpsmodulegenerator select,
34 | div#oxpsmodulegenerator textarea {
35 | border: 1px solid #808080;
36 | }
37 |
38 | div#oxpsmodulegenerator input[type="text"],
39 | div#oxpsmodulegenerator select {
40 | height: 20px;
41 | }
42 |
43 | div#oxpsmodulegenerator input[type="text"],
44 | div#oxpsmodulegenerator textarea {
45 | width: 200px;
46 | }
47 |
48 | div#oxpsmodulegenerator textarea.wider {
49 | width: 360px;
50 | }
51 |
52 | div#oxpsmodulegenerator textarea[rows="3"] {
53 | height: 64px;
54 | }
55 |
56 | div#oxpsmodulegenerator textarea[rows="1"] {
57 | height: 36px;
58 | }
59 |
60 | div#oxpsmodulegenerator span.req {
61 | color: red;
62 | }
63 |
64 | div#oxpsmodulegenerator input[type="submit"] {
65 | padding: 6px 20px;
66 | }
67 |
--------------------------------------------------------------------------------
/copy_this/modules/oxps/modulegenerator/core/module.tpl/module/views/admin/en/oxpsmodule_lang.php.tpl:
--------------------------------------------------------------------------------
1 | renderFileComment()}]
3 |
4 | [{assign var='sModuleCamelCaseId' value=$oModule->getModuleId(true)}]
5 | [{assign var='aModuleSettings' value=$oModule->getSettings()}]
6 |
7 | $sLangName = 'English';
8 |
9 | $aLang = array(
10 | 'charset' => 'UTF-8',
11 | '[{$oModule->getModuleId()}]' => '[{$oModule->getTitle()}]',
12 |
13 | [{if $aModuleSettings}]
14 | // Settings interface translations
15 | [{if $oModule->renderTasks()}]// TODO: Adjust the settings translation if needed.
16 | [{/if}]
17 | 'SHOP_MODULE_GROUP_[{$sModuleCamelCaseId}]Settings' => '[{$oModule->getTitle()}] Module Settings',
18 | [{foreach from=$aModuleSettings key='iSettingKey' item='aModuleSetting'}]
19 | 'SHOP_MODULE_[{$sModuleCamelCaseId}][{$aModuleSetting->name}]' => '[{$oModule->camelCaseToHumanReadable($aModuleSetting->name)}]',
20 | [{if $aModuleSetting->type eq 'select'}]
21 | 'SHOP_MODULE_[{$sModuleCamelCaseId}][{$aModuleSetting->name}]_' => ' - ',
22 | [{assign var='aSelectOptions' value=$oModule->getSelectSettingOptions($aModuleSetting->constrains)}]
23 | [{foreach from=$aSelectOptions item='sOption'}]
24 | 'SHOP_MODULE_[{$sModuleCamelCaseId}][{$aModuleSetting->name}]_[{$sOption}]' => '[{$sOption}]',
25 | [{/foreach}]
26 | [{/if}]
27 | [{/foreach}]
28 | [{/if}]
29 |
30 | [{if $oModule->renderTasks()}]// TODO: Follow this pattern to add more translation. Delete this comment.
31 | [{/if}][{if $oModule->renderSamples()}]//'[{$oModule->getVendorPrefix(true)}]_[{$oModule->getModuleFolderName(true)}]_ADMIN_[KEY]' => 'Value',
32 | [{/if}]);
33 |
--------------------------------------------------------------------------------
/copy_this/modules/oxps/modulegenerator/core/module.tpl/module/views/admin/de/oxpsmodule_lang.php.tpl:
--------------------------------------------------------------------------------
1 | renderFileComment()}]
3 |
4 | [{assign var='sModuleCamelCaseId' value=$oModule->getModuleId(true)}]
5 | [{assign var='aModuleSettings' value=$oModule->getSettings()}]
6 |
7 | $sLangName = 'Deutsch';
8 |
9 | $aLang = array(
10 | 'charset' => 'UTF-8', // Supports german language specific chars like: ä, ö. ß, etc.
11 | '[{$oModule->getModuleId()}]' => '[{$oModule->getTitle()}]',
12 |
13 | [{if $aModuleSettings}]
14 | // Settings interface translations
15 | [{if $oModule->renderTasks()}]// TODO: Adjust the settings translation if needed.
16 | [{/if}]
17 | 'SHOP_MODULE_GROUP_[{$sModuleCamelCaseId}]Settings' => '[TR - [{$oModule->getTitle()}] Module Settings]',
18 | [{foreach from=$aModuleSettings key='iSettingKey' item='aModuleSetting'}]
19 | 'SHOP_MODULE_[{$sModuleCamelCaseId}][{$aModuleSetting->name}]' => '[TR - [{$oModule->camelCaseToHumanReadable($aModuleSetting->name)}]]',
20 | [{if $aModuleSetting->type eq 'select'}]
21 | 'SHOP_MODULE_[{$sModuleCamelCaseId}][{$aModuleSetting->name}]_' => ' - ',
22 | [{assign var='aSelectOptions' value=$oModule->getSelectSettingOptions($aModuleSetting->constrains)}]
23 | [{foreach from=$aSelectOptions item='sOption'}]
24 | 'SHOP_MODULE_[{$sModuleCamelCaseId}][{$aModuleSetting->name}]_[{$sOption}]' => '[{$sOption}]',
25 | [{/foreach}]
26 | [{/if}]
27 | [{/foreach}]
28 | [{/if}]
29 |
30 | [{if $oModule->renderTasks()}]// TODO: Follow this pattern to add more translation. Delete this comment.
31 | [{/if}][{if $oModule->renderSamples()}]//'[{$oModule->getVendorPrefix(true)}]_[{$oModule->getModuleFolderName(true)}]_ADMIN_[KEY]' => '[TR - Value]',
32 | [{/if}]);
33 |
--------------------------------------------------------------------------------
/copy_this/modules/oxps/modulegenerator/core/module.tpl/oxpsextendclass.php.tpl:
--------------------------------------------------------------------------------
1 | renderFileComment()}]
3 | [{assign var='sClassNamePrefix' value=$oModule->getModuleClassName()}]
4 | [{if $sClassRealName}]
5 | [{assign var='sClassName' value=$sClassRealName}]
6 | [{else}]
7 | [{assign var='sClassName' value=$oModule->getFileNameSuffix($sFilePath)}]
8 | [{/if}]
9 | [{assign var='sReadableClassName' value=$sClassName|capitalize}]
10 |
11 | /**
12 | * Class [{$sClassNamePrefix}][{$sReadableClassName}].
13 | * Extends [{$sClassName}].
14 | *
15 | * @see [{$sClassName}]
16 | */
17 | class [{$sClassNamePrefix}][{$sReadableClassName}] extends [{$sClassNamePrefix}][{$sReadableClassName}]_parent
18 | {
19 | [{if $oModule->renderTasks()}]
20 | // TODO: Overload parent class methods or implement new methods for the extended class.
21 | [{/if}]
22 |
23 | [{if $oModule->renderSamples()}]
24 | // An example of an overloaded method which already exists in parent class
25 | // public function [myMethod]($[sSomeParameter] = '')
26 | // {
27 | // /** @var [{$sClassNamePrefix}][{$sReadableClassName}]|[{$sClassName}] $this */
28 | //
29 | [{if $oModule->renderTasks()}]
30 | // // TODO: Implement Your custom logic here or delete this sample
31 | [{/if}]
32 | //
33 | // return $this->_[{$sClassNamePrefix}][{$sReadableClassName}]_[myMethod]_parent($[sSomeParameter]);
34 | // }
35 |
36 |
37 | /**
38 | * Parent `[myMethod]` call. Method required for mocking.
39 | *
40 | * @codeCoverageIgnore
41 | *
42 | * @return mixed
43 | */
44 | /* protected function _[{$sClassNamePrefix}][{$sReadableClassName}]_[myMethod]_parent($[sSomeParameter] = '')
45 | {
46 | return parent::[myMethod]($[sSomeParameter]);
47 | } */
48 | [{/if}]
49 | }
50 |
--------------------------------------------------------------------------------
/copy_this/modules/oxps/modulegenerator/core/module.tpl/oxpswidgetclass.php.tpl:
--------------------------------------------------------------------------------
1 | renderFileComment()}]
3 |
4 | [{assign var='sClassNamePrefix' value=$oModule->getModuleClassName()}]
5 | [{if $sClassRealName}]
6 | [{assign var='sClassName' value=$sClassRealName}]
7 | [{else}]
8 | [{assign var='sClassName' value=$oModule->getFileNameSuffix($sFilePath)}]
9 | [{/if}]
10 |
11 | /**
12 | * Class [{$sClassNamePrefix}][{$sClassName}].
13 | */
14 | class [{$sClassNamePrefix}][{$sClassName}] extends oxWidget
15 | {
16 |
17 | /**
18 | * Names of components (classes) that are initiated and executed
19 | * before any other regular operation.
20 | [{if $oModule->renderTasks()}]
21 | *
22 | * @TODO: Enter components You need for the widget to be loaded. As example ... array('oxcmp_cur' => 1, ...);
23 | [{/if}]
24 | *
25 | * @var array
26 | */
27 | protected $_aComponentNames = array([{if $oModule->renderSamples()}]/*'oxcmp_shop' => 1, 'oxcmp_basket' => 1, 'oxcmp_user' => 1*/[{/if}]);
28 |
29 | /**
30 | * Widget template name.
31 | *
32 | * @var string
33 | */
34 | protected $_sThisTemplate = '[{$oModule->getModuleId()}][{$sClassName|lower}].tpl';
35 |
36 |
37 | [{if $oModule->renderTasks()}]
38 | // TODO: Implement public methods to use in the template to get data. Also You can overload render() method here.
39 | // NOTE: Widget is very close to a controller and works very similar as a controller.
40 | [{/if}]
41 |
42 | [{if $oModule->renderSamples()}]
43 | /**
44 | * A sample method that could be called in the widget template as "$oView->getData()"
45 | *
46 | * @return array
47 | */
48 | /* public function getData()
49 | {
50 | return array('mySampleData');
51 | } */
52 | [{/if}]
53 |
54 | /**
55 | * Returns if view should be cached.
56 | *
57 | * @return bool
58 | */
59 | public function isCacheable()
60 | {
61 | [{if $oModule->renderTasks()}]
62 | // TODO: You can make it false of implement some logic when to cache it and when not.
63 | [{/if}]
64 | return true;
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/copy_this/modules/oxps/modulegenerator/core/module.tpl/oxpslistmodelclass.php.tpl:
--------------------------------------------------------------------------------
1 | renderFileComment()}]
3 | [{assign var='sClassNamePrefix' value=$oModule->getModuleClassName()}]
4 | [{if $sClassRealName}]
5 | [{assign var='sClassName' value=$sClassRealName}]
6 | [{else}]
7 | [{assign var='sClassName' value=$oModule->getFileNameSuffix($sFilePath)}]
8 | [{/if}]
9 | [{assign var='iListClassNameLength' value=$sClassName|count_characters}]
10 | [{math assign='iTruncateLength' equation='iListClassNameLength - 4' iListClassNameLength=$iListClassNameLength}]
11 | [{assign var='sListObjectsClassName' value=$sClassName|truncate:$iTruncateLength:''}]
12 | [{assign var='sTableName' value=$oModule->getModuleId()|cat:'_'}]
13 | [{assign var='sTableName' value=$sTableName|cat:$sListObjectsClassName|lower}]
14 | [{assign var='sFullClassName' value=$sClassNamePrefix|cat:$sClassName}]
15 | [{assign var='sFullObjectName' value=$sClassNamePrefix|cat:$sListObjectsClassName}]
16 |
17 | /**
18 | * Class [{$sFullClassName}].
19 | * [{$sFullObjectName}] list model.
20 | */
21 | class [{$sFullClassName}] extends oxList
22 | {
23 |
24 | /**
25 | * List Object class name
26 | *
27 | * @var string
28 | */
29 | protected $_sObjectsInListName = '[{$sFullObjectName}]';
30 |
31 | [{if $oModule->renderSamples()}]
32 |
33 | // !!!EXAMPLES!!!
34 | [{if $oModule->renderTasks()}]
35 | // TODO: Implement real loaders and delete the examples.
36 |
37 | // NOTE: List class assign loaded object ot itself, so use methods like:
38 | // $this->count / key / next / prev / clear / assign / getArray / getBaseObject / ... and so on!
39 | // If You user objects list in other class, define it with /** @var [{$sFullClassName}][] $oMyObjectsList */
40 | [{/if}]
41 |
42 | /**
43 | * Loads all entries from the table.
44 | */
45 | /* public function loadAll()
46 | {
47 | [{if $oModule->renderTasks()}]
48 | // TODO: Create other loaders like this using `selectString` method.
49 | // NOTE: For MySQL queries user proper case, backticks (`) and keep it clear and readable.
50 | [{/if}]
51 | $sSql = "SELECT * FROM " . getViewName('[{$sTableName}]');
52 |
53 | $this->selectString($sSql);
54 | } */
55 | [{/if}]
56 | }
57 |
--------------------------------------------------------------------------------
/copy_this/modules/oxps/modulegenerator/core/module.tpl/oxpsmodelclass.php.tpl:
--------------------------------------------------------------------------------
1 | renderFileComment()}]
3 | [{assign var='sClassNamePrefix' value=$oModule->getModuleClassName()}]
4 | [{if $sClassRealName}]
5 | [{assign var='sClassName' value=$sClassRealName}]
6 | [{else}]
7 | [{assign var='sClassName' value=$oModule->getFileNameSuffix($sFilePath)}]
8 | [{/if}]
9 | [{assign var='sTableName' value=$oModule->getModuleId()|cat:'_'}]
10 | [{assign var='sTableName' value=$sTableName|cat:$sClassName|lower}]
11 |
12 | /**
13 | * Class [{$sClassNamePrefix}][{$sClassName}].
14 | * [{$sClassName}] model.
15 | */
16 | [{if $oModule->renderTasks()}]
17 | //TODO: Extend oxI18n - if multilingual fields are used
18 | [{/if}]
19 | class [{$sClassNamePrefix}][{$sClassName}] extends oxBase
20 | {
21 |
22 | /**
23 | * Class constructor.
24 | */
25 | public function __construct()
26 | {
27 | parent::__construct();
28 |
29 | [{if $oModule->renderTasks()}]
30 | // TODO: Adjust the table name if needed! Create the table in docs/install.sql.
31 | [{/if}]
32 | $this->init('[{$sTableName}]');
33 | }
34 |
35 | [{if $oModule->renderTasks()}]
36 | // NOTE: If You overload parent methods like save, load, delete, etc.,
37 | // call parent methods through protected functions like "[{$sClassNamePrefix}][{$sClassName}]_[someMethod]_parent(..."
38 |
39 | // For empty OXID use $this->getId();
40 | // And You can use methods like $this-getClassName / getCoreTableName / getViewName / isLoaded ... and so on.
41 | [{/if}]
42 | [{if $oModule->renderSamples()}]
43 |
44 | // !!!EXAMPLES!!!
45 | [{if $oModule->renderTasks()}]
46 | // TODO: Implement real getters, setter, loaders, etc. and delete the examples.
47 | [{/if}]
48 |
49 | /**
50 | * Set [somefield].
51 | *
52 | * @param mixed [someField]
53 | */
54 | /*public function set[SomeField]([someValue])
55 | {
56 | $this->[{$sTableName}]__[somefield] = new oxField([someValue]);
57 | }*/
58 |
59 | /**
60 | * Get [somefield].
61 | *
62 | * @return double
63 | */
64 | /*public function get[SomeField]()
65 | {
66 | return $this->[{$sTableName}]__[somefield]->value;
67 | }*/
68 |
69 | /**
70 | * Load by... [sample function]
71 | *
72 | * @param mixed [mSomeField]
73 | *
74 | * @return mixed
75 | */
76 | // TODO: Replace [mSomeField] and [SOME_FIELD] with real values You need!
77 | /* public function loadBy...([mSomeField])
78 | {
79 | [{if $oModule->renderTasks()}]
80 | // NOTE: For MySQL queries user proper case, backticks (`) and keep it clear and readable.
81 | // NOTE: Database tables are name lowercase, as example "[{$sTableName}]"
82 | // Each new table MUST have a primary key named "OXID" of type char(32)
83 | // Custom fields are named UPPERCASE with Your vendor prefix each, for example "[{$oModule->getVendorPrefix(true)}]MYFIELD"
84 | [{/if}]
85 | $sQuery = sprintf(
86 | "SELECT * FROM `%s` WHERE `[SOME_FIELD]` = %s LIMIT 1",
87 | getViewName('[{$sTableName}]'),
88 | oxDb::getDb()->quote(trim([mSomeField]))
89 | );
90 |
91 | return $this->assignRecord($sQuery);
92 | } */
93 | [{/if}]
94 | }
95 |
--------------------------------------------------------------------------------
/copy_this/modules/oxps/modulegenerator/core/module.tpl/oxpscontrollerclass.php.tpl:
--------------------------------------------------------------------------------
1 | renderFileComment()}]
3 |
4 | [{assign var='sClassNamePrefix' value=$oModule->getModuleClassName()}]
5 | [{if $sClassRealName}]
6 | [{assign var='sClassName' value=$sClassRealName}]
7 | [{else}]
8 | [{assign var='sClassName' value=$oModule->getFileNameSuffix($sFilePath)}]
9 | [{/if}]
10 |
11 | /**
12 | * Class [{$sClassNamePrefix}][{$sClassName}].
13 | */
14 | class [{$sClassNamePrefix}][{$sClassName}] extends oxUBase
15 | {
16 |
17 | /**
18 | * Controller template name.
19 | *
20 | * @var string
21 | */
22 | protected $_sThisTemplate = '[{$oModule->getModuleId()}][{$sClassName|lower}].tpl';
23 |
24 |
25 | [{if $oModule->renderSamples()}]// This is an example of overridden init method that goes before any action and render.
26 | /* public function init()
27 | {
28 | [{if $oModule->renderTasks()}]
29 | // TODO: Implement Your custom logic here or delete this sample
30 | [{/if}]
31 | //$this->_[{$sClassNamePrefix}][{$sClassName}]_init_parent();
32 | } */
33 | [{/if}]
34 |
35 | /**
36 | * Overridden parent method.
37 | [{if $oModule->renderTasks()}]
38 | * TODO: Write a comment on what You will implement here.
39 | [{/if}]
40 | *
41 | * @return mixed
42 | */
43 | public function render()
44 | {
45 | $mReturn = $this->_[{$sClassNamePrefix}][{$sClassName}]_render_parent();
46 |
47 | [{if $oModule->renderTasks()}]
48 | // TODO: Implement Your custom logic here
49 | [{/if}]
50 | [{if $oModule->renderSamples()}]
51 | // $this->setViewData(array('[mMyParam]' => ...)); // To set ir modify view data
52 |
53 | // ... = $this->getConfig()->getRequestParameter('[request_parameter]'); // To get GET/POST parameters
54 |
55 | // $oModule = oxRegistry::get('[{$sClassNamePrefix}]Module'); // Get the module instance
56 |
57 | // /** @var myObject|myObjectParent $oObject */
58 | // $oObject = oxNew('myObject'); // To create new object
59 |
60 | // oxRegistry::getUtils()->redirect(...); // For redirect
61 |
62 | // $this->_oaComponents['oxcmp_..']->...; // To access components
63 |
64 | // $this->getUser(); // To get active shop user
65 |
66 | // oxRegistry::get("oxUtilsView")->addErrorToDisplay(...); // To set error
67 | [{/if}]
68 |
69 | return $mReturn;
70 | }
71 |
72 | [{if $oModule->renderSamples()}]// This is an example of an action (called with '...?...&fnc=[myAction]'. It is triggered before render.
73 | /* public function [myAction]()
74 | {
75 | [{if $oModule->renderTasks()}]
76 | // TODO: Implement Your custom logic here or delete this sample
77 | [{/if}]
78 | } */
79 | [{/if}]
80 |
81 | [{if $oModule->renderSamples()}]
82 | // An example of getter that could be used in template as $oView->[getMyData]()
83 | /* public function [getMyData]()
84 | {
85 | [{if $oModule->renderTasks()}]
86 | // TODO: Implement Your custom logic here or delete this sample
87 | //return ...;
88 | [{/if}]
89 | } */
90 | [{/if}]
91 |
92 | /**
93 | * Parent `render` call. Method required for mocking.
94 | *
95 | * @codeCoverageIgnore
96 | *
97 | * @return mixed
98 | */
99 | protected function _[{$sClassNamePrefix}][{$sClassName}]_render_parent()
100 | {
101 | return parent::render();
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/copy_this/modules/oxps/modulegenerator/core/oxpsmodulegeneratorvalidator.php:
--------------------------------------------------------------------------------
1 | .
19 | *
20 | * @category module
21 | * @package modulegenerator
22 | * @author OXID Professional services
23 | * @link http://www.oxid-esales.com
24 | * @copyright (C) OXID eSales AG 2003-2014
25 | */
26 |
27 | /**
28 | * Class oxpsModuleGeneratorValidator.
29 | * Validation helpers used in module generation processes and data access helpers.
30 | */
31 | class oxpsModuleGeneratorValidator extends oxSuperCfg
32 | {
33 |
34 | /**
35 | * Check if vendor prefix matches official format: 2 to 4 latin lowercase letters.
36 | *
37 | * @param string $sVendorPrefix
38 | *
39 | * @return bool
40 | */
41 | public function validateVendorPrefix($sVendorPrefix)
42 | {
43 | return (bool) preg_match('/^([a-z]{2,4})$/', (string) $sVendorPrefix);
44 | }
45 |
46 | /**
47 | * Validate a name in UpperCamelCase style.
48 | * Accepts only latin letters and numbers, first char is always capitalized latin letter.
49 | *
50 | * @param string $sVariableName
51 | *
52 | * @return bool
53 | */
54 | public function validateCamelCaseName($sVariableName)
55 | {
56 | return (
57 | !empty($sVariableName) and
58 | preg_match('/^([A-Z]{1})([a-zA-Z0-9]{1,63})$/', (string) $sVariableName)
59 | );
60 | }
61 |
62 | /**
63 | * Converts camel case string to human readable string with spaces between words.
64 | * Treats UPPERCASE abbreviations and numbers as separate words.
65 | *
66 | * @param string $sCamelCaseString
67 | *
68 | * @return string
69 | */
70 | public function camelCaseToHumanReadable($sCamelCaseString)
71 | {
72 | // Split CamelCase
73 | $sHumanReadableString = preg_replace('/([A-Z]{1}[a-z]+)/', ' $1', (string) $sCamelCaseString);
74 |
75 | // Split numbers attached to letters
76 | $sHumanReadableString = preg_replace('/([a-zA-Z])([0-9]{1})/', '$1 $2', $sHumanReadableString);
77 |
78 | // Split UPPERCASE attached to words
79 | $sHumanReadableString = preg_replace('/([a-z0-9])([A-Z]{1})/', '$1 $2', $sHumanReadableString);
80 |
81 | return !is_null($sHumanReadableString) ? trim($sHumanReadableString) : $sCamelCaseString;
82 | }
83 |
84 | /**
85 | * Get array value by key, optionally casting its type to desired one.
86 | *
87 | * @param array $aDataArray
88 | * @param mixed $mArrayKey
89 | * @param string $sType
90 | *
91 | * @return bool
92 | */
93 | public function getArrayValue(array $aDataArray, $mArrayKey, $sType = 'string')
94 | {
95 | $mValue = isset($aDataArray[$mArrayKey]) ? $aDataArray[$mArrayKey] : null;
96 |
97 | return settype($mValue, $sType) ? $mValue : null;
98 | }
99 | }
100 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # OXID Module Skeleton Generator
2 |
3 | ----
4 |
5 | Folders structure, empty classes and metadata generation for new OXID eShop modules.
6 |
7 | ### Concentrate only on features - let OXID Module Skeleton Generator create all the rest!
8 | * **Enter Your copyright data in the module settings**
9 | * **Open an easy to use Module Generator Wizard**
10 | * **Enter new module name and optional components**
11 | * **Press "Generate New Module" and its done - new module is now ready to be activated and filled with features!**
12 |
13 | ## OXID Module Skeleton Generator features
14 | - Fully configurable vendor/author parameters for new modules creation
15 | - Vendor folder and vendor metadata automatic creation
16 | - Standard module folders structure creation
17 | - Completely filled module medatada file generation
18 | - Naming based on vendor data and module name
19 | - Created modules follow OXID standards
20 | - Automatic creation of pre-filled README file
21 | - Generation of PHP files comments with all vendor and module data
22 | - Main module class is included in each generated module
23 | - It contains activation/deactivation events
24 | - Support automatic SQL execution on the events
25 | - The class "knows" about its module and provides useful methods
26 | - Generation of skeleton files for...
27 | - Overloaded (extend) classes
28 | - New controllers (also templates are created)
29 | - Model classes
30 | - List model classes (linked with item model classes)
31 | - Widgets (also with templates)
32 | - Smarty blocks metadata and templates generation
33 | - Module settings metadata and translations generation
34 | - Translation files creation
35 | - Module version
36 | - Automatic checkout of tests folder
37 | - And generation of pre-filled tests classes for each new module class
38 | - Configurable GIT repository URL to get tests folder from
39 | - Learning mode
40 | - Creation of hints and to do tasks inside generated files to help proceed with development
41 | - Sample source code generation to give a hint what each class could/should contain
42 | - Generated module is immediately working
43 | - Activate it and events, settings, blocks, controllers, etc. will already be in action!
44 |
45 | ## Installation
46 | - Copy the content of `copy_this/` folder to OXID eShop root folder
47 | - Activate the module in administration area
48 | - Set eShop `modules/` folder writable while generating new modules
49 |
50 | ## Usage
51 | - Make sure eShop `modules/` folder (and also Your vendor sub-folder, if it exists) is writable
52 | - Log in to eShop administration area
53 | - (for first run) Go to _Extensions -> Modules -> OXID Module Skeleton Generator -> Settings -> Vendor and Copyright Settings_ and enter Your vendor, copyright and author data
54 | - Open _Module Generator -> Wizard_ (refresh page if it did not appear after module activation)
55 | - Enter a name for a new module in "UpperCamelCase" format, e.g. "MyModule"
56 | - (optionally) Enter any other options required in a new module (refer to help hints for more info)
57 | - Press "Generate New Module" button
58 | - The module skeleton source is now available in Your vendor sub-folder
59 | - And the module could be activated already in _Extensions -> Modules_
60 |
61 | ## To do and nice to have features for future releases
62 | - Refactor longer classes to move some methods elsewhere
63 | - Extend blocks definition validation and blocks templates naming
64 | - EDIT mode feature: for existing modules, generate/add extra stuff
65 | - Create nice looking generation form with JS/AJAX events to validate and help enter proper values (auto-complete)
66 | - Admin interface presets generation, also with menu.xml
67 | - Generate picture with PNG text overlay with real module name
68 | - PHPStorm style schemes (or some code beautifier) integration - after generation do code formatting
69 | - Copy not all folders, but only required ones (Refactor copyDir by providing "copy scenario" array)
70 | - dbEvent fail on multi-shops and multi-lang in real life projects - need PHP based DB installation
71 |
72 |
--------------------------------------------------------------------------------
/copy_this/modules/oxps/modulegenerator/core/module.tpl/oxpstestclass.php.tpl:
--------------------------------------------------------------------------------
1 | renderFileComment()}]
3 |
4 | [{assign var='sClassNamePrefix' value=$oModule->getModuleClassName()}]
5 | [{if $sClassRealName}]
6 | [{assign var='sClassName' value=$sClassRealName}]
7 | [{else}]
8 | [{assign var='sClassName' value=$oModule->getFileNameSuffix($sFilePath)}]
9 | [{/if}]
10 | [{assign var="sClassFullName" value=$sClassNamePrefix|cat:$sClassName}]
11 |
12 | /**
13 | * Class [{$sClassFullName}]Test
14 | * Tests for core class [{$sClassFullName}].
15 | *
16 | * @see [{$sClassFullName}]
17 | */
18 | class [{$sClassFullName}]Test extends OxidTestCase
19 | {
20 |
21 | /**
22 | * Subject under the test.
23 | *
24 | * @var [{$sClassFullName}]
25 | */
26 | protected $SUT;
27 |
28 |
29 | /**
30 | * Set SUT state before test.
31 | */
32 | public function setUp()
33 | {
34 | parent::setUp();
35 |
36 | [{if $oModule->renderTasks()}]
37 | //TODO: Add more methods to mock.
38 | [{/if}]
39 | $this->SUT = $this->getMock('[{$sClassFullName}]', array('__call'));
40 | }
41 |
42 |
43 | [{if $oModule->renderTasks()}]
44 | // TODO: Implement tests here...
45 | // TODO: Test method naming is: "test[method_name]_[condition_answering_questions_when]_[expected_action_following_word_should]"
46 |
47 | [{/if}]
48 | [{if $oModule->renderSamples()}]
49 | /* public function testMyMethod_thisAndThatConditionMet_doThisAndThatAction()
50 | {
51 | [{if $oModule->renderTasks()}]
52 | // General Good Practices:
53 | // - Keep test method as small and as simple as possible
54 | // - Test one condition per one test
55 | // - Write as many tests as neded to test all conditions
56 |
57 | // TODO: For mocking use techniques like this:
58 | // Create mock object and define itsx expected behavior
59 | $oMyMock = $this->getMock('[someClass]', array('[someMethod]', '[otherClassMethod]'));
60 | $oMyMock->expects($this->once()/exactly($i[x])/never()/at($i[x])/atLeastOnce())
61 | ->method('[otherClassMethod]')
62 | ->with('[Val1]', '[Val2]' / $this->equalTo($m[Val])/anything()/isTrue/False/Null/Json/Type/InstanceOf...()/contains/arrayHasKey/...)
63 | ->will($this->returnValue($m[Val])/returnArgument($i[x])/throwException($o[Exc])/returnValueMap($a[Val])/returnSelf/...);
64 |
65 | // You can set mock inside mock
66 | $oMyClassMock->expects($this->any())->method('myMethod')->with($this->equalTo('argument'))->will(
67 | $this->returnValue($this->getMock(…))
68 | );
69 |
70 | // Also create mocks for protected methods access
71 | $this->getProxyClass('MyClass');
72 | $this->getMock($this->getProxyClassName('MyClass'), array(…));
73 |
74 | // Mock request, cnfig and session data
75 | modConfig::setParameter('param', 'value');
76 | modConfig::getInstance()->setConfigParam('setting', 'value');
77 | modSession::getInstance()->setVar('key', 'value');
78 |
79 | // Set mocks instead of real objects
80 | oxTestModules::addModuleObject('MyClass', $oMyClassMock);
81 | oxRegistry::set('MyClass', $oMyClassMock);
82 |
83 | // Use all the variety of PHPUnit assertions
84 | $this->assert...
85 |
86 | // Create tearDown() method to clear state, reset test data, etc.
87 | [{/if}]
88 | $this->asset[...](..., $this->SUT->myMethod());
89 | } */
90 |
91 | // An example of data provider used for testing
92 | /* public function myDataProvider()
93 | {
94 | return array(
95 | array([val1], [val2]),
96 | array([valA], [valB]),
97 | ...
98 | );
99 | } */
100 |
101 | /**
102 | * @dataProvider myDataProvider
103 | */
104 | /* public function testSomeMethod($mArg, $mExpectedResult)
105 | {
106 | $this->assertSame($mExpectedResult, $this->SUT->someMethod($mArg));
107 | } */
108 | [{/if}]
109 | }
110 |
--------------------------------------------------------------------------------
/copy_this/modules/oxps/modulegenerator/metadata.php:
--------------------------------------------------------------------------------
1 | .
19 | *
20 | * @category module
21 | * @package modulegenerator
22 | * @author OXID Professional services
23 | * @link http://www.oxid-esales.com
24 | * @copyright (C) OXID eSales AG 2003-2014
25 | */
26 |
27 | /**
28 | * Metadata version
29 | */
30 | $sMetadataVersion = '1.1';
31 |
32 | /**
33 | * Module information
34 | */
35 | $aModule = array(
36 | 'id' => 'oxpsmodulegenerator',
37 | 'title' => 'OXID Module Skeleton Generator',
38 | 'description' => array(
39 | 'de' => 'Die Erzeugung von Ordner-Struktur, leere Klassen und Metadata-Datei für neue OXID eShop Module',
40 | 'en' => 'Folders structure, empty classes and metadata generation for new OXID eShop modules.',
41 | ),
42 | 'thumbnail' => 'out/pictures/oxpsmodulegenerator.png',
43 | 'version' => '0.5.0',
44 | 'author' => 'OXID Professional Services',
45 | 'url' => 'http://www.oxid-esales.com',
46 | 'email' => 'info@oxid-esales.com',
47 | 'extend' => array(
48 | 'oxmodule' => 'oxps/modulegenerator/core/oxpsmodulegeneratoroxmodule',
49 | ),
50 | 'files' => array(
51 | 'admin_oxpsmodulegenerator' => 'oxps/modulegenerator/controllers/admin/admin_oxpsmodulegenerator.php',
52 | 'oxpsmodulegeneratorfilesystem' => 'oxps/modulegenerator/core/oxpsmodulegeneratorfilesystem.php',
53 | 'oxpsmodulegeneratorhelper' => 'oxps/modulegenerator/core/oxpsmodulegeneratorhelper.php',
54 | 'oxpsmodulegeneratormodule' => 'oxps/modulegenerator/core/oxpsmodulegeneratormodule.php',
55 | 'oxpsmodulegeneratorrender' => 'oxps/modulegenerator/core/oxpsmodulegeneratorrender.php',
56 | 'oxpsmodulegeneratorsettings' => 'oxps/modulegenerator/core/oxpsmodulegeneratorsettings.php',
57 | 'oxpsmodulegeneratorvalidator' => 'oxps/modulegenerator/core/oxpsmodulegeneratorvalidator.php',
58 | ),
59 | 'templates' => array(
60 | 'admin_oxpsmodulegenerator.tpl' => 'oxps/modulegenerator/views/admin/admin_oxpsmodulegenerator.tpl',
61 | ),
62 | 'settings' => array(
63 | array(
64 | 'group' => 'oxpsModuleGeneratorVendor',
65 | 'name' => 'oxpsModuleGeneratorVendorPrefix',
66 | 'type' => 'str',
67 | 'value' => ''
68 | ),
69 | array(
70 | 'group' => 'oxpsModuleGeneratorVendor',
71 | 'name' => 'oxpsModuleGeneratorModuleAuthor',
72 | 'type' => 'str',
73 | 'value' => ''
74 | ),
75 | array(
76 | 'group' => 'oxpsModuleGeneratorVendor',
77 | 'name' => 'oxpsModuleGeneratorAuthorLink',
78 | 'type' => 'str',
79 | 'value' => ''
80 | ),
81 | array(
82 | 'group' => 'oxpsModuleGeneratorVendor',
83 | 'name' => 'oxpsModuleGeneratorAuthorMail',
84 | 'type' => 'str',
85 | 'value' => ''
86 | ),
87 | array(
88 | 'group' => 'oxpsModuleGeneratorVendor',
89 | 'name' => 'oxpsModuleGeneratorCopyright',
90 | 'type' => 'str',
91 | 'value' => ''
92 | ),
93 | array(
94 | 'group' => 'oxpsModuleGeneratorVendor',
95 | 'name' => 'oxpsModuleGeneratorComment',
96 | 'type' => 'arr',
97 | 'value' => array()
98 | ),
99 | array(
100 | 'group' => 'oxpsModuleGeneratorTests',
101 | 'name' => 'oxpsModuleGeneratorTestsGitUrl',
102 | 'type' => 'str',
103 | 'value' => '',
104 | ),
105 | ),
106 | 'events' => array(
107 | 'onActivate' => 'oxpsModuleGeneratorModule::onActivate',
108 | 'onDeactivate' => 'oxpsModuleGeneratorModule::onDeactivate',
109 | ),
110 | );
111 |
--------------------------------------------------------------------------------
/copy_this/modules/oxps/modulegenerator/core/oxpsmodulegeneratorfilesystem.php:
--------------------------------------------------------------------------------
1 | .
19 | *
20 | * @category module
21 | * @package modulegenerator
22 | * @author OXID Professional services
23 | * @link http://www.oxid-esales.com
24 | * @copyright (C) OXID eSales AG 2003-2014
25 | */
26 |
27 | /**
28 | * Class oxpsModuleGeneratorFileSystem.
29 | * A helper class for files and folders verification, creation and management methods.
30 | */
31 | class oxpsModuleGeneratorFileSystem extends oxSuperCfg
32 | {
33 |
34 | /**
35 | * An alias for PHP function `is_file`.
36 | *
37 | * @param string $sPath
38 | *
39 | * @return bool
40 | */
41 | public function isFile($sPath)
42 | {
43 | return is_file($sPath);
44 | }
45 |
46 | /**
47 | * An alias for PHP function `is_dir`.
48 | *
49 | * @param string $sPath
50 | *
51 | * @return bool
52 | */
53 | public function isDir($sPath)
54 | {
55 | return is_dir($sPath);
56 | }
57 |
58 | /**
59 | * Check if folder exists and create folder(s) recursively if missing.
60 | *
61 | * @param string $sFolderFullPath
62 | */
63 | public function createFolder($sFolderFullPath)
64 | {
65 | if (!$this->isDir($sFolderFullPath)) {
66 |
67 | mkdir($sFolderFullPath, 0777, true);
68 | }
69 | }
70 |
71 | /**
72 | * Create a file using provided path and content, set full access permissions.
73 | *
74 | * @param string $sFileFullPath
75 | * @param string $sFileContent
76 | */
77 | public function createFile($sFileFullPath, $sFileContent, $blIfDoesNotExist = false)
78 | {
79 | $blFileCreated = false;
80 |
81 | if (!$this->isFile($sFileFullPath) or empty($blIfDoesNotExist)) {
82 | $blFileCreated = (bool) file_put_contents($sFileFullPath, $sFileContent);
83 | }
84 |
85 | if ($blFileCreated) {
86 | chmod($sFileFullPath, 0777);
87 | }
88 | }
89 |
90 | /**
91 | * Rename a file.
92 | *
93 | * @param string $sOldPathAndName
94 | * @param string $sNewPathAndName
95 | */
96 | public function renameFile($sOldPathAndName, $sNewPathAndName)
97 | {
98 | if ($this->isFile($sOldPathAndName)) {
99 | rename($sOldPathAndName, $sNewPathAndName);
100 | }
101 | }
102 |
103 | /**
104 | * Recursive directory copying.
105 | * Copies all files and folders to a new location.
106 | *
107 | * @param string $sSourcePath Where to copy from.
108 | * @param string $sDestinationPath Where to copy to.
109 | *
110 | * @return bool
111 | */
112 | public function copyFolder($sSourcePath, $sDestinationPath)
113 | {
114 | $sDS = DIRECTORY_SEPARATOR;
115 |
116 | if (!$this->isDir($sSourcePath) or !($hDir = opendir($sSourcePath))) {
117 | return false;
118 | }
119 |
120 | // Check module path to make sure nothing is missing
121 | $this->createFolder($sDestinationPath);
122 |
123 | while (false !== ($sFile = readdir($hDir))) {
124 | $this->_copy($sFile, $sSourcePath . $sDS . $sFile, $sDestinationPath . $sDS . $sFile);
125 | }
126 |
127 | closedir($hDir);
128 |
129 | return true;
130 | }
131 |
132 | /**
133 | * File copying.
134 | *
135 | * @param string $sSourcePath
136 | * @param string $sDestinationPath
137 | */
138 | public function copyFile($sSourcePath, $sDestinationPath)
139 | {
140 | if ($this->isFile($sSourcePath) and copy($sSourcePath, $sDestinationPath)) {
141 | chmod($sDestinationPath, 0777);
142 | }
143 | }
144 |
145 |
146 | /**
147 | * Check if resource could be copied.
148 | * If it's a file, copy it. If it's a folder, call recursive folder copy.
149 | *
150 | * @param string $sFile
151 | * @param string $sSourcePath
152 | * @param string $sDestinationPath
153 | */
154 | protected function _copy($sFile, $sSourcePath, $sDestinationPath)
155 | {
156 | if (!in_array($sFile, array('.', '..', '.gitkeep'))) {
157 | if ($this->isDir($sSourcePath)) {
158 | $this->copyFolder($sSourcePath, $sDestinationPath);
159 | } else {
160 | $this->copyFile($sSourcePath, $sDestinationPath);
161 | }
162 | }
163 | }
164 | }
165 |
--------------------------------------------------------------------------------
/copy_this/modules/oxps/modulegenerator/core/module.tpl/module/metadata.php.tpl:
--------------------------------------------------------------------------------
1 | renderFileComment()}]
3 |
4 | [{assign var='sVendorDir' value=$oModule->getVendorPrefix()}]
5 | [{assign var='sModuleId' value=$oModule->getModuleId()}]
6 | [{assign var='sModuleCamelCaseId' value=$oModule->getModuleId(true)}]
7 | [{assign var='sModuleFolderName' value=$oModule->getModuleFolderName()}]
8 | [{assign var='aNewClasses' value=$oModule->getClassesToCreate()}]
9 | [{assign var='aControllersClasses' value=$oModule->getClassesToCreate('controllers', 'aClasses')}]
10 | [{assign var='aWidgetsClasses' value=$oModule->getClassesToCreate('widgets', 'aClasses')}]
11 | [{assign var='aExtendClasses' value=$oModule->getClassesToExtend()}]
12 | [{assign var='aModuleBlocks' value=$oModule->getBlocks()}]
13 | [{assign var='aModuleSettings' value=$oModule->getSettings()}]
14 | /**
15 | * Metadata version
16 | */
17 | $sMetadataVersion = '1.1';
18 |
19 | /**
20 | * Module information
21 | */
22 | [{if $oModule->renderTasks()}]/**
23 | * TODO: Replace sample names and paths (like '[ParentClassName]', '[your_template]', etc.) with real ones You need.
24 | * TODO: Uncomment lines You need, add more if needed, delete not required.
25 | * TODO: Remove all this TODO comment.
26 | */
27 | [{/if}]
28 | $aModule = array(
29 | 'id' => '[{$sModuleId}]',
30 | 'title' => array(
31 | 'de' => '[TR - [{$oModule->getTitle()}]]',
32 | 'en' => '[{$oModule->getTitle()}]',
33 | ),
34 | 'description' => array(
35 | 'de' => '[TR - [{$oModule->getDescription()}]]',
36 | 'en' => '[{$oModule->getDescription()}]',
37 | ),
38 | 'thumbnail' => 'out/pictures/picture.png',
39 | 'version' => '[{$oModule->getInitialVersion()}]',
40 | 'author' => '[{$oModule->getAuthorData('name')}]',
41 | 'url' => '[{$oModule->getAuthorData('link')}]',
42 | 'email' => '[{$oModule->getAuthorData('mail')}]',
43 | 'extend' => array(
44 | [{if $aExtendClasses}]
45 | [{foreach from=$aExtendClasses key='sExtendClass' item='mApplicationPath'}]
46 | '[{$sExtendClass}]' => '[{$sVendorDir}]/[{$sModuleFolderName}]/[{$mApplicationPath}][{$sModuleId}][{$sExtendClass}]',
47 | [{/foreach}]
48 | [{/if}]
49 | [{if $oModule->renderSamples()}]//'[ParentClassName]' => '[{$sVendorDir}]/[{$sModuleFolderName}]/[appropriate_folder]/[{$sModuleId}][parent_class_name]',
50 | [{/if}]
51 | ),
52 | 'files' => array(
53 | '[{$sModuleId}]module' => '[{$sVendorDir}]/[{$sModuleFolderName}]/core/[{$sModuleId}]module.php',
54 | [{if $aNewClasses}]
55 | [{foreach from=$aNewClasses key='sObjectType' item='aClassesData'}]
56 | [{assign var='aClasses' value=$aClassesData.aClasses}]
57 | [{foreach from=$aClasses key='sClassKey' item='sClassName'}]
58 | '[{$sModuleId}][{$sClassName|lower}]' => '[{$sVendorDir}]/[{$sModuleFolderName}]/[{$aClassesData.sInModulePath}][{$sModuleId}][{$sClassName|lower}].php',
59 | [{/foreach}]
60 | [{/foreach}]
61 | [{/if}]
62 | [{if $oModule->renderSamples()}]
63 | //'[your_class_name]' => '[{$sVendorDir}]/[{$sModuleFolderName}]/[appropriate_folder]/[{$sModuleId}][your_class_name].php',
64 | [{/if}]
65 | ),
66 | 'templates' => array(
67 | [{if $aControllersClasses}]
68 | [{foreach from=$aControllersClasses item='sControllerClassName'}]
69 | '[{$sModuleId}][{$sControllerClassName|lower}].tpl' => '[{$sVendorDir}]/[{$sModuleFolderName}]/views/pages/[{$sModuleId}][{$sControllerClassName|lower}].tpl',
70 | [{/foreach}]
71 | [{/if}]
72 | [{if $aWidgetsClasses}]
73 | [{foreach from=$aWidgetsClasses item='sWidgetClassName'}]
74 | '[{$sModuleId}][{$sWidgetClassName|lower}].tpl' => '[{$sVendorDir}]/[{$sModuleFolderName}]/views/widgets/[{$sModuleId}][{$sWidgetClassName|lower}].tpl',
75 | [{/foreach}]
76 | [{/if}]
77 | [{if $oModule->renderSamples()}]
78 | //'[your_template].tpl' => '[{$sVendorDir}]/[{$sModuleFolderName}]/views/pages/[theme_folder_path]/[{$sModuleId}][your_template].tpl',
79 | [{/if}]
80 | ),
81 | 'blocks' => array(
82 | [{if $aModuleBlocks}]
83 | [{foreach from=$aModuleBlocks item='aModuleBlock'}]
84 | array(
85 | 'template' => '[{$aModuleBlock->template}]',
86 | 'block' => '[{$aModuleBlock->block}]',
87 | 'file' => '[{$aModuleBlock->file}]',
88 | ),
89 | [{/foreach}]
90 | [{else}]
91 | [{if $oModule->renderSamples()}]/*array(
92 | 'template' => '[theme_folder]/[theme_template].tpl',
93 | 'block' => '[{$sModuleId}]_[your_block_name]',
94 | 'file' => 'views/blocks/[{$sModuleId}][your_block_name].tpl',
95 | ),*/
96 | [{/if}]
97 | [{/if}]
98 | ),
99 | 'settings' => array(
100 | [{if $aModuleSettings}]
101 | [{foreach from=$aModuleSettings key='iSettingKey' item='aModuleSetting'}]
102 | array(
103 | 'group' => '[{$sModuleCamelCaseId}]Settings',
104 | 'name' => '[{$sModuleCamelCaseId}][{$aModuleSetting->name}]',
105 | 'type' => '[{$aModuleSetting->type}]',
106 | 'value' => [{$aModuleSetting->value}],
107 | [{if $aModuleSetting->type eq 'select'}]
108 | 'constrains' => [{$aModuleSetting->constrains}],
109 | [{/if}]
110 | ),
111 | [{/foreach}]
112 | [{else}]
113 | [{if $oModule->renderSamples()}]/*array(
114 | 'group' => '[{$sModuleCamelCaseId}][SettingsGroup]',
115 | 'name' => '[{$sModuleCamelCaseId}][SettingName]',
116 | [{if $oModule->renderTasks()}]
117 | //TODO: Change type to one You need: 'bool', 'str', 'num', 'arr', 'aarr', 'select'. Remove this comment.
118 | [{/if}]
119 | 'type' => 'str',
120 | 'value' => '[initial_setting_value]',
121 | ),*/
122 | [{/if}]
123 | [{/if}]
124 | ),
125 | 'events' => array(
126 | 'onActivate' => '[{$oModule->getModuleClassName()}]Module::onActivate',
127 | 'onDeactivate' => '[{$oModule->getModuleClassName()}]Module::onDeactivate',
128 | ),
129 | );
130 |
--------------------------------------------------------------------------------
/copy_this/modules/oxps/modulegenerator/core/oxpsmodulegeneratormodule.php:
--------------------------------------------------------------------------------
1 | .
19 | *
20 | * @category module
21 | * @package modulegenerator
22 | * @author OXID Professional services
23 | * @link http://www.oxid-esales.com
24 | * @copyright (C) OXID eSales AG 2003-2014
25 | */
26 |
27 | /**
28 | * Class oxpsModuleGeneratorModule.
29 | * Handles module setup, provides additional tools and module related helpers.
30 | */
31 | class oxpsModuleGeneratorModule extends oxModule
32 | {
33 |
34 | /**
35 | * Class constructor.
36 | * Sets current module main data and loads the rest module info.
37 | */
38 | function __construct()
39 | {
40 | $sModuleId = 'oxpsmodulegenerator';
41 |
42 | $this->setModuleData(
43 | array(
44 | 'id' => $sModuleId,
45 | 'title' => 'OXID Module Skeleton Generator',
46 | 'description' => 'Folders structure, empty classes and metadata generation for new OXID eShop modules.',
47 | )
48 | );
49 |
50 | $this->load($sModuleId);
51 |
52 | oxRegistry::set('oxpsModuleGeneratorModule', $this);
53 | }
54 |
55 |
56 | /**
57 | * Module activation script.
58 | */
59 | public static function onActivate()
60 | {
61 | self::clearTmp();
62 | }
63 |
64 | /**
65 | * Module deactivation script.
66 | */
67 | public static function onDeactivate()
68 | {
69 | self::clearTmp();
70 | }
71 |
72 | /**
73 | * Clean temp folder content.
74 | * NOTE: The method is not in File System Helper, because it will also be same in generated modules,
75 | * so it requires to be covered with tests in this class.
76 | *
77 | * @param string $sClearFolderPath Sub-folder path to delete from. Should be a full, valid path inside temp folder.
78 | *
79 | * @return boolean
80 | */
81 | public static function clearTmp($sClearFolderPath = '')
82 | {
83 | $sFolderPath = self::_getFolderToClear($sClearFolderPath);
84 | $hDirHandler = opendir($sFolderPath);
85 |
86 | if (!empty($hDirHandler)) {
87 | while (false !== ($sFileName = readdir($hDirHandler))) {
88 | $sFilePath = $sFolderPath . DIRECTORY_SEPARATOR . $sFileName;
89 | self::_clear($sFileName, $sFilePath);
90 | }
91 |
92 | closedir($hDirHandler);
93 | }
94 |
95 | return true;
96 | }
97 |
98 | /**
99 | * Get translated string by the translation code.
100 | *
101 | * @param string $sCode
102 | * @param boolean $blUseModulePrefix If True - adds the module translations prefix, if False - not.
103 | *
104 | * @return string
105 | */
106 | public function translate($sCode, $blUseModulePrefix = true)
107 | {
108 | if ($blUseModulePrefix) {
109 | $sCode = 'OXPS_MODULEGENERATOR_' . $sCode;
110 | }
111 |
112 | return oxRegistry::getLang()->translateString($sCode, oxRegistry::getLang()->getBaseLanguage(), false);
113 | }
114 |
115 | /**
116 | * Get CMS snippet content by identified ID.
117 | *
118 | * @param string $sIdentifier
119 | * @param bool $blNoHtml
120 | *
121 | * @return string
122 | */
123 | public function getCmsContent($sIdentifier, $blNoHtml = true)
124 | {
125 | $sValue = '';
126 |
127 | /** @var oxContent|oxI18n $oContent */
128 | $oContent = oxNew('oxContent');
129 | $oContent->loadByIdent(trim((string) $sIdentifier));
130 |
131 | if ($oContent->oxcontents__oxcontent instanceof oxField) {
132 | $sValue = (string) $oContent->oxcontents__oxcontent->getRawValue();
133 | $sValue = (empty($blNoHtml) ? $sValue : nl2br(strip_tags($sValue)));
134 | }
135 |
136 | return $sValue;
137 | }
138 |
139 | /**
140 | * Get module setting value.
141 | *
142 | * @param string $sModuleSettingName Module setting parameter name (key).
143 | * @param boolean $blUseModulePrefix If True - adds the module settings prefix, if False - not.
144 | *
145 | * @return mixed
146 | */
147 | public function getSetting($sModuleSettingName, $blUseModulePrefix = true)
148 | {
149 | if ($blUseModulePrefix) {
150 | $sModuleSettingName = 'oxpsModuleGenerator' . (string) $sModuleSettingName;
151 | }
152 |
153 | return oxRegistry::getConfig()->getConfigParam((string) $sModuleSettingName);
154 | }
155 |
156 | /**
157 | * Get module path.
158 | *
159 | * @return string Full path to the module directory.
160 | */
161 | public function getPath()
162 | {
163 | return oxRegistry::getConfig()->getModulesDir() . 'oxps/modulegenerator/';
164 | }
165 |
166 |
167 | /**
168 | * Check if provided path is inside eShop `tpm/` folder or use the `tmp/` folder path.
169 | *
170 | * @param string $sClearFolderPath
171 | *
172 | * @return string
173 | */
174 | protected static function _getFolderToClear($sClearFolderPath = '')
175 | {
176 | $sTempFolderPath = (string) oxRegistry::getConfig()->getConfigParam('sCompileDir');
177 |
178 | if (!empty($sClearFolderPath) and (strpos($sClearFolderPath, $sTempFolderPath) !== false)) {
179 | $sFolderPath = $sClearFolderPath;
180 | } else {
181 | $sFolderPath = $sTempFolderPath;
182 | }
183 |
184 | return $sFolderPath;
185 | }
186 |
187 | /**
188 | * Check if resource could be deleted, then delete it's a file or
189 | * call recursive folder deletion if it's a directory.
190 | *
191 | * @param string $sFileName
192 | * @param string $sFilePath
193 | */
194 | protected static function _clear($sFileName, $sFilePath)
195 | {
196 | if (!in_array($sFileName, array('.', '..', '.gitkeep', '.htaccess'))) {
197 | if (is_file($sFilePath)) {
198 | @unlink($sFilePath);
199 | } else {
200 | self::clearTmp($sFilePath);
201 | }
202 | }
203 | }
204 | }
205 |
--------------------------------------------------------------------------------
/copy_this/modules/oxps/modulegenerator/tests/unit/core/oxpsModuleGeneratorModuleTest.php:
--------------------------------------------------------------------------------
1 | .
19 | *
20 | * @category module
21 | * @package modulegenerator
22 | * @author OXID Professional services
23 | * @link http://www.oxid-esales.com
24 | * @copyright (C) OXID eSales AG 2003-2014
25 | */
26 |
27 | /**
28 | * Class oxpsModuleGeneratorModuleTest
29 | * INTEGRATION tests for core class oxpsModuleGeneratorModule.
30 | *
31 | * @see oxpsModuleGeneratorModule
32 | */
33 | class oxpsModuleGeneratorModuleTest extends OxidTestCase
34 | {
35 |
36 | /**
37 | * Subject under the test.
38 | *
39 | * @var oxpsModuleGeneratorModule
40 | */
41 | protected $SUT;
42 |
43 |
44 | /**
45 | * Set SUT state before test.
46 | */
47 | public function setUp()
48 | {
49 | parent::setUp();
50 |
51 | $this->SUT = new oxpsModuleGeneratorModule();
52 | }
53 |
54 | public static function setUpBeforeClass()
55 | {
56 | parent::setUpBeforeClass();
57 |
58 | importTestdataFile('testdata_remove.sql');
59 | importTestdataFile('testdata_add.sql');
60 | }
61 |
62 | public static function tearDownAfterClass()
63 | {
64 | parent::tearDownAfterClass();
65 |
66 | importTestdataFile('testdata_remove.sql');
67 | }
68 |
69 |
70 | public function testConstructor_loadModuleData()
71 | {
72 | $this->assertSame('oxpsmodulegenerator', $this->SUT->getId());
73 | $this->assertSame('OXID Module Skeleton Generator', $this->SUT->getTitle());
74 | $this->assertSame(
75 | 'Folders structure, empty classes and metadata generation for new OXID eShop modules.',
76 | $this->SUT->getDescription()
77 | );
78 | }
79 |
80 |
81 | public function testOnActivate_clearTempFiles()
82 | {
83 | $sTestFilePath = oxRegistry::getConfig()->getConfigParam('sCompileDir') . DIRECTORY_SEPARATOR . 'test.file';
84 |
85 | file_put_contents($sTestFilePath, 'TEST' . PHP_EOL);
86 |
87 | $this->assertFileExists($sTestFilePath);
88 |
89 | $SUT = $this->SUT;
90 | $SUT::onActivate();
91 |
92 | $this->assertFileNotExists($sTestFilePath);
93 | }
94 |
95 |
96 | public function testOnDeactivate_clearTempFiles()
97 | {
98 | $sTestFilePath = oxRegistry::getConfig()->getConfigParam('sCompileDir') . DIRECTORY_SEPARATOR . 'test.file';
99 |
100 | file_put_contents($sTestFilePath, 'TEST' . PHP_EOL);
101 |
102 | $this->assertFileExists($sTestFilePath);
103 |
104 | $SUT = $this->SUT;
105 | $SUT::onDeactivate();
106 |
107 | $this->assertFileNotExists($sTestFilePath);
108 | }
109 |
110 |
111 | public function testClearTmp_argumentDirProvided_clearsOnlyInsideProvidedDirectory()
112 | {
113 | $sTestFilePath = oxRegistry::getConfig()->getConfigParam('sCompileDir') . 'test.file';
114 | $sSmartyDirPath = oxRegistry::getConfig()->getConfigParam('sCompileDir') . 'smarty';
115 |
116 | // since this is a test, the smarty subdir might not yet exist
117 | if(!is_dir($sSmartyDirPath)) {
118 | mkdir($sSmartyDirPath);
119 | }
120 |
121 | $sSmartyFilePath = $sSmartyDirPath . DIRECTORY_SEPARATOR . 'test.file';
122 |
123 | file_put_contents($sTestFilePath, 'TEST' . PHP_EOL);
124 | file_put_contents($sSmartyFilePath, 'TEST' . PHP_EOL);
125 |
126 | $this->assertFileExists($sTestFilePath);
127 | $this->assertFileExists($sSmartyFilePath);
128 |
129 | $SUT = $this->SUT;
130 | $SUT::clearTmp(oxRegistry::getConfig()->getConfigParam('sCompileDir') . DIRECTORY_SEPARATOR . 'smarty');
131 |
132 | $this->assertFileExists($sTestFilePath);
133 | $this->assertFileNotExists($sSmartyFilePath);
134 | }
135 |
136 |
137 | public function testClearTmp_noArguments_clearsTempFolder()
138 | {
139 | $sTestFilePath = oxRegistry::getConfig()->getConfigParam('sCompileDir') . DIRECTORY_SEPARATOR . 'test.file';
140 |
141 | file_put_contents($sTestFilePath, 'TEST' . PHP_EOL);
142 |
143 | $this->assertFileExists($sTestFilePath);
144 |
145 | $SUT = $this->SUT;
146 | $SUT::clearTmp();
147 |
148 | $this->assertFileNotExists($sTestFilePath);
149 | }
150 |
151 |
152 | public function testTranslate_noSecondArgument_returnModuleTranslationStringByCode()
153 | {
154 | $this->assertSame('OXPS_MODULEGENERATOR_SOME_CODE', $this->SUT->translate('SOME_CODE'));
155 | }
156 |
157 |
158 | public function testTranslate_secondArgumentIsFalse_returnGlobalTranslationStringByCode()
159 | {
160 | $this->assertSame('SOME_CODE', $this->SUT->translate('SOME_CODE', false));
161 | }
162 |
163 |
164 | public function testGetCmsContent_noIdentFound_returnEmptyString()
165 | {
166 | $this->assertSame('', $this->SUT->getCmsContent('oxps_non_existing_ident!'));
167 | }
168 |
169 |
170 | public function testGetCmsContent_noSecondArgument_returnCmsSnippetContentByIdentWithNoHtml()
171 | {
172 | $this->assertSame('Hello, World! ', $this->SUT->getCmsContent('oxpstestident'));
173 | }
174 |
175 |
176 | public function testGetCmsContent_secondArgumentIsFalse_returnCmsSnippetContentByIdentInHtml()
177 | {
178 | $this->assertSame('Hello,
World!
', $this->SUT->getCmsContent('oxpstestident', false));
179 | }
180 |
181 |
182 | public function testGetSetting_noSecondArgument_returnModuleSettingByItsNameWithNoModulePrefix()
183 | {
184 | oxRegistry::getConfig()->setConfigParam('oxpsModuleGeneratorVendorPrefix', 'test');
185 |
186 | $this->assertSame('test', $this->SUT->getSetting('VendorPrefix'));
187 | }
188 |
189 |
190 | public function testGetSetting_secondArgumentIsFalse_returnModuleSettingByItsNameWithNoModulePrefix()
191 | {
192 | oxRegistry::getConfig()->setConfigParam('sAdminEmail', 'test@example.com');
193 |
194 | $this->assertSame('test@example.com', $this->SUT->getSetting('sAdminEmail', false));
195 | }
196 |
197 |
198 | public function testGetPath()
199 | {
200 | $sPath = $this->SUT->getPath();
201 |
202 | $this->assertStringEndsWith('/oxps/modulegenerator/', $sPath);
203 | $this->assertFileExists($sPath);
204 | }
205 | }
206 |
--------------------------------------------------------------------------------
/copy_this/modules/oxps/modulegenerator/tests/unit/core/oxpsModuleGeneratorValidatorTest.php:
--------------------------------------------------------------------------------
1 | .
19 | *
20 | * @category module
21 | * @package modulegenerator
22 | * @author OXID Professional services
23 | * @link http://www.oxid-esales.com
24 | * @copyright (C) OXID eSales AG 2003-2014
25 | */
26 |
27 | /**
28 | * Class oxpsModuleGeneratorValidatorTest
29 | * UNIT tests for core class oxpsModuleGeneratorValidator.
30 | *
31 | * @see oxpsModuleGeneratorValidator
32 | */
33 | class oxpsModuleGeneratorValidatorTest extends OxidTestCase
34 | {
35 |
36 | /**
37 | * Subject under the test.
38 | *
39 | * @var oxpsModuleGeneratorValidator
40 | */
41 | protected $SUT;
42 |
43 |
44 | /**
45 | * Set SUT state before test.
46 | */
47 | public function setUp()
48 | {
49 | parent::setUp();
50 |
51 | $this->SUT = $this->getMock('oxpsModuleGeneratorValidator', array('__call'));
52 | }
53 |
54 |
55 | /**
56 | * @dataProvider vendorPrefixDataProvider
57 | */
58 | public function testValidateVendorPrefix($mValue, $blExpectedResult)
59 | {
60 | $this->assertSame($blExpectedResult, $this->SUT->validateVendorPrefix($mValue));
61 | }
62 |
63 | public function vendorPrefixDataProvider()
64 | {
65 | return array(
66 |
67 | // Invalid values
68 | array('', false),
69 | array(' ', false),
70 | array(0, false),
71 | array(1, false),
72 | array('0000', false),
73 | array('1111', false),
74 | array('OXPS', false),
75 | array('oXps', false),
76 | array('o', false),
77 | array('oxpss', false),
78 |
79 | // Valid values
80 | array('oxps', true),
81 | array('oe', true),
82 | array('abc', true),
83 | array('abcd', true),
84 | );
85 | }
86 |
87 |
88 | /**
89 | * @dataProvider camelCaseNameDataProvider
90 | */
91 | public function testValidateCamelCaseName($mValue, $blExpectedResult)
92 | {
93 | $this->assertSame($blExpectedResult, $this->SUT->validateCamelCaseName($mValue));
94 | }
95 |
96 | public function camelCaseNameDataProvider()
97 | {
98 | return array(
99 |
100 | // Invalid values
101 | array('', false),
102 | array(' ', false),
103 | array(0, false),
104 | array(1, false),
105 | array('0000', false),
106 | array('abc', false),
107 | array('myModule', false),
108 | array('A', false),
109 | array('1module', false),
110 | array('1MyModule', false),
111 | array('MyModuleVeryVeryVeryLongLongLongNameThatIsLongLongAndEvenLongerTheNameReallyIs', false),
112 | array(' MyModule', false),
113 | array('MyModule ', false),
114 |
115 | // Valid values
116 | array('MyModule', true),
117 | array('SuperModuleOne', true),
118 | array('SuperModuleOne2Three', true),
119 | array('OtherModuleABCName', true),
120 | array('MyModuleVeryVeryVeryLongLongLongNameThatIsLongLong', true),
121 | array('Good', true),
122 | array('One', true),
123 | array('Ab', true),
124 | array('Module1', true),
125 | array('Module1And2', true),
126 | );
127 | }
128 |
129 |
130 | /**
131 | * @dataProvider camelCaseToHumanReadableDataProvider
132 | */
133 | public function testCamelCaseToHumanReadable($mValue, $sExpectedResult)
134 | {
135 | $this->assertSame($sExpectedResult, $this->SUT->camelCaseToHumanReadable($mValue));
136 | }
137 |
138 | public function camelCaseToHumanReadableDataProvider()
139 | {
140 | return array(
141 | array('', ''),
142 | array(' ', ''),
143 | array(0, '0'),
144 | array(1, '1'),
145 | array('0000', '0000'),
146 | array('abc', 'abc'),
147 | array('myModule', 'my Module'),
148 | array('A', 'A'),
149 | array('1module', '1module'),
150 | array('1MyModule', '1 My Module'),
151 | array(
152 | 'MyModuleVeryVeryVeryLongLongLongNameThatIsLongLongAndEvenLongerTheNameReallyIs',
153 | 'My Module Very Very Very Long Long Long Name That Is Long Long And Even Longer The Name Really Is'
154 | ),
155 | array('MyModule', 'My Module'),
156 | array('SuperModuleOne', 'Super Module One'),
157 | array('SuperModuleOne2Three', 'Super Module One 2 Three'),
158 | array('OtherModuleABCName', 'Other Module ABC Name'),
159 | array(
160 | 'MyModuleVeryVeryVeryLongLongLongNameThatIsLongLong',
161 | 'My Module Very Very Very Long Long Long Name That Is Long Long'
162 | ),
163 | array('Good', 'Good'),
164 | array('One', 'One'),
165 | array('Ab', 'Ab'),
166 | array('Module1', 'Module 1'),
167 | array('Module1And2', 'Module 1 And 2'),
168 | );
169 | }
170 |
171 |
172 | /**
173 | * @dataProvider arrayValuesDataProvider
174 | */
175 | public function testGetArrayValue(array $aData, $mKey, $sType, $mExpectedResult)
176 | {
177 | $this->assertSame($mExpectedResult, $this->SUT->getArrayValue($aData, $mKey, $sType));
178 | }
179 |
180 | public function arrayValuesDataProvider()
181 | {
182 | return array(
183 | array(array(), '', 'string', ''),
184 | array(array(), 'a', 'string', ''),
185 | array(array('a'), 'a', 'string', ''),
186 | array(array('b' => 'a'), 'a', 'string', ''),
187 | array(array('b' => 'a'), 'a', 'integer', 0),
188 | array(array('b' => 'a'), 'a', 'double', 0.0),
189 | array(array('A' => 2), 'a', 'string', ''),
190 | array(array('a' => 2), 'a', 'string', '2'),
191 | array(array('b' => 3, 'a' => 2), 'a', 'string', '2'),
192 | array(array('b' => 3, 'a' => 2), 'a', 'integer', 2),
193 | array(array('b' => 3, 'a' => 2), 'a', 'double', 2.0),
194 | array(array('b' => 3, 'a' => 2), 'a', 'array', array(2)),
195 | );
196 | }
197 | }
198 |
--------------------------------------------------------------------------------
/copy_this/modules/oxps/modulegenerator/core/oxpsmodulegeneratorrender.php:
--------------------------------------------------------------------------------
1 | .
19 | *
20 | * @category module
21 | * @package modulegenerator
22 | * @author OXID Professional services
23 | * @link http://www.oxid-esales.com
24 | * @copyright (C) OXID eSales AG 2003-2014
25 | */
26 |
27 | /**
28 | * Class oxpsModuleGeneratorRender
29 | * Smarty templates (module files) rendering helper for new copied module files.
30 | */
31 | class oxpsModuleGeneratorRender extends oxSuperCfg
32 | {
33 |
34 | /**
35 | * A module instance to generate stuff for.
36 | *
37 | * @var oxModule
38 | */
39 | protected $_oModule = null;
40 |
41 |
42 | /**
43 | * Alias for `setModule`.
44 | *
45 | * @param oxModule|oxpsModuleGeneratorOxModule $oModule
46 | */
47 | public function init(oxpsModuleGeneratorOxModule $oModule)
48 | {
49 | $this->setModule($oModule);
50 | }
51 |
52 | /**
53 | * Set module instance to generate stuff for.
54 | *
55 | * @param oxModule|oxpsModuleGeneratorOxModule $oModule
56 | */
57 | public function setModule(oxpsModuleGeneratorOxModule $oModule)
58 | {
59 | $this->_oModule = $oModule;
60 | }
61 |
62 | /**
63 | * Get module instance to generate stuff for.
64 | *
65 | * @return oxModule|oxpsModuleGeneratorOxModule.
66 | */
67 | public function getModule()
68 | {
69 | return $this->_oModule;
70 | }
71 |
72 | /**
73 | * Open each given file to render it with Smarty and write processed output back to corresponding file.
74 | * After that file is optionally renamed using files array key as a name.
75 | *
76 | * @param array $aClassesToExtend Module extended classes.
77 | * @param array $aNewClasses New module classes.
78 | *
79 | * @return bool
80 | */
81 | public function renderModuleFiles($aClassesToExtend, $aNewClasses)
82 | {
83 | $aFilesToProcess = $this->_getFilesToProcess($aClassesToExtend, $aNewClasses);
84 | $aNewClasses = array_merge($aClassesToExtend, $aNewClasses);
85 |
86 | $this->renderWithSmartyAndRename($aFilesToProcess, $aNewClasses);
87 |
88 | return true;
89 | }
90 |
91 | /**
92 | * Open each class as Smarty template, render the template and write rendered content back to proper file,
93 | * then rename the file.
94 | * Sets module and class data to Smarty.
95 | *
96 | * @param array $aClasses
97 | * @param array $sClassesNames
98 | */
99 | public function renderWithSmartyAndRename(array $aClasses, array $sClassesNames)
100 | {
101 | $oModule = $this->getModule();
102 | $sModulePath = $oModule->getFullPath();
103 |
104 | /** @var oxpsModuleGeneratorValidator $oValidator */
105 | $oValidator = oxRegistry::get('oxpsModuleGeneratorValidator');
106 |
107 | /** @var oxpsModuleGeneratorFileSystem $oFileSystemHelper */
108 | $oFileSystemHelper = oxRegistry::get('oxpsModuleGeneratorFileSystem');
109 |
110 | // Initialize Smarty and process template files
111 | /** @var Smarty $oSmarty */
112 | $oSmarty = oxRegistry::get("oxUtilsView")->getSmarty();
113 | $oSmarty->assign('oModule', $oModule);
114 |
115 | foreach ($aClasses as $sFileName => $sFilePath) {
116 | $oSmarty->assign('sFilePath', $sFilePath);
117 | $oSmarty->assign('sClassRealName', $oValidator->getArrayValue($sClassesNames, $sFilePath));
118 |
119 | $sFileFullPath = $sModulePath . $sFilePath;
120 |
121 | // Render template file with Smarty and overwrite it
122 | $oFileSystemHelper->createFile($sFileFullPath, $oSmarty->fetch($sFileFullPath));
123 |
124 | if (is_string($sFileName)) {
125 |
126 | // Renaming the file
127 | $sFileName = str_replace('.php.tpl', '.php', $sFileName);
128 | $sNewFullPath = str_replace(basename($sFileFullPath), $sFileName, $sFileFullPath);
129 | $oFileSystemHelper->renameFile($sFileFullPath, $sNewFullPath);
130 | }
131 |
132 | $oSmarty->clear_assign('sFilePath');
133 | $oSmarty->clear_assign('sClassRealName');
134 | }
135 | }
136 |
137 | /**
138 | * Render file comment using a template and author/vendor data.
139 | *
140 | * @param string $sSubPackage Optional subpackage title.
141 | *
142 | * @return mixed
143 | */
144 | public function renderFileComment($sSubPackage = '')
145 | {
146 | $sBaseModulePath = realpath(dirname(__FILE__) . '/../../') . '/';
147 | $sCommentTemplate = $sBaseModulePath . 'modulegenerator/core/module.tpl/oxpscomment.inc.php.tpl';
148 |
149 | /** @var Smarty $oSmarty */
150 | $oSmarty = oxRegistry::get("oxUtilsView")->getSmarty();
151 | $oSmarty->assign('oModule', $this->getModule());
152 |
153 | if (!empty($sSubPackage)) {
154 | $oSmarty->assign('sSubPackage', (string) $sSubPackage);
155 | }
156 |
157 | return $oSmarty->fetch($sCommentTemplate);
158 | }
159 |
160 |
161 | /**
162 | * Collect copied module files, that need to be processed (rendered) with Smarty.
163 | *
164 | * @param array $aClassesToExtend Generated classes that overload (extend) eShop classes.
165 | * @param array $aNewClasses Other newly generated classes.
166 | *
167 | * @return array
168 | */
169 | protected function _getFilesToProcess(array $aClassesToExtend, array $aNewClasses)
170 | {
171 | $sModuleId = $this->getModule()->getModuleId();
172 |
173 | $aFilesToProcess = array(
174 | $sModuleId . '_de_lang.php' => 'translations/de/oxpsmodule_lang.php.tpl',
175 | $sModuleId . '_en_lang.php' => 'translations/en/oxpsmodule_lang.php.tpl',
176 | $sModuleId . 'module.php' => 'core/oxpsmodule.php.tpl',
177 | 'docs/install.sql',
178 | 'docs/README.txt',
179 | 'docs/uninstall.sql',
180 | $sModuleId . '_admin_de_lang.php' => 'views/admin/de/oxpsmodule_lang.php.tpl',
181 | $sModuleId . '_admin_en_lang.php' => 'views/admin/en/oxpsmodule_lang.php.tpl',
182 | 'metadata.php' => 'metadata.php.tpl',
183 | );
184 |
185 | $aFilesToProcess = array_merge($aFilesToProcess, array_keys($aClassesToExtend), array_keys($aNewClasses));
186 |
187 | return $aFilesToProcess;
188 | }
189 | }
190 |
--------------------------------------------------------------------------------
/copy_this/modules/oxps/modulegenerator/views/admin/de/oxpsmodulegenerator_admin_de_lang.php:
--------------------------------------------------------------------------------
1 | .
19 | *
20 | * @category module
21 | * @package modulegenerator
22 | * @author OXID Professional services
23 | * @link http://www.oxid-esales.com
24 | * @copyright (C) OXID eSales AG 2003-2014
25 | */
26 |
27 | $sLangName = 'Deutsch';
28 |
29 | $aLang = array(
30 | 'charset' => 'UTF-8',
31 | 'oxpsmodulegenerator' => 'Modul Generator',
32 | 'oxpsmodulegeneratormodule' => 'Wizard',
33 | 'OXPS_MODULEGENERATOR_ADMIN_TITLE' => 'Modul Skeleton Generator',
34 |
35 | // Settings
36 | 'SHOP_MODULE_GROUP_oxpsModuleGeneratorVendor' => 'Hersteller und Copyright Einstellungen',
37 | 'SHOP_MODULE_oxpsModuleGeneratorVendorPrefix' => 'Hersteller-Präfix für das neue Modul. Es sollte ab zwei bis vier Klein lateinische Buchstaben enthalten, z.B. "abc"',
38 | 'SHOP_MODULE_oxpsModuleGeneratorModuleAuthor' => 'Name von Unternehmen oder Entwickler',
39 | 'SHOP_MODULE_oxpsModuleGeneratorAuthorLink' => 'Website URL des Modulauthors',
40 | 'SHOP_MODULE_oxpsModuleGeneratorAuthorMail' => 'E-Mail-Adresse des Modulauthors',
41 | 'SHOP_MODULE_oxpsModuleGeneratorCopyright' => 'Copyright bis zum aktuellen Jahr. z.B. "My Company, 2001-"',
42 | 'SHOP_MODULE_oxpsModuleGeneratorComment' => 'Kommentar-Text für PHP Dateien. Jede Zeile beginnt mit *
' .
43 | 'Normalerweise sollte es Hinweise und Kurz Lizenz Info stehen',
44 |
45 | 'SHOP_MODULE_GROUP_oxpsModuleGeneratorTests' => 'Module Tests Einstellungen',
46 | 'SHOP_MODULE_oxpsModuleGeneratorTestsGitUrl' => 'URL eines entfernten GIT-Repository für Tests-Ordner für generierte Module zu klonen',
47 |
48 | // Module generation form
49 | 'OXPS_MODULEGENERATOR_ADMIN_MODULE_NAME' => 'Modul Name',
50 | 'OXPS_MODULEGENERATOR_ADMIN_MODULE_NAME_HINT' => 'Kurzbezeichnung des Moduls (Großbuchstaben, camel case, z.B. "MyModule")',
51 | 'OXPS_MODULEGENERATOR_ADMIN_RENDER_TASKS' => 'Lernhinweise',
52 | 'OXPS_MODULEGENERATOR_ADMIN_RENDER_TASKS_HINT' => 'Hilfreiche Hinweise, die den Lernprozess unterstützen.',
53 | 'OXPS_MODULEGENERATOR_ADMIN_RENDER_SAMPLES' => 'Beispiel erstellen',
54 | 'OXPS_MODULEGENERATOR_ADMIN_RENDER_SAMPLES_HINT' => 'Kommentierten Beispielinhalt erstellen um die Entwicklung zu beschleunigen und an jede Klassenfunktionalität zu erinnern.',
55 | 'OXPS_MODULEGENERATOR_ADMIN_OVERRIDE_CLASSES' => 'Erweiterte Klassen',
56 | 'OXPS_MODULEGENERATOR_ADMIN_OVERRIDE_CLASSES_HINT' => 'Liste aller zu erweiternder Klassen, eine pro Zeile z.B. "oxarticle"',
57 | 'OXPS_MODULEGENERATOR_ADMIN_CREATE_CONTROLLERS' => 'Controller erstellen',
58 | 'OXPS_MODULEGENERATOR_ADMIN_CREATE_CONTROLLERS_HINT' => 'Einen Controller Namen pro Zeile (Großbuchstaben, camel case z.B. "MyController")',
59 | 'OXPS_MODULEGENERATOR_ADMIN_CREATE_MODELS' => 'Models erstellen',
60 | 'OXPS_MODULEGENERATOR_ADMIN_CREATE_MODELS_HINT' => 'Einen Model Namen pro Zeile (Großbuchstaben, camel case z.B. "MyItemModel")',
61 | 'OXPS_MODULEGENERATOR_ADMIN_CREATE_LISTS' => 'Listen erstellen',
62 | 'OXPS_MODULEGENERATOR_ADMIN_CREATE_LISTS_HINT' => 'Wiederhole die Namen der Modelle um eine Liste zu generieren, z.B. "MyItemModel"',
63 | 'OXPS_MODULEGENERATOR_ADMIN_CREATE_WIDGETS' => 'Widgets erstellen',
64 | 'OXPS_MODULEGENERATOR_ADMIN_CREATE_WIDGETS_HINT' => 'Einen Widget pro Zeile (Großbuchstaben, camel case z.B. "MyWidget")',
65 | 'OXPS_MODULEGENERATOR_ADMIN_CREATE_BLOCKS' => 'Blocks erstellen',
66 | 'OXPS_MODULEGENERATOR_ADMIN_CREATE_BLOCKS_HINT' => 'Einen Block pro Zeile (Name und Template-Pfad, kleingeschrieben und durch "@" getrennt, ein Paar pro Zeile z.B. "details_productmain_title@page/details/inc/productmain.tpl")',
67 | 'OXPS_MODULEGENERATOR_ADMIN_MODULE_SETTINGS' => 'Modul Settings erstellen',
68 | 'OXPS_MODULEGENERATOR_ADMIN_MODULE_SETTING_NAME' => 'Name',
69 | 'OXPS_MODULEGENERATOR_ADMIN_MODULE_SETTING_TYPE' => 'Typ',
70 | 'OXPS_MODULEGENERATOR_ADMIN_MODULE_SETTING_VALUE' => 'Standardwert',
71 | 'OXPS_MODULEGENERATOR_ADMIN_CREATE_SETTINGS_HINT' => 'Initialwert (z.B. Checkbox - "0" or "1", String - "my value", Nummer - "7.88", usw. - Ein Wert pro Zeile.
' .
72 | 'Alte Shop Versionen unterstützen nicht den Einstellungs-Typ "Number"',
73 | 'OXPS_MODULEGENERATOR_ADMIN_MODULE_INIT_VERSION' => 'Initiale Modulversion',
74 | 'OXPS_MODULEGENERATOR_ADMIN_HAS_ADMINISTRATION' => 'Adminoberfläche erstellen',
75 | 'OXPS_MODULEGENERATOR_ADMIN_HAS_ADMINISTRATION_HINT' => 'Gibt an ob das Modul eine Adminoberfläche benötigt.',
76 | 'OXPS_MODULEGENERATOR_ADMIN_CHECKOUT_UNIT_TESTS' => 'Ckeckout Unit tests',
77 | 'OXPS_MODULEGENERATOR_ADMIN_CHECKOUT_UNIT_TESTS_HINT' => 'Klone den neuesten Generic-Test-Ordner aus dem GIT. Anmerkung: Die Umgebung sollte entsprechend konfiguriert sein!',
78 | 'OXPS_MODULEGENERATOR_ADMIN_MODULE_GENERATE' => 'Neues Modul anlegen',
79 |
80 | // Module generation form errors and messages
81 | 'OXPS_MODULEGENERATOR_ADMIN_MODULE_ERROR_NO_VENDOR' => 'Achtung! Hersteller oder Autor Parameter sind nicht konfiguriert.
' .
82 | 'Bitte öffnen Sie Erweiterungen -> Module -> OXID Module Skeleton Generator -> Einstell. -> Hersteller und Copyright Einstellungen ' .
83 | 'und geben Sie Hersteller, Copyright und Autor an.',
84 | 'OXPS_MODULEGENERATOR_ADMIN_MODULE_ERROR_INVALID_VENDOR' => 'ERROR! Hersteller-Präfix ist ungültig. Es sollte aus zwei bis vier lateinischen Kleinbuchstaben bestehen.',
85 | 'OXPS_MODULEGENERATOR_ADMIN_MODULE_ERROR_INVALID_NAME' => 'ERROR! Module Name ist ungültig oder existiert bereits. Bitte nur eindeutige Großbuchstaben (camel case) verwenden, z.B. "MyModule"',
86 | 'OXPS_MODULEGENERATOR_ADMIN_MODULE_MSG_GENERATION_SUCCESS' => 'Ihr Modul wurde erfolgreich generiert! Bitte prüfen Sie in Erweiterungen -> Module und den Source-Code in Ihrem Hersteller-Verzeichnis.'
87 | );
88 |
--------------------------------------------------------------------------------
/copy_this/modules/oxps/modulegenerator/views/admin/en/oxpsmodulegenerator_admin_en_lang.php:
--------------------------------------------------------------------------------
1 | .
19 | *
20 | * @category module
21 | * @package modulegenerator
22 | * @author OXID Professional services
23 | * @link http://www.oxid-esales.com
24 | * @copyright (C) OXID eSales AG 2003-2014
25 | */
26 |
27 | $sLangName = 'English';
28 |
29 | $aLang = array(
30 | 'charset' => 'UTF-8',
31 | 'oxpsmodulegenerator' => 'Module Generator',
32 | 'oxpsmodulegeneratormodule' => 'Wizard',
33 | 'OXPS_MODULEGENERATOR_ADMIN_TITLE' => 'Module Skeleton Generator',
34 |
35 | // Settings
36 | 'SHOP_MODULE_GROUP_oxpsModuleGeneratorVendor' => 'Vendor and Copyright Settings',
37 | 'SHOP_MODULE_oxpsModuleGeneratorVendorPrefix' => 'Vendor prefix used for module generation. It should contain two to four lowercase latin letters, e.g. "abc"',
38 | 'SHOP_MODULE_oxpsModuleGeneratorModuleAuthor' => 'Module authors\' name. Company or developer full name.',
39 | 'SHOP_MODULE_oxpsModuleGeneratorAuthorLink' => 'Module authors\' website URL.',
40 | 'SHOP_MODULE_oxpsModuleGeneratorAuthorMail' => 'Module authors\' contact email.',
41 | 'SHOP_MODULE_oxpsModuleGeneratorCopyright' => 'Module copyright part that goes before current year. For example: "My Company, 2001-"',
42 | 'SHOP_MODULE_oxpsModuleGeneratorComment' => 'File comment text used in PHP files. Start each line with an asterisk: `*`.
' .
43 | 'Normally it should contain legal notices and short license info.',
44 |
45 | 'SHOP_MODULE_GROUP_oxpsModuleGeneratorTests' => 'Generated Modules Tests Settings',
46 | 'SHOP_MODULE_oxpsModuleGeneratorTestsGitUrl' => 'URL of a remote GIT repository to clone tests folder from for generated modules.',
47 |
48 | // Module generation form
49 | 'OXPS_MODULEGENERATOR_ADMIN_MODULE_NAME' => 'Module name',
50 | 'OXPS_MODULEGENERATOR_ADMIN_MODULE_NAME_HINT' => 'Enter short, capitalized camel case name of new module, e.g. "MyModule"',
51 | 'OXPS_MODULEGENERATOR_ADMIN_RENDER_TASKS' => 'Learning hints',
52 | 'OXPS_MODULEGENERATOR_ADMIN_RENDER_TASKS_HINT' => 'Renders To Do comments, explanations and useful hints for learning.',
53 | 'OXPS_MODULEGENERATOR_ADMIN_RENDER_SAMPLES' => 'Create examples',
54 | 'OXPS_MODULEGENERATOR_ADMIN_RENDER_SAMPLES_HINT' => 'Renders commented sample content to make development faster and remind of each class features.',
55 | 'OXPS_MODULEGENERATOR_ADMIN_OVERRIDE_CLASSES' => 'Extend classes',
56 | 'OXPS_MODULEGENERATOR_ADMIN_OVERRIDE_CLASSES_HINT' => 'List classes to overload (extend), each from new line, e.g. "oxarticle"',
57 | 'OXPS_MODULEGENERATOR_ADMIN_CREATE_CONTROLLERS' => 'Create controllers',
58 | 'OXPS_MODULEGENERATOR_ADMIN_CREATE_CONTROLLERS_HINT' => 'Enter capitalized camel case names each from new line, e.g. "MyController"',
59 | 'OXPS_MODULEGENERATOR_ADMIN_CREATE_MODELS' => 'Create models',
60 | 'OXPS_MODULEGENERATOR_ADMIN_CREATE_MODELS_HINT' => 'Enter capitalized camel case names each from new line, e.g. "MyItemModel"',
61 | 'OXPS_MODULEGENERATOR_ADMIN_CREATE_LISTS' => 'Create lists',
62 | 'OXPS_MODULEGENERATOR_ADMIN_CREATE_LISTS_HINT' => 'Repeat item models names, to create list models, e.g. "MyItemModel"',
63 | 'OXPS_MODULEGENERATOR_ADMIN_CREATE_WIDGETS' => 'Create widgets',
64 | 'OXPS_MODULEGENERATOR_ADMIN_CREATE_WIDGETS_HINT' => 'Enter capitalized camel case names each from new line, e.g. "MyWidget"',
65 | 'OXPS_MODULEGENERATOR_ADMIN_CREATE_BLOCKS' => 'Create blocks',
66 | 'OXPS_MODULEGENERATOR_ADMIN_CREATE_BLOCKS_HINT' => 'Enter block name and template path, both lowercase, separated by "@", each pair from new line, e.g. "details_productmain_title@page/details/inc/productmain.tpl"',
67 | 'OXPS_MODULEGENERATOR_ADMIN_MODULE_SETTINGS' => 'Create module settings',
68 | 'OXPS_MODULEGENERATOR_ADMIN_MODULE_SETTING_NAME' => 'Name',
69 | 'OXPS_MODULEGENERATOR_ADMIN_MODULE_SETTING_TYPE' => 'Type',
70 | 'OXPS_MODULEGENERATOR_ADMIN_MODULE_SETTING_VALUE' => 'Default value',
71 | 'OXPS_MODULEGENERATOR_ADMIN_CREATE_SETTINGS_HINT' => 'Enter initial values like in examples: Checkbox - "0" or "1", String - "my value", Number - "7.88", for other types - each value from new line.
' .
72 | 'NOTE: Older eShop versions don\'t support "Number" setting type.',
73 | 'OXPS_MODULEGENERATOR_ADMIN_MODULE_INIT_VERSION' => 'Initial module version',
74 | 'OXPS_MODULEGENERATOR_ADMIN_HAS_ADMINISTRATION' => 'Has admin interface',
75 | 'OXPS_MODULEGENERATOR_ADMIN_HAS_ADMINISTRATION_HINT' => 'Select this option if module requires administration interface.',
76 | 'OXPS_MODULEGENERATOR_ADMIN_CHECKOUT_UNIT_TESTS' => 'Ckeckout Unit tests',
77 | 'OXPS_MODULEGENERATOR_ADMIN_CHECKOUT_UNIT_TESTS_HINT' => 'Clone latest version of generic tests folder from GIT. NOTE: Your environment should be configured to access configured GIT repository!',
78 | 'OXPS_MODULEGENERATOR_ADMIN_MODULE_GENERATE' => 'Create New Module',
79 |
80 | // Module generation form errors and messages
81 | 'OXPS_MODULEGENERATOR_ADMIN_MODULE_ERROR_NO_VENDOR' => 'Attention! Vendor or author parameters are not configured.
' .
82 | 'Please open Extensions -> Modules -> OXID Module Skeleton Generator -> Settings -> Vendor and Copyright Settings ' .
83 | 'and enter Your vendor, copyright and author data.',
84 | 'OXPS_MODULEGENERATOR_ADMIN_MODULE_ERROR_INVALID_VENDOR' => 'ERROR! Module vendor prefix configured in settings is invalid. It should contain two to four lowercase latin letters.',
85 | 'OXPS_MODULEGENERATOR_ADMIN_MODULE_ERROR_INVALID_NAME' => 'ERROR! Module name is invalid or module exists already. Use unique capitalized camel case name, e.g. "MyModule"',
86 | 'OXPS_MODULEGENERATOR_ADMIN_MODULE_MSG_GENERATION_SUCCESS' => 'Success! New module have been generated! Please check in Extensions -> Modules and the source code in Your vendor sub-folder.',
87 | );
88 |
--------------------------------------------------------------------------------
/copy_this/modules/oxps/modulegenerator/core/module.tpl/module/core/oxpsmodule.php.tpl:
--------------------------------------------------------------------------------
1 | renderFileComment()}]
3 |
4 | [{assign var='sModuleClassName' value=$oModule->getModuleClassName()|cat:'Module'}]
5 | /**
6 | * Class [{$sModuleClassName}]
7 | * Handles module setup, provides additional tools and module related helpers.
8 | *
9 | * @codeCoverageIgnore
10 | */
11 | class [{$sModuleClassName}] extends oxModule
12 | {
13 |
14 | /**
15 | * Class constructor.
16 | * Sets current module main data and loads the rest module info.
17 | */
18 | function __construct()
19 | {
20 | $sModuleId = '[{$oModule->getModuleId()}]';
21 |
22 | $this->setModuleData(
23 | array(
24 | 'id' => $sModuleId,
25 | 'title' => '[{$oModule->getTitle()}]',
26 | 'description' => '[{$oModule->getTitle()}] Module',
27 | )
28 | );
29 |
30 | $this->load($sModuleId);
31 |
32 | oxRegistry::set('[{$sModuleClassName}]', $this);
33 | }
34 |
35 |
36 | /**
37 | * Module activation script.
38 | */
39 | public static function onActivate()
40 | {
41 | return self::_dbEvent('install.sql', 'Error activating module: ');
42 | }
43 |
44 | /**
45 | * Module deactivation script.
46 | */
47 | public static function onDeactivate()
48 | {
49 | self::_dbEvent('uninstall.sql', 'Error deactivating module: ');
50 | }
51 |
52 | /**
53 | * Clean temp folder content.
54 | *
55 | * @param string $sClearFolderPath Sub-folder path to delete from. Should be a full, valid path inside temp folder.
56 | *
57 | * @return boolean
58 | */
59 | public static function clearTmp($sClearFolderPath = '')
60 | {
61 | $sFolderPath = self::_getFolderToClear($sClearFolderPath);
62 | $hDirHandler = opendir($sFolderPath);
63 |
64 | if (!empty($hDirHandler)) {
65 | while (false !== ($sFileName = readdir($hDirHandler))) {
66 | $sFilePath = $sFolderPath . DIRECTORY_SEPARATOR . $sFileName;
67 | self::_clear($sFileName, $sFilePath);
68 | }
69 |
70 | closedir($hDirHandler);
71 | }
72 |
73 | return true;
74 | }
75 |
76 | /**
77 | * Get translated string by the translation code.
78 | *
79 | * @param string $sCode
80 | * @param boolean $blUseModulePrefix If True - adds the module translations prefix, if False - not.
81 | *
82 | * @return string
83 | */
84 | public function translate($sCode, $blUseModulePrefix = true)
85 | {
86 | if ($blUseModulePrefix) {
87 | $sCode = '[{$oModule->getVendorPrefix(true)}]_[{$oModule->getModuleFolderName(true)}]_' . $sCode;
88 | }
89 |
90 | return oxRegistry::getLang()->translateString($sCode, oxRegistry::getLang()->getBaseLanguage(), false);
91 | }
92 |
93 | /**
94 | * Get CMS snippet content by identified ID.
95 | *
96 | * @param string $sIdentifier
97 | * @param bool $blNoHtml
98 | *
99 | * @return string
100 | */
101 | public function getCmsContent($sIdentifier, $blNoHtml = true)
102 | {
103 | $sValue = '';
104 |
105 | /** @var oxContent|oxI18n $oContent */
106 | $oContent = oxNew('oxContent');
107 | $oContent->loadByIdent(trim((string) $sIdentifier));
108 |
109 | if ($oContent->oxcontents__oxcontent instanceof oxField) {
110 | $sValue = (string) $oContent->oxcontents__oxcontent->getRawValue();
111 | $sValue = (empty($blNoHtml) ? $sValue : nl2br(strip_tags($sValue)));
112 | }
113 |
114 | return $sValue;
115 | }
116 |
117 | /**
118 | * Get module setting value.
119 | *
120 | * @param string $sModuleSettingName Module setting parameter name (key).
121 | * @param boolean $blUseModulePrefix If True - adds the module settings prefix, if False - not.
122 | *
123 | * @return mixed
124 | */
125 | public function getSetting($sModuleSettingName, $blUseModulePrefix = true)
126 | {
127 | if ($blUseModulePrefix) {
128 | $sModuleSettingName = '[{$oModule->getModuleClassName()}]' . (string) $sModuleSettingName;
129 | }
130 |
131 | return oxRegistry::getConfig()->getConfigParam((string) $sModuleSettingName);
132 | }
133 |
134 | /**
135 | * Get module path.
136 | *
137 | * @return string Full path to the module directory.
138 | */
139 | public function getPath()
140 | {
141 | return oxRegistry::getConfig()->getModulesDir() . '[{$oModule->getVendorPrefix()}]/[{$oModule->getModuleFolderName()}]/';
142 | }
143 |
144 |
145 | /**
146 | * Install/uninstall event.
147 | * Executes SQL queries form a file.
148 | *
149 | * @param string $sSqlFile SQL file located in module docs folder (usually install.sql or uninstall.sql).
150 | * @param string $sFailureError An error message to show on failure.
151 | */
152 | protected static function _dbEvent($sSqlFile, $sFailureError = 'Operation failed: ')
153 | {
154 | try {
155 | $oDb = oxDb::getDb();
156 | $sSql = file_get_contents(dirname(__FILE__) . '/../docs/' . (string) $sSqlFile);
157 | $aSql = (array) preg_split("/;\s*\R/", $sSql);
158 |
159 | foreach ($aSql as $sQuery) {
160 | if (!empty($sQuery)) {
161 | $oDb->execute($sQuery);
162 | }
163 | }
164 | } catch (Exception $ex) {
165 | error_log($sFailureError . $ex->getMessage());
166 | }
167 |
168 | [{if $oModule->renderSamples()}]
169 | [{if $oModule->renderTasks()}]
170 | // TODO: Use following lines to update database views if You need that.
171 | [{/if}]
172 | /** @var oxDbMetaDataHandler $oDbHandler */
173 | //$oDbHandler = oxNew('oxDbMetaDataHandler');
174 | //$oDbHandler->updateViews();
175 | [{/if}]
176 |
177 | self::clearTmp();
178 |
179 | return true;
180 | }
181 |
182 | /**
183 | * Check if provided path is inside eShop `tpm/` folder or use the `tmp/` folder path.
184 | *
185 | * @param string $sClearFolderPath
186 | *
187 | * @return string
188 | */
189 | protected static function _getFolderToClear($sClearFolderPath = '')
190 | {
191 | $sTempFolderPath = (string) oxRegistry::getConfig()->getConfigParam('sCompileDir');
192 |
193 | if (!empty($sClearFolderPath) and (strpos($sClearFolderPath, $sTempFolderPath) !== false)) {
194 | $sFolderPath = $sClearFolderPath;
195 | } else {
196 | $sFolderPath = $sTempFolderPath;
197 | }
198 |
199 | return $sFolderPath;
200 | }
201 |
202 | /**
203 | * Check if resource could be deleted, then delete it's a file or
204 | * call recursive folder deletion if it's a directory.
205 | *
206 | * @param string $sFileName
207 | * @param string $sFilePath
208 | */
209 | protected static function _clear($sFileName, $sFilePath)
210 | {
211 | if (!in_array($sFileName, array('.', '..', '.gitkeep', '.htaccess'))) {
212 | if (is_file($sFilePath)) {
213 | @unlink($sFilePath);
214 | } else {
215 | self::clearTmp($sFilePath);
216 | }
217 | }
218 | }
219 | }
220 |
--------------------------------------------------------------------------------
/copy_this/modules/oxps/modulegenerator/core/oxpsmodulegeneratorsettings.php:
--------------------------------------------------------------------------------
1 | .
19 | *
20 | * @category module
21 | * @package modulegenerator
22 | * @author OXID Professional services
23 | * @link http://www.oxid-esales.com
24 | * @copyright (C) OXID eSales AG 2003-2014
25 | */
26 |
27 | /**
28 | * Class oxpsModuleGeneratorSettings
29 | * Generated module settings parsing and validation helper.
30 | */
31 | class oxpsModuleGeneratorSettings extends oxSuperCfg
32 | {
33 |
34 | /**
35 | * Cleans settings array got from request to make it suitable for a module metadata file generation.
36 | *
37 | * @param array $aModuleSettings Raw array got from request, could contain empty or faulty values.
38 | *
39 | * @return array Clean settings array, that could be used in metadata generation.
40 | */
41 | public function getModuleSettings(array $aModuleSettings)
42 | {
43 | /** @var oxpsModuleGeneratorValidator $oValidator */
44 | $oValidator = oxRegistry::get('oxpsModuleGeneratorValidator');
45 |
46 | $aCleanSettings = array();
47 |
48 | foreach ($aModuleSettings as $aModuleSetting) {
49 |
50 | // Get clean name, type and value
51 | $aModuleSetting = (array) $aModuleSetting;
52 | $sSettingName = trim($oValidator->getArrayValue($aModuleSetting, 'name', 'string'));
53 | $sSettingType = $oValidator->getArrayValue($aModuleSetting, 'type', 'string');
54 | $sInitialValue = $oValidator->getArrayValue($aModuleSetting, 'value');
55 |
56 | // Check if name and type are valid
57 | if ($oValidator->validateCamelCaseName($sSettingName) and
58 | in_array($sSettingType, array('bool', 'str', 'num', 'arr', 'aarr', 'select'))
59 | ) {
60 | // Prepare for rendering as raw value (variable as string with quotes and so on)
61 | $aSetting = (array) $this->_getRawSettingValue($sSettingName, $sSettingType, $sInitialValue);
62 |
63 | // Add clean settings entry
64 | $aCleanSettings[] = (object) $aSetting;
65 | }
66 | }
67 |
68 | return $aCleanSettings;
69 | }
70 |
71 |
72 | /**
73 | * Compile a settings entry array to be used in metadata generation.
74 | * Value is a raw output to be rendered in metadata (variable as string with quotes and so on).
75 | *
76 | * @param string $sSettingName
77 | * @param string $sSettingType
78 | * @param string $sInitialValue
79 | *
80 | * @return array
81 | */
82 | protected function _getRawSettingValue($sSettingName, $sSettingType, $sInitialValue)
83 | {
84 | $aSettingParsersMap = array(
85 | 'bool' => '_getBooleanSettingValue',
86 | 'num' => '_getNumericSettingValue',
87 | 'arr' => '_getArraySettingValue',
88 | 'aarr' => '_getAssocArraySettingValue',
89 | 'select' => '_getSelectSettingValue',
90 | );
91 |
92 | if (array_key_exists($sSettingType, $aSettingParsersMap)) {
93 | $sMethod = $aSettingParsersMap[$sSettingType];
94 | $sValue = $this->$sMethod((string) $sInitialValue);
95 | } else {
96 |
97 | // String ("str") type is the default fallback
98 | $sValue = "'" . (string) $sInitialValue . "'";
99 | }
100 |
101 | $aSetting = array(
102 | 'name' => $sSettingName,
103 | 'type' => $sSettingType,
104 | 'value' => $sValue,
105 | );
106 |
107 | if ($sSettingType == 'select') {
108 |
109 | // For "select" type also adds options string under "constrains" key
110 | $aSetting['constrains'] = $this->_getSelectSettingValue($sInitialValue, true);
111 | }
112 |
113 | return $aSetting;
114 | }
115 |
116 | /**
117 | * Boolean type value parser.
118 | *
119 | * @param string $sInitialValue
120 | *
121 | * @return string
122 | */
123 | protected function _getBooleanSettingValue($sInitialValue)
124 | {
125 | return (empty($sInitialValue) or oxStr::getStr()->strtolower($sInitialValue) == 'false')
126 | ? 'false'
127 | : 'true';
128 | }
129 |
130 | /**
131 | * Numeric type value parser.
132 | *
133 | * @param string $sInitialValue
134 | *
135 | * @return float
136 | */
137 | protected function _getNumericSettingValue($sInitialValue)
138 | {
139 | return (double) $sInitialValue;
140 | }
141 |
142 | /**
143 | * Array type value parser.
144 | *
145 | * @param string $sInitialValue
146 | *
147 | * @return string
148 | */
149 | protected function _getArraySettingValue($sInitialValue)
150 | {
151 | $sValue = str_replace(array("\r\n", "\n\r", "\r"), PHP_EOL, $sInitialValue);
152 |
153 | return "array('" . implode("', '", explode(PHP_EOL, $sValue)) . "')";
154 | }
155 |
156 | /**
157 | * Parse clean initial value for assoc array ("aarr") setting type.
158 | *
159 | * @param string $sInitialValue
160 | *
161 | * @return string
162 | */
163 | protected function _getAssocArraySettingValue($sInitialValue)
164 | {
165 | $sInitialValue = str_replace(array("\r\n", "\n\r", "\r"), PHP_EOL, $sInitialValue);
166 | $aInitialValue = array();
167 |
168 | $aLines = explode(PHP_EOL, $sInitialValue);
169 |
170 | foreach ($aLines as $sLine) {
171 | $aKeyAndValue = explode('=>', $sLine);
172 |
173 | if (count($aKeyAndValue) == 2) {
174 | $aInitialValue[] = sprintf(
175 | "'%s' => '%s'",
176 | trim($aKeyAndValue[0]),
177 | trim($aKeyAndValue[1])
178 | );
179 | }
180 | }
181 |
182 | return "array(" . implode(", ", $aInitialValue) . ")";
183 | }
184 |
185 | /**
186 | * Select (drop down) type value parser.
187 | *
188 | * @param string $sInitialValue
189 | * @param bool $blReturnOptions If False returns default select value, if True - options string is returned.
190 | *
191 | * @return string
192 | */
193 | protected function _getSelectSettingValue($sInitialValue, $blReturnOptions = false)
194 | {
195 | $sInitialValue = str_replace(array("\r\n", "\n\r", "\r"), PHP_EOL, $sInitialValue);
196 | $aOptions = explode(PHP_EOL, $sInitialValue);
197 | $sOptions = "'" . implode("|", $aOptions) . "'";
198 | $sInitialValue = "'" . reset($aOptions) . "'";
199 |
200 | return empty($blReturnOptions) ? $sInitialValue : $sOptions;
201 | }
202 | }
203 |
--------------------------------------------------------------------------------
/copy_this/modules/oxps/modulegenerator/tests/unit/core/oxpsModuleGeneratorSettingsTest.php:
--------------------------------------------------------------------------------
1 | .
19 | *
20 | * @category module
21 | * @package modulegenerator
22 | * @author OXID Professional services
23 | * @link http://www.oxid-esales.com
24 | * @copyright (C) OXID eSales AG 2003-2014
25 | */
26 |
27 | /**
28 | * Class oxpsModuleGeneratorSettingsTest
29 | * UNIT tests for core class oxpsModuleGeneratorSettings.
30 | *
31 | * @see oxpsModuleGeneratorSettings
32 | */
33 | class oxpsModuleGeneratorSettingsTest extends OxidTestCase
34 | {
35 |
36 | /**
37 | * Subject under the test.
38 | *
39 | * @var oxpsModuleGeneratorSettings
40 | */
41 | protected $SUT;
42 |
43 |
44 | /**
45 | * Set SUT state before test.
46 | */
47 | public function setUp()
48 | {
49 | parent::setUp();
50 |
51 | $this->SUT = $this->getMock('oxpsModuleGeneratorSettings', array('__call'));
52 | }
53 |
54 |
55 | /**
56 | * @dataProvider moduleSettingsDataProvider
57 | */
58 | public function testGetModuleSettings($sCondition, array $aRawSettings, array $aParsedReturn)
59 | {
60 | $this->assertEquals($aParsedReturn, $this->SUT->getModuleSettings($aRawSettings), $sCondition);
61 | }
62 |
63 | public function moduleSettingsDataProvider()
64 | {
65 | return array(
66 |
67 | // Invalid or empty data
68 | array('Empty input', array(), array()),
69 | array('Empty setting name', array(array('name' => '', 'type' => 'str', 'value' => 'TEST')), array()),
70 | array('Invalid setting name', array(array('name' => 'my_setting', 'type' => 'str', 'value' => 'TEST')), array()),
71 | array('Empty setting type', array(array('name' => 'MySetting', 'type' => '', 'value' => 'TEST')), array()),
72 | array('Invalid setting type', array(array('name' => 'MySetting', 'type' => 'obj', 'value' => 'TEST')), array()),
73 | array('Corrupt data structure', array('name' => 'MySetting', 'type' => 'str', 'value' => 'TEST'), array()),
74 |
75 | // Valid data
76 | array(
77 | 'Boolean setting type - empty value',
78 | array(array('name' => 'MySetting', 'type' => 'bool', 'value' => '')),
79 | array((object) array('name' => 'MySetting', 'type' => 'bool', 'value' => "false"))
80 | ),
81 | array(
82 | 'Boolean setting type - "false" value',
83 | array(array('name' => 'MySetting', 'type' => 'bool', 'value' => 'false')),
84 | array((object) array('name' => 'MySetting', 'type' => 'bool', 'value' => "false"))
85 | ),
86 | array(
87 | 'Boolean setting type - "False" value',
88 | array(array('name' => 'MySetting', 'type' => 'bool', 'value' => 'False')),
89 | array((object) array('name' => 'MySetting', 'type' => 'bool', 'value' => "false"))
90 | ),
91 | array(
92 | 'Boolean setting type - "FALSE" value',
93 | array(array('name' => 'MySetting', 'type' => 'bool', 'value' => 'FALSE')),
94 | array((object) array('name' => 'MySetting', 'type' => 'bool', 'value' => "false"))
95 | ),
96 | array(
97 | 'Boolean setting type - true value',
98 | array(array('name' => 'MySetting', 'type' => 'bool', 'value' => 'true')),
99 | array((object) array('name' => 'MySetting', 'type' => 'bool', 'value' => "true"))
100 | ),
101 | array(
102 | 'Boolean setting type - value 1',
103 | array(array('name' => 'MySetting', 'type' => 'bool', 'value' => '1')),
104 | array((object) array('name' => 'MySetting', 'type' => 'bool', 'value' => "true"))
105 | ),
106 | array(
107 | 'Boolean setting type - value true-like',
108 | array(array('name' => 'MySetting', 'type' => 'bool', 'value' => 'TEST')),
109 | array((object) array('name' => 'MySetting', 'type' => 'bool', 'value' => "true"))
110 | ),
111 |
112 | array(
113 | 'String setting type - empty value',
114 | array(array('name' => 'MySetting', 'type' => 'str', 'value' => '')),
115 | array((object) array('name' => 'MySetting', 'type' => 'str', 'value' => "''"))
116 | ),
117 | array(
118 | 'String setting type - string value',
119 | array(array('name' => 'MySetting', 'type' => 'str', 'value' => 'TEST')),
120 | array((object) array('name' => 'MySetting', 'type' => 'str', 'value' => "'TEST'"))
121 | ),
122 | array(
123 | 'String setting type - name with trash',
124 | array(array('name' => ' MySetting2' . PHP_EOL, 'type' => 'str', 'value' => " TEST\t")),
125 | array((object) array('name' => 'MySetting2', 'type' => 'str', 'value' => "' TEST\t'"))
126 | ),
127 |
128 | array(
129 | 'Numeric setting type - empty value',
130 | array(array('name' => 'MySetting', 'type' => 'num', 'value' => '')),
131 | array((object) array('name' => 'MySetting', 'type' => 'num', 'value' => 0.0))
132 | ),
133 | array(
134 | 'Numeric setting type - value is zero',
135 | array(array('name' => 'MySetting', 'type' => 'num', 'value' => '0')),
136 | array((object) array('name' => 'MySetting', 'type' => 'num', 'value' => 0.0))
137 | ),
138 | array(
139 | 'Numeric setting type - value is integer',
140 | array(array('name' => 'MySetting', 'type' => 'num', 'value' => '10')),
141 | array((object) array('name' => 'MySetting', 'type' => 'num', 'value' => 10.0))
142 | ),
143 | array(
144 | 'Numeric setting type - value is float',
145 | array(array('name' => 'MySetting', 'type' => 'num', 'value' => '10.88')),
146 | array((object) array('name' => 'MySetting', 'type' => 'num', 'value' => 10.88))
147 | ),
148 | array(
149 | 'Numeric setting type - value is a number with trash symbols',
150 | array(array('name' => 'MySetting', 'type' => 'num', 'value' => ' 10.88 ')),
151 | array((object) array('name' => 'MySetting', 'type' => 'num', 'value' => 10.88))
152 | ),
153 |
154 | array(
155 | 'Array setting type - empty value',
156 | array(array('name' => 'MySetting', 'type' => 'arr', 'value' => '')),
157 | array((object) array('name' => 'MySetting', 'type' => 'arr', 'value' => "array('')"))
158 | ),
159 | array(
160 | 'Array setting type - one line input',
161 | array(array('name' => 'MySetting', 'type' => 'arr', 'value' => 'item one')),
162 | array((object) array('name' => 'MySetting', 'type' => 'arr', 'value' => "array('item one')"))
163 | ),
164 | array(
165 | 'Array setting type - multi-line input',
166 | array(array('name' => 'MySetting', 'type' => 'arr', 'value' => 'item one' . PHP_EOL . 'item2')),
167 | array((object) array('name' => 'MySetting', 'type' => 'arr', 'value' => "array('item one', 'item2')"))
168 | ),
169 |
170 | array(
171 | 'Assoc array setting type - empty value',
172 | array(array('name' => 'MySetting', 'type' => 'aarr', 'value' => '')),
173 | array((object) array('name' => 'MySetting', 'type' => 'aarr', 'value' => "array()"))
174 | ),
175 | array(
176 | 'Assoc array setting type - invalid input',
177 | array(array('name' => 'MySetting', 'type' => 'aarr', 'value' => 'a' . PHP_EOL . 'b')),
178 | array((object) array('name' => 'MySetting', 'type' => 'aarr', 'value' => "array()"))
179 | ),
180 | array(
181 | 'Assoc array setting type - one line input',
182 | array(array('name' => 'MySetting', 'type' => 'aarr', 'value' => 'a => b')),
183 | array((object) array('name' => 'MySetting', 'type' => 'aarr', 'value' => "array('a' => 'b')"))
184 | ),
185 | array(
186 | 'Assoc array setting type - multi-line input',
187 | array(array('name' => 'MySetting', 'type' => 'aarr', 'value' => 'a => b' . PHP_EOL . '1=>VALUE')),
188 | array((object) array('name' => 'MySetting', 'type' => 'aarr', 'value' => "array('a' => 'b', '1' => 'VALUE')"))
189 | ),
190 |
191 | array(
192 | 'Select setting type - empty value',
193 | array(array('name' => 'MySetting', 'type' => 'select', 'value' => '')),
194 | array((object) array('name' => 'MySetting', 'type' => 'select', 'value' => "''", 'constrains' => "''"))
195 | ),
196 | array(
197 | 'Select setting type - one line input',
198 | array(array('name' => 'MySetting', 'type' => 'select', 'value' => 'VAL_1')),
199 | array((object) array('name' => 'MySetting', 'type' => 'select', 'value' => "'VAL_1'", 'constrains' => "'VAL_1'"))
200 | ),
201 | array(
202 | 'Select setting type - multi-line input',
203 | array(array('name' => 'MySetting', 'type' => 'select', 'value' => 'VAL_1' . PHP_EOL . '2' . PHP_EOL . 'b')),
204 | array((object) array('name' => 'MySetting', 'type' => 'select', 'value' => "'VAL_1'", 'constrains' => "'VAL_1|2|b'"))
205 | ),
206 | );
207 | }
208 | }
209 |
--------------------------------------------------------------------------------
/copy_this/modules/oxps/modulegenerator/tests/unit/core/oxpsModuleGeneratorFileSystemTest.php:
--------------------------------------------------------------------------------
1 | .
19 | *
20 | * @category module
21 | * @package modulegenerator
22 | * @author OXID Professional services
23 | * @link http://www.oxid-esales.com
24 | * @copyright (C) OXID eSales AG 2003-2014
25 | */
26 |
27 | /**
28 | * Class oxpsModuleGeneratorFileSystemTest
29 | * INTEGRATION tests for core class oxpsModuleGeneratorFileSystem.
30 | *
31 | * @see oxpsModuleGeneratorFileSystem
32 | */
33 | class oxpsModuleGeneratorFileSystemTest extends OxidTestCase
34 | {
35 |
36 | /**
37 | * Subject under the test.
38 | *
39 | * @var oxpsModuleGeneratorFileSystem
40 | */
41 | protected $SUT;
42 |
43 |
44 | /**
45 | * Set SUT state before test.
46 | * Create test files and folders.
47 | */
48 | public function setUp()
49 | {
50 | parent::setUp();
51 |
52 | $this->SUT = new oxpsModuleGeneratorFileSystem();
53 |
54 | @mkdir($this->_getTestPath());
55 | @mkdir($this->_getTestPath('folder'));
56 | @file_put_contents($this->_getTestPath('file.txt'), PHP_EOL);
57 | @file_put_contents($this->_getTestPath('folder/file.txt'), PHP_EOL);
58 | }
59 |
60 | /**
61 | * Clean state after test.
62 | * Remove test files and folders.
63 | */
64 | public function tearDown()
65 | {
66 | @shell_exec('rm -rf ' . $this->_getTestPath());
67 |
68 | parent::tearDown();
69 | }
70 |
71 |
72 | public function testIsDir_directoryDoeNotExist_returnFalse()
73 | {
74 | $this->assertFalse($this->SUT->isDir($this->_getTestPath('not_existing_folder')));
75 | }
76 |
77 | public function testIsDir_pathIsFile_returnFalse()
78 | {
79 | $this->assertFalse($this->SUT->isDir($this->_getTestPath('file.txt')));
80 | }
81 |
82 | public function testIsDir_pathIsExistingFolder_returnTrue()
83 | {
84 | $this->assertTrue($this->SUT->isDir($this->_getTestPath('folder')));
85 | }
86 |
87 |
88 | public function testIsFile_fileDoeNotExist_returnFalse()
89 | {
90 | $this->assertFalse($this->SUT->isFile($this->_getTestPath('not_existing_file.txt')));
91 | }
92 |
93 | public function testIsFile_pathIsFolder_returnFalse()
94 | {
95 | $this->assertFalse($this->SUT->isFile($this->_getTestPath('folder')));
96 | }
97 |
98 | public function testIsFile_pathIsExistingFile_returnTrue()
99 | {
100 | $this->assertTrue($this->SUT->isFile($this->_getTestPath('file.txt')));
101 | }
102 |
103 |
104 | public function testCreateFolder_folderExists_notTryToCreateIt()
105 | {
106 | $sPath = $this->_getTestPath('folder');
107 |
108 | $this->assertFileExists($sPath);
109 | $this->SUT->createFolder($sPath);
110 | $this->assertFileExists($sPath);
111 | }
112 |
113 | public function testCreateFolder_folderDoeNotExists_createFolder()
114 | {
115 | $sPath = $this->_getTestPath('new_folder');
116 |
117 | $this->assertFileNotExists($sPath);
118 | $this->SUT->createFolder($sPath);
119 | $this->assertFileExists($sPath);
120 | }
121 |
122 | public function testCreateFolder_pathIsInsideNonExistingFolder_createFoldersRecursively()
123 | {
124 | $sPath = $this->_getTestPath('sub_folder/new_folder');
125 |
126 | $this->assertFileNotExists($sPath);
127 | $this->SUT->createFolder($sPath);
128 | $this->assertFileExists($sPath);
129 | }
130 |
131 |
132 | public function testCreateFile_fileDoesNotExist_createFile()
133 | {
134 | $sPath = $this->_getTestPath('new_file.txt');
135 |
136 | $this->assertFileNotExists($sPath);
137 | $this->SUT->createFile($sPath, 'TEST NEW FILE');
138 | $this->assertFileExists($sPath);
139 | $this->assertStringEqualsFile($sPath, 'TEST NEW FILE');
140 | }
141 |
142 | public function testCreateFile_fileExistsThirdArgumentEmpty_overwriteFile()
143 | {
144 | $sPath = $this->_getTestPath('file.txt');
145 |
146 | $this->assertFileExists($sPath);
147 | $this->assertStringEqualsFile($sPath, PHP_EOL);
148 |
149 | $this->SUT->createFile($sPath, '!TEST FILE - changed');
150 | $this->assertStringEqualsFile($sPath, '!TEST FILE - changed');
151 | }
152 |
153 | public function testCreateFile_fileExistsThirdArgumentTrue_fileRemainUnchanged()
154 | {
155 | $sPath = $this->_getTestPath('file.txt');
156 |
157 | $this->assertFileExists($sPath);
158 | $this->assertStringEqualsFile($sPath, PHP_EOL);
159 |
160 | $this->SUT->createFile($sPath, '!TEST NEW FILE - changed', true);
161 | $this->assertStringEqualsFile($sPath, PHP_EOL);
162 | }
163 |
164 |
165 | public function testRenameFile_fileDoesNotExist_notIssueRename()
166 | {
167 | $sOldPath = $this->_getTestPath('file-one.txt');
168 | $sNewPath = $this->_getTestPath('file-two.txt');
169 |
170 | $this->assertFileNotExists($sOldPath);
171 | $this->assertFileNotExists($sNewPath);
172 |
173 | $this->SUT->renameFile($sOldPath, $sNewPath);
174 |
175 | $this->assertFileNotExists($sOldPath);
176 | $this->assertFileNotExists($sNewPath);
177 | }
178 |
179 | public function testRenameFile_fileExists_renameTheFile()
180 | {
181 | $sOldPath = $this->_getTestPath('file.txt');
182 | $sNewPath = $this->_getTestPath('file-two.txt');
183 |
184 | $this->assertFileExists($sOldPath);
185 | $this->assertFileNotExists($sNewPath);
186 |
187 | $this->SUT->renameFile($sOldPath, $sNewPath);
188 |
189 | $this->assertFileNotExists($sOldPath);
190 | $this->assertFileExists($sNewPath);
191 | }
192 |
193 |
194 | public function testCopyFolder_folderDoesNotExist_returnFalse()
195 | {
196 | $sOldPath = $this->_getTestPath('folder-one');
197 | $sNewPath = $this->_getTestPath('folder-two');
198 |
199 | $this->assertFileNotExists($sOldPath);
200 | $this->assertFileNotExists($sNewPath);
201 |
202 | $this->assertFalse($this->SUT->copyFolder($sOldPath, $sNewPath));
203 |
204 | $this->assertFileNotExists($sOldPath);
205 | $this->assertFileNotExists($sNewPath);
206 | }
207 |
208 | public function testCopyFolder_folderExists_copyContentAndReturnTrue()
209 | {
210 | $sOldPath = $this->_getTestPath('folder');
211 | $sNewPath = $this->_getTestPath('folder-two');
212 |
213 | $this->assertFileExists($sOldPath);
214 | $this->assertFileNotExists($sNewPath);
215 |
216 | $this->assertTrue($this->SUT->copyFolder($sOldPath, $sNewPath));
217 |
218 | $this->assertFileExists($sOldPath);
219 | $this->assertFileExists($sNewPath);
220 | $this->assertFileExists($this->_getTestPath('folder-two/file.txt'));
221 | }
222 |
223 | public function testCopyFolder_folderExistsWithSubFoldersAndFiles_copyAllContentRecursivelyAndReturnTrue()
224 | {
225 | $sOldPath = $this->_getTestPath('folder');
226 | $sNewPath = $this->_getTestPath('folder-two');
227 |
228 | @mkdir($this->_getTestPath('folder/sub-folder'));
229 | @mkdir($this->_getTestPath('folder/sub-folder/sub-sub-folder'));
230 | @file_put_contents($this->_getTestPath('folder/sub-folder/file-one.txt'), '1');
231 | @file_put_contents($this->_getTestPath('folder/sub-folder/file-two.txt'), '2');
232 | @file_put_contents($this->_getTestPath('folder/sub-folder/sub-sub-folder/file-three.txt'), '3');
233 |
234 | $this->assertFileExists($sOldPath);
235 | $this->assertFileNotExists($sNewPath);
236 |
237 | $this->assertTrue($this->SUT->copyFolder($sOldPath, $sNewPath));
238 |
239 | $this->assertFileExists($sOldPath);
240 | $this->assertFileExists($sNewPath);
241 | $this->assertFileExists($this->_getTestPath('folder-two/file.txt'));
242 | $this->assertFileExists($this->_getTestPath('folder-two/sub-folder'));
243 | $this->assertFileExists($this->_getTestPath('folder-two/sub-folder/file-one.txt'));
244 | $this->assertStringEqualsFile($this->_getTestPath('folder-two/sub-folder/file-one.txt'), '1');
245 | $this->assertFileExists($this->_getTestPath('folder-two/sub-folder/file-two.txt'));
246 | $this->assertStringEqualsFile($this->_getTestPath('folder-two/sub-folder/file-two.txt'), '2');
247 | $this->assertFileExists($this->_getTestPath('folder-two/sub-folder/sub-sub-folder'));
248 | $this->assertFileExists($this->_getTestPath('folder-two/sub-folder/sub-sub-folder/file-three.txt'));
249 | $this->assertStringEqualsFile($this->_getTestPath('folder-two/sub-folder/sub-sub-folder/file-three.txt'), '3');
250 | }
251 |
252 |
253 | public function testCopyFile_fileDoesNotExist_notCopyAnything()
254 | {
255 | $sOldPath = $this->_getTestPath('file-one.txt');
256 | $sNewPath = $this->_getTestPath('file-two.txt');
257 |
258 | $this->assertFileNotExists($sOldPath);
259 | $this->assertFileNotExists($sNewPath);
260 |
261 | $this->SUT->copyFile($sOldPath, $sNewPath);
262 |
263 | $this->assertFileNotExists($sOldPath);
264 | $this->assertFileNotExists($sNewPath);
265 | }
266 |
267 | public function testCopyFile_fileExists_copyTheFile()
268 | {
269 | $sOldPath = $this->_getTestPath('file.txt');
270 | $sNewPath = $this->_getTestPath('file-two.txt');
271 |
272 | $this->assertFileExists($sOldPath);
273 | $this->assertFileNotExists($sNewPath);
274 |
275 | $this->SUT->copyFile($sOldPath, $sNewPath);
276 |
277 | $this->assertFileExists($sOldPath);
278 | $this->assertFileExists($sNewPath);
279 | $this->assertStringEqualsFile($sNewPath, PHP_EOL);
280 | }
281 |
282 |
283 | /**
284 | * Get a path inside test folder in temp directory.
285 | *
286 | * @param string $sPathSuffix
287 | *
288 | * @return string
289 | */
290 | protected function _getTestPath($sPathSuffix = '')
291 | {
292 | return oxRegistry::getConfig()->getConfigParam('sCompileDir') . DIRECTORY_SEPARATOR .
293 | 'test' . DIRECTORY_SEPARATOR . (string) $sPathSuffix;
294 | }
295 | }
296 |
--------------------------------------------------------------------------------
/copy_this/modules/oxps/modulegenerator/tests/unit/core/oxpsModuleGeneratorRenderTest.php:
--------------------------------------------------------------------------------
1 | .
19 | *
20 | * @category module
21 | * @package modulegenerator
22 | * @author OXID Professional services
23 | * @link http://www.oxid-esales.com
24 | * @copyright (C) OXID eSales AG 2003-2014
25 | */
26 |
27 | /**
28 | * Class oxpsModuleGeneratorRenderTest
29 | * UNIT tests for core class oxpsModuleGeneratorRender.
30 | *
31 | * @see oxpsModuleGeneratorRender
32 | */
33 | class oxpsModuleGeneratorRenderTest extends OxidTestCase
34 | {
35 |
36 | /**
37 | * Subject under the test.
38 | *
39 | * @var oxpsModuleGeneratorRender
40 | */
41 | protected $SUT;
42 |
43 |
44 | /**
45 | * Set SUT state before test.
46 | */
47 | public function setUp()
48 | {
49 | parent::setUp();
50 |
51 | $this->SUT = $this->getMock('oxpsModuleGeneratorRender', array('__call'));
52 | }
53 |
54 |
55 | public function testInit()
56 | {
57 | // Module instance mock
58 | $oModule = $this->getMock('oxpsModuleGeneratorOxModule', array('__construct', '__call'));
59 |
60 | $this->SUT->init($oModule);
61 |
62 | $this->assertSame($oModule, $this->SUT->getModule());
63 | }
64 |
65 |
66 | public function testGetModule()
67 | {
68 | // Module instance mock
69 | $oModule = $this->getMock('oxpsModuleGeneratorOxModule', array('__construct', '__call'));
70 |
71 | $this->SUT->setModule($oModule);
72 |
73 | $this->assertSame($oModule, $this->SUT->getModule());
74 | }
75 |
76 |
77 | /**
78 | * Test expect the following sequence of...
79 | *
80 | * ----------------------------------------------------------------------------------------------------------
81 | * Rename file name => Template path FS exec Smarty exec
82 | * ----------------------------------------------------------------------------------------------------------
83 | * 'oxpsmymodule_de_lang.php' => 'translations/de/oxpsmodule_lang.php.tpl', 0-1 1-5
84 | * 'oxpsmymodule_en_lang.php' => 'translations/en/oxpsmodule_lang.php.tpl', 2-3 6-10
85 | * 'oxpsmymodulemodule.php' => 'core/oxpsmodule.php.tpl', 4-5 11-15
86 | * 'docs/install.sql', 6 16-20
87 | * 'docs/README.txt', 7 21-25
88 | * 'docs/uninstall.sql', 8 26-30
89 | * 'oxpsmymodule_admin_de_lang.php' => 'views/admin/de/oxpsmodule_lang.php.tpl', 9-10 31-35
90 | * 'oxpsmymodule_admin_en_lang.php' => 'views/admin/en/oxpsmodule_lang.php.tpl', 11-12 36-40
91 | * 'metadata.php' => 'metadata.php.tpl', 13-14 41-45
92 | * 'models/oxpsmymoduleoxarticle.php', 15 46-50
93 | * 'controllers/oxpsmymodulepage.php', 16 51-55
94 | * 'models/oxpsmymoduleitem.php', 17 56-60
95 | * ----------------------------------------------------------------------------------------------------------
96 | */
97 | public function testRenderModuleFiles()
98 | {
99 | // File system helper mock
100 | $oFileSystem = $this->getMock('oxpsModuleGeneratorFileSystem', array('__call', 'createFile', 'renameFile'));
101 |
102 | /* German translation file */
103 | $oFileSystem->expects($this->at(0))->method('createFile')
104 | ->with(
105 | '/path/to/modules/oxps/mymodule/translations/de/oxpsmodule_lang.php.tpl',
106 | '_processed_de_trans_content_'
107 | );
108 | $oFileSystem->expects($this->at(1))->method('renameFile')
109 | ->with(
110 | '/path/to/modules/oxps/mymodule/translations/de/oxpsmodule_lang.php.tpl',
111 | '/path/to/modules/oxps/mymodule/translations/de/oxpsmymodule_de_lang.php'
112 | );
113 |
114 | /* Readme file */
115 | $oFileSystem->expects($this->at(7))->method('createFile')
116 | ->with('/path/to/modules/oxps/mymodule/docs/README.txt', '_processed_readme_content_');
117 |
118 | /* Extended oxArticle model */
119 | $oFileSystem->expects($this->at(15))->method('createFile')
120 | ->with('/path/to/modules/oxps/mymodule/models/oxpsmymoduleoxarticle.php', '_processed_oxarticle_content_');
121 |
122 | /* New "Item" model */
123 | $oFileSystem->expects($this->at(17))->method('createFile')
124 | ->with('/path/to/modules/oxps/mymodule/models/oxpsmymoduleitem.php', '_processed_item_content_');
125 |
126 | oxRegistry::set('oxpsModuleGeneratorFileSystem', $oFileSystem);
127 |
128 | // Module instance mock
129 | $oModule = $this->getMock(
130 | 'oxpsModuleGeneratorOxModule',
131 | array('__construct', '__call', 'getModuleId', 'getFullPath')
132 | );
133 | $oModule->expects($this->once())->method('getModuleId')->will($this->returnValue('oxpsmymodule'));
134 | $oModule->expects($this->once())->method('getFullPath')->will($this->returnValue('/path/to/modules/oxps/mymodule/'));
135 |
136 | // Smarty mock
137 | /* German translation file */
138 | $oSmarty = $this->getMock('Smarty', array('assign', 'fetch', 'clear_assign'));
139 | $oSmarty->expects($this->at(0))->method('assign')->with('oModule', $oModule);
140 |
141 | $oSmarty->expects($this->at(1))->method('assign')->with('sFilePath', 'translations/de/oxpsmodule_lang.php.tpl');
142 | $oSmarty->expects($this->at(2))->method('assign')->with('sClassRealName', '');
143 | $oSmarty->expects($this->at(3))->method('fetch')
144 | ->with('/path/to/modules/oxps/mymodule/translations/de/oxpsmodule_lang.php.tpl')
145 | ->will($this->returnValue('_processed_de_trans_content_'));
146 | $oSmarty->expects($this->at(4))->method('clear_assign')->with('sFilePath');
147 | $oSmarty->expects($this->at(5))->method('clear_assign')->with('sClassRealName');
148 |
149 | /* Readme file */
150 | $oSmarty->expects($this->at(21))->method('assign')->with('sFilePath', 'docs/README.txt');
151 | $oSmarty->expects($this->at(23))->method('fetch')
152 | ->with('/path/to/modules/oxps/mymodule/docs/README.txt')
153 | ->will($this->returnValue('_processed_readme_content_'));
154 |
155 | /* Extended oxArticle model */
156 | $oSmarty->expects($this->at(46))->method('assign')->with('sFilePath', 'models/oxpsmymoduleoxarticle.php');
157 | $oSmarty->expects($this->at(47))->method('assign')->with('sClassRealName', 'oxArticle');
158 | $oSmarty->expects($this->at(48))->method('fetch')
159 | ->with('/path/to/modules/oxps/mymodule/models/oxpsmymoduleoxarticle.php')
160 | ->will($this->returnValue('_processed_oxarticle_content_'));
161 |
162 | /* Extended oxArticle model */
163 | $oSmarty->expects($this->at(56))->method('assign')->with('sFilePath', 'models/oxpsmymoduleitem.php');
164 | $oSmarty->expects($this->at(57))->method('assign')->with('sClassRealName', 'Item');
165 | $oSmarty->expects($this->at(58))->method('fetch')
166 | ->with('/path/to/modules/oxps/mymodule/models/oxpsmymoduleitem.php')
167 | ->will($this->returnValue('_processed_item_content_'));
168 |
169 | // View utils mock
170 | $oViewUtils = $this->getMock('oxUtilsView', array('__call', 'getSmarty'));
171 | $oViewUtils->expects($this->once())->method('getSmarty')->will($this->returnValue($oSmarty));
172 | oxRegistry::set('oxUtilsView', $oViewUtils);
173 |
174 | $this->SUT->init($oModule);
175 |
176 | $this->assertTrue(
177 | $this->SUT->renderModuleFiles(
178 | array('models/oxpsmymoduleoxarticle.php' => 'oxArticle'),
179 | array(
180 | 'controllers/oxpsmymodulepage.php' => 'Page',
181 | 'models/oxpsmymoduleitem.php' => 'Item',
182 | )
183 | )
184 | );
185 | }
186 |
187 |
188 | public function testRenderFileComment_emptyArgument_rendersCommentWithNoSubPackageInfo()
189 | {
190 | // Module instance mock
191 | $oModule = $this->getMock('oxpsModuleGeneratorOxModule', array('__construct', '__call'));
192 |
193 | // Smarty mock
194 | $oSmarty = $this->getMock('Smarty', array('assign', 'fetch'));
195 | $oSmarty->expects($this->at(0))->method('assign')->with('oModule', $oModule);
196 | $oSmarty->expects($this->at(1))->method('fetch')
197 | ->with($this->stringEndsWith('modulegenerator/core/module.tpl/oxpscomment.inc.php.tpl'))
198 | ->will($this->returnValue('_processed_comment_content_'));
199 |
200 | // View utils mock
201 | $oViewUtils = $this->getMock('oxUtilsView', array('__call', 'getSmarty'));
202 | $oViewUtils->expects($this->once())->method('getSmarty')->will($this->returnValue($oSmarty));
203 | oxRegistry::set('oxUtilsView', $oViewUtils);
204 |
205 | $this->SUT->init($oModule);
206 |
207 | $this->assertSame('_processed_comment_content_', $this->SUT->renderFileComment());
208 | }
209 |
210 | public function testRenderFileComment_argumentNotEmpty_rendersCommentWithSubPackageArgumentInfo()
211 | {
212 | // Module instance mock
213 | $oModule = $this->getMock('oxpsModuleGeneratorOxModule', array('__construct', '__call'));
214 |
215 | // Smarty mock
216 | $oSmarty = $this->getMock('Smarty', array('assign', 'fetch'));
217 | $oSmarty->expects($this->at(0))->method('assign')->with('oModule', $oModule);
218 | $oSmarty->expects($this->at(1))->method('assign')->with('sSubPackage', 'mySubModule');
219 | $oSmarty->expects($this->at(2))->method('fetch')
220 | ->with($this->stringEndsWith('modulegenerator/core/module.tpl/oxpscomment.inc.php.tpl'))
221 | ->will($this->returnValue('_processed_comment_content_'));
222 |
223 | // View utils mock
224 | $oViewUtils = $this->getMock('oxUtilsView', array('__call', 'getSmarty'));
225 | $oViewUtils->expects($this->once())->method('getSmarty')->will($this->returnValue($oSmarty));
226 | oxRegistry::set('oxUtilsView', $oViewUtils);
227 |
228 | $this->SUT->init($oModule);
229 |
230 | $this->assertSame('_processed_comment_content_', $this->SUT->renderFileComment('mySubModule'));
231 | }
232 | }
233 |
--------------------------------------------------------------------------------
/copy_this/modules/oxps/modulegenerator/views/admin/admin_oxpsmodulegenerator.tpl:
--------------------------------------------------------------------------------
1 | [{include file="headitem.tpl" title="OXPS_MODULEGENERATOR_ADMIN_TITLE"|oxmultilangassign}]
2 | [{oxstyle include=$oViewConf->getModuleUrl('oxps/modulegenerator', 'out/src/css/admin_oxpsmodulegenerator.css')}]
3 | [{oxstyle}]
4 |
5 |
6 | [{oxmultilang ident="OXPS_MODULEGENERATOR_ADMIN_TITLE"}]
7 |
8 |
10 |
11 |
12 | [{if $sMessage}]
13 |
14 |
15 | - [{oxmultilang ident=$sMessage}]
16 |
17 |
18 | [{/if}]
19 |
20 |
21 |
22 | |
23 |
231 | |
232 |
233 |
234 | |
235 |
236 |
237 |
238 | [{include file="bottomitem.tpl"}]
--------------------------------------------------------------------------------
/copy_this/modules/oxps/modulegenerator/core/oxpsmodulegeneratorhelper.php:
--------------------------------------------------------------------------------
1 | .
19 | *
20 | * @category module
21 | * @package modulegenerator
22 | * @author OXID Professional services
23 | * @link http://www.oxid-esales.com
24 | * @copyright (C) OXID eSales AG 2003-2014
25 | */
26 |
27 | /**
28 | * Class oxpsModuleGeneratorHelper.
29 | * Implement helpers and additional methods for module generation.
30 | */
31 | class oxpsModuleGeneratorHelper extends oxSuperCfg
32 | {
33 |
34 | /**
35 | * A module instance to generate stuff for.
36 | *
37 | * @var oxModule
38 | */
39 | protected $_oModule = null;
40 |
41 | /**
42 | * File system helper instance.
43 | *
44 | * @var null
45 | */
46 | protected $_oFileSystemHelper = null;
47 |
48 |
49 | /**
50 | * Alias for `setModule`.
51 | *
52 | * @param oxModule|oxpsModuleGeneratorOxModule $oModule
53 | */
54 | public function init(oxpsModuleGeneratorOxModule $oModule)
55 | {
56 | $this->setModule($oModule);
57 | }
58 |
59 | /**
60 | * Set module instance to generate stuff for.
61 | *
62 | * @param oxModule|oxpsModuleGeneratorOxModule $oModule
63 | */
64 | public function setModule(oxpsModuleGeneratorOxModule $oModule)
65 | {
66 | $this->_oModule = $oModule;
67 | }
68 |
69 | /**
70 | * Get module instance to generate stuff for.
71 | *
72 | * @return oxModule|oxpsModuleGeneratorOxModule.
73 | */
74 | public function getModule()
75 | {
76 | return $this->_oModule;
77 | }
78 |
79 | /**
80 | * Get file system management helper instance.
81 | *
82 | * @return oxpsModuleGeneratorFileSystem
83 | */
84 | public function getFileSystemHelper()
85 | {
86 | if (is_null($this->_oFileSystemHelper)) {
87 | $this->_oFileSystemHelper = oxRegistry::get('oxpsModuleGeneratorFileSystem');
88 | }
89 |
90 | return $this->_oFileSystemHelper;
91 | }
92 |
93 | /**
94 | * Check if vendor metadata file is present and crates one if it's missing.
95 | *
96 | * @param string $sVendorFolderPath
97 | */
98 | public function createVendorMetadata($sVendorFolderPath)
99 | {
100 | $oFileSystemHelper = $this->getFileSystemHelper();
101 |
102 | $oFileSystemHelper->createFolder($sVendorFolderPath);
103 | $sVendorMetadataPath = $sVendorFolderPath . DIRECTORY_SEPARATOR . 'vendormetadata.php';
104 |
105 | $oFileSystemHelper->createFile(
106 | $sVendorMetadataPath,
107 | 'getFileSystemHelper();
127 | $oModule = $this->getModule();
128 |
129 | $aClassesToExtend = (array) $oModule->getClassesToExtend();
130 | $sModulePath = $oModule->getFullPath();
131 | $sModuleId = $oModule->getModuleId();
132 |
133 | $aExtendedClasses = array();
134 |
135 | if (!$oFileSystemHelper->isFile($sClassExtendTemplatePath) or !$oFileSystemHelper->isDir($sModulePath)) {
136 | return $aExtendedClasses;
137 | }
138 |
139 | foreach ($aClassesToExtend as $sClassName => $mApplicationPath) {
140 | $sInModulePath = $this->_getPathInsideModule($sModulePath, $mApplicationPath);
141 | $sDestinationPath = $sModulePath . $sInModulePath;
142 | $sClassFileName = $sModuleId . oxStr::getStr()->strtolower($sClassName) . '.php';
143 | $sClassFilePath = $sDestinationPath . $sClassFileName;
144 |
145 | $oFileSystemHelper->copyFile($sClassExtendTemplatePath, $sClassFilePath);
146 |
147 | $aExtendedClasses[$sInModulePath . $sClassFileName] = $this->_getCoreClassName($sClassName);
148 | }
149 |
150 | return $aExtendedClasses;
151 | }
152 |
153 | /**
154 | * Collect information of new classes to create, copy new classes from corresponding templates,
155 | * create templates for controllers and widgets.
156 | *
157 | * @param string $sModuleGeneratorPath
158 | *
159 | * @return array
160 | */
161 | public function createNewClassesAndTemplates($sModuleGeneratorPath)
162 | {
163 | /** @var oxpsModuleGeneratorValidator $oValidator */
164 | $oValidator = oxRegistry::get('oxpsModuleGeneratorValidator');
165 |
166 | $aClassesToCreate = (array) $this->getModule()->getClassesToCreate();
167 | $aCreatedClasses = array();
168 |
169 | foreach ($aClassesToCreate as $sObjectType => $aClassesData) {
170 | $aClassesData = (array) $aClassesData;
171 | $aClasses = (array) $oValidator->getArrayValue($aClassesData, 'aClasses', 'array');
172 | $sClassTemplate = $oValidator->getArrayValue($aClassesData, 'sTemplateName');
173 | $sClassPath = $oValidator->getArrayValue($aClassesData, 'sInModulePath');
174 | $sTemplatePath = $oValidator->getArrayValue($aClassesData, 'sTemplatesPath');
175 |
176 | if (empty($aClasses)) {
177 | continue;
178 | }
179 |
180 | $aNewFiles = $this->_createNewClasses($aClasses, $sClassTemplate, $sClassPath, $sModuleGeneratorPath);
181 | $this->_createNewTemplates($sObjectType, $aNewFiles, $sTemplatePath);
182 |
183 | $aCreatedClasses = array_merge($aCreatedClasses, $aNewFiles);
184 | }
185 |
186 | return $aCreatedClasses;
187 | }
188 |
189 | /**
190 | * Create module blocks templates.
191 | *
192 | * @param string $sModulePath
193 | */
194 | public function createBlock($sModulePath)
195 | {
196 | $aBlock = $this->getModule()->getBlocks();
197 |
198 | if (!empty($aBlock)) {
199 | $this->_createTemplates(array_keys($aBlock), sprintf('%sviews/blocks/', $sModulePath), true);
200 | }
201 | }
202 |
203 | /**
204 | * Clone and copy tests folder into generated module,
205 | * create pre-configured unit test class for each generated module class.
206 | *
207 | * @param oxpsModuleGeneratorRender $oRenderHelper
208 | * @param string $sModuleGeneratorPath
209 | * @param string $sModulePath
210 | * @param array $aClassesToExtend
211 | * @param array $aNewClasses
212 | */
213 | public function fillTestsFolder(oxpsModuleGeneratorRender $oRenderHelper, $sModuleGeneratorPath, $sModulePath,
214 | array $aClassesToExtend, array $aNewClasses)
215 | {
216 | if ($this->_cloneUnitTests($sModulePath)) {
217 | $aAllFiles = array_merge($aClassesToExtend, $aNewClasses);
218 | $sTemplate = sprintf('%score/module.tpl/oxpstestclass.php.tpl', $sModuleGeneratorPath);
219 | $aNewFiles = (array) $this->_copyNewClasses($aAllFiles, $sTemplate, 'tests/unit/modules/', true);
220 |
221 | if (!empty($aNewFiles)) {
222 | $oRenderHelper->renderWithSmartyAndRename(array_keys($aNewFiles), $aNewFiles);
223 | }
224 | }
225 | }
226 |
227 | /**
228 | * Check if provided path inside a module exists, if not choose "core" folder as internal path.
229 | *
230 | * @param string $sModulePath
231 | * @param string $mInnerPath
232 | *
233 | * @return string
234 | */
235 | protected function _getPathInsideModule($sModulePath, $mInnerPath)
236 | {
237 | if (!empty($mInnerPath) and $this->getFileSystemHelper()->isDir($sModulePath . $mInnerPath)) {
238 | $sPathInsideModule = $mInnerPath;
239 | } else {
240 | $sPathInsideModule = 'core/';
241 | }
242 |
243 | return $sPathInsideModule;
244 | }
245 |
246 | /**
247 | * Check if class template file and path are valid and create new classes using the provided class template and path.
248 | *
249 | * @param array $aClasses
250 | * @param string $sClassTemplate
251 | * @param string $sClassPath
252 | * @param string $sModuleGeneratorPath
253 | *
254 | * @return array
255 | */
256 | protected function _createNewClasses(array $aClasses, $sClassTemplate, $sClassPath, $sModuleGeneratorPath)
257 | {
258 | $aNewFiles = array();
259 |
260 | if (!empty($sClassTemplate) and !empty($sClassPath)) {
261 | $sTemplatePath = sprintf('%score/module.tpl/%s', $sModuleGeneratorPath, $sClassTemplate);
262 | $aNewFiles = $this->_copyNewClasses($aClasses, $sTemplatePath, $sClassPath);
263 | }
264 |
265 | return $aNewFiles;
266 | }
267 |
268 | /**
269 | * Check if class type requires a template to be created,
270 | * check template path and the classes and then create new templates.
271 | *
272 | * @param string $sObjectType
273 | * @param array $aNewFiles
274 | * @param string $sTemplatePath
275 | */
276 | protected function _createNewTemplates($sObjectType, array $aNewFiles, $sTemplatePath)
277 | {
278 | if (in_array($sObjectType, array('controllers', 'widgets')) and
279 | !empty($aNewFiles) and !empty($sTemplatePath)
280 | ) {
281 | $sTemplateDestination = sprintf('%sviews/%s/', $this->getModule()->getFullPath(), $sTemplatePath);
282 | $this->_createTemplates($aNewFiles, $sTemplateDestination);
283 | }
284 | }
285 |
286 | /**
287 | * Get format string for newly generated templates demo content.
288 | *
289 | * @param bool $blBlocks If True, renders block template content, if False - controller/widget template content.
290 | *
291 | * @return string
292 | */
293 | protected function _getTemplateContentFormat($blBlocks = false)
294 | {
295 | if (empty($blBlocks)) {
296 | $sDemoContent = 'A Blank %s Template
' . PHP_EOL .
297 | 'This is a template located in %s belonging to class %s
';
298 | } else {
299 | $sDemoContent = 'A Blank Block Template
' . PHP_EOL .
300 | 'This is a template for block %s located in %s
' . PHP_EOL .
301 | '[{$smarty.block.parent}]';
302 | }
303 |
304 | return $sDemoContent;
305 | }
306 |
307 | /**
308 | * Create new classes using a template and provided class names by copying this template to the provided path.
309 | *
310 | * @param array $aClasses Class names array.
311 | * @param string $sTemplatePath Template file full path.
312 | * @param string $sInModulePath Module inner path to copy to.
313 | * @param bool $blTestClasses If True, treat as test classes.
314 | *
315 | * @return array
316 | */
317 | protected function _copyNewClasses(array $aClasses, $sTemplatePath, $sInModulePath, $blTestClasses = false)
318 | {
319 | $oFileSystemHelper = $this->getFileSystemHelper();
320 | $aCopiedClasses = array();
321 |
322 | if (!$oFileSystemHelper->isFile($sTemplatePath) or
323 | !$oFileSystemHelper->isDir($this->getModule()->getFullPath() . $sInModulePath)
324 | ) {
325 | return $aCopiedClasses;
326 | }
327 |
328 | foreach ($aClasses as $mKey => $sClass) {
329 | list($sClassFilePath, $sProcessedFileKey) = $this->_getNewClassPathAndKey(
330 | $mKey, $sClass, $sInModulePath, $blTestClasses
331 | );
332 | $oFileSystemHelper->copyFile($sTemplatePath, $sClassFilePath);
333 |
334 | $aCopiedClasses[$sProcessedFileKey] = $sClass;
335 | }
336 |
337 | return $aCopiedClasses;
338 | }
339 |
340 | /**
341 | * Compile full path to a new class and a key value to use for created classes array.
342 | * It depends on whatever it is a Unit test class or general PHP class.
343 | *
344 | * @param int|string $mKey
345 | * @param string $sClass
346 | * @param string $sInModulePath
347 | * @param bool $blTestClasses
348 | *
349 | * @return array
350 | */
351 | protected function _getNewClassPathAndKey($mKey, $sClass, $sInModulePath, $blTestClasses = false)
352 | {
353 | $oModule = $this->getModule();
354 |
355 | $sModuleId = $oModule->getModuleId();
356 | $sModulePath = $oModule->getFullPath();
357 |
358 | if (empty($blTestClasses)) {
359 | $sClassFileName = sprintf('%s%s.php', $sModuleId, oxStr::getStr()->strtolower($sClass));
360 | $sClassFilePath = $sModulePath . $sInModulePath . $sClassFileName;
361 | $sProcessedFileKey = $sInModulePath . $sClassFileName;
362 | } else {
363 | $sClassFileName = sprintf('%s%sTest.php', $sModuleId, oxStr::getStr()->strtolower($sClass));
364 | $sClassDirPath = $sModulePath . $sInModulePath . dirname($mKey) . DIRECTORY_SEPARATOR;
365 | $this->getFileSystemHelper()->createFolder($sClassDirPath);
366 | $sClassFilePath = $sClassDirPath . $sClassFileName;
367 | $sProcessedFileKey = $sInModulePath . dirname($mKey) . DIRECTORY_SEPARATOR . $sClassFileName;
368 | }
369 |
370 | return array($sClassFilePath, $sProcessedFileKey);
371 | }
372 |
373 | /**
374 | * Create template files for a given classes in provided location.
375 | *
376 | * @param array $aClasses Class names array to create templates for.
377 | * @param string $sDestinationPath A full path to folder to create templates in.
378 | * @param bool $blBlocks If true block templates are generated.
379 | *
380 | * @return bool
381 | */
382 | protected function _createTemplates(array $aClasses, $sDestinationPath, $blBlocks = false)
383 | {
384 | $oFileSystemHelper = $this->getFileSystemHelper();
385 |
386 | if (!$oFileSystemHelper->isDir($sDestinationPath)) {
387 | return false;
388 | }
389 |
390 | $oModule = $this->getModule();
391 |
392 | $sModuleId = $oModule->getModuleId();
393 | $sClassPrefix = $oModule->getModuleClassName();
394 |
395 | $sDemoContentFormat = $this->_getTemplateContentFormat($blBlocks);
396 |
397 | foreach ($aClasses as $sClass) {
398 | $sTemplateFileName = sprintf('%s%s.tpl', $sModuleId, oxStr::getStr()->strtolower($sClass));
399 | $sTemplateFilePath = $sDestinationPath . $sTemplateFileName;
400 | $sTemplateContent = sprintf($sDemoContentFormat, $sClass, $sTemplateFilePath, $sClassPrefix . $sClass);
401 |
402 | $oFileSystemHelper->createFile($sTemplateFilePath, $sTemplateContent);
403 | }
404 |
405 | return true;
406 | }
407 |
408 | /**
409 | * Get real class name of existing core class (for class that are being extended).
410 | *
411 | * @param string $sClassName
412 | *
413 | * @return string
414 | */
415 | protected function _getCoreClassName($sClassName)
416 | {
417 | if (!class_exists($sClassName)) {
418 | return $sClassName;
419 | }
420 |
421 | $oReflection = new ReflectionClass(new $sClassName());
422 |
423 | return $oReflection->getName();
424 | }
425 |
426 | /**
427 | * Clone tests library (Generic Test Folder) to temp location,
428 | * then copy tests library into the module and do a cleanup.
429 | *
430 | * @param string $sModulePath Full path to a module.
431 | *
432 | * @return bool
433 | */
434 | protected function _cloneUnitTests($sModulePath)
435 | {
436 | /** @var oxpsModuleGeneratorModule $oModule */
437 | $oModule = oxRegistry::get('oxpsModuleGeneratorModule');
438 | $sGitUrl = (string) $oModule->getSetting('TestsGitUrl');
439 |
440 | if (empty($sGitUrl)) {
441 | return false;
442 | }
443 |
444 | $sTmpDir = sys_get_temp_dir() . '/tests' . date('YmdHis') . mt_rand(10000, 99999) . '/';
445 | $aCommands = array(
446 | sprintf('git clone %s %s', $sGitUrl, $sTmpDir),
447 | sprintf('cp -R %stests/* %stests/', $sTmpDir, $sModulePath),
448 | sprintf('chmod 0777 -R %stests', $sModulePath),
449 | sprintf('dos2unix %stests/*.sh', $sModulePath),
450 | sprintf('rm -rf %s', $sTmpDir),
451 | );
452 |
453 | foreach ($aCommands as $sCommand) {
454 | $this->_shellExec($sCommand);
455 | }
456 |
457 | return $this->getFileSystemHelper()->isDir($sModulePath . 'tests/unit/');
458 | }
459 |
460 | /**
461 | * An alias for PHP function `shell_exec`.
462 | * Errors are suspended.
463 | *
464 | * @codeCoverageIgnore
465 | *
466 | * @param string $sCommand
467 | */
468 | protected function _shellExec($sCommand)
469 | {
470 | @shell_exec((string) $sCommand);
471 | }
472 | }
473 |
--------------------------------------------------------------------------------
/copy_this/modules/oxps/modulegenerator/core/oxpsmodulegeneratoroxmodule.php:
--------------------------------------------------------------------------------
1 | .
19 | *
20 | * @category module
21 | * @package modulegenerator
22 | * @author OXID Professional services
23 | * @link http://www.oxid-esales.com
24 | * @copyright (C) OXID eSales AG 2003-2014
25 | */
26 |
27 | /**
28 | * Class oxpsModuleGeneratorOxModule overloads oxModule
29 | * Extends oxModule class to add extra fields and tools for modules generation.
30 | * The class becomes a container for all information required to generate module.
31 | * NOTE: This class is very long, but it cannot be split since consists mostly of getters and setters.
32 | *
33 | * @see oxModule
34 | */
35 | class oxpsModuleGeneratorOxModule extends oxpsModuleGeneratorOxModule_parent
36 | {
37 |
38 | /**
39 | * Vendor directory name and module vendor prefix.
40 | *
41 | * @var string
42 | */
43 | protected $_sVendorPrefix = '';
44 |
45 | /**
46 | * Module author/vendor data: name, link, mail, copyright and file comment.
47 | *
48 | * @var array
49 | */
50 | protected $_aAuthorData = array();
51 |
52 | /**
53 | * Validator helper instance.
54 | *
55 | * @var null|oxpsModuleGeneratorValidator
56 | */
57 | protected $_oValidator = null;
58 |
59 |
60 | /**
61 | * Set module vendor prefix. It is also a vendor directory name.
62 | *
63 | * @param string $sVendorPrefix
64 | *
65 | * @return string
66 | */
67 | public function setVendorPrefix($sVendorPrefix)
68 | {
69 | $this->_sVendorPrefix = $sVendorPrefix;
70 | }
71 |
72 | /**
73 | * Get module vendor prefix. It is also vendor directory name.
74 | *
75 | * @param bool $blUppercase
76 | *
77 | * @return string
78 | */
79 | public function getVendorPrefix($blUppercase = false)
80 | {
81 | if (!empty($blUppercase)) {
82 | return oxStr::getStr()->strtoupper($this->_sVendorPrefix);
83 | }
84 |
85 | return $this->_sVendorPrefix;
86 | }
87 |
88 | /**
89 | * Set module author/vendor data. It is used in metadata, README file and PHP files comments.
90 | *
91 | * @param array $aAuthorData
92 | */
93 | public function setAuthorData(array $aAuthorData)
94 | {
95 | $this->_aAuthorData = $aAuthorData;
96 | }
97 |
98 | /**
99 | * Get module author/vendor data. It is used in metadata, README file and PHP files comments.
100 | *
101 | * @param string $mField
102 | *
103 | * @return array|string
104 | */
105 | public function getAuthorData($mField = null)
106 | {
107 | if (!is_null($mField)) {
108 | return $this->getArrayValue($this->_aAuthorData, $mField);
109 | }
110 |
111 | return $this->_aAuthorData;
112 | }
113 |
114 | /**
115 | * Get validation and data access helper instance.
116 | *
117 | * @return oxpsModuleGeneratorValidator
118 | */
119 | public function getValidator()
120 | {
121 | if (is_null($this->_oValidator)) {
122 | $this->_oValidator = oxRegistry::get('oxpsModuleGeneratorValidator');
123 | }
124 |
125 | return $this->_oValidator;
126 | }
127 |
128 | /**
129 | * Get module ID.
130 | *
131 | * @param bool $blCamelCase If True - returns CamelCase ID interpretation (module classes prefix),
132 | * if False - a lowercase value.
133 | *
134 | * @return string|null
135 | */
136 | public function getModuleId($blCamelCase = false)
137 | {
138 | /** @var oxpsModuleGeneratorOxModule|oxModule $this */
139 |
140 | return empty($blCamelCase) ? $this->getId() : $this->getInfo('oxpsmodulegenerator_class');
141 | }
142 |
143 | /**
144 | * Get module folder name.
145 | *
146 | * @param boolean $blUppercase If True - returns uppercase name, if False - lowercase.
147 | *
148 | * @return string|null
149 | */
150 | public function getModuleFolderName($blUppercase = false)
151 | {
152 | /** @var oxpsModuleGeneratorOxModule|oxModule $this */
153 |
154 | $sFolderName = $this->getInfo('oxpsmodulegenerator_folder');
155 |
156 | if ($blUppercase and !is_null($sFolderName)) {
157 | $sFolderName = oxStr::getStr()->strtoupper($sFolderName);
158 | }
159 |
160 | return $sFolderName;
161 | }
162 |
163 | /**
164 | * Get module main class name. An alias for getModuleId method with True argument.
165 | *
166 | * @return string|boolean
167 | */
168 | public function getModuleClassName()
169 | {
170 | return $this->getModuleId(true);
171 | }
172 |
173 | /**
174 | * Get a list of classes to overload (extend).
175 | *
176 | * @return array
177 | */
178 | public function getClassesToExtend()
179 | {
180 | /** @var oxpsModuleGeneratorOxModule|oxModule $this */
181 |
182 | return (array) $this->getInfo('oxpsmodulegenerator_extend_classes');
183 | }
184 |
185 | /**
186 | * Get a list of new classes to create.
187 | * Each entry comes as array with:
188 | * `aClasses` - An array of classes names.
189 | * `sTemplateName` - A template to use for new classes creation.
190 | * `sInModulePath` - A path inside a module to place files in.
191 | * `sTemplatesPath` - A folder to keep related class template in.
192 | *
193 | * @param null|string $sObjectType Objects type to return, e.g. 'models'. Returns all if null.
194 | * @param null|string $sObjectsParam Objects param to return, e.g. 'aClasses'. Returns all if null.
195 | *
196 | * @return array|string
197 | */
198 | public function getClassesToCreate($sObjectType = null, $sObjectsParam = null)
199 | {
200 | /** @var oxpsModuleGeneratorOxModule|oxModule $this */
201 |
202 | $mData = array(
203 | 'widgets' => array(
204 | 'aClasses' => (array) $this->getInfo('oxpsmodulegenerator_widgets'),
205 | 'sTemplateName' => 'oxpswidgetclass.php.tpl',
206 | 'sInModulePath' => 'components/widgets/',
207 | 'sTemplatesPath' => 'widgets',
208 | ),
209 | 'controllers' => array(
210 | 'aClasses' => (array) $this->getInfo('oxpsmodulegenerator_controllers'),
211 | 'sTemplateName' => 'oxpscontrollerclass.php.tpl',
212 | 'sInModulePath' => 'controllers/',
213 | 'sTemplatesPath' => 'pages',
214 | ),
215 | 'models' => array(
216 | 'aClasses' => (array) $this->getInfo('oxpsmodulegenerator_models'),
217 | 'sTemplateName' => 'oxpsmodelclass.php.tpl',
218 | 'sInModulePath' => 'models/',
219 | ),
220 | 'list_models' => array(
221 | 'aClasses' => (array) $this->getInfo('oxpsmodulegenerator_list_models'),
222 | 'sTemplateName' => 'oxpslistmodelclass.php.tpl',
223 | 'sInModulePath' => 'models/',
224 | ),
225 | );
226 |
227 | if (!is_null($sObjectType)) {
228 |
229 | // Get only one type of classes
230 | $mData = (array) $this->getArrayValue($mData, $sObjectType, 'array');
231 |
232 | if (!is_null($sObjectsParam)) {
233 |
234 | // Get only one param of one class type
235 | $sType = ($sObjectsParam == 'aClasses') ? 'array' : 'string';
236 | $mData = $this->getArrayValue($mData, $sObjectsParam, $sType);
237 | }
238 | }
239 |
240 | return $mData;
241 | }
242 |
243 | /**
244 | * Get module blocks array.
245 | *
246 | * @return array
247 | */
248 | public function getBlocks()
249 | {
250 | /** @var oxpsModuleGeneratorOxModule|oxModule $this */
251 |
252 | return (array) $this->getInfo('oxpsmodulegenerator_blocks');
253 | }
254 |
255 | /**
256 | * Get module settings array.
257 | *
258 | * @return array
259 | */
260 | public function getSettings()
261 | {
262 | /** @var oxpsModuleGeneratorOxModule|oxModule $this */
263 |
264 | return (array) $this->getInfo('oxpsmodulegenerator_module_settings');
265 | }
266 |
267 | /**
268 | * Parser setting type "select" options.
269 | *
270 | * @param string $sOptions
271 | *
272 | * @return array
273 | */
274 | public function getSelectSettingOptions($sOptions)
275 | {
276 | return (array) explode('|', str_replace("'", "", trim($sOptions)));
277 | }
278 |
279 | /**
280 | * Get module version.
281 | *
282 | * @return string
283 | */
284 | public function getInitialVersion()
285 | {
286 | /** @var oxpsModuleGeneratorOxModule|oxModule $this */
287 |
288 | return (string) $this->getInfo('oxpsmodulegenerator_module_init_version');
289 | }
290 |
291 | /**
292 | * Should the generator render "To Do" hints and tasks, e.g. hints how to use metadata samples, etc.
293 | *
294 | * @return bool
295 | */
296 | public function renderTasks()
297 | {
298 | /** @var oxpsModuleGeneratorOxModule|oxModule $this */
299 |
300 | return (bool) $this->getInfo('oxpsmodulegenerator_render_tasks');
301 | }
302 |
303 | /**
304 | * Should the generator render sample data and example code, e.g. sample metadata lines, etc.
305 | *
306 | * @return bool
307 | */
308 | public function renderSamples()
309 | {
310 | /** @var oxpsModuleGeneratorOxModule|oxModule $this */
311 |
312 | return (bool) $this->getInfo('oxpsmodulegenerator_render_samples');
313 | }
314 |
315 | /**
316 | * Get a full path of vendor directory.
317 | *
318 | * @return string
319 | */
320 | public function getVendorPath()
321 | {
322 | /** @var oxpsModuleGeneratorOxModule|oxModule $this */
323 |
324 | return $this->getConfig()->getModulesDir() . $this->getVendorPrefix() . '/';
325 | }
326 |
327 | /**
328 | * Get a full path to the module directory.
329 | *
330 | * @return string
331 | */
332 | public function getFullPath()
333 | {
334 | return $this->getVendorPath() . $this->getModuleFolderName() . '/';
335 | }
336 |
337 |
338 | /**
339 | * Generate a module.
340 | * Creates blank pre-configure module skeleton in a vendor folder.
341 | *
342 | * @todo (nice2have): move to generation helper class.
343 | *
344 | * @param string $sModuleName CamelCase module name to use as a base for new module naming.
345 | * @param array $aGenerationOptions Additional module generation options:
346 | * `aExtendClasses` - A list of classes to overload (extend).
347 | * `aNewControllers` - A list of controllers to create.
348 | * `aNewModels` - A list of models (item models) to create.
349 | * `aNewLists` - Repeat some or all of item models to create list models.
350 | * `aNewWidgets` - A list of widgets to create.
351 | * `aNewBlocks` - A list of blocks data to create.
352 | * `aModuleSettings` - Data for module settings to create.
353 | * `sInitialVersion` - Initial version value for a new module.
354 | * `blFetchUnitTests` - Whatever to clone PHPUnit tests from GIT or not.
355 | * `blRenderTasks` - Option to render "To Do" tasks comments.
356 | * `blRenderSamples` - Option to render sample data comments.
357 | *
358 | * @return bool
359 | */
360 | public function generateModule($sModuleName, array $aGenerationOptions = array())
361 | {
362 | // Initialize helpers
363 | /** @var oxpsModuleGeneratorHelper $oHelper */
364 | $oHelper = oxRegistry::get('oxpsModuleGeneratorHelper');
365 | $oHelper->init($this);
366 |
367 | /** @var oxpsModuleGeneratorRender $oRenderHelper */
368 | $oRenderHelper = oxRegistry::get('oxpsModuleGeneratorRender');
369 | $oRenderHelper->init($this);
370 |
371 | // Set module data - initializes it with new module info
372 | $this->_setNewModuleData($sModuleName, $aGenerationOptions);
373 |
374 | // Get new module and module generation template full paths
375 | $sModuleGeneratorPath = oxRegistry::get('oxpsModuleGeneratorModule')->getPath();
376 | $sModulePath = $this->getFullPath();
377 |
378 | // Copy the module from a folder structure with templates to a new module path
379 | $oHelper->createVendorMetadata($this->getVendorPath());
380 | $oHelper->getFileSystemHelper()->copyFolder($sModuleGeneratorPath . 'core/module.tpl/module/', $sModulePath);
381 |
382 | // Create classes to overload (extend)
383 | $aClassesToExtend = (array) $oHelper->createClassesToExtend(
384 | $sModuleGeneratorPath . 'core/module.tpl/oxpsextendclass.php.tpl'
385 | );
386 |
387 | // Create new module classes and templates
388 | $aNewClasses = (array) $oHelper->createNewClassesAndTemplates($sModuleGeneratorPath);
389 |
390 | // Create blocks templates
391 | $oHelper->createBlock($sModulePath);
392 |
393 | // Process copied module files as Smarty templates to fill them with the real module data
394 | $oRenderHelper->renderModuleFiles($aClassesToExtend, $aNewClasses);
395 |
396 | // Clone PHP Unit tests libraries if the option is checked and configured
397 | if ($this->getArrayValue($aGenerationOptions, 'blFetchUnitTests')) {
398 | $oHelper->fillTestsFolder($oRenderHelper, $sModuleGeneratorPath, $sModulePath, $aClassesToExtend, $aNewClasses);
399 | }
400 |
401 | return true;
402 | }
403 |
404 |
405 | /**
406 | * Validate new module name: should be "UpperCamelCase" and not yet exist in the configured vendor directory.
407 | *
408 | * @param string $sModuleName
409 | *
410 | * @return boolean
411 | */
412 | public function validateModuleName($sModuleName)
413 | {
414 | return ($this->getValidator()->validateCamelCaseName($sModuleName) and !$this->_moduleExists($sModuleName));
415 | }
416 |
417 | /**
418 | * Get suffix of module file name by its path.
419 | * Expects argument to be something like "path/to/[vendor_prefix][module_name][desired_suffix].php"
420 | *
421 | * @param string $sPath
422 | *
423 | * @return string
424 | */
425 | public function getFileNameSuffix($sPath)
426 | {
427 | $sSuffix = '';
428 | $sFileName = basename($sPath);
429 |
430 | if (!empty($sFileName)) {
431 | $aFileName = explode('.', $sFileName);
432 |
433 | if (!empty($aFileName[0])) {
434 | $sSuffix = str_replace($this->getModuleId(), '', $aFileName[0]);
435 | }
436 | }
437 |
438 | return $sSuffix;
439 | }
440 |
441 | /**
442 | * Render file comment using a template and author/vendor data.
443 | *
444 | * @param string $sSubPackage Optional subpackage title.
445 | *
446 | * @return mixed
447 | */
448 | public function renderFileComment($sSubPackage = '')
449 | {
450 | /** @var oxpsModuleGeneratorRender $oRenderHelper */
451 | $oRenderHelper = oxRegistry::get('oxpsModuleGeneratorRender');
452 | $oRenderHelper->init($this);
453 |
454 | return $oRenderHelper->renderFileComment($sSubPackage);
455 | }
456 |
457 | /**
458 | * An alias for validator class method.
459 | * Converts camel case string to human readable string with spaces between words.
460 | * Treats UPPERCASE abbreviations and numbers as separate words.
461 | *
462 | * @param string $sCamelCaseString
463 | *
464 | * @return string
465 | */
466 | public function camelCaseToHumanReadable($sCamelCaseString)
467 | {
468 | return $this->getValidator()->camelCaseToHumanReadable($sCamelCaseString);
469 | }
470 |
471 | /**
472 | * An alias for validator class method.
473 | * Get array value by key, optionally casting its type to desired one.
474 | *
475 | * @param array $aDataArray
476 | * @param mixed $mArrayKey
477 | * @param string $sType
478 | *
479 | * @return bool
480 | */
481 | public function getArrayValue(array $aDataArray, $mArrayKey, $sType = 'string')
482 | {
483 | return $this->getValidator()->getArrayValue($aDataArray, $mArrayKey, $sType);
484 | }
485 |
486 |
487 | /**
488 | * Compile additional module params and set all module data.
489 | *
490 | * @param string $sModuleName Module name in CamelCase style.
491 | * @param array $aOptions Additional module generation options.
492 | */
493 | protected function _setNewModuleData($sModuleName, array $aOptions = array())
494 | {
495 | /** @var oxpsModuleGeneratorOxModule|oxModule $this */
496 | /** @var oxpsModuleGeneratorSettings $oSettingsParser */
497 | $oSettingsParser = oxRegistry::get('oxpsModuleGeneratorSettings');
498 | $oStr = oxStr::getStr();
499 | $sVendorPrefix = $this->getVendorPrefix();
500 | $sVarPrefix = $oStr->strtoupper($sVendorPrefix);
501 | $sModuleFolder = $oStr->strtolower($sModuleName);
502 | $sModuleClass = $sVendorPrefix . $sModuleName;
503 | $sModuleId = $oStr->strtolower($sModuleClass);
504 | $sReadableName = $this->camelCaseToHumanReadable($sModuleName);
505 | $aModuleData = array(
506 | // Default parent class params
507 | 'id' => $sModuleId,
508 | 'title' => $sVarPrefix . ' ' . $sReadableName,
509 | 'description' => $sVarPrefix . ' ' . $sReadableName . ' Module',
510 |
511 | // Additional params for new module generation
512 | 'oxpsmodulegenerator_name' => $sModuleName,
513 | 'oxpsmodulegenerator_folder' => $sModuleFolder,
514 | 'oxpsmodulegenerator_class' => $sModuleClass,
515 | 'oxpsmodulegenerator_extend_classes' => $this->getArrayValue($aOptions, 'aExtendClasses', 'array'),
516 | 'oxpsmodulegenerator_controllers' => $this->getArrayValue($aOptions, 'aNewControllers', 'array'),
517 | 'oxpsmodulegenerator_models' => $this->getArrayValue($aOptions, 'aNewModels', 'array'),
518 | 'oxpsmodulegenerator_list_models' => $this->getArrayValue($aOptions, 'aNewLists', 'array'),
519 | 'oxpsmodulegenerator_widgets' => $this->getArrayValue($aOptions, 'aNewWidgets', 'array'),
520 | 'oxpsmodulegenerator_blocks' => $this->getArrayValue($aOptions, 'aNewBlocks', 'array'),
521 | 'oxpsmodulegenerator_module_settings' => $oSettingsParser->getModuleSettings(
522 | (array) $this->getArrayValue($aOptions, 'aModuleSettings', 'array')
523 | ),
524 | 'oxpsmodulegenerator_module_init_version' => $this->getArrayValue($aOptions, 'sInitialVersion'),
525 | 'oxpsmodulegenerator_render_tasks' => $this->getArrayValue($aOptions, 'blRenderTasks', 'bool'),
526 | 'oxpsmodulegenerator_render_samples' => $this->getArrayValue($aOptions, 'blRenderSamples', 'bool'),
527 | );
528 |
529 | $this->setModuleData($aModuleData);
530 | }
531 |
532 | /**
533 | * Check if module with provided name exists in the configured vendor directory.
534 | *
535 | * @param string $sModuleName
536 | *
537 | * @return boolean
538 | */
539 | protected function _moduleExists($sModuleName)
540 | {
541 | /** @var oxpsModuleGeneratorFileSystem $oFileSystemHelper */
542 | $oFileSystemHelper = oxRegistry::get('oxpsModuleGeneratorFileSystem');
543 |
544 | return $oFileSystemHelper->isDir($this->getVendorPath() . oxStr::getStr()->strtolower($sModuleName));
545 | }
546 | }
547 |
--------------------------------------------------------------------------------
/copy_this/modules/oxps/modulegenerator/controllers/admin/admin_oxpsmodulegenerator.php:
--------------------------------------------------------------------------------
1 | .
19 | *
20 | * @category module
21 | * @package modulegenerator
22 | * @author OXID Professional services
23 | * @link http://www.oxid-esales.com
24 | * @copyright (C) OXID eSales AG 2003-2014
25 | */
26 |
27 | /**
28 | * Class Admin_oxpsModuleGenerator.
29 | * Module Generator GUI controller.
30 | *
31 | * @todo (nice2have) Class got too long -> move some methods to validation helper or some other class.
32 | */
33 | class Admin_oxpsModuleGenerator extends oxAdminView
34 | {
35 |
36 | /**
37 | * Current class template name.
38 | *
39 | * @var string
40 | */
41 | protected $_sThisTemplate = 'admin_oxpsmodulegenerator.tpl';
42 |
43 | /**
44 | * Module instance used as information container for new module generation.
45 | *
46 | * @var oxpsModuleGeneratorOxModule
47 | */
48 | protected $_oModule;
49 |
50 |
51 | /**
52 | * Overridden parent method.
53 | * Initializes internal variables for module instance.
54 | */
55 | public function init()
56 | {
57 | /** @var oxpsModuleGeneratorOxModule $oModule */
58 | $oModule = oxNew('oxpsModuleGeneratorOxModule');
59 | $oModule->setVendorPrefix($this->getVendorPrefix());
60 | $oModule->setAuthorData($this->getAuthorData());
61 |
62 | $this->_oModule = $oModule;
63 |
64 | // Parent call
65 | $this->_Admin_oxpsModuleGenerator_init_parent();
66 | }
67 |
68 | /**
69 | * Overridden parent method.
70 | * Adds module instance to view data.
71 | *
72 | * @return string
73 | */
74 | public function render()
75 | {
76 | // Assign additional view data
77 | $this->_addViewData(array('oModule' => $this->getModule()));
78 |
79 | // Set an error if vendor/author data is not configured in the module settings
80 | if (!$this->_isVendorConfigured()) {
81 | $this->_setMessage('OXPS_MODULEGENERATOR_ADMIN_MODULE_ERROR_NO_VENDOR');
82 | }
83 |
84 | // Add clean module generation options and form values to view data
85 | $this->_addViewData(array('oValues' => (object) $this->_getFormValues()));
86 |
87 | // Parent render call
88 | return $this->_Admin_oxpsModuleGenerator_render_parent();
89 | }
90 |
91 |
92 | /**
93 | * Get module instance.
94 | *
95 | * @return oxpsModuleGeneratorOxModule
96 | */
97 | public function getModule()
98 | {
99 | return $this->_oModule;
100 | }
101 |
102 | /**
103 | * Get vendor prefix stored in settings.
104 | *
105 | * @return string
106 | */
107 | public function getVendorPrefix()
108 | {
109 | return (string) oxRegistry::get('oxpsModuleGeneratorModule')->getSetting('VendorPrefix');
110 | }
111 |
112 | /**
113 | * Get module author/vendor data from settings: name, link, mail, copyright and file comment.
114 | *
115 | * @return array
116 | */
117 | public function getAuthorData()
118 | {
119 | /** @var oxpsModuleGeneratorModule $oModuleGeneratorModule */
120 | $oModuleGeneratorModule = oxRegistry::get('oxpsModuleGeneratorModule');
121 |
122 | return array(
123 | 'name' => (string) $oModuleGeneratorModule->getSetting('ModuleAuthor'),
124 | 'link' => (string) $oModuleGeneratorModule->getSetting('AuthorLink'),
125 | 'mail' => (string) $oModuleGeneratorModule->getSetting('AuthorMail'),
126 | 'copy' => (string) $oModuleGeneratorModule->getSetting('Copyright'),
127 | 'info' => ' ' . trim(implode(PHP_EOL . ' ', (array) $oModuleGeneratorModule->getSetting('Comment'))),
128 | );
129 | }
130 |
131 | /**
132 | * Module generation action.
133 | * Collects, cleans and validates form data, calls generation, sets messages.
134 | */
135 | public function generateModule()
136 | {
137 | // Get module name from request
138 | $sModuleName = $this->_getTextParam('modulegenerator_module_name');
139 |
140 | // Get module generation options
141 | $aGenerationOptions = $this->_getGenerationOptions();
142 |
143 | /** @var oxpsModuleGeneratorValidator $oValidator */
144 | $oValidator = oxRegistry::get('oxpsModuleGeneratorValidator');
145 |
146 | if (!$oValidator->validateVendorPrefix($this->getVendorPrefix())) {
147 |
148 | // Set an error if configured module vendor prefix is not valid
149 | $this->_setMessage('OXPS_MODULEGENERATOR_ADMIN_MODULE_ERROR_INVALID_VENDOR');
150 | } elseif (!$this->getModule()->validateModuleName($sModuleName)) {
151 |
152 | // Set an error if module name is not valid
153 | $this->_setMessage('OXPS_MODULEGENERATOR_ADMIN_MODULE_ERROR_INVALID_NAME');
154 | } elseif ($this->getModule()->generateModule($sModuleName, $aGenerationOptions)
155 | ) {
156 |
157 | // Set success massage
158 | $this->_setMessage('OXPS_MODULEGENERATOR_ADMIN_MODULE_MSG_GENERATION_SUCCESS', false);
159 | }
160 | }
161 |
162 |
163 | /**
164 | * Check if vendor/author data is configured in the module settings.
165 | *
166 | * @return bool
167 | */
168 | protected function _isVendorConfigured()
169 | {
170 | $sVendorPrefix = $this->getVendorPrefix();
171 |
172 | return !empty($sVendorPrefix);
173 | }
174 |
175 | /**
176 | * Add additional array to the view data.
177 | *
178 | * @param array $aViewData Assoc array of parameters to add to view data.
179 | */
180 | protected function _addViewData($aViewData)
181 | {
182 | if (!empty($aViewData) and is_array($aViewData)) {
183 | $this->setViewData(array_merge($this->getViewData(), $aViewData));
184 | }
185 | }
186 |
187 | /**
188 | * Collect request data, parse it and compile to module generation options array.
189 | *
190 | * @return array
191 | */
192 | protected function _getGenerationOptions()
193 | {
194 | $oConfig = $this->getConfig();
195 |
196 | $aGenerationOptions = array(
197 | 'aExtendClasses' => $this->_validateAndLinkClasses($this->_getTextParam('modulegenerator_extend_classes')),
198 | 'aNewControllers' => $this->_parseMultiLineInput($this->_getTextParam('modulegenerator_controllers')),
199 | 'aNewModels' => $this->_parseMultiLineInput($this->_getTextParam('modulegenerator_models')),
200 | 'aNewLists' => $this->_parseMultiLineInput($this->_getTextParam('modulegenerator_lists')),
201 | 'aNewWidgets' => $this->_parseMultiLineInput($this->_getTextParam('modulegenerator_widgets')),
202 | 'aNewBlocks' => $this->_parseBlocksData(
203 | $this->_getTextParam('modulegenerator_blocks'),
204 | $this->getVendorPrefix(),
205 | $this->_getTextParam('modulegenerator_module_name')
206 | ),
207 | 'aModuleSettings' => (array) $oConfig->getRequestParameter('modulegenerator_settings'),
208 | 'sInitialVersion' => (string) $oConfig->getRequestParameter('modulegenerator_init_version'),
209 | 'blFetchUnitTests' => (bool) $oConfig->getRequestParameter('modulegenerator_fetch_unit_tests'),
210 | 'blRenderTasks' => (bool) $oConfig->getRequestParameter('modulegenerator_render_tasks'),
211 | 'blRenderSamples' => (bool) $oConfig->getRequestParameter('modulegenerator_render_samples'),
212 | );
213 |
214 | return $this->_filterListModels($aGenerationOptions);
215 | }
216 |
217 | /**
218 | * Get initial form values for a case when the form was submitted.
219 | *
220 | * @return array
221 | */
222 | protected function _getFormValues()
223 | {
224 | /** @var oxpsModuleGeneratorValidator $oValidator */
225 | $oValidator = oxRegistry::get('oxpsModuleGeneratorValidator');
226 |
227 | $aOptions = (array) $this->_getGenerationOptions();
228 |
229 | return array(
230 | 'name' => $this->_getTextParam('modulegenerator_module_name'),
231 | 'extend' => $this->_toString(array_keys($oValidator->getArrayValue($aOptions, 'aExtendClasses', 'array'))),
232 | 'controllers' => $this->_toString($oValidator->getArrayValue($aOptions, 'aNewControllers', 'array')),
233 | 'models' => $this->_toString($oValidator->getArrayValue($aOptions, 'aNewModels', 'array')),
234 | 'lists' => $this->_getListModelsFieldValue($oValidator->getArrayValue($aOptions, 'aNewLists', 'array')),
235 | 'widgets' => $this->_toString($oValidator->getArrayValue($aOptions, 'aNewWidgets', 'array')),
236 | 'blocks' => $this->_getBlocksFieldValue($oValidator->getArrayValue($aOptions, 'aNewBlocks', 'array')),
237 | 'settings' => $oValidator->getArrayValue($aOptions, 'aModuleSettings', 'array'),
238 | 'version' => $this->_getFormVersionFieldValue($oValidator->getArrayValue($aOptions, 'sInitialVersion')),
239 | 'tests' => $oValidator->getArrayValue($aOptions, 'blFetchUnitTests', 'boolean'),
240 | 'tasks' => $oValidator->getArrayValue($aOptions, 'blRenderTasks', 'boolean'),
241 | 'samples' => $oValidator->getArrayValue($aOptions, 'blRenderSamples', 'boolean'),
242 | );
243 | }
244 |
245 | /**
246 | * Convert array to a multi-line string.
247 | *
248 | * @param array $aData
249 | *
250 | * @return string
251 | */
252 | protected function _toString(array $aData)
253 | {
254 | return trim((string) implode(PHP_EOL, $aData));
255 | }
256 |
257 | /**
258 | * Get initial value for list models field.
259 | * Removes "List" suffixes from names.
260 | *
261 | * @param array $aRequestListModels
262 | *
263 | * @return string
264 | */
265 | protected function _getListModelsFieldValue(array $aRequestListModels)
266 | {
267 | /** @var oxStrMb|oxStrRegular $oStr */
268 | $oStr = oxStr::getStr();
269 |
270 | $aLists = array();
271 |
272 | foreach ($aRequestListModels as $sListClassName) {
273 | $aLists[] = $oStr->substr($sListClassName, 0, ($oStr->strlen($sListClassName) - 4));
274 | }
275 |
276 | return $this->_toString($aLists);
277 | }
278 |
279 | /**
280 | * Get initial value for module blocks field.
281 | *
282 | * @param array $aRequestBlocks
283 | *
284 | * @return string
285 | */
286 | protected function _getBlocksFieldValue(array $aRequestBlocks)
287 | {
288 | /** @var oxpsModuleGeneratorValidator $oValidator */
289 | $oValidator = oxRegistry::get('oxpsModuleGeneratorValidator');
290 |
291 | $aBlocks = array();
292 |
293 | foreach ($aRequestBlocks as $oBlock) {
294 | $aBlock = (array) $oBlock;
295 | $aBlocks[] = $oValidator->getArrayValue($aBlock, 'block') . '@' .
296 | $oValidator->getArrayValue($aBlock, 'template');
297 | }
298 |
299 | return $this->_toString($aBlocks);
300 | }
301 |
302 | /**
303 | * Get initial value for module version field.
304 | *
305 | * @param string $sRequestVersion
306 | *
307 | * @return string
308 | */
309 | protected function _getFormVersionFieldValue($sRequestVersion)
310 | {
311 | $sModuleVersion = trim((string) $sRequestVersion);
312 |
313 | if (empty($sModuleVersion)) {
314 | $sModuleVersion = '1.0.0';
315 | }
316 |
317 | return $sModuleVersion;
318 | }
319 |
320 | /**
321 | * Get request parameter as trimmed string.
322 | *
323 | * @param string $sKey
324 | *
325 | * @return string
326 | */
327 | protected function _getTextParam($sKey)
328 | {
329 | return trim((string) oxRegistry::getConfig()->getRequestParameter($sKey));
330 | }
331 |
332 | /**
333 | * Set a message to view data.
334 | * Uses key `sMessage` for the message.
335 | * Sets key `blError` True if it is an error, False for a success/info message.
336 | *
337 | * @param string $sMessage
338 | * @param bool $blError
339 | */
340 | protected function _setMessage($sMessage, $blError = true)
341 | {
342 | $this->_addViewData(array('sMessage' => (string) $sMessage, 'blError' => !empty($blError)));
343 | }
344 |
345 | /**
346 | * Check list of classes and link it with its relative path for each valid class.
347 | *
348 | * @param string $sClasses List of classes names separated with a new line.
349 | *
350 | * @return array With relative application path as value and clean class name as key for each valid class.
351 | */
352 | protected function _validateAndLinkClasses($sClasses)
353 | {
354 | /** @var oxpsModuleGeneratorFileSystem $oFileSystemHelper */
355 | $oFileSystemHelper = oxRegistry::get('oxpsModuleGeneratorFileSystem');
356 | $aClasses = $this->_parseMultiLineInput($sClasses, 'not_empty');
357 | $aValidLinkedClasses = array();
358 | $oConfig = $this->getConfig();
359 | $sBasePath = $oConfig->getConfigParam('sShopDir');
360 |
361 | foreach ($aClasses as $sClassName) {
362 | if (!class_exists($sClassName)) {
363 | continue;
364 | }
365 |
366 | // Build reflection object to get path to a class
367 | $oReflection = new ReflectionClass(new $sClassName());
368 | $sClassPath = (string) $oReflection->getFilename();
369 |
370 | if ($oFileSystemHelper->isFile($sClassPath)) {
371 | $sClassName = oxStr::getStr()->strtolower($sClassName);
372 | $sNoAppPath = str_replace('application' . DIRECTORY_SEPARATOR, '', dirname($sClassPath));
373 | $sClassPath = str_replace($sBasePath, '', $sNoAppPath) . DIRECTORY_SEPARATOR;
374 |
375 | $aValidLinkedClasses[$sClassName] = $sClassPath;
376 | }
377 | }
378 |
379 | return $aValidLinkedClasses;
380 | }
381 |
382 | /**
383 | * Parse new blocks multi-line data to valid metadata blocks definition.
384 | * Each valid element will have a template, block and file keys.
385 | *
386 | * @todo (nice2have): When using block name as blocks list key, block becomes unique in a module.
387 | * Maybe it should not be unique, i.e. module could extend same block many times, or not?
388 | *
389 | * @param string $sBlocks
390 | * @param string $sVendorPrefix
391 | * @param string $sModuleName
392 | *
393 | * @return array
394 | */
395 | protected function _parseBlocksData($sBlocks, $sVendorPrefix, $sModuleName)
396 | {
397 | $sModuleId = oxStr::getStr()->strtolower(sprintf('%s%s', $sVendorPrefix, $sModuleName));
398 | $aBlocks = $this->_parseMultiLineInput($sBlocks, 'not_empty');
399 | $aValidBlocks = array();
400 |
401 | foreach ($aBlocks as $sBlockDefinition) {
402 | $aBlock = $this->_parseBlockDefinition($sBlockDefinition, $sModuleId);
403 |
404 | if (isset($aBlock['template'], $aBlock['block'], $aBlock['file'])) {
405 | $aValidBlocks[sprintf('_%s', $aBlock['block'])] = (object) $aBlock;
406 | }
407 | }
408 |
409 | return $aValidBlocks;
410 | }
411 |
412 | /**
413 | * Parse block definition from string to metadata block entry array.
414 | *
415 | * @todo (nice2have): Validate block name [a-z{1}a-z_{1,}] and check if template exists in active theme?
416 | *
417 | * @param string $sBlockDefinition String in format "[block_name]@[path/to/existing/template.tpl]"
418 | * @param string $sModuleId
419 | *
420 | * @return array
421 | */
422 | protected function _parseBlockDefinition($sBlockDefinition, $sModuleId)
423 | {
424 | /** @var oxpsModuleGeneratorValidator $oValidator */
425 | $oValidator = oxRegistry::get('oxpsModuleGeneratorValidator');
426 |
427 | $sBlockDefinition = trim((string) $sBlockDefinition);
428 | $aBlockDefinition = !empty($sBlockDefinition) ? explode("@", $sBlockDefinition) : array();
429 |
430 | $sBlockName = $oValidator->getArrayValue($aBlockDefinition, 0);
431 | $sTemplatePath = $oValidator->getArrayValue($aBlockDefinition, 1);
432 |
433 | if (empty($sBlockName) or empty($sTemplatePath)) {
434 | return array();
435 | }
436 |
437 | return array(
438 | 'template' => $sTemplatePath,
439 | 'block' => $sBlockName,
440 | 'file' => sprintf('views/blocks/%s_%s.tpl', $sModuleId, $sBlockName),
441 | );
442 | }
443 |
444 | /**
445 | * Parse multi-line string input as array and validate each line.
446 | * Line validation is one of following:
447 | * `not_empty` - there must be something in the line
448 | * `camel_case` - a value must be in "UpperCamelCase" format
449 | *
450 | * @todo (nice2have): Check class names among all types to be unique
451 | *
452 | * @param string $sInput
453 | * @param string $sLineValidation A validation rule name.
454 | *
455 | * @return array
456 | */
457 | protected function _parseMultiLineInput($sInput, $sLineValidation = 'camel_case')
458 | {
459 | $aInput = (array) explode(PHP_EOL, (string) $sInput);
460 | $aValidInput = array();
461 |
462 | foreach ($aInput as $sLine) {
463 | $sLine = trim((string) $sLine);
464 |
465 | if ($this->_isLineInputValid($sLine, $sLineValidation) and !in_array($sLine, $aValidInput)) {
466 | $aValidInput[] = $sLine;
467 | }
468 | }
469 |
470 | return $aValidInput;
471 | }
472 |
473 | /**
474 | * Check if a value passes specified validation rule.
475 | *
476 | * @param string $sValue
477 | * @param string $sValidationRule
478 | *
479 | * @return bool
480 | */
481 | protected function _isLineInputValid($sValue, $sValidationRule)
482 | {
483 | $blIsValid = false;
484 |
485 | switch ($sValidationRule) {
486 | case 'not_empty';
487 | $blIsValid = !empty($sValue);
488 | break;
489 |
490 | case 'camel_case':
491 | /** @var oxpsModuleGeneratorValidator $oValidator */
492 | $oValidator = oxRegistry::get('oxpsModuleGeneratorValidator');
493 | $blIsValid = (bool) $oValidator->validateCamelCaseName($sValue);
494 | break;
495 | }
496 |
497 | return $blIsValid;
498 | }
499 |
500 | /**
501 | * Filter generation options to check if list models were set and if those list models match item models.
502 | * List model is added only if item model with same name was also set.
503 | * Adds "List" prefix for each valid list model.
504 | *
505 | * @param array $aData
506 | *
507 | * @return array
508 | */
509 | protected function _filterListModels(array $aData)
510 | {
511 | /** @var oxpsModuleGeneratorValidator $oValidator */
512 | $oValidator = oxRegistry::get('oxpsModuleGeneratorValidator');
513 |
514 | $aLists = (array) $oValidator->getArrayValue($aData, 'aNewLists', 'array');
515 | $aModels = (array) $oValidator->getArrayValue($aData, 'aNewModels', 'array');
516 |
517 | foreach ($aLists as $mKey => $sNewListClass) {
518 | if (!in_array($sNewListClass, $aModels)) {
519 | unset($aLists[$mKey]);
520 | } else {
521 | $aLists[$mKey] = sprintf('%sList', $sNewListClass);
522 | }
523 | }
524 |
525 | $aData['aNewLists'] = $aLists;
526 |
527 | return $aData;
528 | }
529 |
530 |
531 | /**
532 | * Parent `init` call. Method required for mocking.
533 | *
534 | * @codeCoverageIgnore
535 | *
536 | * @return null
537 | */
538 | protected function _Admin_oxpsModuleGenerator_init_parent()
539 | {
540 | return parent::init();
541 | }
542 |
543 | /**
544 | * Parent `render` call. Method required for mocking.
545 | *
546 | * @codeCoverageIgnore
547 | *
548 | * @return null
549 | */
550 | protected function _Admin_oxpsModuleGenerator_render_parent()
551 | {
552 | return parent::render();
553 | }
554 | }
555 |
--------------------------------------------------------------------------------