├── .github
└── workflows
│ └── php.yml
├── .gitignore
├── .readthedocs.yml
├── .travis.yml
├── README.md
├── build-library.bash
├── build.sh
├── build.xml
├── composer.json
├── composer.lock
├── docs
├── .gitignore
├── dev-internals-build.md
├── dev-internals-enviornment.md
├── dev-internals-introduction.md
├── dev-internals-pestle-import.md
├── extra.css
├── index.md
├── magento2-composer.md
├── magento2-database.md
├── magento2-di-observers.md
├── magento2-generate-acl.md
├── magento2-generate-full-module.md
├── magento2-generate-ui.md
├── magento2-introduction.md
├── magento2-module-setup.md
├── magento2-mvc.md
├── magento2-other-introduction.md
├── magento2-other-other.md
├── magento2-others.md
├── magento2-quick-conversions.md
├── magento2-scans-and-reports.md
├── pestle-generate.md
├── pestle-io.md
└── pestle-third-party.md
├── gen-event-list.sh
├── library
├── all.php
└── autoload.php
├── license.txt
├── mkdocs.yml
├── modules
└── pulsestorm
│ ├── alanstormdotcom
│ └── rsync
│ │ └── module.php
│ ├── cli
│ ├── ascii_table
│ │ └── module.php
│ ├── build_command_list
│ │ └── module.php
│ ├── code_generation
│ │ └── module.php
│ ├── format_php
│ │ └── module.php
│ ├── md_to_say
│ │ └── module.php
│ ├── monty_hall_problem
│ │ └── module.php
│ ├── self_update
│ │ └── module.php
│ └── token_parse
│ │ └── module.php
│ ├── faker
│ └── names
│ │ └── module.php
│ ├── financial
│ └── parse_citicard
│ │ └── module.php
│ ├── generate
│ └── pestle
│ │ └── command
│ │ └── module.php
│ ├── gs
│ └── combine
│ │ └── module.php
│ ├── magento1
│ └── convert
│ │ ├── generatemaps
│ │ └── module.php
│ │ ├── magentoinc
│ │ └── module.php
│ │ └── unirgy
│ │ └── module.php
│ ├── magento2
│ ├── cli
│ │ ├── base_directory
│ │ │ └── module.php
│ │ ├── baz_bar
│ │ │ ├── Baz_Bar
│ │ │ └── module.php
│ │ ├── check_acl
│ │ │ └── module.php
│ │ ├── check_class_and_namespace
│ │ │ └── module.php
│ │ ├── check_htaccess
│ │ │ └── module.php
│ │ ├── check_registration
│ │ │ └── module.php
│ │ ├── check_templates
│ │ │ └── module.php
│ │ ├── class_from_path
│ │ │ └── module.php
│ │ ├── class_list
│ │ │ └── module.php
│ │ ├── convert_class
│ │ │ └── module.php
│ │ ├── convert_observers_xml
│ │ │ └── module.php
│ │ ├── convert_selenium_id_for_codecept
│ │ │ └── module.php
│ │ ├── convert_system_xml
│ │ │ └── module.php
│ │ ├── dev_import
│ │ │ └── module.php
│ │ ├── dev_namespace
│ │ │ └── module.php
│ │ ├── export_module
│ │ │ └── module.php
│ │ ├── extract_mage2_system_xml_paths
│ │ │ └── module.php
│ │ ├── extract_session
│ │ │ └── module.php
│ │ ├── fix_direct_om
│ │ │ └── module.php
│ │ ├── fix_permissions_modphp
│ │ │ └── module.php
│ │ ├── foo_bar
│ │ │ └── module.php
│ │ ├── format_xml_string
│ │ │ └── module.php
│ │ ├── generate
│ │ │ ├── acl
│ │ │ │ └── module.php
│ │ │ ├── command
│ │ │ │ └── module.php
│ │ │ ├── config_helper
│ │ │ │ └── module.php
│ │ │ ├── crud
│ │ │ │ └── model
│ │ │ │ │ └── module.php
│ │ │ ├── di
│ │ │ │ └── module.php
│ │ │ ├── install
│ │ │ │ └── module.php
│ │ │ ├── layout_xml
│ │ │ │ └── module.php
│ │ │ ├── mage2_command
│ │ │ │ └── module.php
│ │ │ ├── menu
│ │ │ │ └── module.php
│ │ │ ├── module
│ │ │ │ └── module.php
│ │ │ ├── observer
│ │ │ │ └── module.php
│ │ │ ├── plugin_xml
│ │ │ │ └── module.php
│ │ │ ├── psr_log_level
│ │ │ │ └── module.php
│ │ │ ├── registration
│ │ │ │ └── module.php
│ │ │ ├── route
│ │ │ │ └── module.php
│ │ │ ├── theme
│ │ │ │ └── module.php
│ │ │ └── view
│ │ │ │ └── module.php
│ │ ├── hello_argument
│ │ │ └── module.php
│ │ ├── hello_world
│ │ │ └── module.php
│ │ ├── help
│ │ │ └── module.php
│ │ ├── library
│ │ │ └── module.php
│ │ ├── list_commands
│ │ │ └── module.php
│ │ ├── magento2
│ │ │ └── generate
│ │ │ │ ├── acl
│ │ │ │ ├── change_title
│ │ │ │ │ └── module.php
│ │ │ │ └── module.php
│ │ │ │ ├── command
│ │ │ │ └── module.php
│ │ │ │ ├── config_helper
│ │ │ │ └── module.php
│ │ │ │ ├── controller_edit_acl
│ │ │ │ └── module.php
│ │ │ │ ├── crud_model
│ │ │ │ └── module.php
│ │ │ │ ├── di
│ │ │ │ └── module.php
│ │ │ │ ├── full_module
│ │ │ │ └── module.php
│ │ │ │ ├── install
│ │ │ │ └── module.php
│ │ │ │ ├── menu
│ │ │ │ └── module.php
│ │ │ │ ├── module
│ │ │ │ └── module.php
│ │ │ │ ├── observer
│ │ │ │ └── module.php
│ │ │ │ ├── plugin_xml
│ │ │ │ └── module.php
│ │ │ │ ├── preference
│ │ │ │ └── module.php
│ │ │ │ ├── psr_log_level
│ │ │ │ └── module.php
│ │ │ │ ├── registration
│ │ │ │ └── module.php
│ │ │ │ ├── route
│ │ │ │ └── module.php
│ │ │ │ ├── theme
│ │ │ │ └── module.php
│ │ │ │ ├── ui
│ │ │ │ ├── add-column-actions
│ │ │ │ │ └── module.php
│ │ │ │ ├── add-column-sections
│ │ │ │ │ └── module.php
│ │ │ │ ├── add_to_layout
│ │ │ │ │ └── module.php
│ │ │ │ ├── form
│ │ │ │ │ └── module.php
│ │ │ │ └── grid
│ │ │ │ │ └── module.php
│ │ │ │ └── view
│ │ │ │ └── module.php
│ │ ├── orphan_content
│ │ │ └── module.php
│ │ ├── pandoc_md
│ │ │ └── module.php
│ │ ├── path_from_class
│ │ │ └── module.php
│ │ ├── pestle_clear_cache
│ │ │ └── module.php
│ │ ├── read_rest_schema
│ │ │ └── module.php
│ │ ├── search_controllers
│ │ │ └── module.php
│ │ ├── test_namespace_integrity
│ │ │ └── module.php
│ │ ├── test_output
│ │ │ └── module.php
│ │ ├── testbed
│ │ │ └── module.php
│ │ └── xml_template
│ │ │ └── module.php
│ ├── codemigration
│ │ └── rename
│ │ │ └── module.php
│ └── generate
│ │ ├── classchild
│ │ └── module.php
│ │ ├── registerpackage
│ │ └── module.php
│ │ ├── remove_named_node
│ │ └── module.php
│ │ ├── schemaaddcolumn
│ │ └── module.php
│ │ ├── schemaupgrade
│ │ └── module.php
│ │ ├── servicecontract
│ │ └── module.php
│ │ └── ui
│ │ ├── addcolumntext
│ │ └── module.php
│ │ ├── addformfield
│ │ └── module.php
│ │ ├── addformfieldset
│ │ └── module.php
│ │ └── addschemacolumn
│ │ └── module.php
│ ├── mysql
│ └── keycheck
│ │ └── module.php
│ ├── nexmo
│ ├── sendtext
│ │ └── module.php
│ ├── storecredentials
│ │ └── module.php
│ ├── verifyrequest
│ │ └── module.php
│ └── verifysendcode
│ │ └── module.php
│ ├── nofrills
│ └── build_book
│ │ └── module.php
│ ├── paypal
│ └── csv_to_iif
│ │ └── module.php
│ ├── pestle
│ ├── clear_cache
│ │ └── module.php
│ ├── config
│ │ └── module.php
│ ├── exportassymfony
│ │ └── module.php
│ ├── importer
│ │ └── module.php
│ ├── library
│ │ └── module.php
│ ├── run_file
│ │ └── module.php
│ ├── runner
│ │ └── module.php
│ └── version
│ │ └── module.php
│ ├── phpdotnet
│ └── module.php
│ ├── postscript
│ └── check
│ │ └── module.php
│ ├── solonoble
│ └── module.php
│ └── xml_library
│ └── module.php
├── pestle-autocomplete.sh
├── pestle_dev
├── phar-stub.php
├── phar.readonly.ini
├── runner.php
├── tests-integration
├── GenerateModuleTest.php
├── GenerateRouteTest.php
├── HelloWorldTest.php
└── PestleTestIntegration.php
├── tests
├── AdminClassNameTest.php
├── AppCodeRefactorTest.php
├── ArgumentParsingTest.php
├── ClassParsingTest.php
├── CommandExistsTest.php
├── ComposerPackageTest.php
├── ConfigTest.php
├── DoubleImportTest.php
├── FirstTest.php
├── FunctionNameParsingTest.php
├── GenerateInstallSchemaTest.php
├── GenerateMage2CommandTest.php
├── GenerateRouteTest.php
├── GenerateWithColonTest.php
├── LibraryTest.php
├── NamespaceRefactoringTest.php
├── PestleBaseTest.php
├── PhpCollideTest.php
├── PostAppCodeRefactorTest.php
├── RunnerTestHarnessTest.php
├── SimpleXmlAddNodesXpathTest.php
├── WindowsTest.php
└── fixtures
│ ├── AdminClassName
│ ├── BaseAdminArgs.php
│ └── BaseFrontendArgs.php
│ └── FunctionNameParsing
│ ├── Application.php
│ ├── Command.php
│ ├── ConfirmableTrait.php
│ ├── DetectsApplicationNamespace.php
│ ├── GeneratorCommand.php
│ ├── OutputStyle.php
│ └── Parser.php
└── travis
├── for-lint.sh
└── travis-ci-apache
/.github/workflows/php.yml:
--------------------------------------------------------------------------------
1 | name: PHP Composer
2 |
3 | on:
4 | push:
5 | branches: [ master ]
6 | pull_request:
7 | branches: [ master ]
8 |
9 | jobs:
10 | build:
11 |
12 | runs-on: ubuntu-latest
13 |
14 | steps:
15 | - uses: actions/checkout@v2
16 | - uses: shivammathur/setup-php@master
17 | with:
18 | php-version: '7.4'
19 |
20 | - name: Validate composer.json and composer.lock
21 | run: composer validate
22 |
23 | - name: Cache Composer packages
24 | id: composer-cache
25 | uses: actions/cache@v2
26 | with:
27 | path: vendor
28 | key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }}
29 | restore-keys: |
30 | ${{ runner.os }}-php-
31 |
32 | - name: Install dependencies
33 | if: steps.composer-cache.outputs.cache-hit != 'true'
34 | run: composer install --prefer-dist --no-progress --no-suggest
35 |
36 | # Add a test script to composer.json, for instance: "test": "vendor/bin/phpunit"
37 | # Docs: https://getcomposer.org/doc/articles/scripts.md
38 |
39 | - name: Run test suite
40 | run: vendor/bin/phpunit tests
41 |
42 | - name: Run PHP version
43 | run: php --version
44 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | vendor/
2 | .DS_Store
3 | build/
4 | pestle.phar
5 | build2.sh
6 | test.php
7 | .idea
8 | .vscode
9 | modules/pulsestorm/parsing
10 | tags
11 | site/
12 |
--------------------------------------------------------------------------------
/.readthedocs.yml:
--------------------------------------------------------------------------------
1 | # .readthedocs.yml
2 | # Read the Docs configuration file
3 | # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
4 |
5 | # Required
6 | version: 2
7 |
8 | # Build documentation in the docs/ directory with Sphinx
9 | #sphinx:
10 | # configuration: docs/conf.py
11 |
12 | # Build documentation with MkDocs
13 | mkdocs:
14 | configuration: mkdocs.yml
15 |
--------------------------------------------------------------------------------
/build-library.bash:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | VER_FROM_TAG=`git tag | tail -n 1 | xargs echo 'pestle Ver'`
3 | VER_FROM_PESTLE=`pestle_dev version`
4 |
5 | #if [ "$VER_FROM_TAG" != "$VER_FROM_PESTLE" ]
6 | #then
7 | # echo "pestle version and latest tag do not match, bailing"
8 | # exit
9 | #fi
10 |
11 | echo " library/all.php
12 | find modules/ -name module.php | xargs pestle_dev pestle:export_module >> library/all.php
--------------------------------------------------------------------------------
/build.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | VER_FROM_TAG=`git tag | tail -n 1 | xargs echo 'pestle Ver'`
4 | VER_FROM_PESTLE=`php pestle_dev version`
5 |
6 | if [ "$VER_FROM_TAG" != "$VER_FROM_PESTLE" ]
7 | then
8 | echo "pestle version and latest tag do not match, bailing"
9 | exit
10 | fi
11 |
12 | php -d phar.readonly=0 vendor/bin/phing package_phar
13 | chmod +x pestle.phar
14 | #mv pestle.phar ~/bin/pestle.phar
15 |
--------------------------------------------------------------------------------
/build.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "pulsestorm/pestle",
3 | "description":"A CLI framework for module based PHP code. Also has numerous Magento 2 code generation commands. ",
4 | "require": {
5 | "michelf/php-markdown": "1.6.0",
6 | "ext-xml": "*",
7 | "abraham/twitteroauth": "0.7.2",
8 | "fzaninotto/faker": "^1.6.0",
9 | "nexmo/client":"@beta",
10 | "pear/numbers_words":"0.18.1"
11 | },
12 |
13 | "require-dev": {
14 | "phpunit/phpunit": "^6.5",
15 | "phing/phing": "2.*",
16 | "phpspec/prophecy":"1.7.0",
17 | "magento/magento-coding-standard": "^4.0"
18 | },
19 | "autoload": {
20 | "files": ["library/autoload.php"]
21 | },
22 | "license": "MIT",
23 | "scripts":{
24 | "test":"php vendor/bin/phpunit tests"
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/docs/.gitignore:
--------------------------------------------------------------------------------
1 | site/
2 |
--------------------------------------------------------------------------------
/docs/dev-internals-build.md:
--------------------------------------------------------------------------------
1 | ## Building Pestle
2 |
3 | Alright! You've made your changes and you're ready to do some end-to-end testing. In other words, you want to build pestle's `.phar` file and see if your stuff actually works.
4 |
5 | Pestle uses the [venerable phing build tool](https://www.phing.info/) to create its `phar` file. Unfortunately, when PHP started shipping with the ini setting `phar.readonly` set to `1`, they semi-broke our build system. In order to build a `.phar`, you'll need to invoke `phing` with the following.
6 |
7 | ```
8 | $ php -d phar.readonly=0 vendor/bin/phing package_phar
9 | ```
10 |
11 | This uses the PHP `-d` command line option to set the `phar.readonly=0` value to zero, and then invokes the `package_phar` build step.
12 |
13 | Once this command finishes running, you should have a brand new `pestle.phar` in your root project directory.
14 |
15 | ```
16 | $ ls pestle.phar
17 | pestle.phar
18 | ```
19 |
20 | ## Build a Release
21 |
22 | Right now the release process is only semi-automated. We're [working towards 100% automation](https://github.com/astorm/pestle/issues/472), but something something cobbler's children.
23 |
24 | To build a release, we
25 |
26 | 1. Create a fresh clone of the repo
27 | 2. Run `composer install`
28 | 3. Update the version string in `modules/pulsestorm/pestle/importer/module.php`
29 | 4. Build the library by running `./build-library.bash`
30 | 5. Commit your changes.
31 | 6. Tag the current commit with the version from #3
32 | 7. Push the tags (`git push --tags`)
33 | 8. Check Travis
34 | 9. Once travis is passing, run `build.sh` to build the latest `.phar`
35 | 10. Upload the `phar` to `http://pestle.pulsestorm.net/pestle.phar`
36 | 11. Once uploaded, make a copy in the form of pestle-x-x-x.phar to capture the version
37 |
38 | Right now, every step here can be completed by anyone _except_ #10 and #11, which requires access credentials to pestle.pulsestorm.net.
39 |
40 | If you love build systems and have opinions on way to automate this, [your feedback and participation is welcome](https://github.com/astorm/pestle/issues/472).
41 |
--------------------------------------------------------------------------------
/docs/dev-internals-introduction.md:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/docs/extra.css:
--------------------------------------------------------------------------------
1 | code.plaintext span.hljs-keyword,
2 | code.plaintext span.hljs-symbol,
3 | code.plaintext span.hljs-string
4 | {
5 | font-weight:normal;
6 | color:black;
7 | }
8 |
--------------------------------------------------------------------------------
/docs/index.md:
--------------------------------------------------------------------------------
1 | ## Introduction
2 |
3 | Pestle is two, (or maybe three), different things.
4 |
5 | **Number 1**: Pestle is a set of code generation tools for the PHP framework that powers the open source version of Magento 2.
6 |
7 | **Number 2**: Pestle is, itself, a framework for writing command line PHP programs and modules that can import **functions** from other programs and modules _w
8 |
9 | **Number 3**: Pestle is how I, Alan Storm, organize many of the the one-off command line PHP Programs that have helped me throughout my career.
10 |
11 | This documentation is also split into three sections.
12 |
13 | First, we'll cover [Pestle's code and configuration generation ability w/r/t Magento two](https://pestle.readthedocs.io/en/latest/magento2-introduction/).
14 |
15 | Second, we'll cover some of the [one-off Magento 2 scripts](https://pestle.readthedocs.io/en/latest/magento2-other-introduction/) that ship with pestle. Many of these aren't as robust as they might be, but still offer useful functionality or a good start **towards** a more robust solution.
16 |
17 | Finally, we'll close with some information about developing the core pestle code base itself -- both how to *use* pestle for your own command line programs, as well as work with the internals of pestle's framework code.
18 |
19 | ## Getting Started
20 |
21 | The easiest way to get started is to grab the latest build using curl
22 |
23 | ```plaintext
24 | $ curl -LO http://pestle.pulsestorm.net/pestle.phar
25 | ```
26 |
27 | Pestle is distributed as a PHP `phar` file -- [that's short for PHP archive](https://www.php.net/manual/en/book.phar.php). A `phar` file allows you to bundle up a bunch of PHP and distribute it as a single program. You should be able to run a `phar` with a specific version of PHP, *or* execute the `phar` file itself.
28 |
29 | ```plaintext
30 | $ php pestle.phar
31 | $ chmod +x pestle.phar
32 | $ ./pestle.phar
33 | $ mv pestle.phar /usr/local/bin
34 | $ pestle.phar # assumes /usr/local/bin is in your $PATH
35 | ```
36 |
37 | Most of these docs will presume you're executing `pestle.phar` directly via a directory that's in your shell's path.
38 |
39 | You can see a list of available commands with the following
40 |
41 | ```plaintext
42 | $ pestle.phar list-commands
43 | ```
44 |
45 | and get help for a specific command (`magento2:generate:module` below) with
46 |
47 | ```plaintext
48 | $ pestle.phar help magento2:generate:module
49 | ```
50 |
--------------------------------------------------------------------------------
/docs/magento2-database.md:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/docs/magento2-introduction.md:
--------------------------------------------------------------------------------
1 | ## What is Magento 2?
2 |
3 | The open-source version of Magento 2 (variously called Magento Community Edition or Magento Open Source) and the "on-premises" version (variously called Enterprise Edition or Magento Commerce) is written using the PHP programming language. It's an evolution of the Magento 1 codebase, which was also written using PHP, and incorporated components of Zend Framework -- a third party framework for developing web applications in PHP.
4 |
5 | The original core Magento 1 developers built *their own* MVC framework. The various teams that have worked on Magento since evolved that framework slightly, but in Magento 2 the core concepts remained the same -- they just became more verbose.
6 |
7 | Magento code is organized into modules. These modules share a set of global configuration objects -- each module can read/write to these global configuration objects by adding XML configuration files to its own `etc` folder. These files are merged to create the global configuration. Magento provides core modules for doing web application-y things like MVC, HTML Layout rendering, monkey-patching PHP class files, etc. They also provide core modules that implement a web-based online retail store.
8 |
9 | If developers want to change or build-on Magento 2's functionality, they'll need to create their own modules.
10 |
11 | ## Pestle's magento:generate:... Commands
12 |
13 | Pestle commands in the `magento:generate` namespace allow users to automatically generate the myriad files needed for basic Magento module functionality. This includes things like the basic module structure, controllers and routing files, view files, observers, upgrade migrations, UI Components, etc. Pestle takes the grunt work out of remembering which files make up a module's structure,
14 |
15 | In addition to the finely grained code generation commands, pestle also features a command to generate a "complete skeleton" module that contains everything a developer would need to persist information to the database and a backend UI for doing the same. To learn more read the [Generate Full Module](https://pestle.readthedocs.io/en/latest/magento2-generate-full-module/) section of the docs.
16 |
--------------------------------------------------------------------------------
/docs/magento2-other-introduction.md:
--------------------------------------------------------------------------------
1 | TODO: write docs
2 |
--------------------------------------------------------------------------------
/docs/magento2-other-other.md:
--------------------------------------------------------------------------------
1 | ## fix-permissions-modphp
2 |
3 | TODO: WRITE THE DOCS!
4 |
5 | ```plaintext
6 | Usage:
7 | $ pestle.phar magento2:fix-permissions-modphp
8 |
9 | Arguments:
10 |
11 | Options:
12 |
13 | Help:
14 | ALPHA: "Fixes" permissions for development boxes
15 | running mod_php by setting things to 777.
16 | @command magento2:fix-permissions-modphp
17 | ```
18 |
19 | ## code-migration:rename
20 |
21 | TODO: WRITE THE DOCS!
22 |
23 | ```plaintext
24 | Usage:
25 | $ pestle.phar magento2:code-migration:rename
26 |
27 | Arguments:
28 |
29 | Options:
30 |
31 | Help:
32 | ALPHA: Rename .converted files
33 |
34 | @command magento2:code-migration:rename
35 | @argument path Path to module? [app/code/Package/Module]
36 | ```
37 |
--------------------------------------------------------------------------------
/docs/magento2-quick-conversions.md:
--------------------------------------------------------------------------------
1 | ## class-from-path
2 |
3 | TODO: WRITE THE DOCS!
4 |
5 | ```plaintext
6 | Usage:
7 | $ pestle.phar magento2:class-from-path
8 |
9 | Arguments:
10 |
11 | Options:
12 |
13 | Help:
14 | Turns a Magento file path into a PHP class
15 | Long
16 | Description
17 | @command magento2:class-from-path
18 | ```
19 |
20 | ## convert-class
21 |
22 | TODO: WRITE THE DOCS!
23 |
24 | ```plaintext
25 | Usage:
26 | $ pestle.phar magento2:convert-class
27 |
28 | Arguments:
29 |
30 | Options:
31 |
32 | Help:
33 | ALPHA: Partially converts Magento 1 class to Magento 2
34 | Long
35 | Description
36 | @command magento2:convert-class
37 | ```
38 |
39 | ## convert-observers-xml
40 |
41 | TODO: WRITE THE DOCS!
42 |
43 | ```plaintext
44 | Usage:
45 | $ pestle.phar magento2:convert-observers-xml
46 |
47 | Arguments:
48 |
49 | Options:
50 |
51 | Help:
52 | ALPHA: Partially converts Magento 1 config.xml to Magento 2
53 | Long
54 | Description
55 | @command magento2:convert-observers-xml
56 | ```
57 |
58 | ## convert-system-xml
59 |
60 | TODO: WRITE THE DOCS!
61 |
62 | ```plaintext
63 | Usage:
64 | $ pestle.phar magento2:convert-system-xml
65 |
66 | Arguments:
67 |
68 | Options:
69 |
70 | Help:
71 | ALPHA: Partially Converts Magento 1 system.xml into Magento 2
72 | system.xml
73 | @command magento2:convert-system-xml
74 | ```
75 |
76 | ## extract-mage2-system-xml-paths
77 |
78 | TODO: WRITE THE DOCS!
79 |
80 | ```plaintext
81 | Usage:
82 | $ pestle.phar magento2:extract-mage2-system-xml-paths
83 |
84 | Arguments:
85 |
86 | Options:
87 |
88 | Help:
89 | Generates Mage2 config.xml
90 | Extracts configuration path's from a Magento 2 module's
91 | system.xml file, and then generates a config.xml file
92 | for the creation of default values
93 |
94 | @command magento2:extract-mage2-system-xml-paths
95 | ```
96 |
97 | ## fix-direct-om
98 |
99 | TODO: WRITE THE DOCS!
100 |
101 | ```plaintext
102 | Usage:
103 | $ pestle.phar magento2:fix-direct-om
104 |
105 | Arguments:
106 |
107 | Options:
108 |
109 | Help:
110 | ALPHA: Fixes direct use of PHP Object Manager
111 | argument foobar @callback exampleOfACallback
112 | @command magento2:fix-direct-om
113 | @argument folder Folder to scan
114 | @argument extensions File extensions? [php, phtml]
115 | ```
116 |
117 | ## path-from-class
118 |
119 | TODO: WRITE THE DOCS!
120 |
121 | ```plaintext
122 | Usage:
123 | $ pestle.phar magento2:path-from-class
124 |
125 | Arguments:
126 |
127 | Options:
128 |
129 | Help:
130 | Turns a PHP class into a Magento 2 path
131 | Long
132 | Description
133 | @command magento2:path-from-class
134 | ```
135 |
--------------------------------------------------------------------------------
/docs/magento2-scans-and-reports.md:
--------------------------------------------------------------------------------
1 | ## base-dir
2 |
3 | TODO: WRITE THE DOCS!
4 |
5 | ```plaintext
6 | Usage:
7 | $ pestle.phar magento2:base-dir
8 |
9 | Arguments:
10 |
11 | Options:
12 |
13 | Help:
14 | Output the base magento2 directory
15 |
16 | @command magento2:base-dir
17 | ```
18 |
19 | ## check-templates
20 |
21 | TODO: WRITE THE DOCS!
22 |
23 | ```plaintext
24 | Usage:
25 | $ pestle.phar magento2:check-templates
26 |
27 | Arguments:
28 |
29 | Options:
30 |
31 | Help:
32 | Checks for incorrectly named template folder
33 | Long
34 | Description
35 | @command magento2:check-templates
36 | ```
37 |
38 | ## class-list
39 |
40 | TODO: WRITE THE DOCS!
41 |
42 | ```plaintext
43 | Usage:
44 | $ pestle.phar magento2:class-list
45 |
46 | Arguments:
47 |
48 | Options:
49 |
50 | Help:
51 | Get a list of all of magento2's extensible classes
52 |
53 | @command magento2:class-list
54 | ```
55 |
56 | ## read-rest-schema
57 |
58 | TODO: WRITE THE DOCS!
59 |
60 | ```plaintext
61 | Usage:
62 | $ pestle.phar magento2:read-rest-schema
63 |
64 | Arguments:
65 |
66 | Options:
67 |
68 | Help:
69 | BETA: Magento command, reads the rest schema on a Magento system
70 |
71 | @command magento2:read-rest-schema
72 | @argument url Base Url? [http://magento-2-with-keys.dev/]
73 | ```
74 |
75 | ## scan:acl-used
76 |
77 | TODO: WRITE THE DOCS!
78 |
79 | ```plaintext
80 | Usage:
81 | $ pestle.phar magento2:scan:acl-used
82 |
83 | Arguments:
84 |
85 | Options:
86 |
87 | Help:
88 | Scans modules for ACL rule ids, makes sure they're all used/defined
89 |
90 | @command magento2:scan:acl-used
91 | @argument dir Which Directory?
92 | ```
93 |
94 | ## scan:class-and-namespace
95 |
96 | TODO: WRITE THE DOCS!
97 |
98 | ```plaintext
99 | Usage:
100 | $ pestle.phar magento2:scan:class-and-namespace
101 |
102 | Arguments:
103 |
104 | Options:
105 |
106 | Help:
107 | BETA: Scans a Magento 2 module for misnamed PHP classes
108 | @command magento2:scan:class-and-namespace
109 | @argument folder Which Folder?
110 | ```
111 |
112 | ## scan:htaccess
113 |
114 | TODO: WRITE THE DOCS!
115 |
116 | ```plaintext
117 | Usage:
118 | $ pestle.phar magento2:scan:htaccess
119 |
120 | Arguments:
121 |
122 | Options:
123 |
124 | Help:
125 | ALPHA: Checks for missing Magento 2 HTACCESS files from a hard coded
126 | list
127 | @command magento2:scan:htaccess
128 | ```
129 |
130 | ## scan:registration
131 |
132 | TODO: WRITE THE DOCS!
133 |
134 | ```plaintext
135 | Usage:
136 | $ pestle.phar magento2:scan:registration
137 |
138 | Arguments:
139 |
140 | Options:
141 |
142 | Help:
143 | Scans Magento 2 directories for missing registration.php files
144 | Long
145 | Description
146 | @command magento2:scan:registration
147 | ```
148 |
149 | ## search:search-controllers
150 |
151 | TODO: WRITE THE DOCS!
152 |
153 | ```plaintext
154 | Usage:
155 | $ pestle.phar magento2:search:search-controllers
156 |
157 | Arguments:
158 |
159 | Options:
160 |
161 | Help:
162 | Searches controllers
163 | @command magento2:search:search-controllers
164 | ```
165 |
--------------------------------------------------------------------------------
/docs/pestle-third-party.md:
--------------------------------------------------------------------------------
1 | TODO: write docs
2 |
--------------------------------------------------------------------------------
/gen-event-list.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #requires pcre2grep
3 | #run this command from a magento root directory to generate a (incomplete?) list of emitted events
4 | #to be used with observer generate autocomplete
5 |
6 | MAGE_ROOT=app/code/Magento
7 |
8 | pcre2grep --buffer-size=50M -M -r -o1 "eventManager->dispatch\s*\(\s*([\'\"][^\'\"]*[\'\"])" $MAGE_ROOT \
9 | | sed -e 's/.*://g' \
10 | | xargs --replace=EVENT echo 'echo "EVENT"'
11 |
12 | #-M is for multiline match
13 | #-r recusrive search
14 | #-o1 outputs only the first capture group (our event)
15 |
16 | #regex matches all dispatched events that match regex
17 | #regex matches eventManager->dispatch
18 | #followed by white space then a literal (
19 | #then any number of white space
20 | #then we capture the first string that appears
21 | # capture a ' or a "
22 | # followed by any number of anything that's not a ' or a "
23 | # followed by the matching ' or a "
24 |
25 | #this regex will also capture php code within "" that's meant to be evaluated
26 | # such as "admin_system_config_changed_section_{$this->getSection()}" (so far the only match)
27 | #it will also capture strings that begin with a ' and end with a " or vice versa (minor todo: we don't want that, but it shouldn't matter)
28 |
29 | #the sed erases the directory paths
30 | #the xargs generates the final echo command list to be used
--------------------------------------------------------------------------------
/library/autoload.php:
--------------------------------------------------------------------------------
1 | $value) {
20 | $length = strlen($key) + strlen($value);
21 | $longestLine = ($length > $longestLine) ? $length : $longestLine;
22 | }
23 |
24 | $longestLine += 5;
25 |
26 | $containerLine = '+'.str_repeat('-', $longestLine) . '+';
27 | output($containerLine);
28 |
29 | foreach($accounts as $key=>$value) {
30 | $paddingKey = str_repeat(' ', $longestKey - strlen($key) + 1);
31 | $paddingValue = str_repeat(' ',
32 | $longestLine - strlen($paddingKey . $key . $value . ' | '));
33 |
34 | // $paddingValue = ' ';
35 | output( '| ' .
36 | $key .
37 | $paddingKey . '| '.
38 | $value .
39 | $paddingValue . '|');
40 | }
41 | output($containerLine);
42 | $print = 'SUM: ' . number_format($sum);
43 | $length = $longestLine - strlen($print) - 1;
44 | $padding = str_repeat(' ', $length);
45 | // $padding = ' ';
46 | output('| ' . $print . $padding . '|');
47 | output($containerLine);
48 | }
49 |
50 | /**
51 | * @command library
52 | */
53 | function pestle_cli()
54 | {
55 | }
56 |
--------------------------------------------------------------------------------
/modules/pulsestorm/cli/build_command_list/module.php:
--------------------------------------------------------------------------------
1 | append($objects);
25 | }
26 | return $iterator;
27 | // return $objects;
28 | }
29 |
30 | function includeAllModuleFiles()
31 | {
32 | $objects = getListOfFilesInModuleFolder();
33 | // $path = realpath('modules/');
34 | // $objects = new RecursiveIteratorIterator(
35 | // new RecursiveDirectoryIterator($path),
36 | // RecursiveIteratorIterator::SELF_FIRST
37 | // );
38 | foreach($objects as $name => $object){
39 | $info = pathinfo($name);
40 | if($info['basename'] == 'module.php')
41 | {
42 | require_once $name;
43 | }
44 | }
45 |
46 | }
47 |
48 | function buildCommandList()
49 | {
50 | includeAllModuleFiles();
51 |
52 | $functions = get_defined_functions();
53 | $lookup = [];
54 | foreach($functions['user'] as $function)
55 | {
56 | if(strpos($function, 'pestle_cli') === false)
57 | {
58 | continue;
59 | }
60 | $r = new ReflectionFunction($function);
61 | // $doc_comment = getDocCommentAsString($function);
62 | $parsed_doc_command = parseDocBlockIntoParts($r->getDocComment());
63 |
64 | $command = array_key_exists('command', $parsed_doc_command)
65 | ? $parsed_doc_command['command'] : ['pestle-none-set'];
66 |
67 | $command = array_shift($command);
68 |
69 | $lookup[$command] = $r->getFilename();
70 | }
71 | cacheCommandList($lookup);
72 | return $lookup;
73 | }
74 |
75 | function cacheCommandList($lookup)
76 | {
77 | $cache_dir = getCacheDir();
78 | file_put_contents($cache_dir . '/command-list.ser', serialize($lookup));
79 | }
80 |
81 | /**
82 | * Builds the command list
83 | * @command pestle:build-command-list
84 | */
85 | function pestle_cli($argv)
86 | {
87 | $lookup = buildCommandList();
88 | foreach($lookup as $command=>$file)
89 | {
90 | output($command);
91 | }
92 |
93 | }
94 |
95 |
--------------------------------------------------------------------------------
/modules/pulsestorm/cli/format_php/module.php:
--------------------------------------------------------------------------------
1 | token_value === ';' && $next_token->token_name !== 'T_CLOSE_TAG')
21 | {
22 | return true;
23 | }
24 |
25 | return false;
26 | }
27 |
28 | /**
29 | * ALPHA: Experiments with a PHP formatter.
30 | *
31 | * @command php:format-php
32 | * @argument file Which file?
33 | */
34 | function pestle_cli($argv)
35 | {
36 | define('START', 0);
37 | define('PARSE_IF', 1);
38 | define('INSIDE_IF_BLOCK', 2);
39 |
40 | $file = $argv['file'];
41 | $tokens = pestle_token_get_all(file_get_contents($file));
42 |
43 | //remove whitespace tokens
44 | $tokens = array_filter($tokens, function($token){
45 | return $token->token_name !== 'T_WHITESPACE';
46 | });
47 | $tokens = array_values($tokens);
48 |
49 | $state = 0;
50 | $indent_level = 0;
51 | foreach($tokens as $key=>$token)
52 | {
53 | $before = '';
54 | $after = '';
55 |
56 | //state switching
57 | if($token->token_name == 'T_IF')
58 | {
59 | $state = PARSE_IF;
60 | }
61 |
62 | if($state == PARSE_IF && $token->token_value === ':')
63 | {
64 | $indent_level++;
65 | $state = INSIDE_IF_BLOCK;
66 | }
67 |
68 | if($state == INSIDE_IF_BLOCK && $token->token_name === 'T_ENDIF')
69 | {
70 | $state = START;
71 | $indent_level--;
72 | }
73 |
74 | //manipuate extra output tokens
75 | if($token->token_value === '{')
76 | {
77 | $indent_level++;
78 | $after = "\n" . str_repeat(" ", $indent_level);
79 | }
80 |
81 | if($token->token_value === '}')
82 | {
83 | $indent_level--;
84 | $after = "\n" . str_repeat(" ", $indent_level);
85 | }
86 |
87 | if($token->token_name === 'T_CLOSE_TAG')
88 | {
89 | $after = "\n" . str_repeat(" ", $indent_level);
90 | }
91 |
92 | if(tokenIsSemiColonAndNextTokenIsNotTCloseTag($tokens, $key))
93 | {
94 | $after = "\n" . str_repeat(" ", $indent_level);
95 | }
96 |
97 | if($token->token_name === 'T_INLINE_HTML' && !trim($token->token_value))
98 | {
99 | continue;
100 | }
101 | //do output
102 | echo $before;
103 | echo $token->token_value;
104 | echo $after;
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/modules/pulsestorm/cli/md_to_say/module.php:
--------------------------------------------------------------------------------
1 | .+?
%six',
25 | '
[CODE SNIPPED].
',
26 | $html
27 | );
28 | $html = str_replace('','
',$html);
29 |
30 | $tmp = tempnam('/tmp', 'md_to_say') . '.html';
31 | file_put_contents($tmp, $html);
32 |
33 | $cmd = 'textutil -convert txt ' . $tmp;
34 | `$cmd`;
35 |
36 | $tmp_txt = swapExtension($tmp, 'html','txt');
37 | $tmp_aiff = swapExtension($tmp, 'html','aiff');
38 |
39 | $cmd = "say -f $tmp_txt -o $tmp_aiff";
40 | output($cmd);
41 | // `$cmd`;
42 | // $tmp_txt = preg_replace('%\.html$%','.txt', $tmp);
43 |
44 | output($tmp_aiff);
45 | output("Done");
46 | }
47 |
--------------------------------------------------------------------------------
/modules/pulsestorm/cli/self_update/module.php:
--------------------------------------------------------------------------------
1 | name;
24 | $name = $faker->name;
25 | $email = preg_replace('%[^a-zA-Z0-9_-]%','',$name) . '@' . $domain;
26 | output($name . "\t" . $email);
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/modules/pulsestorm/financial/parse_citicard/module.php:
--------------------------------------------------------------------------------
1 | $value)
17 | {
18 | if(is_numeric($key))
19 | {
20 | unset($data[$key]);
21 | }
22 | }
23 | return $data;
24 | }
25 |
26 | function file_get_contents_csv($filename,$has_headers=true)
27 | {
28 | $all = array();
29 | $file = fopen($filename,'r');
30 | if($has_headers)
31 | {
32 | apply_column_headers(fgetcsv($file));
33 | }
34 | while($data = fgetcsv($file))
35 | {
36 | if($has_headers)
37 | {
38 | $all[] = apply_column_headers($data);
39 | }
40 | else
41 | {
42 | $all[] = $data;
43 | }
44 |
45 | }
46 | fclose($file);
47 |
48 | return $all;
49 | }
50 |
51 | function parseDescription($string)
52 | {
53 | return [
54 | 'description'=>trim($string)
55 | ];
56 | // preg_match('%\d\d\d-\d\d\d-\d\d\d\d%', $string, $matches);
57 | // $phone = array_pop($matches);
58 | //
59 | // $state =
60 | }
61 |
62 | /**
63 | * BETA: Parses Citicard's CSV files into yaml
64 | *
65 | * @command parsing:citicard
66 | * @argument file File to Parse?
67 | * @argument count Starting Count?
68 | */
69 | function pestle_cli($argv)
70 | {
71 | $file = $argv['file'];
72 | $count = $argv['count'];
73 | $items = file_get_contents_csv($file);
74 | foreach($items as $item)
75 | {
76 | $parts = parseDescription($item['Description']);
77 | $description = $parts['description'];
78 | if($description === 'ELECTRONIC PAYMENT-THANK YOU')
79 | {
80 | continue;
81 | }
82 | // 120-Paid On 03/10/2016:028.28 Do it Best Hardware
83 | output($count,'-Paid On ', $item['Date'],':',$item['Debit'],
84 | ' ', $description);
85 | $count++;
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/modules/pulsestorm/generate/pestle/command/module.php:
--------------------------------------------------------------------------------
1 | 0)
17 | {
18 | $Path = $argv[0];
19 | }
20 |
21 | foreach(glob($path . '/*/*') as $file)
22 | {
23 | $parts = explode('/', $file);
24 | $module = implode('_', array_slice($parts, count($parts) - 2));
25 |
26 | $file = $file . '/' . 'registration.php';
27 | if(file_exists($file))
28 | {
29 | output("Registration Exists");
30 | $contents = file_get_contents($file);
31 | if(strpos($contents, "'" . $module . "'") !== false)
32 | {
33 | output("Registration contains $module string");
34 | continue;
35 | }
36 | output("However, it's missing single quoted '$module' string");
37 | output("");
38 | continue;
39 | }
40 | output("No $file");
41 | $answer = input("Create? [Y/n]", 'n');
42 | if($answer !== 'Y')
43 | {
44 | continue;
45 | }
46 | file_put_contents($file, templateRegistrationPhp($module));
47 | output("Created $file");
48 | output("");
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/modules/pulsestorm/magento2/cli/check_templates/module.php:
--------------------------------------------------------------------------------
1 | 0)
21 | {
22 | $class[] = $part;
23 | }
24 | }
25 | array_shift($class);
26 |
27 | $class_name = array_pop($class);
28 | $body = '<' . '?' . 'php' . "\n" .
29 | 'namespace ' . implode('\\', $class) . ";\n" .
30 | 'class ' . str_replace('.php','',$class_name) . "\n" . '{}';
31 |
32 | output($body);
33 | }
--------------------------------------------------------------------------------
/modules/pulsestorm/magento2/cli/convert_class/module.php:
--------------------------------------------------------------------------------
1 | {$scope}, $xml);
28 | output($scope);
29 | output($xml_new->asXml());
30 | output('--------------------------------------------------');
31 | }
32 | }
33 |
34 | }
--------------------------------------------------------------------------------
/modules/pulsestorm/magento2/cli/dev_import/module.php:
--------------------------------------------------------------------------------
1 | ');
31 | foreach($tree as $section=>$groups)
32 | {
33 | $section = $xml->default->addChild($section);
34 | foreach($groups as $group=>$fields)
35 | {
36 | $group = $section->addChild($group);
37 | foreach($fields as $field)
38 | {
39 | $group->addChild($field, 'DEFAULTVALUE');
40 | }
41 | }
42 | }
43 | echo $xml->asXml();
44 | }
45 |
--------------------------------------------------------------------------------
/modules/pulsestorm/magento2/cli/extract_session/module.php:
--------------------------------------------------------------------------------
1 | preserveWhitespace = false;
16 | $dom->loadXml($xml_string);
17 | $dom->formatOutput = true;
18 | $output = $dom->saveXml();
19 |
20 | return $output;
21 | }
22 |
--------------------------------------------------------------------------------
/modules/pulsestorm/magento2/cli/generate/acl/module.php:
--------------------------------------------------------------------------------
1 | ::top,<$module_name$>::config,]
19 | */
20 | function pestle_cli($argv)
21 | {
22 | extract($argv);
23 | $rule_ids = explode(',', $rule_ids);
24 | $rule_ids = array_filter($rule_ids);
25 |
26 | $path = getBaseModuleDir($module_name) . '/etc/acl.xml';
27 | if(!file_exists($path))
28 | {
29 | $xml = simplexml_load_string(getBlankXml('acl'));
30 | writeStringToFile($path, $xml->asXml());
31 | }
32 | $xml = simplexml_load_file($path);
33 |
34 | $xpath = 'acl/resources/resource[@id=Magento_Backend::admin]';
35 |
36 | foreach($rule_ids as $id)
37 | {
38 | $id = trim($id);
39 | $xpath .= '/resource[@id='.$id.',@title=TITLE HERE FOR]';
40 | }
41 | simpleXmlAddNodesXpath($xml,$xpath);
42 |
43 | writeStringToFile($path, formatXmlString($xml->asXml()));
44 | output("Created $path");
45 | }
46 |
47 | function exported_pestle_cli($argv)
48 | {
49 | return pestle_cli($argv);
50 | }
--------------------------------------------------------------------------------
/modules/pulsestorm/magento2/cli/generate/command/module.php:
--------------------------------------------------------------------------------
1 | asXml()));
36 | }
37 | return $path_di_xml;
38 | }
39 |
40 | /**
41 | * Generates bin/magento command files
42 | * This command generates the necessary files and configuration
43 | * for a new command for Magento 2's bin/magento command line program.
44 | *
45 | * pestle.phar generate_command Pulsestorm_Generate Example
46 | *
47 | * Creates
48 | * app/code/Pulsestorm/Generate/Command/Example.php
49 | * app/code/Pulsestorm/Generate/etc/di.xml
50 | *
51 | * @command generate-command
52 | * @argument module_name In which module? [Pulsestorm_Helloworld]
53 | * @argument command_name Command Name? [Testbed]
54 | */
55 | function pestle_cli($argv)
56 | {
57 | $module_info = getModuleInformation($argv['module_name']);
58 | $namespace = $module_info->vendor;
59 | $module_name = $module_info->name;
60 | $module_shortname = $module_info->short_name;
61 | $module_dir = $module_info->folder;
62 | $command_name = $argv['command_name'];
63 | // $command_name = input("Command Name?", 'Testbed');
64 |
65 | output($module_dir);
66 |
67 | createPhpClass($module_dir, $namespace, $module_shortname, $command_name);
68 |
69 | $path_di_xml = createDiIfNeeded($module_dir);
70 |
71 | $xml_di = simplexml_load_file($path_di_xml);
72 |
73 | //get commandlist node
74 | $nodes = $xml_di->xpath('/config/type[@name="Magento\Framework\Console\CommandList"]');
75 | $xml_type_commandlist = array_shift($nodes);
76 | if(!$xml_type_commandlist)
77 | {
78 | $xml_type_commandlist = $xml_di->addChild('type');
79 | $xml_type_commandlist['name'] = 'Magento\Framework\Console\CommandList';
80 | }
81 |
82 | $argument = simpleXmlAddNodesXpath($xml_type_commandlist,
83 | '/arguments/argument[@name=commands,@xsi:type=array]');
84 |
85 | $full_class = $namespace.'\\'.$module_shortname.'\\Command\\' . $command_name;
86 | $item_name = str_replace('\\', '_', strToLower($full_class));
87 | $item = $argument->addChild('item', $full_class);
88 | $item->addAttribute('name', $item_name);
89 | $item->addAttribute('xsi:type', 'object', 'http://www.w3.org/2001/XMLSchema-instance');
90 |
91 | $xml_di = formatXmlString($xml_di->asXml());
92 |
93 | writeStringToFile($path_di_xml, $xml_di);
94 |
95 | }
96 |
97 | function exported_pestle_cli($argv)
98 | {
99 | return pestle_cli($argv);
100 | }
--------------------------------------------------------------------------------
/modules/pulsestorm/magento2/cli/generate/config_helper/module.php:
--------------------------------------------------------------------------------
1 | scopeConfig = $scopeConfig;
32 | }
33 |
34 | public function get($path=null)
35 | {
36 | $config = $this->scopeConfig->getValue($this->getTopLevelName());
37 | if($config === null)
38 | {
39 | return null;
40 | }
41 | if(!$path)
42 | {
43 | return $config;
44 | }
45 | $parts = explode(\'/\',$path);
46 |
47 | foreach($parts as $part)
48 | {
49 | if(!array_key_exists($part, $config))
50 | {
51 | return null;
52 | }
53 | $config = $config[$part];
54 | }
55 |
56 | return $config;
57 | }
58 |
59 | protected function getTopLevelName()
60 | {
61 | return self::CONFIG_TOP;
62 | }
63 | }
64 | ');
65 |
66 | output($template);
67 | }
68 |
69 | function exported_pestle_cli($argv)
70 | {
71 | return pestle_cli($argv);
72 | }
--------------------------------------------------------------------------------
/modules/pulsestorm/magento2/cli/generate/install/module.php:
--------------------------------------------------------------------------------
1 | > magento_umask";
38 | $cmds[] = "echo \"We're about to ask for your MySQL password so we can create the database\"";
39 | $cmds[] = "echo 'CREATE DATABASE $db_name' | mysql -uroot -p";
40 |
41 | $cmds[] = "php bin/magento setup:install --admin-email $admin_email --admin-firstname $admin_first_name --admin-lastname $admin_last_name --admin-password $admin_password --admin-user $admin_user --backend-frontname admin --base-url http://$url --db-host 127.0.0.1 --db-name $db_name --db-password $db_pass --db-user $db_user --session-save files --use-rewrites 1 --use-secure 0 -vvv";
42 | $cmds[] = 'php bin/magento sampledata:deploy';
43 | $cmds[] = 'php bin/magento cache:enable';
44 |
45 | array_map(function($cmd){
46 | output($cmd);
47 | }, $cmds);
48 | }
49 |
50 | function exported_pestle_cli($argv)
51 | {
52 | return pestle_cli($argv);
53 | }
--------------------------------------------------------------------------------
/modules/pulsestorm/magento2/cli/generate/layout_xml/module.php:
--------------------------------------------------------------------------------
1 | folder;
17 | }
18 |
19 | function getPackageDir($base_dir, $namespace, $name) {
20 | $result = getModuleInformation(implode('_', [$namespace,$name]), $base_dir);
21 | return $result->folder_package;
22 | }
23 |
24 |
25 | /**
26 | * Generates new module XML, adds to file system
27 | * This command generates the necessary files and configuration
28 | * to add a new module to a Magento 2 system.
29 | *
30 | * pestle.phar Pulsestorm TestingCreator 0.0.1
31 | *
32 | * @argument namespace Vendor Namespace? [Pulsestorm]
33 | * @argument name Module Name? [Testbed]
34 | * @argument version Version? [0.0.1]
35 | * @command generate-module
36 | */
37 | function pestle_cli($argv)
38 | {
39 | $namespace = $argv['namespace'];
40 | $name = $argv['name'];
41 | $version = $argv['version'];
42 |
43 | $full_module_name = implode('_', [$namespace, $name]);
44 |
45 | $config = simplexml_load_string(getBlankXml('module'));
46 | $module = $config->addChild('module');
47 | $module->addAttribute('name' , $full_module_name);
48 | $module->addAttribute('setup_version', $version);
49 | $xml = $config->asXml();
50 |
51 | $base_dir = getBaseMagentoDir();
52 | $module_dir = getModuleDir($base_dir, $namespace, $name);
53 | $package_dir = getPackageDir($base_dir, $namespace, $name);
54 | $etc_dir = $module_dir . '/etc';
55 | $reg_path = $module_dir . '/registration.php';
56 |
57 | if(is_dir($etc_dir))
58 | {
59 | output("Module directory [$etc_dir] already exists");
60 | } else {
61 | output("Creating [$etc_dir] ");
62 | mkdir($etc_dir, 0755, $etc_dir);
63 | }
64 |
65 | writeFormattedXmlStringToFile($etc_dir . '/module.xml', $xml);
66 | output("Created: " . $etc_dir . '/module.xml');
67 |
68 | $register = templateRegistrationPhp($full_module_name);
69 | writeStringToFile($reg_path, $register);
70 | output("Created: " . $reg_path);
71 | }
72 |
73 | function exported_pestle_cli($argv)
74 | {
75 | return pestle_cli($argv);
76 | }
77 |
78 |
--------------------------------------------------------------------------------
/modules/pulsestorm/magento2/cli/generate/observer/module.php:
--------------------------------------------------------------------------------
1 | _listener]
21 | * @argument model_name Class Name? [<$module$>\Model\Observer]
22 | */
23 | function pestle_cli($argv)
24 | {
25 | $module = $argv['module'];
26 | $event_name = $argv['event_name'];
27 | $observer_name = $argv['observer_name'];
28 | $model_name = $argv['model_name'];
29 | $method_name = 'execute';
30 |
31 | $path_xml_event = initilizeModuleConfig(
32 | $module,
33 | 'events.xml',
34 | 'urn:magento:framework:Event/etc/events.xsd'
35 | );
36 |
37 | $xml = simplexml_load_file($path_xml_event);
38 | $nodes = $xml->xpath('//event[@name="' . $event_name . '"]');
39 | $node = array_shift($nodes);
40 | $event = $node;
41 | if(!$node)
42 | {
43 | $event = $node ? $node : $xml->addChild('event');
44 | $event->addAttribute('name', $event_name);
45 | }
46 | $observer = $event->addChild('observer');
47 | $observer->addAttribute('name', $observer_name);
48 | $observer->addAttribute('instance', $model_name);
49 | // $observer->addAttribute('method', $method_name);
50 |
51 | output("Creating: $path_xml_event");
52 | $path = writeStringToFile($path_xml_event, $xml->asXml());
53 |
54 | output("Creating: $model_name");
55 | $contents = createClassTemplate($model_name, false, '\Magento\Framework\Event\ObserverInterface');
56 | $contents = str_replace('<$body$>',
57 | "\n" .
58 | ' public function execute(\Magento\Framework\Event\Observer $observer){exit(__FILE__);}' .
59 | "\n" , $contents);
60 | createClassFile($model_name, $contents);
61 | }
62 |
63 | function exported_pestle_cli($argv)
64 | {
65 | return pestle_cli($argv);
66 | }
--------------------------------------------------------------------------------
/modules/pulsestorm/magento2/cli/generate/psr_log_level/module.php:
--------------------------------------------------------------------------------
1 | $value)
19 | {
20 | output($key . "\t\t" . $value);
21 | }
22 | }
23 |
24 | function exported_pestle_cli($argv)
25 | {
26 | return pestle_cli($argv);
27 | }
--------------------------------------------------------------------------------
/modules/pulsestorm/magento2/cli/generate/registration/module.php:
--------------------------------------------------------------------------------
1 | folder . '/view/' .
17 | $area . '/templates/' . $template;
18 |
19 | output("Creating $path");
20 | writeStringToFile($path, 'This is my template, there are many like it, but this one is mine.
');
21 |
22 | }
23 |
24 | function createHandleFile($module_info, $area, $template, $class, $handle, $layout)
25 | {
26 | $xml = simplexml_load_string(getBlankXml('layout_handle'));
27 | $name = strToLower($module_info->name) .
28 | '_block_' .
29 | strToLower(getShortClassNameFromClass($class));
30 |
31 | simpleXmlAddNodesXpath($xml,
32 | 'referenceContainer[@name=content]/block[' .
33 | '@template=' . $template . ',' .
34 | '@class=' . $class . ',' .
35 | '@name=' . $name . ']'
36 | );
37 |
38 | $xml['layout'] = $layout;
39 | if($layout === '' || $area === 'adminhtml')
40 | {
41 | unset($xml['layout']);
42 | }
43 |
44 | $path = $module_info->folder . '/view/' .
45 | $area . '/layout/' . $handle . '.xml';
46 |
47 | output("Creating: $path");
48 | writeStringToFile($path, $xml->asXml());
49 |
50 | }
51 |
52 | function createBlockClass($module_info, $block_name, $area='frontname')
53 | {
54 | $class_name = str_replace('_', '\\', $module_info->name) .
55 | '\Block\\';
56 | if($area === 'adminhtml')
57 | {
58 | $class_name .= 'Adminhtml\\';
59 | }
60 | $class_name .= ucwords($block_name);
61 |
62 | output("Creating: " . $class_name);
63 | $baseClass = '\Magento\Framework\View\Element\Template';
64 | if($area === 'adminhtml')
65 | {
66 | $baseClass = '\Magento\Backend\Block\Template';
67 | }
68 | $contents = createClassTemplate($class_name, $baseClass);
69 | $contents = str_replace('<$body$>', "\n".' function _prepareLayout(){}'."\n", $contents);
70 | createClassFile($class_name, $contents);
71 | return $class_name;
72 | }
73 |
74 | /**
75 | * Generates a Magento 2 view
76 | *
77 | * Wrapped by magento:... version of command
78 | *
79 | * @command generate-view
80 | * @argument module_name Which Module? [Pulsestorm_HelloGenerate]
81 | * @argument area Which Area? [frontend]
82 | * @argument handle Which Handle? [<$module_name$>_index_index]
83 | * @argument block_name Block Name? [Main]
84 | * @argument template Template File? [content.phtml]
85 | * @argument layout Layout (ignored for adminhtml) ? [1column]
86 | */
87 | function pestle_cli($argv)
88 | {
89 | $module_name = $argv['module_name'];
90 | $area = $argv['area'];
91 | $handle = $argv['handle'];
92 | $block_name = $argv['block_name'];
93 | $template = $argv['template'];
94 | $layout = $argv['layout'];
95 |
96 | $module_info = getModuleInformation($module_name);
97 |
98 | createTemplateFile($module_info, $area, $template);
99 | $class = createBlockClass($module_info, $block_name, $area);
100 | createHandleFile($module_info, $area, $template, $class, $handle, $layout);
101 |
102 | }
103 |
104 | function exported_pestle_cli($argv)
105 | {
106 | return pestle_cli($argv);
107 | }
--------------------------------------------------------------------------------
/modules/pulsestorm/magento2/cli/hello_argument/module.php:
--------------------------------------------------------------------------------
1 | 1)
25 | {
26 | exitWithErrorMessage("Found more than one node with {$argv['acl_rule_id']}");
27 | }
28 |
29 | $node = array_pop($nodes);
30 | $node['title'] = $argv['title'];
31 |
32 | writeStringToFile($argv['path_acl'], $xml->asXml());
33 | output("Changed Title");
34 | }
35 |
--------------------------------------------------------------------------------
/modules/pulsestorm/magento2/cli/magento2/generate/acl/module.php:
--------------------------------------------------------------------------------
1 | ::top,<$module_name$>::config,]
13 | */
14 | function pestle_cli($argv)
15 | {
16 | return exported_pestle_cli($argv);
17 | }
18 |
--------------------------------------------------------------------------------
/modules/pulsestorm/magento2/cli/magento2/generate/command/module.php:
--------------------------------------------------------------------------------
1 | ::unique_identifier]
32 | * @argument resource ACL Resource [<$id$>]
33 | * @argument title Link Title [My Link Title]
34 | * @argument action Three Segment Action [frontname/index/index]
35 | * @argument sortOrder Sort Order? [10]
36 | */
37 |
38 | function pestle_cli($argv)
39 | {
40 | // output("Hi");
41 | return exported_pestle_cli($argv);
42 | }
43 |
--------------------------------------------------------------------------------
/modules/pulsestorm/magento2/cli/magento2/generate/module/module.php:
--------------------------------------------------------------------------------
1 | _listener]
44 | * @argument model_name @callback getModelName
45 | */
46 | function pestle_cli($argv)
47 | {
48 | //* @argument model_name Class Name? [<$module$>\Model\Observer]
49 | return exported_pestle_cli($argv);
50 | }
51 |
--------------------------------------------------------------------------------
/modules/pulsestorm/magento2/cli/magento2/generate/plugin_xml/module.php:
--------------------------------------------------------------------------------
1 | \Plugin\<$class$>]
16 | * @option use-type-hint Add type hint to subject?
17 | * @command magento2:generate:plugin-xml
18 | */
19 | function pestle_cli($argv, $options)
20 | {
21 | return exported_pestle_cli($argv, $options);
22 | }
23 |
--------------------------------------------------------------------------------
/modules/pulsestorm/magento2/cli/magento2/generate/preference/module.php:
--------------------------------------------------------------------------------
1 | folder . '/etc/di.xml';
15 | if(!file_exists($path_di))
16 | {
17 | $xml = simplexml_load_string(getBlankXml('di'));
18 | writeStringToFile($path_di, $xml->asXml());
19 | output("Created new $path_di");
20 | }
21 | $xml = simplexml_load_file($path_di);
22 | return [
23 | 'path'=>$path_di,
24 | 'xml'=>$xml
25 | ];
26 | }
27 |
28 | function generateDiConfiguration($argv)
29 | {
30 | $moduleInfo = getModuleInformation($argv['module']);
31 | $pathAndXml = loadOrCreateDiXml($moduleInfo);
32 | $path = $pathAndXml['path'];
33 | $di_xml = $pathAndXml['xml'];
34 |
35 | $preference = $di_xml->addChild('preference');
36 | $preference['for'] = $argv['for'];
37 | $preference['type'] = $argv['type'];
38 |
39 | writeStringToFile($path, formatXmlString($di_xml->asXml()));
40 |
41 | }
42 |
43 | function isTypeInterface($type)
44 | {
45 | //string detection for now -- change to actually examine system?
46 | return strpos($type, 'Interface') !== false;
47 | }
48 |
49 | function generateNewClass($argv)
50 | {
51 | $pathType = getPathFromClass($argv['type']);
52 |
53 | $typeGlobalNs = '\\' . trim($argv['for'],'\\');
54 | $classContents = createClassTemplate($argv['type'], $typeGlobalNs);
55 | if(isTypeInterface($typeGlobalNs))
56 | {
57 | $classContents = createClassTemplate($argv['type'], null, $typeGlobalNs);
58 | }
59 |
60 | $classContents = str_replace('<$body$>', '',$classContents);
61 |
62 | if(!file_exists($pathType))
63 | {
64 | output("Creating $pathType");
65 | writeStringToFile($pathType, $classContents);
66 | }
67 | else
68 | {
69 | output("$pathType already exists, skipping creation");
70 | }
71 | }
72 |
73 | /**
74 | * Generates a Magento 2.1 ui grid listing and support classes.
75 | *
76 | * @command magento2:generate:preference
77 | * @argument module Which Module? [Pulsestorm_Helloworld]
78 | * @argument for For which Class/Interface/Type? [Pulsestorm\Helloworld\Model\FooInterface]
79 | * @argument type New Concrete Class? [Pulsestorm\Helloworld\Model\NewModel]
80 | */
81 | function pestle_cli($argv)
82 | {
83 | generateDiConfiguration($argv);
84 | generateNewClass($argv);
85 |
86 | // output("Created file $path_plugin");
87 | // output("This command will add to di.xml (create if needed)");
88 | // output("This command will also generate a class");
89 | // output("If passed an interface, class will implement");
90 | // output("If passed a class, class will extend");
91 | // output("Simple text matching for interface detection?");
92 | // generateUiComponentXmlFile(
93 | // $argv['grid_id'], $argv['db_id_column'], $module_info);
94 | //
95 | // generateDataProviderClass(
96 | // $module_info, $argv['grid_id'], $argv['collection_resource'] . 'Factory');
97 | //
98 | // generatePageActionClass(
99 | // $module_info, $argv['grid_id'], $argv['db_id_column']);
100 | //
101 | // output("Don't forget to add this to your layout XML with ");
102 | }
103 |
--------------------------------------------------------------------------------
/modules/pulsestorm/magento2/cli/magento2/generate/psr_log_level/module.php:
--------------------------------------------------------------------------------
1 | addChild('actionsColumn');
61 | $actionsColumn->addAttribute('name', 'actions');
62 | $actionsColumn->addAttribute('class', $actionsClass);
63 | $argument = addArgument($actionsColumn, 'data', 'array');
64 | $configItem = addItem($argument, 'config', 'array');
65 | $indexField = addItem($configItem, 'indexField', 'string', $argv['index_field']);
66 |
67 | output(
68 | formatXmlString($xml->asXml())
69 | );
70 |
71 | //
72 | //
73 | // -
74 | //
- false
75 | // - 107
76 | // - pulsestorm_todocrud_todoitem_id
77 | //
78 | //
79 | //
80 |
81 | }
82 |
--------------------------------------------------------------------------------
/modules/pulsestorm/magento2/cli/magento2/generate/ui/add-column-sections/module.php:
--------------------------------------------------------------------------------
1 | addChild('selectionsColumn');
35 | $sectionsColumn->addAttribute('name', $argv['column_name']);
36 | $argument = addArgument($sectionsColumn, 'data', 'array');
37 | $configItem = addItem($argument, 'config', 'array');
38 | $indexField = addItem($configItem, 'indexField', 'string', $argv['index_field']);
39 |
40 | writeStringToFile($argv['listing_file'], formatXmlString($xml->asXml()));
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/modules/pulsestorm/magento2/cli/magento2/generate/ui/add_to_layout/module.php:
--------------------------------------------------------------------------------
1 | 1)
35 | {
36 | exitWithErrorMessage("BAILING: Found more than one name=\"".$argv['block_name']."\" node.\n");
37 | }
38 | return array_pop($nodes);
39 | }
40 |
41 | /**
42 | * Adds a node to a named node in a layout update XML file
43 | *
44 | * @command magento2:generate:ui:add-to-layout
45 | * @argument path_layout Layout XML File?
46 | * @argument block_name Block or Reference Name?
47 | * @argument ui_component_name UI Component Name?
48 | */
49 | function pestle_cli($argv)
50 | {
51 | $xml = simplexml_load_file($argv['path_layout']);
52 | validateNoSuchComponent($xml, $argv['ui_component_name']);
53 | $node = getContentNode($xml, $argv);
54 |
55 | $node->addChild('uiComponent')
56 | ->addAttribute('name', $argv['ui_component_name']);
57 | $xmlString = formatXmlString($xml->asXml());
58 | writeStringToFile($argv['path_layout'], $xmlString);
59 | output("Added Component");
60 | }
61 |
--------------------------------------------------------------------------------
/modules/pulsestorm/magento2/cli/magento2/generate/view/module.php:
--------------------------------------------------------------------------------
1 | _index_index]
14 | * @argument block_name Block Name? [Main]
15 | * @argument template Template File? [content.phtml]
16 | * @argument layout Layout (ignored for adminhtml) ? [1column]
17 | */
18 | function pestle_cli($argv)
19 | {
20 | return exported_pestle_cli($argv);
21 | }
22 |
--------------------------------------------------------------------------------
/modules/pulsestorm/magento2/cli/pandoc_md/module.php:
--------------------------------------------------------------------------------
1 | $items)
29 | {
30 | foreach($items as $item)
31 | {
32 | $contents = file_get_contents($item);
33 | if(strpos($contents, 'execute') !== false)
34 | {
35 | $return[$item] = $contents;
36 | }
37 | }
38 | }
39 |
40 | return $return;
41 |
42 | }
43 |
44 | function getExecuteMethods($controllers)
45 | {
46 | foreach($controllers as $file=>$contents)
47 | {
48 | $execute = getFunctionFromClass($contents, 'execute');
49 | output($file);
50 | output('--------------------------------------------------');
51 | output($execute);
52 | output('');
53 |
54 | }
55 | }
56 |
57 | /**
58 | * Searches controllers
59 | * @command magento2:search:search-controllers
60 | */
61 | function pestle_cli($argv)
62 | {
63 | $base = inputOrIndex("Which folder to search?",'vendor/magento',$argv,0);
64 | $controllers = getAllControllerFiles($base);
65 | $controllers = getControllersWithExecuteMethod($controllers);
66 | $controllers = getExecuteMethods($controllers);
67 | }
68 |
--------------------------------------------------------------------------------
/modules/pulsestorm/magento2/cli/test_output/module.php:
--------------------------------------------------------------------------------
1 |
8 |
9 | ';
10 |
11 | }
12 |
13 | function getBlankXmlView()
14 | {
15 | return '';
16 | }
17 |
18 | function getBlankXmlAcl()
19 | {
20 | return '
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 | ';
29 | }
30 |
31 | function getBlankXmlMenu()
32 | {
33 | return '
34 |
35 |
37 | ';
38 | }
39 |
40 | function getBlankXmlUiGrid()
41 | {
42 | return '';
43 | }
44 |
45 | function getBlankXmlTheme()
46 | {
47 | return '';
48 | }
49 |
50 | function getBlankXmlRoutes()
51 | {
52 | $config_attributes = 'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd"';
53 | return trim('');
54 |
55 | }
56 |
57 | function getBlankXmlDi()
58 | {
59 | return '
60 |
61 | ';
62 |
63 | }
64 |
65 | function getBlankXml($type)
66 | {
67 | $function = 'Pulsestorm\Magento2\Cli\Xml_Template';
68 | $function .= '\getBlankXml' . ucWords(strToLower($type));
69 | if(function_exists($function))
70 | {
71 | return call_user_func($function);
72 | }
73 | throw new Exception("No such type, $type ($function)");
74 | }
75 |
76 | function getBlankXmlLayout_handle()
77 | {
78 | return '
79 |
80 | ';
81 | }
82 |
83 | function getBlankXmlWebapi()
84 | {
85 | return '
87 | ';
88 | }
89 | /**
90 | * Converts Zend Log Level into PSR Log Level
91 | * @command library
92 | */
93 | function pestle_cli($argv)
94 | {
95 | }
--------------------------------------------------------------------------------
/modules/pulsestorm/magento2/codemigration/rename/module.php:
--------------------------------------------------------------------------------
1 | 0)
34 | {
35 | exitWithErrorMessage("BAILING: Found *.php.old files -- looks like you already ran this command.");
36 | }
37 |
38 | // var_dump($olds);
39 | // exit(__FUNCTION__ . "\n");
40 | // $path = 'm2-converted';
41 | // $path = 'app/code/LCG/Ambassador';
42 | $oldFiles = `find $path/ -name '*.php'`;
43 | $convertedFiles = `find $path/ -name '*.php.converted'`;
44 |
45 |
46 |
47 | $oldFiles = explode("\n", $oldFiles);
48 | $oldFiles = array_filter($oldFiles);
49 | foreach($oldFiles as $file)
50 | {
51 | $cmd = sprintf('mv %s %s', $file, $file . '.old');
52 | runCommand($cmd);
53 | }
54 |
55 | $convertedFiles = explode("\n", $convertedFiles);
56 | $convertedFiles = array_filter($convertedFiles);
57 | foreach($convertedFiles as $file)
58 | {
59 | $newPhpFile = preg_replace('%.php.converted$%', '.php', $file);
60 | $cmd = sprintf('mv %s %s', $file, $newPhpFile);
61 | runCommand($cmd);
62 | }
63 |
64 | }
65 |
--------------------------------------------------------------------------------
/modules/pulsestorm/magento2/generate/remove_named_node/module.php:
--------------------------------------------------------------------------------
1 | ? [block]
16 | * @argument name The {node_name}="" value? []
17 | */
18 | function pestle_cli($argv)
19 | {
20 | $xml = simplexml_load_file($argv['path_xml']);
21 | $nodes = getByAttributeXmlBlockWithNodeNames(
22 | 'name', $xml, $argv['name'], [$argv['node_name']]);
23 |
24 | if(count($nodes) === 0)
25 | {
26 | exitWithErrorMessage("Bailing: No such node.");
27 | }
28 |
29 | if(count($nodes) > 1)
30 | {
31 | exitWithErrorMessage("Bailing: Found more than one node.");
32 | }
33 |
34 | $node = $nodes[0];
35 |
36 | if(count($node->children()) > 0)
37 | {
38 | exitWithErrorMessage("Bailing: Contains child nodes");
39 | }
40 |
41 | unset($node[0]); //http://stackoverflow.com/questions/262351/remove-a-child-with-a-specific-attribute-in-simplexml-for-php/16062633#16062633
42 |
43 | writeStringToFile(
44 | $argv['path_xml'],formatXmlString($xml->asXml())
45 | );
46 | output("Node Removed");
47 | }
48 |
--------------------------------------------------------------------------------
/modules/pulsestorm/magento2/generate/schemaaddcolumn/module.php:
--------------------------------------------------------------------------------
1 | getTable('table_name'))->addColumn
17 | * and if found, scanning to the ; and inserting the addColumn
18 | *
19 | * @command magento2:generate:schema-add-column
20 | * @argument php_file PHP file with newTable call? [skip]
21 | * @argument table Database Table? (packagename_modulename_modelnames)
22 | * @argument column Columns Name? (new_column)
23 | * @argument column_type @callback selectColumnType
24 | */
25 | function pestle_cli($argv, $options)
26 | {
27 | return exported_pestle_cli($argv, $options);
28 | }
29 |
30 | function selectColumnType($arguments, $index, $fullArguments)
31 | {
32 | if(isset($arguments[$index]))
33 | {
34 | return $arguments[$index];
35 | }
36 | $types = array_values(getColumnTypes());
37 | $value = inputFromArray("Column Type?", $types, 1);
38 | return $value;
39 | }
40 |
--------------------------------------------------------------------------------
/modules/pulsestorm/magento2/generate/ui/addformfield/module.php:
--------------------------------------------------------------------------------
1 | getName() !== 'form')
13 | {
14 | exitWithErrorMessage('ERROR: This does not look like a file.');
15 | }
16 |
17 | $fieldsets = $xml->xpath('/form/fieldset[@name="'.$argv['fieldset'].'"]');
18 | if(count($fieldsets) !== 1)
19 | {
20 | exitWithErrorMessage('ERROR: XML file should have exactly one name="'.$argv['fieldset'].'" fieldset.');
21 | }
22 |
23 | $fields = $xml->xpath('/form/fieldset/field[@name="'.$argv['field'].'"]');
24 | if(count($fields) > 0)
25 | {
26 | exitWithErrorMessage("ERROR: XML file already has a name=\"{$argv['field']}\" field.");
27 | }
28 | }
29 |
30 | function getNextSortOrderFromXml($xml)
31 | {
32 | $nodes = $xml->xpath('//item[@name="sortOrder"]');
33 | $max = array_reduce($nodes, function($carry, $item){
34 | $item = (int) $item;
35 | if($carry > $item)
36 | {
37 | return $carry;
38 | }
39 | return $item;
40 | }, 0);
41 |
42 | return $max + 10;
43 | }
44 |
45 |
46 | /**
47 | * Adds a Form Field
48 | *
49 | * @command magento2:generate:ui:add-form-field
50 | * @argument path_xml Path to Form XML File?
51 | * @argument field Field Name? [title]
52 | * @argument label Label? [Title]
53 | * @argument fieldset Fieldset Name? [general]
54 | * @option is-required Is field required?
55 | */
56 | function pestle_cli($argv, $options)
57 | {
58 | $xml = simplexml_load_file($argv['path_xml']);
59 | validateXml($xml, $argv);
60 | $fieldsets = $xml->xpath('/form/fieldset[@name="'.$argv['fieldset'].'"]');
61 | $fieldset = array_shift($fieldsets);
62 |
63 | $dataType = 'text';
64 | $formElement = 'input';
65 | $sortOrder = '25';
66 |
67 | $field = $fieldset->addChild('field');
68 | $field->addAttribute('name', $argv['field']);
69 | // addSpecificChild('field', $fieldset,);
70 | $argument = addSpecificChild('argument', $field, 'data', 'array');
71 | $itemConfig = addSpecificChild('item', $argument, 'config', 'array');
72 | $itemDataType = addSpecificChild('item', $itemConfig, 'dataType', 'string', $dataType);
73 | $itemLabel = addSpecificChild('item', $itemConfig, 'label', 'string', $argv['label']);
74 | $itemFormElement = addSpecificChild('item', $itemConfig, 'formElement', 'string', $formElement);
75 | $itemSortOrder = addSpecificChild('item', $itemConfig, 'sortOrder', 'string', getNextSortOrderFromXml($fieldset));
76 | $itemDataScope = addSpecificChild('item', $itemConfig, 'dataScope', 'string', $argv['field']);
77 |
78 | $itemValidation = addSpecificChild('item', $itemConfig, 'validation', 'array');
79 | $required = is_null($options['is-required']) ? 'false' : 'true';
80 | $itemRequiredEntry = addSpecificChild('item', $itemValidation, 'required-entry', 'boolean', $required);
81 |
82 | writeStringToFile(
83 | $argv['path_xml'],
84 | formatXmlString($xml->asXml())
85 | );
86 | }
87 |
88 |
89 |
90 |
--------------------------------------------------------------------------------
/modules/pulsestorm/magento2/generate/ui/addformfieldset/module.php:
--------------------------------------------------------------------------------
1 | getName() !== 'form')
13 | {
14 | exitWithErrorMessage('ERROR: This does not look like a file.');
15 | }
16 |
17 | $fieldsets = $xml->xpath('/form/fieldset[@name="'.$argv['fieldset'].'"]');
18 | if(count($fieldsets) !== 0)
19 | {
20 | exitWithErrorMessage('ERROR: XML file already has one name="'.$argv['fieldset'].'" fieldset.');
21 | }
22 |
23 | }
24 | /**
25 | * Add a Fieldset to a Form
26 | *
27 | * @command magento2:generate:ui:add-form-fieldset
28 | * @argument path_xml Path to Form XML File?
29 | * @argument fieldset Fieldset Name? [newfieldset]
30 | * @argument label Label? [NewFieldset]
31 | */
32 | function pestle_cli($argv)
33 | {
34 | $xml = simplexml_load_file($argv['path_xml']);
35 | validateXml($xml, $argv);
36 | $formels = $xml->xpath('/form');
37 | $formel = array_shift($formels);
38 | $fieldset = $formel->addChild('fieldset');
39 | $fieldset->addAttribute('name', $argv['fieldset']);
40 | $argument = addSpecificChild('argument', $fieldset, 'data', 'array');
41 | $itemConfig = addSpecificChild('item', $argument, 'config', 'array');
42 | $itemLabel = addSpecificChild('item', $itemConfig, 'label', 'string', $argv['label']);
43 | $itemCollaps = addSpecificChild('item', $itemConfig, 'collapsible', 'boolean', 'true');
44 |
45 | //output(formatXmlString($xml->asXml()));
46 | writeStringToFile(
47 | $argv['path_xml'],
48 | formatXmlString($xml->asXml())
49 | );
50 | }
51 |
--------------------------------------------------------------------------------
/modules/pulsestorm/nexmo/sendtext/module.php:
--------------------------------------------------------------------------------
1 | getMessage());
13 | }
14 | /**
15 | * Sends a text message
16 | *
17 | * @command nexmo:send-text
18 | * @argument to Send to phone number?
19 | * @argument from From phone number? [12155167753]
20 | * @argument text Text to send? [You are the best!]
21 | */
22 | function pestle_cli($argv)
23 | {
24 | $client = getClient();
25 | $message = false;
26 | try
27 | {
28 | $message = $client->message()->send([
29 | 'to' => $argv['to'],
30 | 'from' => $argv['from'],
31 | 'text' => $argv['text']
32 | ]);
33 | }
34 | catch(Exception $e)
35 | {
36 | handleException($e);
37 | }
38 | if($message)
39 | {
40 | output($message->getResponseData());
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/modules/pulsestorm/nexmo/storecredentials/module.php:
--------------------------------------------------------------------------------
1 | key;
12 | $secret = $data->secret;
13 | $client = new \Nexmo\Client(new \Nexmo\Client\Credentials\Basic($key, $secret));
14 | return $client;
15 | }
16 |
17 | function getCredentialFilePath()
18 | {
19 | return '/tmp/.nexmo';
20 | }
21 |
22 | function readFromCredentialFile()
23 | {
24 | $path = getCredentialFilePath();
25 | $o = false;
26 | if(file_exists(getCredentialFilePath()))
27 | {
28 | $o = json_decode(
29 | file_get_contents(
30 | $path
31 | )
32 | );
33 | }
34 | if(!$o)
35 | {
36 | $o = new stdClass;
37 | }
38 |
39 | return $o;
40 | }
41 |
42 | function writeToCredentialFile($data)
43 | {
44 | $path = getCredentialFilePath();
45 | $result = file_put_contents($path, json_encode($data));
46 | chmod($path, 0600);
47 | return $result;
48 | }
49 |
50 | /**
51 | * Stores Nexmo API in temp file
52 | *
53 | * @command nexmo:store-credentials
54 | * @argument key Key? []
55 | * @argument password Secret/Password? []
56 | */
57 | function pestle_cli($argv)
58 | {
59 | $data = readFromCredentialFile();
60 | $data->key = $argv['key'];
61 | $data->secret = $argv['password'];
62 | writeToCredentialFile($data);
63 | }
64 |
--------------------------------------------------------------------------------
/modules/pulsestorm/nexmo/verifyrequest/module.php:
--------------------------------------------------------------------------------
1 | getMessage());
13 | }
14 |
15 | function sendVerifyRequest($client, $number, $brand)
16 | {
17 | $clientVerify = $client->verify();
18 | $verification = [
19 | 'number' => $number,
20 | 'brand' => $brand
21 | ];
22 |
23 | $response = false;
24 | try
25 | {
26 | $response = $clientVerify->start($verification);
27 | }
28 | catch(Exception $e)
29 | {
30 | handleException($e);
31 | }
32 | return $response;
33 | }
34 |
35 | /**
36 | * Sends initial request to verify user's phone number
37 | *
38 | * @command nexmo:verify-request
39 | * @argument to Phone number to verify?
40 | * @argument brand Brand/Prefix string for code message? [MyApp]
41 | */
42 | function pestle_cli($argv)
43 | {
44 | $client = getClient();
45 | $verifyRequestResponse = sendVerifyRequest(
46 | $client, $argv['to'], $argv['brand']);
47 | if($verifyRequestResponse)
48 | {
49 | $json = $verifyRequestResponse->getResponseData();
50 | output($json);
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/modules/pulsestorm/nexmo/verifysendcode/module.php:
--------------------------------------------------------------------------------
1 | verify();
12 | $result = false;
13 | try
14 | {
15 | $result = $clientVerify->check(
16 | $verificationRequestId,
17 | $code
18 | );
19 | }
20 | catch(\Exception $e)
21 | {
22 | output(get_class($e));
23 | output($e->getMessage());
24 | }
25 | return $result;
26 | }
27 |
28 | /**
29 | * Nexmo Verify API: Second Step
30 | *
31 | * @command nexmo:verify-sendcode
32 | * @argument request_id Request ID? (from nexmo:verify-request) []
33 | * @argument code The four or six digit code? []
34 | */
35 | function pestle_cli($argv)
36 | {
37 | $client = getClient();
38 | $result = sendVerifyVerification($client, $argv['request_id'], $argv['code']);
39 | if($result)
40 | {
41 | output($result->getResponseData());
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/modules/pulsestorm/pestle/clear_cache/module.php:
--------------------------------------------------------------------------------
1 | token_value;
45 | $functionNameToBody[$functionName] = getFunctionFromCode($contents, $functionName);
46 | }
47 |
48 | return $functionNameToBody;
49 | }
50 |
51 | function getPestleImportsFunctionBodiesFromContents($contents)
52 | {
53 | $imports = getPestleImportsFromCode($contents);
54 | $importedFunctionsToFiles = array_combine($imports,
55 | array_map(function($function){
56 | return getPathFromFunctionName($function);
57 | }, $imports));
58 | $importedFunctionsToContents = array_map(function($file){
59 | return file_get_contents($file);
60 | }, $importedFunctionsToFiles);
61 |
62 | $functionsFromImport = [];
63 | foreach($importedFunctionsToContents as $function=>$contents)
64 | {
65 | $parts = explode('\\', $function);
66 | $functionName = array_pop($parts);
67 | $functionsFromImport[$functionName] = getFunctionFromCode($contents, $functionName);
68 | }
69 | return $functionsFromImport;
70 | }
71 |
72 | /**
73 | * Exports a Pestle Module as a Symfony Console Command
74 | *
75 | * @command pestle:export-as-symfony
76 | * @argument command_to_export Export Which Pestle Command? [hello-world]
77 | * @argument full_class_name Full Symfony Class Name [Pulsestorm\SymfonyConsole\TestCommand]
78 | */
79 | function pestle_cli($argv)
80 | {
81 | output("@TODO: replace function calls with $this->functionCall");
82 | output("@TODO: Functions from pestle import: Need to rename to avoid naming conflicts");
83 | output(" Maybe use a slashless full namespace name?");
84 | // $list = loadSerializedCommandListFromCache();
85 | $commandModule = loadSerializedCommandListFromCache()[$argv['command_to_export']];
86 | $contents = file_get_contents($commandModule);
87 |
88 | $functions = getFunctionBodiesFromCommandModueContents($contents);
89 | $functionsFromImports = getPestleImportsFunctionBodiesFromContents($contents);
90 |
91 | $classBody = getSymfonyConsoleBaseBody() .
92 | implode("\n\n", $functions) .
93 | implode("\n\n", $functionsFromImports);
94 |
95 | $class = createClassTemplateWithUse($argv['full_class_name'], 'Command');
96 | $class = str_replace('<$use$>' , getSymfonyConsoleBaseUse(), $class);
97 | $class = str_replace('<$body$>' , $classBody, $class);
98 | output($class);
99 | output("Done");
100 | }
101 |
--------------------------------------------------------------------------------
/modules/pulsestorm/pestle/run_file/module.php:
--------------------------------------------------------------------------------
1 | ',
20 | '',
21 | $xmlString);
22 | return $xml;
23 | }
24 |
25 | function getXmlNamespaceFromPrefix($xml, $prefix)
26 | {
27 | $namespaces = $xml->getDocNamespaces();
28 | if(array_key_exists($prefix, $namespaces))
29 | {
30 | return $namespaces[$prefix];
31 | }
32 |
33 | throw new Exception("Unkonwn namespace in " . __FILE__);
34 | }
35 |
36 | function simpleXmlAddNodesXpathReturnOriginal($xml, $path)
37 | {
38 | $result = simpleXmlAddNodesXpathWorker($xml, $path);
39 | return $result['original'];
40 | }
41 |
42 | function simpleXmlAddNodesXpath($xml, $path)
43 | {
44 | $result = simpleXmlAddNodesXpathWorker($xml, $path);
45 | return $result['child'];
46 | }
47 |
48 | function simpleXmlAddNodesXpathWorker($xml, $path)
49 | {
50 | $path = trim($path,'/');
51 | $node = $xml;
52 | foreach(explode('/',$path) as $part)
53 | {
54 | $parts = explode('[', $part);
55 | $node_name = array_shift($parts);
56 | $is_new_node = true;
57 | if(isset($node->{$node_name}))
58 | {
59 | $is_new_node = false;
60 | $node = $node->{$node_name};
61 | }
62 | else
63 | {
64 | $node = $node->addChild($node_name);
65 | }
66 |
67 |
68 | $attribute_string = trim(array_pop($parts),']');
69 | if(!$attribute_string) { continue; }
70 | $pairs = explode(',',$attribute_string);
71 | foreach($pairs as $pair)
72 | {
73 | if(!$is_new_node) { continue; }
74 | list($key,$value) = explode('=',$pair);
75 | if(strpos($key, '@') !== 0)
76 | {
77 | throw new Exception("Invalid Attribute Key");
78 | }
79 | $key = trim($key, '@');
80 | if(strpos($key, ':') !== false)
81 | {
82 | list($namespace_prefix, $rest) = explode(':', $key);
83 | $namespace = getXmlNamespaceFromPrefix($xml, $namespace_prefix);
84 | $node->addAttribute($key, $value, $namespace);
85 | }
86 | else
87 | {
88 | $node->addAttribute($key, $value);
89 | }
90 |
91 | }
92 | // exit;
93 | }
94 |
95 | return [
96 | 'original'=>$xml,
97 | 'child'=>$node
98 | ];
99 | }
100 |
101 | function getByAttributeXmlBlockWithNodeNames($attributeName, $xml, $value, $names=null)
102 | {
103 | $search = '//*[@'.$attributeName.'="' . $value . '"]';
104 | $nodes = $xml->xpath($search);
105 | $nodes = array_filter($nodes, function($node) use ($names){
106 | if(!$names) { return true; }
107 | return in_array($node->getName(), $names);
108 | });
109 | return $nodes;
110 | }
111 |
112 | function getNamedXmlBlockWithNodeNames($xml, $name, $names)
113 | {
114 | return getByAttributeXmlBlockWithNodeNames('name', $xml, $name, $names);
115 | }
116 |
117 | function formatXmlString($string)
118 | {
119 | $dom = new DomDocument;
120 | $dom->preserveWhiteSpace = false;
121 | $dom->formatOutput = true;
122 | $dom->loadXml($string);
123 | $string = $dom->saveXml();
124 |
125 | $string = preg_replace('%(^\s*)%m', '$1$1', $string);
126 |
127 | return $string;
128 | }
--------------------------------------------------------------------------------
/pestle_dev:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env php
2 | result = $this->runCommand();
24 | }
25 |
26 | /**
27 | * Check module declaration file exists.
28 | *
29 | * @test
30 | */
31 | // public function xtestModuleFileExists()
32 | // {
33 | // $result = file_exists(__DIR__.'/../app/code/Pulsestore/Testbed/etc/module.xml');
34 | // $this->assertTrue($result);
35 | // }
36 | //
37 | // /**
38 | // * Check module registration file exists.
39 | // *
40 | // * @test
41 | // */
42 | // public function xtestRegistrationFileExists()
43 | // {
44 | // $result = file_exists(__DIR__.'/../app/code/Pulsestore/Testbed/registration.php');
45 | // $this->assertTrue($result);
46 | // }
47 | }
48 |
--------------------------------------------------------------------------------
/tests-integration/GenerateRouteTest.php:
--------------------------------------------------------------------------------
1 | runCommand(self::COMMAND);
24 | // $this->result = $this->runCommand();
25 | }
26 |
27 | /**
28 | * Check routes declaration file exists.
29 | *
30 | * @test
31 | */
32 | // public function xtestRoutesFileExists()
33 | // {
34 | // $result = file_exists(__DIR__.'/../app/code/Pulsestorm/HelloWorld/etc/frontend/routes.xml');
35 | // $this->assertTrue($result);
36 | // }
37 | //
38 | // /**
39 | // * Check module registration file exists.
40 | // *
41 | // * @test
42 | // */
43 | // public function xtestControllerFileExists()
44 | // {
45 | // $result = file_exists(__DIR__.'/../app/code/Pulsestorm/HelloWorld/Controller/Index/Index.php');
46 | // $this->assertTrue($result);
47 | // }
48 | }
49 |
--------------------------------------------------------------------------------
/tests-integration/HelloWorldTest.php:
--------------------------------------------------------------------------------
1 | runCommand());
15 | $this->assertEquals($results, 'Hello Sailor');
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/tests-integration/PestleTestIntegration.php:
--------------------------------------------------------------------------------
1 | createFakeMagentoInstance();
34 | $this->removeApp = true;
35 | }
36 | }
37 |
38 | /**
39 | * Tear down the integration tests.
40 | */
41 | protected function tearDown()
42 | {
43 | parent::tearDown();
44 |
45 | if ($this->removeApp) {
46 | $this->deleteDirectoryTree('app');
47 | }
48 | }
49 |
50 | /**
51 | * Create `app/etc/di.xml` so pestle.phar can work.
52 | *
53 | * @return $this
54 | */
55 | protected function createFakeMagentoInstance()
56 | {
57 | mkdir('app');
58 | mkdir('app/etc');
59 | touch('app/etc/di.xml');
60 |
61 | return $this;
62 | }
63 |
64 | /**
65 | * Delete a directory tree: http://php.net/manual/en/function.rmdir.php
66 | *
67 | * @param $directory
68 | *
69 | * @return bool
70 | */
71 | protected function deleteDirectoryTree($directory) {
72 | $files = array_diff(scandir($directory), array('.','..'));
73 | foreach ($files as $file) {
74 | (is_dir("$directory/$file")) ? $this->deleteDirectoryTree("$directory/$file") : unlink("$directory/$file");
75 | }
76 |
77 | return rmdir($directory);
78 | }
79 |
80 | /**
81 | * Check the pestle command is available in the current environment.
82 | *
83 | * @test
84 | */
85 | public function testPestleIsAvailable()
86 | {
87 | $this->assertNotFalse($this->getPestlePackage());
88 | }
89 |
90 | /**
91 | * Check the di.xml exists, if it does not then something is
92 | * wrong with the install.
93 | *
94 | * @test
95 | */
96 | public function testDiXmlExists()
97 | {
98 | $this->assertFileExists('app/etc/di.xml');
99 | }
100 |
101 | /**
102 | * Run a command from users pestle implementation.
103 | *
104 | * @param $cmd
105 | *
106 | * @return mixed
107 | */
108 | protected function runCommand($cmd = false)
109 | {
110 | if (!$cmd) {
111 | $cmd = static::COMMAND;
112 | }
113 |
114 | $pestle = $this->getPestlePackage();
115 | return `$pestle $cmd`;
116 | }
117 |
118 | /**
119 | * Check if a package is available.
120 | *
121 | * @param $package
122 | *
123 | * @return bool
124 | */
125 | protected function isPackageAvailable($package) {
126 | return (empty(`which $package`) ? false : true);
127 | }
128 |
129 | /**
130 | * Get the correct pestle package name from the users system.
131 | *
132 | * @return string|bool
133 | */
134 | protected function getPestlePackage()
135 | {
136 | if(!$this->packageName === null) {
137 | return $this->packageName;
138 | }
139 |
140 | $this->packageName = false;
141 |
142 | foreach($this->packageNames as $packageName) {
143 | if ($this->isPackageAvailable($packageName)) {
144 | $this->packageName = $packageName;
145 | break;
146 | }
147 | }
148 |
149 | return $this->packageName;
150 | }
151 | }
152 |
--------------------------------------------------------------------------------
/tests/AdminClassNameTest.php:
--------------------------------------------------------------------------------
1 | assertEquals(-1, -1);
12 | }
13 |
14 | public function testBaseFrontendArgs()
15 | {
16 | $controllerClass = createControllerClass(
17 | 'Pulsestorm\HelloWorld\Controller\Index\Index',
18 | 'frontend',
19 | 'some-acl-rule-name');
20 | $fixture = $this->loadFixture(__METHOD__);
21 | $this->assertEquals($fixture, $controllerClass);
22 | // echo $controllerClass;
23 | }
24 |
25 | public function testBaseAdminArgs()
26 | {
27 | $controllerClass = createControllerClass(
28 | 'Pulsestorm\HelloWorld\Controller\Adminhtml\Index\Index',
29 | 'adminhtml',
30 | 'some-acl-rule-name');
31 | $fixture = $this->loadFixture(__METHOD__);
32 | $this->assertEquals($fixture, $controllerClass);
33 | // echo $controllerClass;
34 | }
35 |
36 | protected function loadFixture($method)
37 | {
38 | return file_get_contents(__DIR__ . '/fixtures/AdminClassName/' .
39 | preg_replace('%^.*?::test%','',$method) . '.php' );
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/tests/AppCodeRefactorTest.php:
--------------------------------------------------------------------------------
1 | assertEquals(-1, -1);
34 | }
35 |
36 | public function testGetModulePathInFullModuleGeneration() {
37 | $result = getRelativeModulePath('Foo', 'Bar', self::PATH_FAKE_BASE);
38 | $this->assertEquals('app/code/Foo/Bar', $result);
39 | }
40 |
41 | public function testGetFullModulePath() {
42 | $result = getFullModulePath('Foo', 'Bar', self::PATH_FAKE_BASE);
43 | $this->assertEquals('/fake/base/app/code/Foo/Bar', $result);
44 | }
45 |
46 | public function testGetModuleBaseDir() {
47 | $result = getModuleBaseDir('Foo_Bar', self::PATH_FAKE_BASE);
48 | $this->assertEquals('/fake/base/app/code/Foo/Bar', $result);
49 | // $this->assertEquals('/fake/base/app/code/Foo/Bar', $result);
50 | }
51 |
52 | public function testCreateClassFilePath() {
53 | $result = createClassFilePath('Foo\Bar\Baz\Bap', self::PATH_FAKE_BASE);
54 | $this->assertEquals('/fake/base/app/code/Foo/Bar/Baz/Bap.php', $result);
55 | }
56 |
57 | public function testGetPathFromClass() {
58 | $result = getPathFromClass('Foo\Bar\Baz\Bap', self::PATH_FAKE_BASE);
59 | $this->assertEquals('/fake/base/app/code/Foo/Bar/Baz/Bap.php', $result);
60 | }
61 |
62 | public function testGetAppCode() {
63 | // should always return app/code, since that's the function's
64 | // name. When we get to creating stuff in someone's folder
65 | // we'll want to use a different function. This test holds
66 | // us to that.
67 | $this->assertEquals('app/code', getAppCodePath());
68 | }
69 |
70 | public function testGetBaseMagentoDirFromFile() {
71 | $path1 = self::PATH_FAKE_BASE . '/app/code/Foo/Bar/Model/Thing.php';
72 | $path2 = self::PATH_FAKE_BASE . '/vendor/some-vendor/some-module/src/Foo/Bar/Model/Thing.php';
73 |
74 | $result1 = getBaseMagentoDirFromFile($path1, true);
75 | $result2 = getBaseMagentoDirFromFile($path2, true);
76 |
77 | $this->assertEquals(self::PATH_FAKE_BASE . '/app/code', $result1);
78 | $this->assertEquals(self::PATH_FAKE_BASE . '/vendor', $result2);
79 | }
80 |
81 | public function testGetModuleDir() {
82 | $result = getModuleDir(self::PATH_FAKE_BASE, 'Foo', 'Bar');
83 | $this->assertEquals('/fake/base/app/code/Foo/Bar', $result);
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/tests/ClassParsingTest.php:
--------------------------------------------------------------------------------
1 | assertEquals($information['full-class'], 'Foo\Bar\Baz\Test');
20 | $this->assertEquals($information['full-extends'], 'Science\Fair');
21 | }
22 |
23 | public function testTwo()
24 | {
25 | $information = extractClassInformationFromClassContents('<' . '?php' . "\n" .'
26 | namespace Foo\Bar;
27 |
28 | use Baz\Bing\Boo;
29 | use Baz\Bing\Magic;
30 | class Test extends Boo{
31 | }');
32 | $this->assertEquals($information['full-class'], 'Foo\Bar\Test');
33 | $this->assertEquals($information['full-extends'], 'Baz\Bing\Boo');
34 | }
35 |
36 | public function testThree()
37 | {
38 | $information = extractClassInformationFromClassContents('<' . '?php' . "\n" .'
39 | namespace Foo\Bar;
40 |
41 | use Baz\Bing\Boo;
42 | use Baz\Bing\Magic;
43 | class Test extends Bar\Fee{
44 | }');
45 | $this->assertEquals($information['full-class'], 'Foo\Bar\Test');
46 | $this->assertEquals($information['full-extends'], 'Foo\Bar\Fee');
47 | }
48 |
49 | public function testFour()
50 | {
51 | $information = extractClassInformationFromClassContents('<' . '?php' . "\n" .'
52 | namespace Foo\Bar;
53 |
54 | use Baz\Bing\Boo;
55 | use Baz\Bing\Magic;
56 |
57 | class Test extends Magic\Fi{
58 | }');
59 | $this->assertEquals($information['full-class'], 'Foo\Bar\Test');
60 | $this->assertEquals($information['full-extends'], 'Baz\Bing\Magic\Fi');
61 | }
62 |
63 | }
--------------------------------------------------------------------------------
/tests/ComposerPackageTest.php:
--------------------------------------------------------------------------------
1 | getPathToModuleFileUnderTest(
13 | // 'modules/pulsestorm/magento2/cli/library/module.php');
14 | // require_once $path;
15 | // }
16 |
17 | public function testSetup()
18 | {
19 | $this->assertEquals(-1, -1);
20 | }
21 |
22 | public function testConfigLoading()
23 | {
24 | $path = getPathConfig();
25 | $this->assertTrue(is_string($path));
26 | $this->assertTrue(is_dir($path));
27 |
28 | $path = getPathConfig('test');
29 | $parts = explode('/', $path);
30 |
31 | $testDotJson = array_pop($parts);
32 | $dotPestle = array_pop($parts);
33 |
34 | $this->assertEquals('test.json', $testDotJson);
35 | $this->assertEquals('.pestle', $dotPestle);
36 |
37 | $object = loadConfig('test');
38 | $this->assertTrue(is_object($object));
39 | }
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/tests/ConfigTest.php:
--------------------------------------------------------------------------------
1 | baseDirName = '/tmp/' . uniqid();
26 | }
27 |
28 | public function testStorage() {
29 | $this->assertEquals('file', storageMethod());
30 | }
31 |
32 | public function testStorageSetMemory() {
33 | storageMethod('memory');
34 | $this->assertEquals('memory', storageMethod());
35 | $this->configTests();
36 | }
37 |
38 | public function testStorageSetFile() {
39 | storageMethod('file');
40 | $this->assertEquals('file', storageMethod());
41 | getOrSetConfigBase($this->baseDirName);
42 | $this->assertEquals($this->baseDirName, getOrSetConfigBase());
43 | $this->configTests();
44 | }
45 |
46 | private function configTests() {
47 | $type = 'some-config';
48 |
49 | // loadng a blank config returns a stdClass
50 | $config = loadConfig($type);
51 | $this->assertTrue(is_object($config));
52 | $this->assertEquals([], get_object_vars($config));
53 |
54 | $config->Pulsestorm_Science = '/foo/baz/bar';
55 | saveConfig($type, $config);
56 |
57 | $config = loadConfig($type);
58 | $this->assertEquals('/foo/baz/bar', $config->Pulsestorm_Science);
59 | }
60 |
61 | }
62 |
--------------------------------------------------------------------------------
/tests/DoubleImportTest.php:
--------------------------------------------------------------------------------
1 | assertEquals($string,'Hello' . "\n");
19 | }
20 |
21 | public function testSecondOutput()
22 | {
23 | pestle_import('Pulsestorm\Magento2\Cli\Test_Output\output');
24 | ob_start();
25 | output("Hello");
26 | $string = ob_get_clean();
27 | $this->assertEquals($string,'I am hard coded and here for a test.');
28 | }
29 |
30 | public function testBothAtOne()
31 | {
32 | pestle_import('Pulsestorm\Pestle\Library\output');
33 | ob_start();
34 | output("Hello");
35 | $string = ob_get_clean();
36 | $this->assertEquals($string,'Hello' . "\n");
37 |
38 | pestle_import('Pulsestorm\Magento2\Cli\Test_Output\output');
39 | ob_start();
40 | output("Hello");
41 | $string = ob_get_clean();
42 | $this->assertEquals($string,'I am hard coded and here for a test.');
43 | }
44 |
45 | }
--------------------------------------------------------------------------------
/tests/FirstTest.php:
--------------------------------------------------------------------------------
1 | assertEquals(-1, -1);
10 | }
11 | }
--------------------------------------------------------------------------------
/tests/GenerateInstallSchemaTest.php:
--------------------------------------------------------------------------------
1 | assertTrue(is_string($result));
12 | }
13 |
14 | public function testGenerateBlank()
15 | {
16 | $result = generateInstallSchemaTable(
17 | 'unit_test', 'ModelTest', [], 'A testing table'
18 | );
19 | $fixture = ' $table = $installer->getConnection()->newTable(
20 | $installer->getTable(\'unit_test\')
21 | )->addColumn(
22 | \'modeltest_id\',
23 | \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
24 | null,
25 | [ \'identity\' => true, \'nullable\' => false, \'primary\' => true, \'unsigned\' => true ],
26 | \'Entity ID\'
27 | )->addColumn(
28 | \'title\',
29 | \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
30 | 255,
31 | [ \'nullable\' => false ],
32 | \'Demo Title\'
33 | )->addColumn(
34 | \'creation_time\',
35 | \Magento\Framework\DB\Ddl\Table::TYPE_TIMESTAMP,
36 | null,
37 | [ \'nullable\' => false, \'default\' => \Magento\Framework\DB\Ddl\Table::TIMESTAMP_INIT ],
38 | \'Creation Time\'
39 | )->addColumn(
40 | \'update_time\',
41 | \Magento\Framework\DB\Ddl\Table::TYPE_TIMESTAMP,
42 | null,
43 | [ \'nullable\' => false, \'default\' => \Magento\Framework\DB\Ddl\Table::TIMESTAMP_INIT_UPDATE ],
44 | \'Modification Time\'
45 | )->addColumn(
46 | \'is_active\',
47 | \Magento\Framework\DB\Ddl\Table::TYPE_SMALLINT,
48 | null,
49 | [ \'nullable\' => false, \'default\' => \'1\' ],
50 | \'Is Active\'
51 | )->setComment(
52 | \'A testing table\'
53 | );
54 | $installer->getConnection()->createTable($table);';
55 | $this->assertEquals(
56 | $result,
57 | $fixture
58 | );
59 | }
60 | }
--------------------------------------------------------------------------------
/tests/GenerateMage2CommandTest.php:
--------------------------------------------------------------------------------
1 | assertEquals('Pulsestorm\Magento2\Cli\Science', $path);
15 | }
16 |
17 | public function testNamespaceGenerate2()
18 | {
19 | $path = createNamespaceFromNamespaceAndCommandName('Pulsestorm\Magento2\Cli','generate_science');
20 | $this->assertEquals('Pulsestorm\Magento2\Cli\Generate\Science', $path);
21 | }
22 |
23 | public function testNamespaceGenerate3()
24 | {
25 | $path = createNamespaceFromNamespaceAndCommandName('Pulsestorm\Magento2\Cli','foo_science');
26 | $this->assertEquals('Pulsestorm\Magento2\Cli\Foo_Science', $path);
27 | }
28 | }
--------------------------------------------------------------------------------
/tests/GenerateRouteTest.php:
--------------------------------------------------------------------------------
1 | assertEquals(
14 | $class,
15 | 'Pulsestorm\Hellotest\Controller\Index\Index'
16 | );
17 | }
18 |
19 | public function testFrontendWithArg()
20 | {
21 | $module = 'Pulsestorm_Hellotest';
22 | $area = 'frontend';
23 | $class = createControllerClassName($module, $area);
24 | $this->assertEquals(
25 | $class,
26 | 'Pulsestorm\Hellotest\Controller\Index\Index'
27 | );
28 | }
29 |
30 | public function testAdminhtmlWithArg()
31 | {
32 | $module = 'Pulsestorm_Hellotest';
33 | $area = 'adminhtml';
34 | $class = createControllerClassName($module, $area);
35 | $this->assertEquals(
36 | $class,
37 | 'Pulsestorm\Hellotest\Controller\Adminhtml\Index\Index'
38 | );
39 | }
40 |
41 | public function testGetRouterIdFromAreaFrontend()
42 | {
43 | $this->assertEquals('standard', getRouterIdFromArea('frontend'));
44 | }
45 |
46 | public function testGetRouterIdFromAreaAdminhtml()
47 | {
48 | $this->assertEquals('admin', getRouterIdFromArea('adminhtml'));
49 | }
50 |
51 | }
--------------------------------------------------------------------------------
/tests/GenerateWithColonTest.php:
--------------------------------------------------------------------------------
1 | assertEquals('Foo\Baz\Bar\Test', $value);
14 | }
15 |
16 | public function testBaseline2()
17 | {
18 | //createNamespaceFromNamespaceAndCommandName($namespace_module, $command_name)
19 | $value = createNamespaceFromNamespaceAndCommandName('Foo\Baz\Bar', 'test_command');
20 | $this->assertEquals('Foo\Baz\Bar\Test_Command', $value);
21 | }
22 |
23 | public function testBaseline3()
24 | {
25 | //createNamespaceFromNamespaceAndCommandName($namespace_module, $command_name)
26 | $value = createNamespaceFromNamespaceAndCommandName('Foo\Baz\Bar', 'generate_test_command_thing');
27 | $this->assertEquals('Foo\Baz\Bar\Generate\Test\Command\Thing', $value);
28 | }
29 |
30 | // public function testCommandWithColon()
31 | // {
32 | // //createNamespaceFromNamespaceAndCommandName($namespace_module, $command_name)
33 | // $value = createNamespaceFromNamespaceAndCommandName('Foo\Baz\Bar', 'test:command');
34 | // $this->assertEquals('Foo\Baz\Bar\Test\Command', $value);
35 | // }
36 | }
--------------------------------------------------------------------------------
/tests/LibraryTest.php:
--------------------------------------------------------------------------------
1 | getPathToModuleFileUnderTest(
13 | 'modules/pulsestorm/magento2/cli/library/module.php');
14 | require_once $path;
15 | }
16 |
17 | public function testSetup()
18 | {
19 | $this->assertEquals(-1, -1);
20 | }
21 |
22 | public function testCreateClassTemplate()
23 | {
24 | $fixture = '<' . '?php
25 | namespace ;
26 |
27 | /**
28 | * Class Foo
29 | */
30 | class Foo
31 | {<$body$>}' . "\n";
32 |
33 | $template = createClassTemplate('Foo');
34 | $this->assertEquals($template, $fixture);
35 | }
36 |
37 | public function testIsAboveRoot1()
38 | {
39 | $path = '/foo/baz/bar/../../../../';
40 | $this->assertTrue(isAboveRoot($path));
41 | }
42 |
43 | public function testIsAboveRoot2()
44 | {
45 | $path = '/foo/baz/bar/../../../..';
46 | $this->assertTrue(isAboveRoot($path));
47 | }
48 |
49 | public function testIsAboveRoot3()
50 | {
51 | $path = '/foo/baz/bar/../../..';
52 | $this->assertTrue(!isAboveRoot($path));
53 | }
54 |
55 | public function testIsAboveRoot4()
56 | {
57 | $path = '/foo/baz/bar/../..';
58 | $this->assertTrue(!isAboveRoot($path));
59 | }
60 | }
--------------------------------------------------------------------------------
/tests/NamespaceRefactoringTest.php:
--------------------------------------------------------------------------------
1 | assertEquals(trim($results), "Hello");
20 | }
21 |
22 | public function testsFunctionExists()
23 | {
24 | $this->assertTrue(function_exists('glob_recursive'));
25 | }
26 |
27 | // public function testNamespaceCalledFrom()
28 | // {
29 | // $namespace = getNamespaceCalledFrom();
30 | // $this->assertEquals($namespace, __NAMESPACE__);
31 | // }
32 | //
33 | // public function testNamespaceCalledFromFunction()
34 | // {
35 | // $namespace = cleverHackToTestReflectionFunction();
36 | // $this->assertEquals($namespace, __NAMESPACE__);
37 | // }
38 | }
39 |
40 | function cleverHackToTestReflectionFunction()
41 | {
42 | return getNamespaceCalledFrom();
43 | }
44 |
45 | /**
46 | * @command library
47 | */
48 | function pestle_cli()
49 | {
50 | }
--------------------------------------------------------------------------------
/tests/PestleBaseTest.php:
--------------------------------------------------------------------------------
1 | assertTrue(true);
25 | }
26 |
27 | protected function getPathToModuleFileUnderTest($file)
28 | {
29 | return __DIR__ . '/../' . $file;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/tests/PhpCollideTest.php:
--------------------------------------------------------------------------------
1 | assertTrue($function_exists);
12 | //undoing magic conversion of php global
13 | //functions for the time being.
14 | $this->assertTrue(true);
15 | }
16 | }
--------------------------------------------------------------------------------
/tests/RunnerTestHarnessTest.php:
--------------------------------------------------------------------------------
1 | runCommand('hello_world'));
9 | $this->assertEquals('Hello Sailor', $results);
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/tests/SimpleXmlAddNodesXpathTest.php:
--------------------------------------------------------------------------------
1 | assertEquals(-1, -1);
13 | }
14 |
15 | public function testBaseline()
16 | {
17 | $xml = simplexml_load_string('');
18 | $node = simpleXmlAddNodesXpath($xml, 'foo/bar[@baz=hello]/science');
19 |
20 | $this->assertTrue(
21 | strpos(
22 | $xml->asXml(),
23 | ''
24 | ) !== false
25 | );
26 |
27 | $this->assertEquals($node->getName(), 'science');
28 | }
29 |
30 | public function testSimpleXmlAddNodesXpathReturnOriginal()
31 | {
32 | $xml = simplexml_load_string('');
33 | $node = simpleXmlAddNodesXpathReturnOriginal($xml, 'foo/bar[@baz=hello]/science');
34 |
35 | $this->assertTrue(
36 | strpos(
37 | $xml->asXml(),
38 | ''
39 | ) !== false
40 | );
41 |
42 | $this->assertEquals($node->getName(), 'root');
43 | }
44 | }
--------------------------------------------------------------------------------
/tests/WindowsTest.php:
--------------------------------------------------------------------------------
1 | assertTrue(is_dir($dir));
12 | }
13 |
14 | public function testGetExecutableFromPath() {
15 | $unix = pestleGetExecutableFromPath('/foo/baz/bar');
16 | $windows = pestleGetExecutableFromPath('\sing\a\song');
17 |
18 | $this->assertEquals($unix, 'bar');
19 | $this->assertEquals($windows, 'song');
20 | }
21 |
22 | }
23 |
--------------------------------------------------------------------------------
/tests/fixtures/AdminClassName/BaseAdminArgs.php:
--------------------------------------------------------------------------------
1 | resultPageFactory = $resultPageFactory;
14 | parent::__construct($context);
15 | }
16 |
17 | public function execute()
18 | {
19 | return $this->resultPageFactory->create();
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/tests/fixtures/AdminClassName/BaseFrontendArgs.php:
--------------------------------------------------------------------------------
1 | resultPageFactory = $resultPageFactory;
12 | parent::__construct($context);
13 | }
14 |
15 | public function execute()
16 | {
17 | return $this->resultPageFactory->create();
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/tests/fixtures/FunctionNameParsing/ConfirmableTrait.php:
--------------------------------------------------------------------------------
1 | getDefaultConfirmCallback() : $callback;
31 |
32 | $shouldConfirm = $callback instanceof Closure ? call_user_func($callback) : $callback;
33 |
34 | if ($shouldConfirm) {
35 | if ($this->option('force')) {
36 | return true;
37 | }
38 |
39 | $this->alert($warning);
40 |
41 | $confirmed = $this->confirm('Do you really wish to run this command?');
42 |
43 | if (! $confirmed) {
44 | $this->comment('Command Cancelled!');
45 |
46 | return false;
47 | }
48 | }
49 |
50 | return true;
51 | }
52 |
53 | /**
54 | * Get the default confirmation callback.
55 | *
56 | * @return \Closure
57 | */
58 | protected function getDefaultConfirmCallback()
59 | {
60 | return function () {
61 | return $this->getLaravel()->environment() == 'production';
62 | };
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/tests/fixtures/FunctionNameParsing/DetectsApplicationNamespace.php:
--------------------------------------------------------------------------------
1 | getNamespace();
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/tests/fixtures/FunctionNameParsing/OutputStyle.php:
--------------------------------------------------------------------------------
1 | output = $output;
38 |
39 | parent::__construct($input, $output);
40 | }
41 |
42 | /**
43 | * Returns whether verbosity is quiet (-q).
44 | *
45 | * @return bool
46 | */
47 | public function isQuiet()
48 | {
49 | return $this->output->isQuiet();
50 | }
51 |
52 | /**
53 | * Returns whether verbosity is verbose (-v).
54 | *
55 | * @return bool
56 | */
57 | public function isVerbose()
58 | {
59 | return $this->output->isVerbose();
60 | }
61 |
62 | /**
63 | * Returns whether verbosity is very verbose (-vv).
64 | *
65 | * @return bool
66 | */
67 | public function isVeryVerbose()
68 | {
69 | return $this->output->isVeryVerbose();
70 | }
71 |
72 | /**
73 | * Returns whether verbosity is debug (-vvv).
74 | *
75 | * @return bool
76 | */
77 | public function isDebug()
78 | {
79 | return $this->output->isDebug();
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/travis/for-lint.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | ## Our travis CI/CD will run this script from the root of a Magento
4 | ## folder. Put pestle commands here to generate code in the
5 | ## Pulsestorm_Travis module. At the end of the CI we'll run phpcs
6 | ## against this folder to ensure generate code
7 |
8 |
9 | ## putting some basic files in place so we can merge and tackle
10 | ## the "phpcs-ification" of things in stages
11 | mkdir -p app/code/Pulsestorm/Travis
12 | printf " app/code/Pulsestorm/Travis/Test.php
13 |
14 | ## test generate:crud-model, rm InstallSchema backup file
15 | pestle.phar magento2:generate:crud-model Pulsestorm_Travis Thing
16 | find app/code/Pulsestorm/Travis -type f -name '*.bak*' -exec rm '{}' \;
--------------------------------------------------------------------------------
/travis/travis-ci-apache:
--------------------------------------------------------------------------------
1 |
2 | # [...]
3 |
4 |
5 | Options FollowSymLinks MultiViews ExecCGI
6 | AllowOverride All
7 | Order deny,allow
8 | Allow from all
9 | Require all granted
10 |
11 |
12 | # Wire up Apache to use Travis CI's php-fpm.
13 |
14 |
15 | Require all granted
16 |
17 | AddHandler php5-fcgi .php
18 | Action php5-fcgi /php5-fcgi
19 | Alias /php5-fcgi /usr/lib/cgi-bin/php5-fcgi
20 | FastCgiExternalServer /usr/lib/cgi-bin/php5-fcgi -host 127.0.0.1:9000 -pass-header Authorization
21 |
22 |
23 | ServerName magento-2-travis.dev
24 | ServerAlias www.magento-2-travis.dev
25 | DocumentRoot %TRAVIS_BUILD_DIR%/magento2/pub
26 |
27 |
28 | # [...]
29 |
--------------------------------------------------------------------------------